Skip to content

Commit

Permalink
http support
Browse files Browse the repository at this point in the history
  • Loading branch information
pjfanning committed Dec 26, 2023
1 parent 6bbb8ce commit 0d42f2b
Show file tree
Hide file tree
Showing 7 changed files with 246 additions and 108 deletions.
9 changes: 9 additions & 0 deletions NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
sbt-pekko-build
Copyright 2022, 2023 Contributors

This product includes software developed at
The Apache Software Foundation (https://www.apache.org/).

This product contains significant parts that were originally based on software from Lightbend (Akka <https://akka.io/>).
This code was distributed under the Apache License, Version 2.0 License.
Copyright (C) 2009-2022 Lightbend Inc. <https://www.lightbend.com>
25 changes: 25 additions & 0 deletions src/main/scala/com/github/pjfanning/pekkobuild/Dependency.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.github.pjfanning.pekkobuild

import sbt.VersionNumber

sealed trait Dependency {
def version: String
// The version to use in api/japi/docs links,
// so 'x.y', 'x.y.z', 'current' or 'snapshot'
def link: String
}

case class Artifact(version: String, isSnapshot: Boolean) extends Dependency {
override def link: String =
VersionNumber(version) match { case VersionNumber(Seq(x, y, _*), _, _) => s"$x.$y" }
}

object Artifact {
def apply(version: String): Artifact = {
val isSnap = version.endsWith("-SNAPSHOT")
new Artifact(version, isSnap)
}
}
case class Sources(uri: String, link: String = "current") extends Dependency {
def version: String = link
}
113 changes: 5 additions & 108 deletions src/main/scala/com/github/pjfanning/pekkobuild/PekkoDependency.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,10 @@

package com.github.pjfanning.pekkobuild

import sbt._
import sbt.Keys._
object PekkoDependency extends VersionRegex {
override val checkProject: String = "pekko-cluster-sharding-typed"

import scala.util.matching.Regex.Groups

object PekkoDependency {

sealed trait Pekko {
def version: String
// The version to use in api/japi/docs links,
// so 'x.y', 'x.y.z', 'current' or 'snapshot'
def link: String
}
case class Artifact(version: String, isSnapshot: Boolean) extends Pekko {
override def link = VersionNumber(version) match { case VersionNumber(Seq(x, y, _*), _, _) => s"$x.$y" }
}
object Artifact {
def apply(version: String): Artifact = {
val isSnap = version.endsWith("-SNAPSHOT")
new Artifact(version, isSnap)
}
}
case class Sources(uri: String, link: String = "current") extends Pekko {
def version = link
}

def pekkoDependency(defaultVersion: String): Pekko =
def pekkoDependency(defaultVersion: String): Dependency =
Option(System.getProperty("pekko.sources")) match {
case Some(pekkoSources) =>
Sources(pekkoSources)
Expand All @@ -54,7 +31,8 @@ object PekkoDependency {
}

private val defaultPekkoVersion = System.getProperty("pekko.build.pekko.min.version", "1.0.2")
val default = pekkoDependency(defaultPekkoVersion)
val minPekkoVersion: String = "1.0.0"
val default: Dependency = pekkoDependency(defaultPekkoVersion)

lazy val snapshot10x = Artifact(determineLatestSnapshot("1.0"), true)
lazy val snapshotMain = Artifact(determineLatestSnapshot(), true)
Expand All @@ -70,85 +48,4 @@ object PekkoDependency {
case Artifact(version, _) => version
case Sources(uri, _) => uri
}

implicit class RichProject(project: Project) {

/** Adds either a source or a binary dependency, depending on whether the above settings are set */
def addPekkoModuleDependency(module: String, config: String = "", pekko: Pekko = default): Project =
pekko match {
case Sources(sources, _) =>
val moduleRef = ProjectRef(uri(sources), module)
val withConfig: ClasspathDependency =
if (config == "") moduleRef
else moduleRef % config

project.dependsOn(withConfig)
case Artifact(pekkoVersion, pekkoSnapshot) =>
project.settings(
libraryDependencies += {
if (config == "")
"org.apache.pekko" %% module % pekkoVersion
else
"org.apache.pekko" %% module % pekkoVersion % config
},
resolvers ++= (if (pekkoSnapshot)
Seq(Resolver.ApacheMavenSnapshotsRepo)
else Nil)
)
}
}

private def determineLatestSnapshot(prefix: String = ""): String = determineLatestVersion(true, prefix)

private def determineLatestRelease(prefix: String = ""): String = determineLatestVersion(false, prefix)

private def determineLatestVersion(useSnapshots: Boolean, prefix: String): String = {
import sbt.librarymanagement.Http.http
import gigahorse.GigahorseSupport.url
import scala.concurrent.Await
import scala.concurrent.duration._

val regex =
if (useSnapshots) """href=".*/((\d+)\.(\d+)\.(\d+)(-(M|RC)(\d+))?\+(\d+)-[0-9a-f]+-SNAPSHOT)/""""
else """>.*((\d+)\.(\d+)\.(\d+)(-(M|RC)(\d+))?)/<"""
val versionR = regex.r
val repo = if (useSnapshots) Resolver.ApacheMavenSnapshotsRepo.root else Resolver.DefaultMavenRepositoryRoot

// pekko-cluster-sharding-typed_2.13 seems to be the last nightly published by `pekko-publish-nightly` so if that's there then it's likely the rest also made it
val body = Await
.result(
http.run(url(s"${repo}org/apache/pekko/pekko-cluster-sharding-typed_2.13/")),
10.seconds
)
.bodyAsString

// we use tagNumber set as Integer.MAX_VALUE when there is no tagNumber
// this ensures that RC and Milestone versions are treated as older than non-RC/non-milestone versions
val allVersions =
if (useSnapshots)
versionR
.findAllMatchIn(body)
.map { case Groups(full, ep, maj, min, _, _, tagNumber, offset) =>
(ep.toInt,
maj.toInt,
min.toInt,
Option(tagNumber).map(_.toInt).getOrElse(Integer.MAX_VALUE),
offset.toInt
) -> full
}
.filter(_._2.startsWith(prefix))
.toVector
.sortBy(_._1)
else
versionR
.findAllMatchIn(body)
.map { case Groups(full, ep, maj, min, _, _, tagNumber) =>
(ep.toInt, maj.toInt, min.toInt, Option(tagNumber).map(_.toInt).getOrElse(Integer.MAX_VALUE)) -> full
}
.filter(_._2.startsWith(prefix))
.toVector
.sortBy(_._1)

allVersions.last._2
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* license agreements; and to You under the Apache License, version 2.0:
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* This file is part of the Apache Pekko project, which was derived from Akka.
*/

/*
* Copyright (C) 2017-2020 Lightbend Inc. <https://www.lightbend.com>
*/

package com.github.pjfanning.pekkobuild

object PekkoHttpDependency extends VersionRegex {
override val checkProject: String = "pekko-http-testkit"

def pekkoHttpDependency(defaultVersion: String): Dependency =
Option(System.getProperty("pekko.http.sources")) match {
case Some(pekkoSources) =>
Sources(pekkoSources)
case None =>
Option(System.getProperty("pekko.build.pekko.http.version")) match {
case Some("main") => snapshotMain
case Some("1.0.x") => snapshot10x
case Some("latest-release") => latestRelease
case Some("default") | None => Artifact(defaultVersion)
case Some(other) => Artifact(other, true)
}
}

private val defaultPekkoHttpVersion = System.getProperty("pekko.build.pekko.http.min.version", "1.0.0")
val default: Dependency = pekkoHttpDependency(defaultPekkoHttpVersion)

lazy val snapshot10x = Artifact(determineLatestSnapshot("1.0"), true)
lazy val snapshotMain = Artifact(determineLatestSnapshot(), true)
lazy val latestRelease = Artifact(determineLatestRelease(), false)

val pekkoHttpVersion: String = default match {
case Artifact(version, _) => version
case Sources(uri, _) => uri
}

def pekkoHttpVersionDerivedFromDefault(overrideDefaultPekkoHttpVersion: String): String =
pekkoHttpDependency(overrideDefaultPekkoHttpVersion) match {
case Artifact(version, _) => version
case Sources(uri, _) => uri
}
}
78 changes: 78 additions & 0 deletions src/main/scala/com/github/pjfanning/pekkobuild/VersionRegex.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* license agreements; and to You under the Apache License, version 2.0:
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* This file is part of the Apache Pekko project, which was derived from Akka.
*/

/*
* Copyright (C) 2017-2020 Lightbend Inc. <https://www.lightbend.com>
*/

package com.github.pjfanning.pekkobuild

import sbt.Resolver

import scala.util.matching.Regex.Groups

trait VersionRegex {
// choose a project that is one of the last to be published (eg `pekko-cluster-sharding-typed`)
// `_2.13` is assumed
protected val checkProject: String

protected def determineLatestSnapshot(prefix: String = ""): String = determineLatestVersion(true, prefix)

protected def determineLatestRelease(prefix: String = ""): String = determineLatestVersion(false, prefix)

protected def determineLatestVersion(useSnapshots: Boolean, prefix: String): String = {
import sbt.librarymanagement.Http.http
import gigahorse.GigahorseSupport.url
import scala.concurrent.Await
import scala.concurrent.duration._

val regex =
if (useSnapshots) """href=".*/((\d+)\.(\d+)\.(\d+)(-(M|RC)(\d+))?\+(\d+)-[0-9a-f]+-SNAPSHOT)/""""
else """>.*((\d+)\.(\d+)\.(\d+)(-(M|RC)(\d+))?)/<"""
val versionR = regex.r
val repo = if (useSnapshots) Resolver.ApacheMavenSnapshotsRepo.root else Resolver.DefaultMavenRepositoryRoot

// pekko-cluster-sharding-typed_2.13 seems to be the last nightly published by `pekko-publish-nightly` so if that's there then it's likely the rest also made it
val body = Await
.result(
http.run(url(s"${repo}org/apache/pekko/${checkProject}_2.13/")),
10.seconds
)
.bodyAsString

// we use tagNumber set as Integer.MAX_VALUE when there is no tagNumber
// this ensures that RC and Milestone versions are treated as older than non-RC/non-milestone versions
val allVersions =
if (useSnapshots)
versionR
.findAllMatchIn(body)
.map { case Groups(full, ep, maj, min, _, _, tagNumber, offset) =>
(ep.toInt,
maj.toInt,
min.toInt,
Option(tagNumber).map(_.toInt).getOrElse(Integer.MAX_VALUE),
offset.toInt
) -> full
}
.filter(_._2.startsWith(prefix))
.toVector
.sortBy(_._1)
else
versionR
.findAllMatchIn(body)
.map { case Groups(full, ep, maj, min, _, _, tagNumber) =>
(ep.toInt, maj.toInt, min.toInt, Option(tagNumber).map(_.toInt).getOrElse(Integer.MAX_VALUE)) -> full
}
.filter(_._2.startsWith(prefix))
.toVector
.sortBy(_._1)

allVersions.last._2
}
}
50 changes: 50 additions & 0 deletions src/main/scala/com/github/pjfanning/pekkobuild/package.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* license agreements; and to You under the Apache License, version 2.0:
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* This file is part of the Apache Pekko project, which was derived from Akka.
*/

/*
* Copyright (C) 2017-2020 Lightbend Inc. <https://www.lightbend.com>
*/

package com.github.pjfanning

import sbt._
import sbt.Keys.{libraryDependencies, resolvers}
import sbt.{ClasspathDependency, Project, ProjectRef, Resolver, uri}

package object pekkobuild {
implicit class RichProject(project: Project) {

/** Adds either a source or a binary dependency, depending on whether the above settings are set */
def addPekkoModuleDependency(module: String,
config: String = "",
pekko: Dependency = PekkoDependency.default
): Project =
pekko match {
case Sources(sources, _) =>
val moduleRef = ProjectRef(uri(sources), module)
val withConfig: ClasspathDependency =
if (config == "") moduleRef
else moduleRef % config

project.dependsOn(withConfig)
case Artifact(pekkoVersion, pekkoSnapshot) =>
project.settings(
libraryDependencies += {
if (config == "")
"org.apache.pekko" %% module % pekkoVersion
else
"org.apache.pekko" %% module % pekkoVersion % config
},
resolvers ++= (if (pekkoSnapshot)
Seq(Resolver.ApacheMavenSnapshotsRepo)
else Nil)
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.github.pjfanning.pekkobuild

import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec

class PekkoHttpDependencySpec extends AnyWordSpec with Matchers {
"PekkoHttpDependency" should {
"eval pekkoHttpVersionDerivedFromDefault" in {
PekkoHttpDependency.pekkoHttpVersionDerivedFromDefault("1.0.0") shouldEqual "1.0.0"
}
}
}

0 comments on commit 0d42f2b

Please sign in to comment.