sbt/build.sbt

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

1327 lines
45 KiB
Plaintext
Raw Normal View History

2014-12-18 13:57:05 +01:00
import Dependencies._
2019-12-08 00:39:30 +01:00
import com.typesafe.tools.mima.core.ProblemFilters._
import com.typesafe.tools.mima.core._
2018-07-31 02:28:42 +02:00
import local.Scripted
import java.nio.file.{ Files, Path => JPath }
import java.util.Locale
2024-10-09 08:53:58 +02:00
import sbt.internal.inc.Analysis
2024-10-11 10:24:21 +02:00
import com.eed3si9n.jarjarabrams.ModuleCoordinate
2019-12-08 00:39:30 +01:00
// ThisBuild settings take lower precedence,
// but can be shared across the multi projects.
2019-05-13 19:59:58 +02:00
ThisBuild / version := {
2024-10-08 14:06:00 +02:00
val v = "2.0.0-SNAPSHOT"
2019-05-13 19:59:58 +02:00
nightlyVersion.getOrElse(v)
}
2024-10-09 09:36:37 +02:00
ThisBuild / Utils.version2_13 := "2.0.0-SNAPSHOT"
2020-10-04 06:09:15 +02:00
ThisBuild / versionScheme := Some("early-semver")
ThisBuild / scalafmtOnCompile := !(Global / insideCI).value
ThisBuild / Test / scalafmtOnCompile := !(Global / insideCI).value
2022-11-28 16:45:10 +01:00
// ThisBuild / turbo := true
ThisBuild / usePipelining := false // !(Global / insideCI).value
ThisBuild / organization := "org.scala-sbt"
ThisBuild / description := "sbt is an interactive build tool"
ThisBuild / licenses := List("Apache-2.0" -> url("https://github.com/sbt/sbt/blob/develop/LICENSE"))
ThisBuild / javacOptions ++= Seq("-source", "1.8", "-target", "1.8")
ThisBuild / Compile / doc / javacOptions := Nil
ThisBuild / developers := List(
Developer("harrah", "Mark Harrah", "@harrah", url("https://github.com/harrah")),
Developer("eed3si9n", "Eugene Yokota", "@eed3si9n", url("https://github.com/eed3si9n")),
Developer("jsuereth", "Josh Suereth", "@jsuereth", url("https://github.com/jsuereth")),
Developer("dwijnand", "Dale Wijnand", "@dwijnand", url("https://github.com/dwijnand")),
Developer("eatkins", "Ethan Atkins", "@eatkins", url("https://github.com/eatkins")),
Developer(
"gkossakowski",
"Grzegorz Kossakowski",
"@gkossakowski",
url("https://github.com/gkossakowski")
),
Developer("Duhemm", "Martin Duhem", "@Duhemm", url("https://github.com/Duhemm"))
)
ThisBuild / homepage := Some(url("https://github.com/sbt/sbt"))
ThisBuild / scmInfo := Some(
ScmInfo(url("https://github.com/sbt/sbt"), "git@github.com:sbt/sbt.git")
)
ThisBuild / resolvers += Resolver.mavenLocal
ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always
2025-08-11 12:39:47 +02:00
ThisBuild / mimaFailOnNoPrevious := false
2019-05-13 19:59:58 +02:00
Global / semanticdbEnabled := !(Global / insideCI).value
2021-09-18 23:37:41 +02:00
// Change main/src/main/scala/sbt/plugins/SemanticdbPlugin.scala too, if you change this.
2024-12-17 04:22:33 +01:00
Global / semanticdbVersion := "4.9.9"
val excludeLint = SettingKey[Set[Def.KeyedInitialize[?]]]("excludeLintKeys")
Global / excludeLint := (Global / excludeLint).?.value.getOrElse(Set.empty)
Global / excludeLint += Utils.componentID
Global / excludeLint += scriptedBufferLog
Global / excludeLint += checkPluginCross
def commonSettings: Seq[Setting[?]] = Def.settings(
2019-05-11 09:42:06 +02:00
headerLicense := Some(
HeaderLicense.Custom(
"""|sbt
2023-06-20 13:42:07 +02:00
|Copyright 2023, Scala center
|Copyright 2011 - 2022, Lightbend, Inc.
2018-02-01 15:53:05 +01:00
|Copyright 2008 - 2010, Mark Harrah
|Licensed under Apache License 2.0 (see LICENSE)
2018-02-01 15:53:05 +01:00
|""".stripMargin
2019-05-11 09:42:06 +02:00
)
),
2018-02-01 15:53:05 +01:00
scalaVersion := baseScalaVersion,
evictionErrorLevel := Level.Info,
2024-10-09 09:36:37 +02:00
Utils.componentID := None,
2025-06-18 00:23:25 +02:00
resolvers += Resolver.sonatypeCentralSnapshots,
testFrameworks += TestFramework("hedgehog.sbt.Framework"),
testFrameworks += TestFramework("verify.runner.Framework"),
2024-10-09 09:36:37 +02:00
Global / concurrentRestrictions += Utils.testExclusiveRestriction,
2021-05-03 05:25:23 +02:00
Test / testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"),
Test / testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-verbosity", "2"),
compile / javacOptions ++= Seq("-Xlint", "-Xlint:-serial"),
/*
2019-03-22 07:28:14 +01:00
Compile / doc / scalacOptions ++= {
import scala.sys.process._
val devnull = ProcessLogger(_ => ())
val tagOrSha = ("git describe --exact-match" #|| "git rev-parse HEAD").lineStream(devnull).head
2018-02-22 02:33:45 +01:00
Seq(
"-sourcepath",
2021-05-03 05:25:23 +02:00
(LocalRootProject / baseDirectory).value.getAbsolutePath,
2018-02-22 02:33:45 +01:00
"-doc-source-url",
2019-03-22 07:28:14 +01:00
s"https://github.com/sbt/sbt/tree/$tagOrSha€{FILE_PATH}.scala"
2018-02-22 02:33:45 +01:00
)
},
*/
Compile / javafmtOnCompile := Def
.taskDyn(if ((scalafmtOnCompile).value) Compile / javafmt else Def.task(()))
.value,
Test / javafmtOnCompile := Def
.taskDyn(if ((Test / scalafmtOnCompile).value) Test / javafmt else Def.task(()))
.value,
Compile / unmanagedSources / inputFileStamps :=
(Compile / unmanagedSources / inputFileStamps).dependsOn(Compile / javafmtOnCompile).value,
Test / unmanagedSources / inputFileStamps :=
(Test / unmanagedSources / inputFileStamps).dependsOn(Test / javafmtOnCompile).value,
2021-05-03 05:25:23 +02:00
Test / publishArtifact := false,
run / fork := true,
2018-02-01 15:53:05 +01:00
)
def utilCommonSettings: Seq[Setting[?]] = Def.settings(
baseSettings,
)
2014-12-18 05:38:10 +01:00
def minimalSettings: Seq[Setting[?]] =
2024-10-09 09:36:37 +02:00
commonSettings ++ customCommands ++ Utils.publishPomSettings
2014-12-18 05:38:10 +01:00
def baseSettings: Seq[Setting[?]] =
2024-10-09 09:36:37 +02:00
minimalSettings ++ Seq(Utils.projectComponent) ++ Utils.baseScalacOptions ++ Licensed.settings
2014-12-18 05:38:10 +01:00
def testedBaseSettings: Seq[Setting[?]] =
2014-12-18 05:38:10 +01:00
baseSettings ++ testDependencies
2025-08-11 12:39:47 +02:00
val sbt20Plus =
2021-05-03 05:25:23 +02:00
Seq(
2025-08-11 12:39:47 +02:00
"2.0.0-RC2",
2021-05-03 05:25:23 +02:00
)
2025-08-11 12:39:47 +02:00
val mimaSettings = mimaSettingsSince(sbt20Plus)
def mimaSettingsSince(versions: Seq[String]): Seq[Def.Setting[?]] = Def settings (
mimaPreviousArtifacts := {
2019-04-18 09:14:04 +02:00
val crossVersion = if (crossPaths.value) CrossVersion.binary else CrossVersion.disabled
2025-08-11 12:39:47 +02:00
if (sbtPlugin.value) {
versions
.map(v =>
Defaults.sbtPluginExtra(
m = organization.value % moduleName.value % v,
sbtV = "2",
scalaV = scalaBinaryVersion.value
)
)
.toSet
} else {
versions.map(v => organization.value % moduleName.value % v cross crossVersion).toSet
}
2018-03-12 18:21:22 +01:00
},
mimaBinaryIssueFilters ++= Seq(
// Changes in the internal package
2018-03-12 18:21:22 +01:00
exclude[DirectMissingMethodProblem]("sbt.internal.*"),
exclude[FinalClassProblem]("sbt.internal.*"),
exclude[FinalMethodProblem]("sbt.internal.*"),
exclude[IncompatibleResultTypeProblem]("sbt.internal.*"),
exclude[ReversedMissingMethodProblem]("sbt.internal.*"),
2018-03-12 18:21:22 +01:00
),
2017-07-20 18:31:39 +02:00
)
val scriptedSbtMimaSettings = Def.settings(mimaPreviousArtifacts := Set())
2017-04-21 09:14:31 +02:00
lazy val sbtRoot: Project = (project in file("."))
2024-12-18 06:24:44 +01:00
.aggregate(
(allProjects diff Seq(lmCoursierShaded))
.map(p => LocalProject(p.id)): _*
)
2017-04-21 09:14:31 +02:00
.settings(
minimalSettings,
2018-10-05 09:04:22 +02:00
onLoadMessage := {
val version = sys.props("java.specification.version")
2023-08-11 16:08:11 +02:00
""" __ __
2018-10-05 09:04:22 +02:00
| _____/ /_ / /_
| / ___/ __ \/ __/
2023-08-11 16:08:11 +02:00
| (__ ) /_/ / /_
| /____/_.___/\__/
2018-10-05 09:04:22 +02:00
|Welcome to the build for sbt.
|""".stripMargin +
2019-05-11 09:42:06 +02:00
(if (version != "1.8")
s"""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
| Java version is $version. We recommend java 8.
2018-10-05 09:04:22 +02:00
|!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!""".stripMargin
2019-05-11 09:42:06 +02:00
else "")
2018-10-05 09:04:22 +02:00
},
2024-10-09 09:36:37 +02:00
Utils.baseScalacOptions,
2017-05-08 15:34:41 +02:00
Docs.settings,
scalacOptions += "-Ymacro-expand:none", // for both sxr and doc
2024-10-09 09:36:37 +02:00
Utils.publishPomSettings,
2017-05-08 15:34:41 +02:00
otherRootSettings,
2024-10-09 09:36:37 +02:00
Utils.noPublish,
2017-05-30 08:44:13 +02:00
publishLocal := {},
2021-05-03 05:25:23 +02:00
Global / commands += Command
.single("sbtOn")((state, dir) => s"sbtProj/Test/runMain sbt.RunFromSourceMain $dir" :: state),
2019-10-17 23:27:43 +02:00
mimaSettings,
2019-10-20 06:41:53 +02:00
mimaPreviousArtifacts := Set.empty,
buildThinClient := (sbtClientProj / buildThinClient).evaluated,
nativeImage := (sbtClientProj / nativeImage).value,
installNativeThinClient := {
// nativeInstallDirectory can be set globally or in a gitignored local file
val dir = nativeInstallDirectory.?.value
val target = Def.spaceDelimited("").parsed.headOption match {
case Some(p) => file(p).toPath
case _ =>
dir match {
2020-08-14 04:56:02 +02:00
case Some(d) => d / "sbtn"
case _ =>
val msg = "Expected input parameter <path>: installNativeExecutable /usr/local/bin"
throw new IllegalStateException(msg)
}
}
val base = baseDirectory.value.toPath
val exec = (sbtClientProj / nativeImage).value.toPath
streams.value.log.info(s"installing thin client ${base.relativize(exec)} to ${target}")
Files.copy(exec, target, java.nio.file.StandardCopyOption.REPLACE_EXISTING)
}
)
// This is used to configure an sbt-launcher for this version of sbt.
lazy val bundledLauncherProj =
2017-04-21 09:14:31 +02:00
(project in file("launch"))
.enablePlugins(SbtLauncherPlugin)
2017-04-21 09:14:31 +02:00
.settings(
minimalSettings,
inConfig(Compile)(Transform.configSettings),
)
.settings(
name := "sbt-launch",
moduleName := "sbt-launch",
description := "sbt application launcher",
autoScalaLibrary := false,
crossPaths := false,
2022-06-13 09:17:15 +02:00
Compile / doc / javacOptions := Nil,
2021-05-03 05:25:23 +02:00
Compile / packageBin := sbtLaunchJar.value,
2019-10-17 23:27:43 +02:00
mimaSettings,
mimaPreviousArtifacts := Set()
2017-04-21 09:14:31 +02:00
)
2014-12-18 05:38:10 +01:00
/* ** subproject declarations ** */
2014-12-18 05:38:10 +01:00
val collectionProj = project
.in(file("util-collection"))
.dependsOn(utilPosition, utilCore)
.settings(
2021-12-06 08:06:26 +01:00
name := "Collections",
testedBaseSettings,
2017-07-20 18:31:39 +02:00
libraryDependencies ++= Seq(sjsonNewScalaJson.value),
2020-07-08 01:52:52 +02:00
libraryDependencies ++= (CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, major)) if major <= 12 => Seq()
2021-12-06 08:06:26 +01:00
case _ => Seq(scalaPar)
2020-07-08 01:52:52 +02:00
}),
2017-07-20 18:31:39 +02:00
mimaSettings,
2024-03-17 09:54:20 +01:00
conflictWarning := ConflictWarning.disable,
)
// Command line-related utilities.
val completeProj = (project in file("internal") / "util-complete")
.dependsOn(collectionProj, utilControl, utilLogging)
.settings(
testedBaseSettings,
name := "Completion",
2017-07-20 18:31:39 +02:00
libraryDependencies += jline,
Support scala 2.13 console in thin client In order to make the console task work with scala 2.13 and the thin client, we need to provide a way for the scala repl to use an sbt provided jline3 terminal instead of the default terminal typically built by the repl. We also need to put jline 3 higher up in the classloading hierarchy to ensure that two versions of jline 3 are not loaded (which makes it impossible to share the sbt terminal with the scala terminal). One impact of this change is the decoupling of the version of jline-terminal used by the in process scala console and the version of jline-terminal specified by the scala version itself. It is possible to override this by setting the `useScalaReplJLine` flag to true. When that is set, the scala REPL will run in a fully isolated classloader. That will ensure that the versions are consistent. It will, however, for sure break the thin client and may interfere with the embedded shell ui. As part of this work, I also discovered that jline 3 Terminal.getSize is very slow. In jline 2, the terminal attributes were automatically cached with a timeout of, I think, 1 second so it wasn't a big deal to call Terminal.getAttributes. The getSize method in jline 3 is not cached and it shells out to run a tty command. This caused a significant performance regression in sbt because when progress is enabled, we call Terminal.getSize whenever we log any messages. I added caching of getSize at the TerminalImpl level to address this. The timeout is 1 second, which seems responsive enough for most use cases. We could also move the calculation onto a background thread and have it periodically updated, but that seems like overkill.
2020-07-20 19:12:04 +02:00
libraryDependencies += jline3Reader,
libraryDependencies += jline3Builtins,
2017-07-20 18:31:39 +02:00
mimaSettings,
// Parser is used publicly, so we can't break bincompat.
mimaBinaryIssueFilters := Seq(
2017-12-04 17:18:08 +01:00
),
)
.configure(addSbtIO)
// A logic with restricted negation as failure for a unique, stable model
val logicProj = (project in file("internal") / "util-logic")
.dependsOn(collectionProj, utilRelation)
.settings(
testedBaseSettings,
2017-07-20 18:31:39 +02:00
name := "Logic",
mimaSettings,
)
// defines Java structures used across Scala versions, such as the API structures and relationships extracted by
// the analysis compiler phases and passed back to sbt. The API structures are defined in a simple
// format from which Java sources are generated by the datatype generator Projproject
lazy val utilInterface = (project in file("internal") / "util-interface").settings(
baseSettings,
2024-10-09 09:36:37 +02:00
Utils.javaOnlySettings,
crossPaths := false,
autoScalaLibrary := false,
2022-06-13 09:17:15 +02:00
Compile / doc / javacOptions := Nil,
name := "Util Interface",
exportJars := true,
2025-08-11 12:39:47 +02:00
mimaSettings,
)
lazy val utilControl = (project in file("internal") / "util-control").settings(
utilCommonSettings,
name := "Util Control",
2025-08-11 12:39:47 +02:00
mimaSettings,
)
lazy val utilPosition = (project in file("internal") / "util-position")
.settings(
utilCommonSettings,
name := "Util Position",
scalacOptions += "-language:experimental.macros",
2025-08-17 01:23:34 +02:00
libraryDependencies ++= Seq(scalatest % "test"),
2025-08-11 12:39:47 +02:00
mimaSettings,
)
lazy val utilCore = project
.in(file("internal") / "util-core")
.settings(
utilCommonSettings,
name := "Util Core",
2024-10-09 09:36:37 +02:00
Utils.keywordsSettings,
2025-08-11 12:39:47 +02:00
mimaSettings
)
lazy val utilLogging = project
.in(file("internal") / "util-logging")
.enablePlugins(ContrabandPlugin, JsonCodecPlugin)
.dependsOn(utilInterface, utilCore)
.settings(
utilCommonSettings,
name := "Util Logging",
libraryDependencies ++=
Upgrade LineReader to JLine3 This commit upgrades sbt to using jline3. The advantage to jline3 is that it has a significantly better tab completion engine that is more similar to what you get from zsh or fish. The diff is bigger than I'd hoped because there are a number of behaviors that are different in jline3 vs jline2 in how the library consumes input streams and implements various features. I also was unable to remove jline2 because we need it for older versions of the scala console to work correctly with the thin client. As a result, the changes are largely additive. A good amount of this commit was in adding more protocol so that the remote client can forward its jline3 terminal information to the server. There were a number of minor changes that I made that either fixed outstanding ui bugs from #5620 or regressions due to differences between jline3 and jline2. The number one thing that caused problems is that the jline3 LineReader insists on using a NonBlockingInputStream. The implementation ofo NonBlockingInputStream seems buggy. Moreover, sbt internally uses a non blocking input stream for system in so jline is adding non blocking to an already non blocking stream, which is frustrating. A long term solution might be to consider insourcing LineReader.java from jline3 and just adapting it to use an sbt terminal rather than fighting with the jline3 api. This would also have the advantage of not conflicting with other versions of jline3. Even if we don't, we may want to shade jline3 if that is possible.
2020-06-30 17:57:57 +02:00
Seq(
jline,
Support scala 2.13 console in thin client In order to make the console task work with scala 2.13 and the thin client, we need to provide a way for the scala repl to use an sbt provided jline3 terminal instead of the default terminal typically built by the repl. We also need to put jline 3 higher up in the classloading hierarchy to ensure that two versions of jline 3 are not loaded (which makes it impossible to share the sbt terminal with the scala terminal). One impact of this change is the decoupling of the version of jline-terminal used by the in process scala console and the version of jline-terminal specified by the scala version itself. It is possible to override this by setting the `useScalaReplJLine` flag to true. When that is set, the scala REPL will run in a fully isolated classloader. That will ensure that the versions are consistent. It will, however, for sure break the thin client and may interfere with the embedded shell ui. As part of this work, I also discovered that jline 3 Terminal.getSize is very slow. In jline 2, the terminal attributes were automatically cached with a timeout of, I think, 1 second so it wasn't a big deal to call Terminal.getAttributes. The getSize method in jline 3 is not cached and it shells out to run a tty command. This caused a significant performance regression in sbt because when progress is enabled, we call Terminal.getSize whenever we log any messages. I added caching of getSize at the TerminalImpl level to address this. The timeout is 1 second, which seems responsive enough for most use cases. We could also move the calculation onto a background thread and have it periodically updated, but that seems like overkill.
2020-07-20 19:12:04 +02:00
jline3Terminal,
jline3JNI,
jline3Native,
Upgrade LineReader to JLine3 This commit upgrades sbt to using jline3. The advantage to jline3 is that it has a significantly better tab completion engine that is more similar to what you get from zsh or fish. The diff is bigger than I'd hoped because there are a number of behaviors that are different in jline3 vs jline2 in how the library consumes input streams and implements various features. I also was unable to remove jline2 because we need it for older versions of the scala console to work correctly with the thin client. As a result, the changes are largely additive. A good amount of this commit was in adding more protocol so that the remote client can forward its jline3 terminal information to the server. There were a number of minor changes that I made that either fixed outstanding ui bugs from #5620 or regressions due to differences between jline3 and jline2. The number one thing that caused problems is that the jline3 LineReader insists on using a NonBlockingInputStream. The implementation ofo NonBlockingInputStream seems buggy. Moreover, sbt internally uses a non blocking input stream for system in so jline is adding non blocking to an already non blocking stream, which is frustrating. A long term solution might be to consider insourcing LineReader.java from jline3 and just adapting it to use an sbt terminal rather than fighting with the jline3 api. This would also have the advantage of not conflicting with other versions of jline3. Even if we don't, we may want to shade jline3 if that is possible.
2020-06-30 17:57:57 +02:00
log4jApi,
log4jCore,
disruptor,
sjsonNewScalaJson.value,
),
2024-06-04 14:49:37 +02:00
testDependencies,
2021-12-20 08:00:30 +01:00
Compile / generateContrabands / contrabandCodecsDependencies := List(sjsonNewCore.value),
2021-05-03 05:25:23 +02:00
Compile / generateContrabands / sourceManaged := baseDirectory.value / "src" / "main" / "contraband-scala",
Compile / managedSourceDirectories +=
baseDirectory.value / "src" / "main" / "contraband-scala",
2021-05-03 05:25:23 +02:00
Compile / generateContrabands / contrabandFormatsForType := { tpe =>
val old = (Compile / generateContrabands / contrabandFormatsForType).value
val name = tpe.removeTypeParameters.name
if (name == "Throwable") Nil
else old(tpe)
},
2023-05-14 06:38:34 +02:00
Test / fork := true,
2025-08-11 12:39:47 +02:00
mimaSettings,
mimaBinaryIssueFilters ++= Seq(
),
)
.configure(addSbtIO)
lazy val utilRelation = (project in file("internal") / "util-relation")
.settings(
utilCommonSettings,
name := "Util Relation",
libraryDependencies ++= Seq(scalacheck % "test"),
2025-08-11 12:39:47 +02:00
mimaSettings,
)
// Persisted caching based on sjson-new
lazy val utilCache = project
.in(file("util-cache"))
.enablePlugins(
ContrabandPlugin,
Spelling (#8028) * spelling: 1.x Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: a Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: aether Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: anymore Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: artifact Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: available Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: be Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: bridge Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: cannot Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: case-insensitive Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: checksum Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: class loads Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: contra Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: dependencies Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: dependency Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: dependent Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: deriveds Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: describes Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: early Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: enclosed Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: evaluation Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: excluding Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: execution Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: for Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: frequently Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: github Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: green Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: https://www Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: https Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: in-sourcing Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: include Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: incompatible Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: indefinitely Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: information Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: inputted Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: just Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: lastmodifiedtimes Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: latest Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: manifest Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: miscellaneous Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: more Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: neither Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: never Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: nonexistent Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: opted Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: outputting Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: params Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: performance Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: preceding Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: presentation Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: project Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: projects Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: protocol Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: related Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: representation Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: res Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: resolverlist Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: resolverset Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: response Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: returned Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: sbt_version Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: scalacheck Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: sentinels Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: separates Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: serves Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: should Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: significant Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: specifically Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: substitute Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: suppress Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: terminal Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: the Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: title Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: transitive Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: version Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: versions Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: want Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: wanting Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: whether Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * link: sbt Cached Resolution Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * link: Testing sbt plugins Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> --------- Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
2025-02-04 07:11:28 +01:00
// we generate JsonCodec only for actionresult.contra
JsonCodecPlugin,
)
.dependsOn(utilLogging)
.settings(
testedBaseSettings,
name := "Util Cache",
libraryDependencies ++=
Seq(
sjsonNewCore.value,
sjsonNewScalaJson.value,
2025-08-17 01:23:34 +02:00
sjsonNewMurmurhash.value
),
Compile / managedSourceDirectories +=
baseDirectory.value / "src" / "main" / "contraband-scala",
Compile / generateContrabands / sourceManaged := baseDirectory.value / "src" / "main" / "contraband-scala",
Compile / generateContrabands / contrabandFormatsForType := ContrabandConfig.getFormats,
2025-08-11 12:39:47 +02:00
mimaSettings,
Test / fork := true,
)
.configure(
addSbtIO,
addSbtCompilerInterface,
)
// Builds on cache to provide caching for filesystem-related operations
lazy val utilTracking = (project in file("util-tracking"))
.dependsOn(utilCache)
.settings(
utilCommonSettings,
name := "Util Tracking",
libraryDependencies ++= Seq(scalatest % "test"),
2025-08-11 12:39:47 +02:00
mimaSettings,
mimaBinaryIssueFilters ++= Seq(
)
)
.configure(addSbtIO)
lazy val utilScripted = (project in file("internal") / "util-scripted")
.dependsOn(utilLogging, utilInterface)
.settings(
utilCommonSettings,
name := "Util Scripted",
2024-10-23 01:25:51 +02:00
libraryDependencies += scalaParsers,
2025-08-11 12:39:47 +02:00
mimaSettings,
)
.configure(addSbtIO)
2014-12-18 05:38:10 +01:00
/* **** Intermediate-level Modules **** */
// Runner for uniform test interface
2017-04-21 09:14:31 +02:00
lazy val testingProj = (project in file("testing"))
.enablePlugins(ContrabandPlugin, JsonCodecPlugin)
.dependsOn(workerProj, utilLogging)
2017-04-21 09:14:31 +02:00
.settings(
baseSettings,
2014-12-18 05:38:10 +01:00
name := "Testing",
2020-01-10 14:41:55 +01:00
libraryDependencies ++= Seq(
2024-10-23 01:25:51 +02:00
scalaXml,
2019-05-11 09:42:06 +02:00
testInterface,
launcherInterface,
2022-01-17 08:27:44 +01:00
sjsonNewScalaJson.value,
sjsonNewCore.value,
2019-05-11 09:42:06 +02:00
),
2024-03-17 09:54:20 +01:00
conflictWarning := ConflictWarning.disable,
2021-05-03 05:25:23 +02:00
Compile / managedSourceDirectories +=
baseDirectory.value / "src" / "main" / "contraband-scala",
2021-05-03 05:25:23 +02:00
Compile / generateContrabands / sourceManaged := baseDirectory.value / "src" / "main" / "contraband-scala",
Compile / generateContrabands / contrabandFormatsForType := ContrabandConfig.getFormats,
2017-07-20 18:31:39 +02:00
mimaSettings,
2018-03-07 21:31:24 +01:00
mimaBinaryIssueFilters ++= Seq(
2018-03-12 16:18:42 +01:00
)
2017-04-21 09:14:31 +02:00
)
.configure(addSbtIO, addSbtCompilerClasspath)
2014-12-18 05:38:10 +01:00
lazy val workerProj = (project in file("worker"))
.dependsOn(exampleWorkProj % Test)
.settings(
name := "worker",
testedBaseSettings,
Compile / doc / javacOptions := Nil,
crossPaths := false,
autoScalaLibrary := false,
libraryDependencies ++= Seq(gson, testInterface),
libraryDependencies += "org.scala-lang" %% "scala3-library" % scalaVersion.value % Test,
// run / fork := false,
Test / fork := true,
2025-08-11 12:39:47 +02:00
mimaSettings,
)
.configure(addSbtIOForTest)
lazy val exampleWorkProj = (project in file("internal") / "example-work")
.settings(
minimalSettings,
name := "example work",
publish / skip := true,
)
2014-12-18 05:38:10 +01:00
// Basic task engine
2017-04-21 09:14:31 +02:00
lazy val taskProj = (project in file("tasks"))
.dependsOn(collectionProj, utilControl)
2017-04-21 09:14:31 +02:00
.settings(
testedBaseSettings,
2017-07-20 18:31:39 +02:00
name := "Tasks",
mimaSettings,
2019-03-08 21:26:15 +01:00
mimaBinaryIssueFilters ++= Seq(
)
2017-04-21 09:14:31 +02:00
)
2014-12-18 05:38:10 +01:00
// Standard task system. This provides map, flatMap, join, and more on top of the basic task model.
2017-04-21 09:14:31 +02:00
lazy val stdTaskProj = (project in file("tasks-standard"))
.dependsOn(collectionProj, utilLogging, utilCache)
2017-04-21 09:14:31 +02:00
.dependsOn(taskProj % "compile;test->test")
.settings(
testedBaseSettings,
2014-12-18 05:38:10 +01:00
name := "Task System",
2024-10-09 09:36:37 +02:00
Utils.testExclusive,
2017-07-20 18:31:39 +02:00
mimaSettings,
2019-05-29 15:43:14 +02:00
mimaBinaryIssueFilters ++= Seq(
),
2017-04-21 09:14:31 +02:00
)
.configure(addSbtIO)
2014-12-18 05:38:10 +01:00
// Embedded Scala code runner
2017-04-21 09:14:31 +02:00
lazy val runProj = (project in file("run"))
2017-06-16 22:11:33 +02:00
.enablePlugins(ContrabandPlugin)
.dependsOn(collectionProj, utilLogging, utilControl)
2017-04-21 09:14:31 +02:00
.settings(
testedBaseSettings,
2017-05-12 00:33:12 +02:00
name := "Run",
2021-05-03 05:25:23 +02:00
Compile / managedSourceDirectories +=
2017-05-12 00:33:12 +02:00
baseDirectory.value / "src" / "main" / "contraband-scala",
2021-05-03 05:25:23 +02:00
Compile / generateContrabands / sourceManaged := baseDirectory.value / "src" / "main" / "contraband-scala",
2017-07-20 18:31:39 +02:00
mimaSettings,
2018-03-12 16:18:42 +01:00
mimaBinaryIssueFilters ++= Seq(
)
2017-04-21 09:14:31 +02:00
)
.configure(addSbtIO, addSbtCompilerClasspath)
2014-12-18 05:38:10 +01:00
2018-02-01 15:53:11 +01:00
val sbtProjDepsCompileScopeFilter =
2019-05-11 09:42:06 +02:00
ScopeFilter(
inDependencies(LocalProject("sbtProj"), includeRoot = false),
inConfigurations(Compile)
)
2018-02-01 15:53:11 +01:00
lazy val scriptedSbtProj = (project in file("scripted-sbt"))
Explicitly set scripted and server test classpath This commit makes it so that the scalaVersion, sbtVersion and classpath are always passed in as parameters to any method that creates an sbt server -- either for scripted or for the sbt server tests. By making that change, I was able to change the implementation of scripted in the sbt project to use publishLocalBin instead of publishLocal. This makes the scripted tests start much faster (doc alone can easily take 30 second) with messing with the build to exclude slow tasks from publishLocal. As part of this change, I removed the test dependency on scriptedSbtRedux for sbtProj and instead had scriptedSbtRedux depend on sbtProj. This allowed me to remove some messy LocalProject logic in the resourceGenerators for scriptedSbtReduxProj. I also had to remove a number of imports in the scriptedSbtReduxProj because the definitions available in the sbt package object became available. I also removed the dependency on sbt-buildinfo and instead pass the values from the build into test classes using scalatest properties. I ran into a number of minor issues with the build info plugin, namely that I couldn't get fullClasspathAsJars to reliably run as a BuildInfo key. It also is somewhat more clear to me to just rely on the built in scalatest functionality. The big drawback is that the scalatest properties can only be strings, but that restriction isn't really a problem here (strangely the TestData structure has a field configMap which is effectively Map[String, Any] but Any is actually always String given how the TestData is created as part of framework initialization. Since scripted no longer publishes, scriptedUnpublished is now effectively an alias for scripted. To get publishLocalBin working, I had to copy private code from IvyXml.scala into PublishBinPlugin. Once we publish a new version of sbt, we can remove the copied code and invoke IvyXml.makeIvyXmlBefore directly.
2020-01-12 04:52:36 +01:00
.dependsOn(sbtProj % "compile;test->test", commandProj, utilLogging, utilScripted)
2017-04-21 09:14:31 +02:00
.settings(
baseSettings,
name := "scripted-sbt",
2017-07-20 18:31:39 +02:00
libraryDependencies ++= Seq(launcherInterface % "provided"),
mimaSettings,
scriptedSbtMimaSettings,
2025-08-11 12:39:47 +02:00
mimaSettings,
)
2024-10-09 08:53:58 +02:00
.dependsOn(lmCore)
.configure(addSbtIO, addSbtCompilerInterface)
lazy val remoteCacheProj = (project in file("sbt-remote-cache"))
.dependsOn(sbtProj)
.settings(
sbtPlugin := true,
baseSettings,
name := "sbt-remote-cache",
pluginCrossBuild / sbtVersion := version.value,
publishMavenStyle := true,
2025-08-11 12:39:47 +02:00
mimaSettings,
libraryDependencies += remoteapis,
)
2014-12-18 05:38:10 +01:00
// Implementation and support code for defining actions.
2017-04-21 09:14:31 +02:00
lazy val actionsProj = (project in file("main-actions"))
.enablePlugins(ContrabandPlugin, JsonCodecPlugin)
.dependsOn(
completeProj,
runProj,
stdTaskProj,
taskProj,
testingProj,
utilCache,
utilLogging,
utilRelation,
utilTracking,
workerProj,
protocolProj,
)
2017-04-21 09:14:31 +02:00
.settings(
testedBaseSettings,
name := "Actions",
2017-07-20 18:31:39 +02:00
libraryDependencies += sjsonNewScalaJson.value,
libraryDependencies ++= Seq(gigahorseApacheHttp, jline3Terminal),
Compile / managedSourceDirectories +=
baseDirectory.value / "src" / "main" / "contraband-scala",
Compile / generateContrabands / sourceManaged := baseDirectory.value / "src" / "main" / "contraband-scala",
Compile / generateContrabands / contrabandFormatsForType := ContrabandConfig.getFormats,
// Test / fork := true,
Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat,
2017-07-20 18:31:39 +02:00
mimaSettings,
2017-04-21 09:14:31 +02:00
)
2024-10-09 08:53:58 +02:00
.dependsOn(lmCore)
2017-04-21 09:14:31 +02:00
.configure(
addSbtIO,
addSbtCompilerInterface,
addSbtCompilerClasspath,
addSbtCompilerApiInfo,
addSbtZinc
2017-04-21 09:14:31 +02:00
)
lazy val protocolProj = (project in file("protocol"))
2017-06-16 22:11:33 +02:00
.enablePlugins(ContrabandPlugin, JsonCodecPlugin)
.dependsOn(collectionProj, utilLogging)
2017-04-21 09:14:31 +02:00
.settings(
2016-12-01 09:14:07 +01:00
testedBaseSettings,
name := "Protocol",
2022-01-18 05:21:38 +01:00
libraryDependencies ++= Seq(sjsonNewScalaJson.value, sjsonNewCore.value, ipcSocket),
2024-12-11 05:29:49 +01:00
Compile / scalacOptions += "-source:3.7",
2021-05-03 05:25:23 +02:00
Compile / managedSourceDirectories +=
baseDirectory.value / "src" / "main" / "contraband-scala",
2021-05-03 05:25:23 +02:00
Compile / generateContrabands / sourceManaged := baseDirectory.value / "src" / "main" / "contraband-scala",
Compile / generateContrabands / contrabandFormatsForType := ContrabandConfig.getFormats,
2017-07-20 18:31:39 +02:00
mimaSettings,
2018-03-12 16:18:42 +01:00
mimaBinaryIssueFilters ++= Seq(
2020-05-12 17:34:34 +02:00
// ignore missing or incompatible methods in sbt.internal
exclude[IncompatibleMethTypeProblem]("sbt.internal.*"),
2018-03-12 16:18:42 +01:00
exclude[DirectMissingMethodProblem]("sbt.internal.*"),
)
2017-04-21 09:14:31 +02:00
)
2016-12-01 09:14:07 +01:00
2014-12-18 05:38:10 +01:00
// General command support and core commands not specific to a build system
2017-04-21 09:14:31 +02:00
lazy val commandProj = (project in file("main-command"))
2017-06-16 22:11:33 +02:00
.enablePlugins(ContrabandPlugin, JsonCodecPlugin)
.dependsOn(protocolProj, completeProj, utilLogging, runProj, utilCache)
2017-04-21 09:14:31 +02:00
.settings(
testedBaseSettings,
name := "Command",
2022-01-18 05:21:38 +01:00
libraryDependencies ++= Seq(
launcherInterface,
sjsonNewCore.value,
sjsonNewScalaJson.value,
templateResolverApi
),
2021-05-03 05:25:23 +02:00
Compile / managedSourceDirectories +=
baseDirectory.value / "src" / "main" / "contraband-scala",
2021-05-03 05:25:23 +02:00
Compile / generateContrabands / sourceManaged := baseDirectory.value / "src" / "main" / "contraband-scala",
Compile / generateContrabands / contrabandFormatsForType := ContrabandConfig.getFormats,
2017-07-20 18:31:39 +02:00
mimaSettings,
mimaBinaryIssueFilters ++= Vector(
),
2021-05-03 05:25:23 +02:00
Compile / headerCreate / unmanagedSources := {
val old = (Compile / headerCreate / unmanagedSources).value
2019-05-11 09:42:06 +02:00
old filterNot { x =>
(x.getName startsWith "NG") || (x.getName == "ReferenceCountedFileDescriptor.java")
}
},
2017-04-21 09:14:31 +02:00
)
2024-10-09 08:53:58 +02:00
.dependsOn(lmCore)
2017-06-23 18:58:00 +02:00
.configure(
addSbtIO,
addSbtCompilerInterface,
2017-06-23 18:58:00 +02:00
addSbtCompilerClasspath,
Add global file repository task Every time that the compile task is run, there are potentially a large number of iops that must occur in order for sbt to generate the source file list as well as for zinc to check which files have changed since the last build. This can lead to a noticeable delay between when a build is started (either manually or by triggered execution) and when compilation actually begins. To reduce this latency, I am adding a global view of the file system that will be stored in BasicKeys.globalFileTreeView. To make this work, I introduce the StampedFile trait, which augments the java.io.File class with a stamp method that returns the zinc stamp for the file. For source files, this will be a hash of the file, while for binaries, it is just the last modified time. In order to gain access to the sbt.internal.inc.Stamper class, I had to append addSbtZinc to the commandProj configurations. This view may or may not use an in-memory cache of the file system tree to return the results. Because there is always the risk of the cache getting out of sync with the actual file system, I both make it optional to use a cache and provide a mechanism for flushing the cache. Moreover, the in-memory cache implementation in sbt.io, which is backed by a swoval FileTreeRepository, has the property that touching a monitored directory invalidates the entire directory within the cache, so the flush command isn't even strictly needed in general. Because caching is optional, the global is of a FileTreeDataView, which doesn't specify a caching strategy. Subsequent commits will make use of this to potentially speed up incremental compilation by caching the Stamps of the source files so that zinc does not need to compute the hashes itself and will allow for continuous builds to use the cache to monitor events instead of creating a new, standalone FileEventMonitor.
2018-08-26 01:43:48 +02:00
addSbtZinc
2017-06-23 18:58:00 +02:00
)
2014-12-18 05:38:10 +01:00
// The core macro project defines the main logic of the DSL, abstracted
2019-07-28 05:49:24 +02:00
// away from several sbt implementors (tasks, settings, et cetera).
2017-05-23 23:53:04 +02:00
lazy val coreMacrosProj = (project in file("core-macros"))
.dependsOn(
collectionProj,
utilCache,
)
2017-05-23 23:53:04 +02:00
.settings(
testedBaseSettings,
name := "Core Macros",
SettingKey[Boolean]("exportPipelining") := false,
2017-07-20 18:31:39 +02:00
mimaSettings,
)
2014-12-18 05:38:10 +01:00
// Fixes scope=Scope for Setting (core defined in collectionProj) to define the settings system used in build definitions
2017-04-21 09:14:31 +02:00
lazy val mainSettingsProj = (project in file("main-settings"))
.dependsOn(
completeProj,
commandProj,
stdTaskProj,
coreMacrosProj,
logicProj,
utilLogging,
utilCache,
utilRelation,
)
2017-04-21 09:14:31 +02:00
.settings(
testedBaseSettings,
name := "Main Settings",
2021-05-03 05:25:23 +02:00
Test / testOptions ++= {
Explicitly set scripted and server test classpath This commit makes it so that the scalaVersion, sbtVersion and classpath are always passed in as parameters to any method that creates an sbt server -- either for scripted or for the sbt server tests. By making that change, I was able to change the implementation of scripted in the sbt project to use publishLocalBin instead of publishLocal. This makes the scripted tests start much faster (doc alone can easily take 30 second) with messing with the build to exclude slow tasks from publishLocal. As part of this change, I removed the test dependency on scriptedSbtRedux for sbtProj and instead had scriptedSbtRedux depend on sbtProj. This allowed me to remove some messy LocalProject logic in the resourceGenerators for scriptedSbtReduxProj. I also had to remove a number of imports in the scriptedSbtReduxProj because the definitions available in the sbt package object became available. I also removed the dependency on sbt-buildinfo and instead pass the values from the build into test classes using scalatest properties. I ran into a number of minor issues with the build info plugin, namely that I couldn't get fullClasspathAsJars to reliably run as a BuildInfo key. It also is somewhat more clear to me to just rely on the built in scalatest functionality. The big drawback is that the scalatest properties can only be strings, but that restriction isn't really a problem here (strangely the TestData structure has a field configMap which is effectively Map[String, Any] but Any is actually always String given how the TestData is created as part of framework initialization. Since scripted no longer publishes, scriptedUnpublished is now effectively an alias for scripted. To get publishLocalBin working, I had to copy private code from IvyXml.scala into PublishBinPlugin. Once we publish a new version of sbt, we can remove the copied code and invoke IvyXml.makeIvyXmlBefore directly.
2020-01-12 04:52:36 +01:00
val cp = (Test / fullClasspathAsJars).value.map(_.data).mkString(java.io.File.pathSeparator)
val framework = TestFrameworks.ScalaTest
Tests.Argument(framework, s"-Dsbt.server.classpath=$cp") ::
Tests.Argument(framework, s"-Dsbt.server.version=${version.value}") ::
Tests.Argument(framework, s"-Dsbt.server.scala.version=${scalaVersion.value}") :: Nil
},
2017-07-20 18:31:39 +02:00
mimaSettings,
mimaBinaryIssueFilters ++= Seq(
),
2017-04-21 09:14:31 +02:00
)
2024-10-09 08:53:58 +02:00
.dependsOn(lmCore)
.configure(addSbtIO, addSbtCompilerInterface, addSbtCompilerClasspath)
2014-12-18 05:38:10 +01:00
2019-04-18 09:14:04 +02:00
lazy val zincLmIntegrationProj = (project in file("zinc-lm-integration"))
.settings(
name := "Zinc LM Integration",
testedBaseSettings,
2021-05-03 05:25:23 +02:00
Test / testOptions +=
Explicitly set scripted and server test classpath This commit makes it so that the scalaVersion, sbtVersion and classpath are always passed in as parameters to any method that creates an sbt server -- either for scripted or for the sbt server tests. By making that change, I was able to change the implementation of scripted in the sbt project to use publishLocalBin instead of publishLocal. This makes the scripted tests start much faster (doc alone can easily take 30 second) with messing with the build to exclude slow tasks from publishLocal. As part of this change, I removed the test dependency on scriptedSbtRedux for sbtProj and instead had scriptedSbtRedux depend on sbtProj. This allowed me to remove some messy LocalProject logic in the resourceGenerators for scriptedSbtReduxProj. I also had to remove a number of imports in the scriptedSbtReduxProj because the definitions available in the sbt package object became available. I also removed the dependency on sbt-buildinfo and instead pass the values from the build into test classes using scalatest properties. I ran into a number of minor issues with the build info plugin, namely that I couldn't get fullClasspathAsJars to reliably run as a BuildInfo key. It also is somewhat more clear to me to just rely on the built in scalatest functionality. The big drawback is that the scalatest properties can only be strings, but that restriction isn't really a problem here (strangely the TestData structure has a field configMap which is effectively Map[String, Any] but Any is actually always String given how the TestData is created as part of framework initialization. Since scripted no longer publishes, scriptedUnpublished is now effectively an alias for scripted. To get publishLocalBin working, I had to copy private code from IvyXml.scala into PublishBinPlugin. Once we publish a new version of sbt, we can remove the copied code and invoke IvyXml.makeIvyXmlBefore directly.
2020-01-12 04:52:36 +01:00
Tests.Argument(TestFrameworks.ScalaTest, s"-Dsbt.zinc.version=$zincVersion"),
2025-08-11 12:39:47 +02:00
mimaSettings,
2020-04-24 23:43:07 +02:00
mimaBinaryIssueFilters ++= Seq(
),
libraryDependencies += launcherInterface,
2019-04-18 09:14:04 +02:00
)
2024-10-09 08:53:58 +02:00
.dependsOn(lmCore, lmIvy)
.configure(addSbtZincCompileCore)
2019-04-18 09:14:04 +02:00
lazy val buildFileProj = (project in file("buildfile"))
.dependsOn(
mainSettingsProj,
)
.settings(
testedBaseSettings,
name := "build file",
libraryDependencies ++= Seq(scalaCompiler),
2025-08-11 12:39:47 +02:00
mimaSettings,
)
2024-10-09 08:53:58 +02:00
.dependsOn(lmCore, lmIvy)
.configure(addSbtIO, addSbtCompilerInterface, addSbtZincCompileCore)
2016-11-23 16:17:34 +01:00
// The main integration project for sbt. It brings all of the projects together, configures them, and provides for overriding conventions.
2017-04-21 09:14:31 +02:00
lazy val mainProj = (project in file("main"))
2017-06-16 22:11:33 +02:00
.enablePlugins(ContrabandPlugin)
2019-05-11 09:42:06 +02:00
.dependsOn(
actionsProj,
2022-09-20 09:49:26 +02:00
buildFileProj,
2019-05-11 09:42:06 +02:00
mainSettingsProj,
runProj,
commandProj,
collectionProj,
zincLmIntegrationProj,
utilLogging,
2019-05-11 09:42:06 +02:00
)
2017-04-21 09:14:31 +02:00
.settings(
testedBaseSettings,
2014-12-18 05:38:10 +01:00
name := "Main",
2018-10-05 19:32:40 +02:00
checkPluginCross := {
val sv = scalaVersion.value
2020-01-10 14:41:55 +01:00
val f = baseDirectory.value / "src" / "main" / "scala" / "sbt" / "PluginCross.scala"
2021-01-11 01:23:43 +01:00
if (sv.startsWith("2.12") && !IO.readLines(f).exists(_.contains(s""""$sv""""))) {
2020-01-10 14:41:55 +01:00
sys.error(s"PluginCross.scala does not match up with the scalaVersion $sv")
2021-01-11 01:23:43 +01:00
}
},
2020-01-10 14:41:55 +01:00
libraryDependencies ++=
2022-10-18 16:08:23 +02:00
(Seq(
2024-10-23 01:25:51 +02:00
scalaXml,
2022-10-18 16:08:23 +02:00
sjsonNewScalaJson.value,
sjsonNewCore.value,
launcherInterface,
caffeine,
) ++ log4jModules),
2021-01-11 01:23:43 +01:00
libraryDependencies ++= (scalaVersion.value match {
case v if v.startsWith("2.12.") => List()
case _ => List(scalaPar)
}),
2021-05-03 05:25:23 +02:00
Compile / managedSourceDirectories +=
baseDirectory.value / "src" / "main" / "contraband-scala",
2021-05-03 05:25:23 +02:00
Compile / generateContrabands / sourceManaged := baseDirectory.value / "src" / "main" / "contraband-scala",
Test / testOptions += Tests
2019-05-11 10:52:42 +02:00
.Argument(TestFrameworks.ScalaCheck, "-minSuccessfulTests", "1000"),
SettingKey[Boolean]("usePipelining") := false,
2023-11-25 00:51:20 +01:00
// TODO: Fix doc
Compile / doc / sources := Nil,
2025-08-11 12:39:47 +02:00
mimaSettings,
// mimaBinaryIssueFilters ++= Vector(),
2017-04-21 09:14:31 +02:00
)
2024-10-09 12:13:42 +02:00
.dependsOn(lmCore, lmIvy, lmCoursierShadedPublishing)
2024-10-09 08:53:58 +02:00
.configure(addSbtIO, addSbtCompilerInterface, addSbtZincCompileCore)
2014-12-18 05:38:10 +01:00
// Strictly for bringing implicits and aliases from subsystems into the top-level sbt namespace through a single package object
// technically, we need a dependency on all of mainProj's dependencies, but we don't do that since this is strictly an integration project
// with the sole purpose of providing certain identifiers without qualification (with a package object)
2021-04-20 05:43:15 +02:00
lazy val sbtProj = (project in file("sbt-app"))
Explicitly set scripted and server test classpath This commit makes it so that the scalaVersion, sbtVersion and classpath are always passed in as parameters to any method that creates an sbt server -- either for scripted or for the sbt server tests. By making that change, I was able to change the implementation of scripted in the sbt project to use publishLocalBin instead of publishLocal. This makes the scripted tests start much faster (doc alone can easily take 30 second) with messing with the build to exclude slow tasks from publishLocal. As part of this change, I removed the test dependency on scriptedSbtRedux for sbtProj and instead had scriptedSbtRedux depend on sbtProj. This allowed me to remove some messy LocalProject logic in the resourceGenerators for scriptedSbtReduxProj. I also had to remove a number of imports in the scriptedSbtReduxProj because the definitions available in the sbt package object became available. I also removed the dependency on sbt-buildinfo and instead pass the values from the build into test classes using scalatest properties. I ran into a number of minor issues with the build info plugin, namely that I couldn't get fullClasspathAsJars to reliably run as a BuildInfo key. It also is somewhat more clear to me to just rely on the built in scalatest functionality. The big drawback is that the scalatest properties can only be strings, but that restriction isn't really a problem here (strangely the TestData structure has a field configMap which is effectively Map[String, Any] but Any is actually always String given how the TestData is created as part of framework initialization. Since scripted no longer publishes, scriptedUnpublished is now effectively an alias for scripted. To get publishLocalBin working, I had to copy private code from IvyXml.scala into PublishBinPlugin. Once we publish a new version of sbt, we can remove the copied code and invoke IvyXml.makeIvyXmlBefore directly.
2020-01-12 04:52:36 +01:00
.dependsOn(mainProj)
2017-04-21 09:14:31 +02:00
.settings(
testedBaseSettings,
2014-12-18 05:38:10 +01:00
name := "sbt",
2015-09-14 09:27:22 +02:00
normalizedName := "sbt",
2021-01-11 01:23:43 +01:00
version := {
if (scalaVersion.value == baseScalaVersion) version.value
2024-10-09 09:36:37 +02:00
else Utils.version2_13.value
2021-01-11 01:23:43 +01:00
},
2017-07-20 18:31:39 +02:00
crossPaths := false,
2021-01-11 01:23:43 +01:00
crossTarget := { target.value / scalaVersion.value },
javaOptions ++= Seq("-Xdebug", "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005"),
2017-07-20 18:31:39 +02:00
mimaSettings,
mimaBinaryIssueFilters ++= sbtIgnoredProblems,
)
2020-02-14 15:01:11 +01:00
.settings(
Test / run / connectInput := true,
Test / run / outputStrategy := Some(StdoutOutput),
Test / run / fork := true,
2021-05-03 05:25:23 +02:00
Test / testOptions ++= {
2020-02-14 15:01:11 +01:00
val cp = (Test / fullClasspathAsJars).value.map(_.data).mkString(java.io.File.pathSeparator)
val framework = TestFrameworks.ScalaTest
Tests.Argument(framework, s"-Dsbt.server.classpath=$cp") ::
Tests.Argument(framework, s"-Dsbt.server.version=${version.value}") ::
Tests.Argument(framework, s"-Dsbt.server.scala.version=${scalaVersion.value}") :: Nil
},
)
2022-09-20 09:49:26 +02:00
.configure(addSbtIO)
// addSbtCompilerBridge
lazy val serverTestProj = (project in file("server-test"))
.dependsOn(sbtProj % "compile->test", scriptedSbtProj % "compile->test")
.settings(
testedBaseSettings,
2024-10-09 09:36:37 +02:00
Utils.noPublish,
// make server tests serial
Test / watchTriggers += baseDirectory.value.toGlob / "src" / "server-test" / **,
Test / parallelExecution := false,
2018-03-26 16:37:25 +02:00
Test / run / connectInput := true,
Test / run / outputStrategy := Some(StdoutOutput),
Test / run / fork := true,
Test / sourceGenerators += Def.task {
val rawClasspath =
(Compile / fullClasspathAsJars).value.map(_.data).mkString(java.io.File.pathSeparator)
val cp =
2021-11-14 14:59:34 +01:00
if (scala.util.Properties.isWin) rawClasspath.replace("\\", "\\\\")
else rawClasspath
val content = {
s"""|
|package testpkg
|
|object TestProperties {
| val classpath = "$cp"
| val version = "${version.value}"
| val scalaVersion = "${scalaVersion.value}"
|}
""".stripMargin
}
2021-12-12 07:49:11 +01:00
val file =
(Test / target).value / "generated" / "src" / "test" / "scala" / "testpkg" / "TestProperties.scala"
IO.write(file, content)
file :: Nil
Explicitly set scripted and server test classpath This commit makes it so that the scalaVersion, sbtVersion and classpath are always passed in as parameters to any method that creates an sbt server -- either for scripted or for the sbt server tests. By making that change, I was able to change the implementation of scripted in the sbt project to use publishLocalBin instead of publishLocal. This makes the scripted tests start much faster (doc alone can easily take 30 second) with messing with the build to exclude slow tasks from publishLocal. As part of this change, I removed the test dependency on scriptedSbtRedux for sbtProj and instead had scriptedSbtRedux depend on sbtProj. This allowed me to remove some messy LocalProject logic in the resourceGenerators for scriptedSbtReduxProj. I also had to remove a number of imports in the scriptedSbtReduxProj because the definitions available in the sbt package object became available. I also removed the dependency on sbt-buildinfo and instead pass the values from the build into test classes using scalatest properties. I ran into a number of minor issues with the build info plugin, namely that I couldn't get fullClasspathAsJars to reliably run as a BuildInfo key. It also is somewhat more clear to me to just rely on the built in scalatest functionality. The big drawback is that the scalatest properties can only be strings, but that restriction isn't really a problem here (strangely the TestData structure has a field configMap which is effectively Map[String, Any] but Any is actually always String given how the TestData is created as part of framework initialization. Since scripted no longer publishes, scriptedUnpublished is now effectively an alias for scripted. To get publishLocalBin working, I had to copy private code from IvyXml.scala into PublishBinPlugin. Once we publish a new version of sbt, we can remove the copied code and invoke IvyXml.makeIvyXmlBefore directly.
2020-01-12 04:52:36 +01:00
},
2017-04-21 09:14:31 +02:00
)
2017-10-20 05:18:43 +02:00
val isWin = scala.util.Properties.isWin
val isLinux = scala.util.Properties.isLinux
val isArmArchitecture: Boolean = sys.props
.getOrElse("os.arch", "")
.toLowerCase(Locale.ROOT) == "aarch64"
val buildThinClient =
inputKey[JPath]("generate a java implementation of the thin client")
// Use a TaskKey rather than SettingKey for nativeInstallDirectory so it can left unset by default
val nativeInstallDirectory = taskKey[JPath]("The install directory for the native executable")
val installNativeThinClient = inputKey[JPath]("Install the native executable")
lazy val sbtClientProj = (project in file("client"))
.enablePlugins(NativeImagePlugin)
.dependsOn(commandProj)
.settings(
commonSettings,
2024-10-09 09:36:37 +02:00
Utils.noPublish,
name := "sbt-client",
2024-10-28 04:55:30 +01:00
bspEnabled := false,
crossPaths := false,
exportJars := true,
2022-12-09 00:40:34 +01:00
libraryDependencies += scalatest % Test,
Compile / mainClass := Some("sbt.client.Client"),
nativeImageReady := { () =>
()
},
2024-10-11 19:34:55 +02:00
nativeImageVersion := "23.0",
nativeImageJvm := "graalvm-java23",
nativeImageOutput := {
val outputDir = (target.value / "bin").toPath
if (!Files.exists(outputDir)) {
Files.createDirectories(outputDir)
}
outputDir.resolve("sbtn").toFile
},
nativeImageOptions ++= Seq(
"--no-fallback",
s"--initialize-at-run-time=sbt.client",
2024-10-20 04:02:40 +02:00
// "The current machine does not support all of the following CPU features that are required by
// the image: [CX8, CMOV, FXSR, MMX, SSE, SSE2, SSE3, SSSE3, SSE4_1, SSE4_2, POPCNT, LZCNT, AVX,
// AVX2, BMI1, BMI2, FMA, F16C]."
"-march=compatibility",
// "--verbose",
"-H:IncludeResourceBundles=jline.console.completer.CandidateListCompletionHandler",
"-H:+ReportExceptionStackTraces",
"-H:-ParseRuntimeOptions",
2020-08-14 04:56:02 +02:00
s"-H:Name=${target.value / "bin" / "sbtn"}",
),
buildThinClient := {
val isFish = Def.spaceDelimited("").parsed.headOption.fold(false)(_ == "--fish")
val ext = if (isWin) ".bat" else if (isFish) ".fish" else ".sh"
val output = target.value.toPath / "bin" / s"${if (isFish) "fish-" else ""}client$ext"
java.nio.file.Files.createDirectories(output.getParent)
val cp = (Compile / fullClasspathAsJars).value.map(_.data)
val args =
if (isWin) "%*" else if (isFish) s"$$argv" else s"$$*"
java.nio.file.Files.write(
output,
s"""
|${if (isWin) "@echo off" else s"#!/usr/bin/env ${if (isFish) "fish" else "sh"}"}
|
|java -cp ${cp.mkString(java.io.File.pathSeparator)} sbt.client.Client --jna $args
""".stripMargin.linesIterator.toSeq.tail.mkString("\n").getBytes
)
output.toFile.setExecutable(true)
output
},
)
/*
lazy val sbtBig = (project in file(".big"))
.dependsOn(sbtProj)
.settings(
name := "sbt-big",
normalizedName := "sbt-big",
crossPaths := false,
assemblyShadeRules.in(assembly) := {
val packagesToBeShaded = Seq(
"fastparse",
"jawn",
"scalapb",
)
packagesToBeShaded.map( prefix => {
ShadeRule.rename(s"$prefix.**" -> s"sbt.internal.$prefix.@1").inAll
})
},
assemblyMergeStrategy in assembly := {
case "LICENSE" | "NOTICE" => MergeStrategy.first
case x => (assemblyMergeStrategy in assembly).value(x)
},
artifact.in(Compile, packageBin) := artifact.in(Compile, assembly).value,
assemblyOption.in(assembly) ~= { _.copy(includeScala = false) },
addArtifact(artifact.in(Compile, packageBin), assembly),
pomPostProcess := { node =>
new RuleTransformer(new RewriteRule {
override def transform(node: XmlNode): XmlNodeSeq = node match {
case e: Elem if node.label == "dependency" =>
Comment(
"the dependency that was here has been absorbed via sbt-assembly"
)
case _ => node
}
}).transform(node).head
},
)
2019-05-11 09:42:06 +02:00
*/
// util projects used by Zinc and Lm
lazy val lowerUtils = (project in (file("internal") / "lower"))
.aggregate(lowerUtilProjects.map(p => LocalProject(p.id)): _*)
.settings(
2024-10-09 09:36:37 +02:00
Utils.noPublish
)
lazy val upperModules = (project in (file("internal") / "upper"))
.aggregate(
((allProjects diff lowerUtilProjects)
2024-12-18 06:24:44 +01:00
diff Seq(bundledLauncherProj, lmCoursierShaded)).map(p => LocalProject(p.id)): _*
)
.settings(
2024-10-09 09:36:37 +02:00
Utils.noPublish
)
lazy val sbtIgnoredProblems = {
2017-11-29 22:45:02 +01:00
Vector(
2017-04-21 09:14:31 +02:00
)
}
2014-12-18 05:38:10 +01:00
def scriptedTask(launch: Boolean): Def.Initialize[InputTask[Unit]] = Def.inputTask {
val _ = publishLocalBinAll.value
val launchJar = s"-Dsbt.launch.jar=${(bundledLauncherProj / Compile / packageBin).value}"
2017-04-21 09:14:31 +02:00
Scripted.doScripted(
(scriptedSbtProj / scalaInstance).value,
2017-04-21 09:14:31 +02:00
scriptedSource.value,
scriptedBufferLog.value,
2018-01-24 14:42:18 +01:00
Def.setting(Scripted.scriptedParser(scriptedSource.value)).parsed,
2017-04-21 09:14:31 +02:00
scriptedPrescripted.value,
scriptedLaunchOpts.value ++ (if (launch) Some(launchJar) else None),
Explicitly set scripted and server test classpath This commit makes it so that the scalaVersion, sbtVersion and classpath are always passed in as parameters to any method that creates an sbt server -- either for scripted or for the sbt server tests. By making that change, I was able to change the implementation of scripted in the sbt project to use publishLocalBin instead of publishLocal. This makes the scripted tests start much faster (doc alone can easily take 30 second) with messing with the build to exclude slow tasks from publishLocal. As part of this change, I removed the test dependency on scriptedSbtRedux for sbtProj and instead had scriptedSbtRedux depend on sbtProj. This allowed me to remove some messy LocalProject logic in the resourceGenerators for scriptedSbtReduxProj. I also had to remove a number of imports in the scriptedSbtReduxProj because the definitions available in the sbt package object became available. I also removed the dependency on sbt-buildinfo and instead pass the values from the build into test classes using scalatest properties. I ran into a number of minor issues with the build info plugin, namely that I couldn't get fullClasspathAsJars to reliably run as a BuildInfo key. It also is somewhat more clear to me to just rely on the built in scalatest functionality. The big drawback is that the scalatest properties can only be strings, but that restriction isn't really a problem here (strangely the TestData structure has a field configMap which is effectively Map[String, Any] but Any is actually always String given how the TestData is created as part of framework initialization. Since scripted no longer publishes, scriptedUnpublished is now effectively an alias for scripted. To get publishLocalBin working, I had to copy private code from IvyXml.scala into PublishBinPlugin. Once we publish a new version of sbt, we can remove the copied code and invoke IvyXml.makeIvyXmlBefore directly.
2020-01-12 04:52:36 +01:00
scalaVersion.value,
version.value,
(scriptedSbtProj / Test / fullClasspathAsJars).value
.map(_.data)
.filterNot(_.getName.contains("scala-compiler")),
2022-10-02 07:58:37 +02:00
(bundledLauncherProj / Compile / packageBin).value,
streams.value.log
2017-04-21 09:14:31 +02:00
)
2014-12-18 05:38:10 +01:00
}
lazy val publishLauncher = TaskKey[Unit]("publish-launcher")
2017-04-21 09:14:31 +02:00
def allProjects =
Seq(
logicProj,
completeProj,
2017-04-21 09:14:31 +02:00
testingProj,
taskProj,
stdTaskProj,
runProj,
scriptedSbtProj,
2017-04-21 09:14:31 +02:00
protocolProj,
actionsProj,
commandProj,
mainSettingsProj,
2019-04-18 09:14:04 +02:00
zincLmIntegrationProj,
2017-04-21 09:14:31 +02:00
mainProj,
sbtProj,
2017-05-26 06:59:49 +02:00
bundledLauncherProj,
sbtClientProj,
buildFileProj,
utilCache,
utilTracking,
2024-03-17 21:32:02 +01:00
collectionProj,
coreMacrosProj,
remoteCacheProj,
lmCore,
lmIvy,
2024-10-09 10:48:43 +02:00
lmCoursierDefinitions,
lmCoursier,
lmCoursierShaded,
lmCoursierShadedPublishing,
workerProj,
) ++ lowerUtilProjects
// These need to be cross published to 2.12 and 2.13 for Zinc
lazy val lowerUtilProjects =
Seq(
utilCore,
utilControl,
utilInterface,
utilLogging,
utilPosition,
utilRelation,
utilScripted,
2017-04-21 09:14:31 +02:00
)
2015-02-03 04:44:02 +01:00
lazy val nonRoots = allProjects.map(p => LocalProject(p.id))
2014-12-18 05:38:10 +01:00
2018-07-31 02:28:42 +02:00
ThisBuild / scriptedBufferLog := true
2021-12-12 07:49:11 +01:00
ThisBuild / scriptedPrescripted := { _ => }
2018-07-31 02:28:42 +02:00
2017-04-21 09:14:31 +02:00
def otherRootSettings =
Seq(
2022-10-02 07:58:37 +02:00
scripted := scriptedTask(true).evaluated,
scriptedUnpublished := scriptedTask(true).evaluated,
2021-05-03 05:25:23 +02:00
scriptedSource := (sbtProj / sourceDirectory).value / "sbt-test",
scripted / watchTriggers += scriptedSource.value.toGlob / **,
scriptedUnpublished / watchTriggers := (scripted / watchTriggers).value,
2019-12-30 01:26:05 +01:00
scriptedLaunchOpts := List("-Xmx1500M", "-Xms512M", "-server") :::
(sys.props.get("sbt.ivy.home") match {
case Some(home) => List(s"-Dsbt.ivy.home=$home")
case _ => Nil
}),
publishLocalBinAll := {
val _ = (Compile / publishLocalBin).all(scriptedProjects).value
},
2017-04-21 09:14:31 +02:00
) ++ inConfig(Scripted.RepoOverrideTest)(
Seq(
2017-06-23 18:58:00 +02:00
scriptedLaunchOpts := List(
"-Xmx1500M",
"-Xms512M",
"-server",
"-Dsbt.override.build.repos=true",
s"""-Dsbt.repository.config=${scriptedSource.value / "repo.config"}"""
2019-12-30 01:26:05 +01:00
) :::
(sys.props.get("sbt.ivy.home") match {
case Some(home) => List(s"-Dsbt.ivy.home=$home")
case _ => Nil
}),
scripted := scriptedTask(true).evaluated,
scriptedUnpublished := scriptedTask(true).evaluated,
2021-05-03 05:25:23 +02:00
scriptedSource := (sbtProj / sourceDirectory).value / "repo-override-test"
2019-05-11 09:42:06 +02:00
)
)
lazy val docProjects: ScopeFilter = ScopeFilter(
2019-05-11 09:42:06 +02:00
inAnyProject -- inProjects(
sbtRoot,
sbtProj,
scriptedSbtProj,
upperModules,
lowerUtils,
2019-05-11 09:42:06 +02:00
),
inConfigurations(Compile)
2014-12-18 05:38:10 +01:00
)
lazy val javafmtOnCompile = taskKey[Unit]("Formats java sources before compile")
2024-10-06 02:46:25 +02:00
lazy val scriptedProjects = ScopeFilter(inAnyProject)
2014-12-18 23:40:20 +01:00
def customCommands: Seq[Setting[?]] = Seq(
2018-02-21 08:28:33 +01:00
commands += Command.command("publishLocalAllModule") { state =>
val extracted = Project.extract(state)
import extracted._
2019-05-11 09:42:06 +02:00
val sv = get(scalaVersion)
val projs = structure.allProjectRefs
2021-12-12 07:49:11 +01:00
val ioOpt = projs find { case ProjectRef(_, id) => id == "ioRoot"; case _ => false }
2018-02-21 08:28:33 +01:00
val utilOpt = projs find { case ProjectRef(_, id) => id == "utilRoot"; case _ => false }
2021-12-12 07:49:11 +01:00
val lmOpt = projs find { case ProjectRef(_, id) => id == "lmRoot"; case _ => false }
2018-02-21 08:28:33 +01:00
val zincOpt = projs find { case ProjectRef(_, id) => id == "zincRoot"; case _ => false }
2021-12-12 07:49:11 +01:00
(ioOpt map { case ProjectRef(build, _) => "{" + build.toString + "}/publishLocal" }).toList :::
(utilOpt map { case ProjectRef(build, _) =>
"{" + build.toString + "}/publishLocal"
}).toList :::
(lmOpt map { case ProjectRef(build, _) =>
"{" + build.toString + "}/publishLocal"
}).toList :::
(zincOpt map { case ProjectRef(build, _) =>
val zincSv = get((ProjectRef(build, "zinc") / scalaVersion))
val csv = get((ProjectRef(build, "compilerBridge") / crossScalaVersions)).toList
(csv flatMap { bridgeSv =>
s"++$bridgeSv" :: ("{" + build.toString + "}compilerBridge/publishLocal") :: Nil
}) :::
List(s"++$zincSv", "{" + build.toString + "}/publishLocal")
2019-05-11 09:42:06 +02:00
}).getOrElse(Nil) :::
List(s"++$sv", "publishLocal") :::
state
2018-02-21 08:28:33 +01:00
},
commands += Command.command("releaseLowerUtils") { state =>
// TODO - Any sort of validation
"clean" ::
"+lowerUtils/compile" ::
"+lowerUtils/publishSigned" ::
state
},
commands += Command.command("release") { state =>
2014-12-18 23:40:20 +01:00
// TODO - Any sort of validation
2021-04-26 05:15:16 +02:00
"upperModules/compile" ::
"upperModules/publishSigned" ::
"bundledLauncherProj/publishSigned" ::
2015-02-21 03:09:43 +01:00
state
},
2014-12-18 23:40:20 +01:00
)
ThisBuild / pomIncludeRepository := (_ => false) // drop repos other than Maven Central from POM
ThisBuild / publishTo := {
2025-06-01 23:53:33 +02:00
val centralSnapshots = "https://central.sonatype.com/repository/maven-snapshots/"
val v = (ThisBuild / version).value
if (v.endsWith("SNAPSHOT")) Some("central-snapshots" at centralSnapshots)
2025-06-01 23:53:33 +02:00
else localStaging.value
}
ThisBuild / publishMavenStyle := true
def lmTestSettings: Seq[Setting[?]] = Def.settings(
Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat,
Test / parallelExecution := false
)
2024-10-09 08:55:37 +02:00
lazy val lmCore = (project in file("lm-core"))
.enablePlugins(ContrabandPlugin, JsonCodecPlugin)
2017-04-26 22:55:38 +02:00
.settings(
2015-08-19 09:56:08 +02:00
commonSettings,
lmTestSettings,
name := "librarymanagement-core",
2022-01-30 05:29:07 +01:00
contrabandSjsonNewVersion := sjsonNewVersion,
libraryDependencies ++= Seq(
jsch,
2024-10-23 01:25:51 +02:00
// scalaReflect,
2022-01-30 05:29:07 +01:00
// scalaCompiler.value,
launcherInterface,
2022-06-13 03:55:09 +02:00
gigahorseApacheHttp,
2024-10-23 01:25:51 +02:00
scalaXml,
2024-10-09 08:53:58 +02:00
sjsonNewScalaJson.value % Optional,
sjsonNewCore.value % Optional,
2024-10-23 01:56:59 +02:00
scalatest % Test,
scalacheck % Test,
2019-08-18 05:06:52 +02:00
scalaVerify % Test,
),
2021-05-03 04:18:03 +02:00
Compile / resourceGenerators += Def
.task(
2024-10-09 09:36:37 +02:00
Utils.generateVersionFile(
version.value,
resourceManaged.value,
streams.value,
2024-10-09 08:53:58 +02:00
(Compile / compile).value.asInstanceOf[Analysis]
)
2017-06-21 14:47:35 +02:00
)
.taskValue,
2018-09-22 05:34:51 +02:00
Compile / scalacOptions ++= (scalaVersion.value match {
case v if v.startsWith("2.12.") => List("-Ywarn-unused:-locals,-explicits,-privates")
case _ => List()
}),
2024-10-08 01:55:45 +02:00
Compile / managedSourceDirectories +=
baseDirectory.value / "src" / "main" / "contraband-scala",
2021-05-03 04:18:03 +02:00
Compile / generateContrabands / sourceManaged := baseDirectory.value / "src" / "main" / "contraband-scala",
Compile / generateContrabands / contrabandFormatsForType := DatatypeConfig.getFormats,
2016-12-14 11:26:53 +01:00
// WORKAROUND sbt/sbt#2205 include managed sources in packageSrc
2021-05-03 04:18:03 +02:00
Compile / packageSrc / mappings ++= {
val srcs = (Compile / managedSources).value
val sdirs = (Compile / managedSourceDirectories).value
2016-12-14 11:26:53 +01:00
val base = baseDirectory.value
2024-10-09 08:53:58 +02:00
import Path._
2016-12-14 11:26:53 +01:00
(((srcs --- sdirs --- base) pair (relativeTo(sdirs) | relativeTo(base) | flat)) toSeq)
2017-07-20 18:13:35 +02:00
},
2025-08-11 12:39:47 +02:00
mimaSettings,
2017-04-26 22:55:38 +02:00
)
2024-10-09 08:53:58 +02:00
.dependsOn(utilLogging, utilPosition, utilCache)
.configure(addSbtIO, addSbtCompilerInterface)
2024-10-09 08:55:37 +02:00
lazy val lmIvy = (project in file("lm-ivy"))
.enablePlugins(ContrabandPlugin, JsonCodecPlugin)
2019-08-18 05:06:52 +02:00
.dependsOn(lmCore)
.settings(
commonSettings,
lmTestSettings,
name := "librarymanagement-ivy",
2022-01-30 05:29:07 +01:00
contrabandSjsonNewVersion := sjsonNewVersion,
2019-08-18 05:06:52 +02:00
libraryDependencies ++= Seq(
ivy,
2024-10-09 08:53:58 +02:00
sjsonNewScalaJson.value,
sjsonNewCore.value,
2024-10-23 01:56:59 +02:00
scalatest % Test,
scalacheck % Test,
2019-08-18 05:06:52 +02:00
scalaVerify % Test,
),
2024-10-08 01:55:45 +02:00
Compile / managedSourceDirectories +=
baseDirectory.value / "src" / "main" / "contraband-scala",
2021-05-03 04:18:03 +02:00
Compile / generateContrabands / sourceManaged := baseDirectory.value / "src" / "main" / "contraband-scala",
Compile / generateContrabands / contrabandFormatsForType := DatatypeConfig.getFormats,
2025-08-11 12:39:47 +02:00
Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat,
mimaSettings,
)
2024-06-04 11:10:52 +02:00
lazy val lmCoursierSettings: Seq[Setting[?]] = Def.settings(
2024-10-09 10:48:43 +02:00
baseSettings,
2024-10-11 13:08:49 +02:00
headerLicense := Some(
HeaderLicense.Custom(
"""|sbt
|Copyright 2024, Scala Center
|Copyright 2015 - 2023, Alexandre Archambault
|Licensed under Apache License 2.0 (see LICENSE)
|""".stripMargin
)
),
2024-10-09 10:48:43 +02:00
developers +=
Developer(
"alexarchambault",
"Alexandre Archambault",
"",
url("https://github.com/alexarchambault")
),
2024-10-11 10:24:21 +02:00
)
2024-10-09 10:48:43 +02:00
lazy val lmCoursierDefinitions = project
2024-10-09 09:17:29 +02:00
.in(file("lm-coursier/definitions"))
.disablePlugins(MimaPlugin)
.settings(
2024-10-09 10:48:43 +02:00
lmCoursierSettings,
2024-10-11 10:24:21 +02:00
scalafixDependencies += "net.hamnaberg" %% "dataclass-scalafix" % dataclassScalafixVersion,
libraryDependencies ++= Seq(
2024-10-09 09:36:37 +02:00
coursier,
"net.hamnaberg" %% "dataclass-annotation" % dataclassScalafixVersion % Provided,
),
2022-12-08 23:31:15 +01:00
conflictWarning := ConflictWarning.disable,
2024-10-09 09:36:37 +02:00
Utils.noPublish,
)
2024-10-09 09:36:37 +02:00
.dependsOn(lmIvy % "provided")
lazy val lmCoursierDependencies = Def.settings(
libraryDependencies ++= Seq(
coursier,
coursierSbtMavenRepo,
"io.get-coursier.jniutils" % "windows-jni-utils-lmcoursier" % jniUtilsVersion,
"net.hamnaberg" %% "dataclass-annotation" % dataclassScalafixVersion % Provided,
"org.scalatest" %% "scalatest" % "3.2.19" % Test,
),
excludeDependencies ++= Seq(
ExclusionRule("org.scala-lang.modules", "scala-xml_2.13"),
),
)
lazy val lmCoursier = project
2024-10-09 09:17:29 +02:00
.in(file("lm-coursier"))
.settings(
2024-10-09 10:48:43 +02:00
lmCoursierSettings,
Mima.settings,
2019-07-02 14:01:08 +02:00
Mima.lmCoursierFilters,
2024-10-11 10:24:21 +02:00
lmCoursierDependencies,
2024-10-11 16:57:28 +02:00
Compile / sourceGenerators += Utils.dataclassGen(lmCoursierDefinitions).taskValue,
)
2024-10-09 09:36:37 +02:00
.dependsOn(
2024-10-09 10:48:43 +02:00
// We depend on lmIvy rather than just lmCore to handle the ModuleDescriptor
// passed to DependencyResolutionInterface.update, which is an IvySbt#Module
// (seems DependencyResolutionInterface.moduleDescriptor is ignored).
2024-10-09 09:36:37 +02:00
lmIvy
)
lazy val lmCoursierShaded = project
2024-10-09 09:17:29 +02:00
.in(file("lm-coursier/target/shaded-module"))
.settings(
2024-10-09 10:48:43 +02:00
lmCoursierSettings,
Mima.settings,
2019-07-02 14:01:08 +02:00
Mima.lmCoursierFilters,
Mima.lmCoursierShadedFilters,
Compile / sources := (lmCoursier / Compile / sources).value,
2024-10-11 10:24:21 +02:00
lmCoursierDependencies,
autoScalaLibrary := false,
libraryDependencies ++= Seq(
scala3Library % Provided,
),
assembly / assemblyOption ~= { _.withIncludeScala(false) },
2024-10-11 10:24:21 +02:00
conflictWarning := ConflictWarning.disable,
Utils.noPublish,
2022-09-23 20:03:55 +02:00
assemblyShadeRules := {
2024-10-11 10:24:21 +02:00
val namespacesToShade = Seq(
2020-05-12 00:16:06 +02:00
"coursier",
"org.fusesource",
"macrocompat",
2020-11-18 15:32:19 +01:00
"io.github.alexarchambault.windowsansi",
2021-08-01 14:18:32 +02:00
"concurrentrefhashmap",
2022-09-23 20:03:55 +02:00
"com.github.ghik",
2021-08-01 14:18:32 +02:00
// pulled by the plexus-archiver stuff that coursier-cache
// depends on for now… can hopefully be removed in the future
"com.google.common",
2022-09-23 20:03:55 +02:00
"com.jcraft",
"com.lmax",
2021-08-01 14:18:32 +02:00
"org.apache.commons",
"org.apache.xbean",
"org.codehaus",
"org.iq80",
2022-12-08 23:31:15 +01:00
"org.tukaani",
"com.github.plokhotnyuk.jsoniter_scala",
"scala.cli",
"com.github.luben.zstd",
"javax.inject" // hope shading this is fine… It's probably pulled via plexus-archiver, that sbt shouldn't use anyway…
2020-05-12 00:16:06 +02:00
)
2024-10-11 10:24:21 +02:00
namespacesToShade.map { ns =>
ShadeRule.rename(ns + ".**" -> s"lmcoursier.internal.shaded.$ns.@1").inAll
}
2020-05-12 00:16:06 +02:00
},
2024-10-11 10:24:21 +02:00
assemblyMergeStrategy := {
case PathList("lmcoursier", "internal", "shaded", "org", "fusesource", _*) =>
MergeStrategy.first
// case PathList("lmcoursier", "internal", "shaded", "package.class") => MergeStrategy.first
// case PathList("lmcoursier", "internal", "shaded", "package$.class") => MergeStrategy.first
case PathList("com", "github") => MergeStrategy.discard
case PathList("com", "jcraft") => MergeStrategy.discard
case PathList("com", "lmax") => MergeStrategy.discard
case PathList("com", "sun") => MergeStrategy.discard
case PathList("com", "swoval") => MergeStrategy.discard
case PathList("com", "typesafe") => MergeStrategy.discard
case PathList("gigahorse") => MergeStrategy.discard
case PathList("jline") => MergeStrategy.discard
case PathList("scala") => MergeStrategy.discard
case PathList("sjsonnew") => MergeStrategy.discard
case PathList("xsbti") => MergeStrategy.discard
case PathList("META-INF", "native", _*) => MergeStrategy.first
case "META-INF/services/lmcoursier.internal.shaded.coursier.jniutils.NativeApi" =>
MergeStrategy.first
case x =>
val oldStrategy = (ThisBuild / assemblyMergeStrategy).value
oldStrategy(x)
}
)
2024-10-09 09:36:37 +02:00
.dependsOn(lmIvy % "provided")
2024-10-11 10:24:21 +02:00
lazy val lmCoursierShadedPublishing = project
.in(file("lm-coursier/target/shaded-publishing-module"))
.settings(
scalaVersion := scala3,
name := "librarymanagement-coursier",
Compile / packageBin := (lmCoursierShaded / assembly).value,
Compile / exportedProducts := Seq(Attributed.blank((Compile / packageBin).value))
)