pekko/project/AkkaBuild.scala

261 lines
11 KiB
Scala
Raw Normal View History

/*
2021-01-08 17:55:38 +01:00
* Copyright (C) 2009-2021 Lightbend Inc. <https://www.lightbend.com>
*/
2011-09-23 10:21:03 +02:00
package akka
import java.io.FileReader
import java.io.{FileInputStream, InputStreamReader}
import java.util.Properties
import java.time.format.DateTimeFormatter
import java.time.ZonedDateTime
import java.time.ZoneOffset
2019-10-03 16:42:41 +02:00
import com.lightbend.paradox.projectinfo.ParadoxProjectInfoPluginKeys._
import com.typesafe.sbt.MultiJvmPlugin.autoImport.MultiJvm
import sbtassembly.AssemblyPlugin.autoImport._
import sbt.Keys._
2017-06-09 04:34:21 -07:00
import sbt._
import JdkOptions.autoImport._
2017-10-04 14:22:25 +02:00
import scala.collection.breakOut
2011-07-04 19:16:43 +12:00
object AkkaBuild {
val enableMiMa = true
2016-05-10 10:49:33 +02:00
val parallelExecutionByDefault = false // TODO: enable this once we're sure it does not break things
2019-05-21 17:35:42 +01:00
lazy val buildSettings = Def.settings(
2017-10-06 10:30:28 +02:00
organization := "com.typesafe.akka",
Dependencies.Versions)
2019-05-21 17:35:42 +01:00
lazy val rootSettings = Def.settings(
UnidocRoot.akkaSettings,
Protobuf.settings,
parallelExecution in GlobalScope := System.getProperty("akka.parallelExecution", parallelExecutionByDefault.toString).toBoolean,
2019-10-03 16:42:41 +02:00
// used for linking to API docs (overwrites `project-info.version`)
ThisBuild / projectInfoVersion := { if (isSnapshot.value) "snapshot" else version.value }
2019-05-21 17:35:42 +01:00
)
lazy val mayChangeSettings = Seq(
description := """|This module of Akka is marked as
|'may change', which means that it is in early
|access mode, which also means that it is not covered
|by commercial support. An module marked 'may change' doesn't
|have to obey the rule of staying binary compatible
|between minor releases. Breaking API changes may be
|introduced in minor releases without notice as we
|refine and simplify based on your feedback. Additionally
|such a module may be dropped in major releases
|without prior deprecation.
2017-10-06 10:30:28 +02:00
|""".stripMargin)
val (mavenLocalResolver, mavenLocalResolverSettings) =
System.getProperty("akka.build.M2Dir") match {
case null => (Resolver.mavenLocal, Seq.empty)
case path =>
// Maven resolver settings
def deliverPattern(outputPath: File): String =
(outputPath / "[artifact]-[revision](-[classifier]).[ext]").absolutePath
val resolver = Resolver.file("user-publish-m2-local", new File(path))
(resolver, Seq(
2017-10-06 10:30:28 +02:00
otherResolvers := resolver :: publishTo.value.toList,
publishM2Configuration := Classpaths.publishConfig(
publishMavenStyle.value,
deliverPattern(crossTarget.value),
if (isSnapshot.value) "integration" else "release",
ivyConfigurations.value.map(c => ConfigRef(c.name)).toVector,
artifacts = packagedArtifacts.value.toVector,
resolverName = resolver.name,
checksums = checksums.in(publishM2).value.toVector,
logging = ivyLoggingLevel.value,
overwrite = true)))
}
2019-05-21 17:35:42 +01:00
lazy val resolverSettings = Def.settings(
// should we be allowed to use artifacts published to the local maven repository
2017-10-06 10:30:28 +02:00
if (System.getProperty("akka.build.useLocalMavenResolver", "false").toBoolean)
2019-05-21 17:35:42 +01:00
resolvers += mavenLocalResolver
else Seq.empty,
// should we be allowed to use artifacts from sonatype snapshots
2017-10-06 10:30:28 +02:00
if (System.getProperty("akka.build.useSnapshotSonatypeResolver", "false").toBoolean)
2019-05-21 17:35:42 +01:00
resolvers += Resolver.sonatypeRepo("snapshots")
else Seq.empty,
pomIncludeRepository := (_ => false), // do not leak internal repositories during staging
)
private def allWarnings: Boolean = System.getProperty("akka.allwarnings", "false").toBoolean
2015-01-30 11:33:33 +01:00
final val DefaultScalacOptions = Seq(
"-encoding", "UTF-8",
"-feature",
"-unchecked",
"-Xlog-reflective-calls",
// 'blessed' since 2.13.1
"-language:higherKinds")
// -XDignore.symbol.file suppresses sun.misc.Unsafe warnings
final val DefaultJavacOptions = Seq("-encoding", "UTF-8", "-Xlint:unchecked", "-XDignore.symbol.file")
2019-05-21 17:35:42 +01:00
lazy val defaultSettings: Seq[Setting[_]] = Def.settings(
resolverSettings,
TestExtras.Filter.settings,
// compile options
scalacOptions in Compile ++= DefaultScalacOptions,
scalacOptions in Compile ++=
JdkOptions.targetJdkScalacOptions(targetSystemJdk.value, optionalDir(jdk8home.value), fullJavaHomes.value),
2019-05-21 17:35:42 +01:00
scalacOptions in Compile ++= (if (allWarnings) Seq("-deprecation") else Nil),
scalacOptions in Test := (scalacOptions in Test).value.filterNot(opt =>
opt == "-Xlog-reflective-calls" || opt.contains("genjavadoc")),
javacOptions in Compile ++= {
DefaultJavacOptions ++
JdkOptions.targetJdkJavacOptions(targetSystemJdk.value, optionalDir(jdk8home.value), fullJavaHomes.value)
},
javacOptions in Test ++= DefaultJavacOptions ++
JdkOptions.targetJdkJavacOptions(targetSystemJdk.value, optionalDir(jdk8home.value), fullJavaHomes.value),
javacOptions in Compile ++= (if (allWarnings) Seq("-Xlint:deprecation") else Nil),
javacOptions in doc := Seq(),
2019-05-21 17:35:42 +01:00
crossVersion := CrossVersion.binary,
ivyLoggingLevel in ThisBuild := UpdateLogging.Quiet,
licenses := Seq(("Apache-2.0", url("https://www.apache.org/licenses/LICENSE-2.0.html"))),
2019-05-21 17:35:42 +01:00
homepage := Some(url("https://akka.io/")),
description := "Akka is a toolkit for building highly concurrent, distributed, and resilient message-driven applications for Java and Scala.",
scmInfo := Some(ScmInfo(
url("https://github.com/akka/akka"),
"scm:git:https://github.com/akka/akka.git",
"scm:git:git@github.com:akka/akka.git",
)),
2019-05-21 17:35:42 +01:00
apiURL := Some(url(s"https://doc.akka.io/api/akka/${version.value}")),
initialCommands :=
"""|import language.postfixOps
|import akka.actor._
|import scala.concurrent._
|import com.typesafe.config.ConfigFactory
|import scala.concurrent.duration._
|import akka.util.Timeout
|var config = ConfigFactory.parseString("akka.stdout-loglevel=INFO,akka.loglevel=DEBUG,pinned{type=PinnedDispatcher,executor=thread-pool-executor,throughput=1000}")
|var remoteConfig = ConfigFactory.parseString("akka.remote.classic.netty{port=0,use-dispatcher-for-io=akka.actor.default-dispatcher,execution-pool-size=0},akka.actor.provider=remote").withFallback(config)
|var system: ActorSystem = null
|implicit def _system = system
|def startSystem(remoting: Boolean = false) { system = ActorSystem("repl", if(remoting) remoteConfig else config); println("dont forget to system.terminate()!") }
|implicit def ec = system.dispatcher
|implicit val timeout: Timeout = Timeout(5 seconds)
|""".stripMargin,
2019-05-21 17:35:42 +01:00
/**
* Test settings
*/
fork in Test := true,
// default JVM config for tests
javaOptions in Test ++= {
val defaults = Seq(
// ## core memory settings
"-XX:+UseG1GC",
// most tests actually don't really use _that_ much memory (>1g usually)
// twice used (and then some) keeps G1GC happy - very few or to no full gcs
"-Xms3g", "-Xmx3g",
// increase stack size (todo why?)
"-Xss2m",
// ## extra memory/gc tuning
// this breaks jstat, but could avoid costly syncs to disc see http://www.evanjones.ca/jvm-mmap-pause.html
"-XX:+PerfDisableSharedMem",
// tell G1GC that we would be really happy if all GC pauses could be kept below this as higher would
// likely start causing test failures in timing tests
"-XX:MaxGCPauseMillis=300",
// nio direct memory limit for artery/aeron (probably)
"-XX:MaxDirectMemorySize=256m",
// faster random source
"-Djava.security.egd=file:/dev/./urandom")
if (sys.props.contains("akka.ci-server"))
defaults ++ Seq("-XX:+PrintGCTimeStamps", "-XX:+PrintGCDetails")
else
defaults
},
// all system properties passed to sbt prefixed with "akka." will be passed on to the forked jvms as is
javaOptions in Test := {
val base = (javaOptions in Test).value
val akkaSysProps: Seq[String] =
sys.props.filter(_._1.startsWith("akka"))
.map { case (key, value) => s"-D$key=$value" }(breakOut)
base ++ akkaSysProps
},
// with forked tests the working directory is set to each module's home directory
// rather than the Akka root, some tests depend on Akka root being working dir, so reset
testGrouping in Test := {
val original: Seq[Tests.Group] = (testGrouping in Test).value
original.map { group =>
group.runPolicy match {
case Tests.SubProcess(forkOptions) =>
group.copy(runPolicy = Tests.SubProcess(forkOptions.withWorkingDirectory(
workingDirectory = Some(new File(System.getProperty("user.dir"))))))
case _ => group
2017-10-04 14:22:25 +02:00
}
2019-05-21 17:35:42 +01:00
}
},
2014-04-25 16:32:43 +02:00
2019-05-21 17:35:42 +01:00
parallelExecution in Test := System.getProperty("akka.parallelExecution", parallelExecutionByDefault.toString).toBoolean,
logBuffered in Test := System.getProperty("akka.logBufferedTests", "false").toBoolean,
2017-10-04 14:22:25 +02:00
2019-05-21 17:35:42 +01:00
// show full stack traces and test case durations
testOptions in Test += Tests.Argument("-oDF"),
mavenLocalResolverSettings,
docLintingSettings,
JdkOptions.targetJdkSettings,
// a workaround for https://github.com/akka/akka/issues/27661
// see also project/Protobuf.scala that introduces /../ to make "intellij happy"
MultiJvm / assembly / fullClasspath := {
val old = (MultiJvm / assembly / fullClasspath).value.toVector
val files = old.map(_.data.getCanonicalFile).distinct
files map { x => Attributed.blank(x) }
},
2019-05-21 17:35:42 +01:00
)
2016-01-13 12:00:46 +01:00
private def optionalDir(path: String): Option[File] =
Option(path).filter(_.nonEmpty).map { path =>
val dir = new File(path)
if (!dir.exists)
throw new IllegalArgumentException(s"Path [$path] not found")
dir
}
2016-01-13 12:00:46 +01:00
lazy val docLintingSettings = Seq(
2017-10-06 10:30:28 +02:00
javacOptions in compile ++= Seq("-Xdoclint:none"),
javacOptions in test ++= Seq("-Xdoclint:none"),
javacOptions in doc ++= {
if (JdkOptions.isJdk8) Seq("-Xdoclint:none")
else Seq("-Xdoclint:none", "--ignore-source-errors")
}
)
2011-07-08 12:53:36 +12:00
def loadSystemProperties(fileName: String): Unit = {
import scala.collection.JavaConverters._
val file = new File(fileName)
if (file.exists()) {
println("Loading system properties from file `" + fileName + "`")
val in = new InputStreamReader(new FileInputStream(file), "UTF-8")
val props = new Properties
props.load(in)
in.close()
sys.props ++ props.asScala
}
}
2017-10-06 10:30:28 +02:00
def majorMinor(version: String): Option[String] = """\d+\.\d+""".r.findFirstIn(version)
2011-07-04 19:16:43 +12:00
}