From 354dd25988bd97ec686148c0a8a54502d19a377c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 22 Sep 2024 15:56:32 -0400 Subject: [PATCH] fix: Fix common settings loading when root is synthetic **Problem** The new common settings feature doesn't work when the root isn't created by the user. **Solution** This fixes common settings by calling `expandCommonSettingsPerBase(...)` on the synthetic root's base first. --- main/src/main/scala/sbt/internal/Load.scala | 350 ++++++++++-------- .../build.sbt | 1 - .../parent-skip-publish/build.sbt | 6 +- .../sbt-test/project-matrix/custom/build.sbt | 16 +- .../sbt-test/project-matrix/java/build.sbt | 16 +- .../sbt-test/project/bare-settings/build.sbt | 13 - .../baz/build.sbt | 1 + .../common-settings-synthetic-root/build.sbt | 28 ++ .../common-settings-synthetic-root/test | 1 + .../project/common-settings/baz/build.sbt | 1 + .../project/common-settings/build.sbt | 33 ++ .../src/sbt-test/project/common-settings/test | 1 + .../src/sbt-test/reporter/nowarn/build.sbt | 14 +- 13 files changed, 275 insertions(+), 206 deletions(-) delete mode 100644 sbt-app/src/sbt-test/project/bare-settings/build.sbt create mode 100644 sbt-app/src/sbt-test/project/common-settings-synthetic-root/baz/build.sbt create mode 100644 sbt-app/src/sbt-test/project/common-settings-synthetic-root/build.sbt create mode 100644 sbt-app/src/sbt-test/project/common-settings-synthetic-root/test create mode 100644 sbt-app/src/sbt-test/project/common-settings/baz/build.sbt create mode 100644 sbt-app/src/sbt-test/project/common-settings/build.sbt create mode 100644 sbt-app/src/sbt-test/project/common-settings/test diff --git a/main/src/main/scala/sbt/internal/Load.scala b/main/src/main/scala/sbt/internal/Load.scala index 48d1b54d14..01b164ef9c 100755 --- a/main/src/main/scala/sbt/internal/Load.scala +++ b/main/src/main/scala/sbt/internal/Load.scala @@ -28,7 +28,7 @@ import sbt.librarymanagement.ivy.{ InlineIvyConfiguration, IvyDependencyResoluti import sbt.librarymanagement.{ Configuration, Configurations, Resolver } import sbt.nio.Settings import sbt.util.{ Logger, Show } -import xsbti.{ HashedVirtualFileRef, VirtualFile } +import xsbti.{ FileConverter, HashedVirtualFileRef, VirtualFile } import xsbti.compile.{ ClasspathOptionsUtil, Compilers } import java.io.File import java.net.URI @@ -943,142 +943,160 @@ private[sbt] object Load { extraSbtFiles: Seq[VirtualFile], converter: MappedFileConverter, ): LoadedProjects = - /*timed(s"Load.loadTransitive(${ newProjects.map(_.id) })", log)*/ { - def load( - newProjects: Seq[Project], - acc: Seq[Project], - generated: Seq[Path], - commonSettings0: Seq[Setting[_]], - ) = - loadTransitive( - newProjects, - buildBase, - plugins, - eval, - machineWideUserSettings, - commonSettings0, - acc, - memoSettings, - log, - makeOrDiscoverRoot = false, - buildUri, - context, - generated, - Nil, - converter, - ) + // alias for parameter forwarding + def loadTransitive1( + newProjects: Seq[Project], + acc: Seq[Project], + generated: Seq[Path], + commonSettings0: Seq[Setting[_]], + ): LoadedProjects = + loadTransitive( + newProjects, + buildBase, + plugins, + eval, + machineWideUserSettings, + commonSettings0, + acc, + memoSettings, + log, + makeOrDiscoverRoot = false, + buildUri, + context, + generated, + Nil, + converter, + ) - // load all relevant configuration files (.sbt, as .scala already exists at this point) - def discover(base: File): DiscoveredProjects = { - val auto = - if (base.getCanonicalFile() == buildBase.getCanonicalFile()) AddSettings.allDefaults - else AddSettings.defaultSbtFiles - - val extraFiles = - if base.getCanonicalFile() == buildBase.getCanonicalFile() && isMetaBuildContext(context) - then extraSbtFiles - else Nil - discoverProjects(auto, base, extraFiles, plugins, eval, memoSettings, converter) - } + // alias for parameter forwarding + def expandCommonSettingsPerBase1(directory: File): Seq[Setting[?]] = + expandCommonSettingsPerBase( + directory = directory, + memoSettings = memoSettings, + extraSbtFiles = extraSbtFiles, + converter = converter, + log = log, + ) - // Step two: - // a. Apply all the project manipulations from .sbt files in order - // b. Deduce the auto plugins for the project - // c. Finalize a project with all its settings/configuration. - def finalizeProject( - p: Project, - files: Seq[VirtualFile], - extraFiles: Seq[VirtualFile], - expand: Boolean - ): (Project, Seq[Project]) = { - val configFiles = files.flatMap(f => memoSettings.get(f)) - val p1: Project = Function.chain(configFiles.flatMap(_.manipulations))(p) - val autoPlugins: Seq[AutoPlugin] = - try plugins.detected.deducePluginsFromProject(p1, log) - catch { case e: AutoPluginException => throw translateAutoPluginException(e, p) } - val p2 = - resolveProject( - p1, - autoPlugins, - plugins, - commonSettings, - machineWideUserSettings, - memoSettings, - extraFiles, - converter, - log - ) - val projectLevelExtra = - if (expand) { - autoPlugins.flatMap( - _.derivedProjects(p2).map(_.setProjectOrigin(ProjectOrigin.DerivedProject)) - ) - } else Nil - (p2, projectLevelExtra) - } + // load all relevant configuration files (.sbt, as .scala already exists at this point) + def discover(base: File): DiscoveredProjects = { + val auto = + if (base.getCanonicalFile() == buildBase.getCanonicalFile()) AddSettings.allDefaults + else AddSettings.defaultSbtFiles + + val extraFiles = + if base.getCanonicalFile() == buildBase.getCanonicalFile() && isMetaBuildContext(context) + then extraSbtFiles + else Nil + discoverProjects(auto, base, extraFiles, plugins, eval, memoSettings, converter) + } - // Discover any new project definition for the base directory of this project, and load all settings. - def discoverAndLoad(p: Project, rest: Seq[Project]): LoadedProjects = { - val DiscoveredProjects(rootOpt, discovered, files, extraFiles, generated) = discover( - p.base + // Step two: + // a. Apply all the project manipulations from .sbt files in order + // b. Deduce the auto plugins for the project + // c. Finalize a project with all its settings/configuration. + def finalizeProject( + p: Project, + files: Seq[VirtualFile], + extraFiles: Seq[VirtualFile], + expand: Boolean + ): (Project, Seq[Project]) = { + val configFiles = files.flatMap(f => memoSettings.get(f)) + val p1: Project = Function.chain(configFiles.flatMap(_.manipulations))(p) + val autoPlugins: Seq[AutoPlugin] = + try plugins.detected.deducePluginsFromProject(p1, log) + catch { case e: AutoPluginException => throw translateAutoPluginException(e, p) } + val p2 = + resolveProjectSettings( + p = p1, + projectPlugins = autoPlugins, + loadedPlugins = plugins, + commonSettings = + commonSettings ++ expandCommonSettingsPerBase1(p1.base.getCanonicalFile()), + machineWideUserSettings = machineWideUserSettings, + memoSettings = memoSettings, + extraSbtFiles = extraFiles, + converter = converter, + log = log, ) + val projectLevelExtra = + if (expand) { + autoPlugins.flatMap( + _.derivedProjects(p2).map(_.setProjectOrigin(ProjectOrigin.DerivedProject)) + ) + } else Nil + (p2, projectLevelExtra) + } - // TODO: We assume here the project defined in a build.sbt WINS because the original was a - // phony. However, we may want to 'merge' the two, or only do this if the original was a - // default generated project. - val root = rootOpt.getOrElse(p) - val (finalRoot, projectLevelExtra) = finalizeProject(root, files, extraFiles, true) - val newProjects = rest ++ discovered ++ projectLevelExtra - val newAcc = acc :+ finalRoot - val newGenerated = generated ++ generatedConfigClassFiles - load(newProjects, newAcc, newGenerated, finalRoot.commonSettings) - } + // Discover any new project definition for the base directory of this project, and load all settings. + def discoverAndLoad(p: Project, rest: Seq[Project]): LoadedProjects = { + val DiscoveredProjects(rootOpt, discovered, files, extraFiles, generated) = discover( + p.base + ) - // Load all config files AND finalize the project at the root directory, if it exists. - // Continue loading if we find any more. - newProjects match - case Seq(next, rest @ _*) => - log.debug(s"[Loading] Loading project ${next.id} @ ${next.base}") - discoverAndLoad(next, rest) - case Nil if makeOrDiscoverRoot => - log.debug(s"[Loading] Scanning directory $buildBase") - val DiscoveredProjects(rootOpt, discovered, files, extraFiles, generated) = discover( - buildBase - ) - val discoveredIdsStr = discovered.map(_.id).mkString(",") - val (root, expand, moreProjects, otherProjects) = - rootOpt match - case Some(root) => - log.debug(s"[Loading] Found root project ${root.id} w/ remaining $discoveredIdsStr") - (root, true, discovered, LoadedProjects(Nil, Nil)) - case None => - log.debug(s"[Loading] Found non-root projects $discoveredIdsStr") - // Here we do something interesting... We need to create an aggregate root project - val otherProjects = load(discovered, acc, Nil, Nil) - val root = { - val existingIds = otherProjects.projects.map(_.id) - val defaultID = autoID(buildBase, context, existingIds) - val refs = existingIds.map(id => ProjectRef(buildUri, id)) - if (discovered.isEmpty || java.lang.Boolean.getBoolean("sbt.root.ivyplugin")) - BuildDef.defaultAggregatedProject(defaultID, buildBase, refs) - else BuildDef.generatedRootSkipPublish(defaultID, buildBase, refs) - } - (root, false, Nil, otherProjects) - val (finalRoot, projectLevelExtra) = - timed(s"Load.loadTransitive: finalizeProject($root)", log) { - finalizeProject(root, files, extraFiles, expand) - } - val newProjects = moreProjects ++ projectLevelExtra - val newAcc = finalRoot +: (acc ++ otherProjects.projects) - val newGenerated = - generated ++ otherProjects.generatedConfigClassFiles ++ generatedConfigClassFiles - load(newProjects, newAcc, newGenerated, finalRoot.commonSettings) - case Nil => - val projectIds = acc.map(_.id).mkString("(", ", ", ")") - log.debug(s"[Loading] Done in $buildBase, returning: $projectIds") - LoadedProjects(acc, generatedConfigClassFiles) + // TODO: We assume here the project defined in a build.sbt WINS because the original was a + // phony. However, we may want to 'merge' the two, or only do this if the original was a + // default generated project. + val root = rootOpt.getOrElse(p) + val (finalRoot, projectLevelExtra) = finalizeProject(root, files, extraFiles, true) + val newProjects = rest ++ discovered ++ projectLevelExtra + val newAcc = acc :+ finalRoot + val newGenerated = generated ++ generatedConfigClassFiles + loadTransitive1(newProjects, newAcc, newGenerated, finalRoot.commonSettings) } + // Load all config files AND finalize the project at the root directory, if it exists. + // Continue loading if we find any more. + newProjects match + case Seq(next, rest @ _*) => + log.debug(s"[Loading] Loading project ${next.id} @ ${next.base}") + discoverAndLoad(next, rest) + case Nil if makeOrDiscoverRoot => + log.debug(s"[Loading] Scanning directory $buildBase") + val DiscoveredProjects(rootOpt, discovered, files, extraFiles, generated) = discover( + buildBase + ) + val discoveredIdsStr = discovered.map(_.id).mkString(",") + val (root, expand, moreProjects, otherProjects) = + rootOpt match + case Some(root) => + log.debug(s"[Loading] Found root project ${root.id} w/ remaining $discoveredIdsStr") + (root, true, discovered, LoadedProjects(Nil, Nil)) + case None => + log.debug(s"[Loading] Found non-root projects $discoveredIdsStr") + // Here we do something interesting... We need to create an aggregate root project + val root = { + val defaultID = autoID(buildBase, context, Nil) + if discovered.isEmpty || java.lang.Boolean.getBoolean("sbt.root.ivyplugin") then + BuildDef.defaultProject(defaultID, buildBase) + else BuildDef.generatedRootSkipPublish(defaultID, buildBase, Nil) + } + val otherProjects = + loadTransitive1( + newProjects = discovered, + acc = acc, + generated = Nil, + commonSettings0 = commonSettings + ++ expandCommonSettingsPerBase1(buildBase.getCanonicalFile()), + ) + val existingIds = otherProjects.projects.map(_.id) + val refs = existingIds.map(id => ProjectRef(buildUri, id)) + (root.aggregate(refs: _*), false, Nil, otherProjects) + val (finalRoot, projectLevelExtra) = + timed(s"Load.loadTransitive: finalizeProject($root)", log) { + finalizeProject(root, files, extraFiles, expand) + } + val newProjects = moreProjects ++ projectLevelExtra + val newAcc = finalRoot +: (acc ++ otherProjects.projects) + val newGenerated = + generated ++ otherProjects.generatedConfigClassFiles ++ generatedConfigClassFiles + loadTransitive1(newProjects, newAcc, newGenerated, finalRoot.commonSettings) + case Nil => + val projectIds = acc.map(_.id).mkString("(", ", ", ")") + log.debug(s"[Loading] Done in $buildBase, returning: $projectIds") + LoadedProjects(acc, generatedConfigClassFiles) + end loadTransitive + private[this] def translateAutoPluginException( e: AutoPluginException, project: Project @@ -1116,18 +1134,18 @@ private[sbt] object Load { * @param extraSbtFiles Extra *.sbt files. * @param log A logger to report auto-plugin issues to. */ - private[sbt] def resolveProject( + private[sbt] def resolveProjectSettings( p: Project, projectPlugins: Seq[AutoPlugin], loadedPlugins: LoadedPlugins, - commonSettings0: Seq[Setting[_]], + commonSettings: Seq[Setting[_]], machineWideUserSettings: InjectSettings, memoSettings: mutable.Map[VirtualFile, LoadedSbtFile], extraSbtFiles: Seq[VirtualFile], converter: MappedFileConverter, log: Logger ): Project = - timed(s"Load.resolveProject(${p.id})", log) { + timed(s"Load.resolveProjectSettings(${p.id})", log) { import AddSettings._ val autoConfigs = projectPlugins.flatMap(_.projectConfigurations) val auto = AddSettings.allDefaults @@ -1150,35 +1168,7 @@ private[sbt] object Load { case _ => Nil expandPluginSettings(auto) } - def buildWideCommonSettings: Seq[Setting[_]] = { - // TODO - This mechanism of applying settings could be off... It's in two places now... - lazy val defaultSbtFiles = configurationSources(p.base.getCanonicalFile()) - .map(_.getAbsoluteFile().toPath()) - .map(converter.toVirtualFile) - lazy val sbtFiles: Seq[VirtualFile] = defaultSbtFiles ++ extraSbtFiles - // Grab all the settings we already loaded from sbt files - def settings(files: Seq[VirtualFile]): Seq[Setting[_]] = - if files.nonEmpty then - log.info( - s"${files.map(_.name()).mkString(s"loading settings for project ${p.id} from ", ",", " ...")}" - ) - else () - for - file <- files - config <- memoSettings.get(file).toSeq - setting <- config.settings - yield setting - def expandCommonSettings(auto: AddSettings): Seq[Setting[_]] = - auto match - case sf: DefaultSbtFiles => settings(sbtFiles.filter(sf.include)) - case q: Sequence => - q.sequence.foldLeft(Seq.empty[Setting[_]]) { (b, add) => - b ++ expandCommonSettings(add) - } - case _ => Nil - commonSettings0 ++ expandCommonSettings(auto) - } - def allProjectSettings: Seq[Setting[_]] = { + def allProjectSettings: Seq[Setting[_]] = // Expand the AddSettings instance into a real Seq[Setting[_]] we'll use on the project def expandSettings(auto: AddSettings): Seq[Setting[_]] = auto match @@ -1190,14 +1180,46 @@ private[sbt] object Load { } case _ => Nil expandSettings(auto) - } + end allProjectSettings + // Finally, a project we can use in buildStructure. - p.copy(settings = allAutoPluginSettings ++ buildWideCommonSettings ++ allProjectSettings) - .setCommonSettings(buildWideCommonSettings) + p.copy(settings = allAutoPluginSettings ++ commonSettings ++ allProjectSettings) + .setCommonSettings(commonSettings) .setAutoPlugins(projectPlugins) .prefixConfigs(autoConfigs: _*) } + private[this] def expandCommonSettingsPerBase( + directory: File, + memoSettings: mutable.Map[VirtualFile, LoadedSbtFile], + extraSbtFiles: Seq[VirtualFile], + converter: MappedFileConverter, + log: Logger + ): Seq[Setting[_]] = + val defaultSbtFiles = configurationSources(directory) + .map(_.getAbsoluteFile().toPath()) + .map(converter.toVirtualFile) + .toVector + val sbtFiles = defaultSbtFiles ++ extraSbtFiles.toVector + // Grab all the settings we already loaded from sbt files + def settings(files: Vector[VirtualFile]): Vector[Setting[_]] = + for + file <- files + config <- memoSettings.get(file).toSeq + setting <- config.settings + yield setting + import AddSettings.* + def expandCommonSettings(auto: AddSettings): Vector[Setting[_]] = + auto match + case sf: DefaultSbtFiles => settings(sbtFiles.filter(sf.include)) + case q: Sequence => + q.sequence.foldLeft(Vector.empty[Setting[_]]) { (b, add) => + b ++ expandCommonSettings(add) + } + case _ => Vector.empty + expandCommonSettings(AddSettings.allDefaults).distinct + end expandCommonSettingsPerBase + /** * This method attempts to discover all Project/settings it can using the configured AddSettings and project base. * diff --git a/sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/build.sbt b/sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/build.sbt index c356d3d6ad..38a5a26fee 100644 --- a/sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/build.sbt +++ b/sbt-app/src/sbt-test/actions/cross-strict-aggregation-scala-3/build.sbt @@ -1,5 +1,4 @@ scalaVersion := "2.12.19" -name := "root" lazy val core = project .settings( diff --git a/sbt-app/src/sbt-test/dependency-management/parent-skip-publish/build.sbt b/sbt-app/src/sbt-test/dependency-management/parent-skip-publish/build.sbt index 8b21bea685..60289aa7e4 100644 --- a/sbt-app/src/sbt-test/dependency-management/parent-skip-publish/build.sbt +++ b/sbt-app/src/sbt-test/dependency-management/parent-skip-publish/build.sbt @@ -1,11 +1,9 @@ -ThisBuild / organization := "com.example" -ThisBuild / ivyPaths := IvyPaths((ThisBuild / baseDirectory).value.toString, Some(((ThisBuild / baseDirectory).value / "ivy" / "cache").toString)) +organization := "com.example" +ivyPaths := IvyPaths((ThisBuild / baseDirectory).value.toString, Some(((ThisBuild / baseDirectory).value / "ivy" / "cache").toString)) name := "root" lazy val core = project .settings( name := "core", - // organization := "com.example", - ivyPaths := IvyPaths((ThisBuild / baseDirectory).value.toString, Some(((ThisBuild / baseDirectory).value / "ivy" / "cache").toString)) ) diff --git a/sbt-app/src/sbt-test/project-matrix/custom/build.sbt b/sbt-app/src/sbt-test/project-matrix/custom/build.sbt index d5bb325f5e..477bd44eff 100644 --- a/sbt-app/src/sbt-test/project-matrix/custom/build.sbt +++ b/sbt-app/src/sbt-test/project-matrix/custom/build.sbt @@ -1,12 +1,11 @@ -ThisBuild / organization := "com.example" -ThisBuild / version := "0.1.0-SNAPSHOT" -ThisBuild / publishMavenStyle := true - -ThisBuild / ivyPaths := { - val base = (ThisBuild / baseDirectory).value - IvyPaths(base.toString, s"$base/ivy-cache") +organization := "com.example" +version := "0.1.0-SNAPSHOT" +publishMavenStyle := true +ivyPaths := { + val base = baseDirectory.value + val thisBuildBase = (ThisBuild / baseDirectory).value + IvyPaths(base.toString, s"$thisBuildBase/ivy-cache") } -publish / skip := true lazy val config12 = ConfigAxis("Config1_2", "config1.2") lazy val config13 = ConfigAxis("Config1_3", "config1.3") @@ -21,7 +20,6 @@ lazy val app = (projectMatrix in file("app")) .dependsOn(core) .settings( name := "app", - ivyPaths := (ThisBuild / ivyPaths).value ) .customRow( scalaVersions = Seq(scala212, scala211), diff --git a/sbt-app/src/sbt-test/project-matrix/java/build.sbt b/sbt-app/src/sbt-test/project-matrix/java/build.sbt index 1b406f42ce..be8995d8de 100644 --- a/sbt-app/src/sbt-test/project-matrix/java/build.sbt +++ b/sbt-app/src/sbt-test/project-matrix/java/build.sbt @@ -1,12 +1,11 @@ -ThisBuild / organization := "com.example" -ThisBuild / version := "0.1.0-SNAPSHOT" -ThisBuild / publishMavenStyle := true - -ThisBuild / ivyPaths := { - val base = (ThisBuild / baseDirectory).value - IvyPaths(base.toString, s"$base/ivy-cache") +organization := "com.example" +version := "0.1.0-SNAPSHOT" +publishMavenStyle := true +ivyPaths := { + val base = baseDirectory.value + val thisBuildBase = (ThisBuild / baseDirectory).value + IvyPaths(base.toString, s"$thisBuildBase/ivy-cache") } -publish / skip := true lazy val config12 = ConfigAxis("Config1_2", "-config1.2") lazy val config13 = ConfigAxis("Config1_3", "-config1.3") @@ -16,7 +15,6 @@ lazy val scala212 = "2.12.10" lazy val app = (projectMatrix in file("app")) .settings( name := "app", - ivyPaths := (ThisBuild / ivyPaths).value ) .customRow( scalaVersions = Seq(scala212), diff --git a/sbt-app/src/sbt-test/project/bare-settings/build.sbt b/sbt-app/src/sbt-test/project/bare-settings/build.sbt deleted file mode 100644 index b9e2841360..0000000000 --- a/sbt-app/src/sbt-test/project/bare-settings/build.sbt +++ /dev/null @@ -1,13 +0,0 @@ -lazy val check = taskKey[Unit]("") -lazy val root = (project in file(".")) -lazy val foo = project -lazy val bar = project - -def scala212 = "2.12.17" -scalaVersion := scala212 - -check := { - assert((root / scalaVersion).value == scala212) - assert((foo / scalaVersion).value == scala212) - assert((bar / scalaVersion).value == scala212) -} diff --git a/sbt-app/src/sbt-test/project/common-settings-synthetic-root/baz/build.sbt b/sbt-app/src/sbt-test/project/common-settings-synthetic-root/baz/build.sbt new file mode 100644 index 0000000000..ba85cb3d79 --- /dev/null +++ b/sbt-app/src/sbt-test/project/common-settings-synthetic-root/baz/build.sbt @@ -0,0 +1 @@ +organization := "com.example.baz" diff --git a/sbt-app/src/sbt-test/project/common-settings-synthetic-root/build.sbt b/sbt-app/src/sbt-test/project/common-settings-synthetic-root/build.sbt new file mode 100644 index 0000000000..8d54a1f7ea --- /dev/null +++ b/sbt-app/src/sbt-test/project/common-settings-synthetic-root/build.sbt @@ -0,0 +1,28 @@ +lazy val check = taskKey[Unit]("") + +def scala212 = "2.12.19" +scalaVersion := scala212 +val o = "com.example" +organization := o + +lazy val foo = project +lazy val bar = project + .settings( + name := "bar", + organization := "com.example.bar", + ) + +lazy val baz = project + +check := { + assert((foo / scalaVersion).value == scala212) + assert((bar / scalaVersion).value == scala212) + assert((baz / scalaVersion).value == scala212) + + assert((foo / organization).value == o) + // Test that bar can override common setting in settings(...) + assert((bar / organization).value == "com.example.bar", s"unexpected bar / organization = {(bar / organization).value}") + // Test that baz/build.sbt bare settings get loaded + assert((baz / organization).value == "com.example.baz", s"unexpected baz/organization") +} +check / aggregate := false diff --git a/sbt-app/src/sbt-test/project/common-settings-synthetic-root/test b/sbt-app/src/sbt-test/project/common-settings-synthetic-root/test new file mode 100644 index 0000000000..15675b1696 --- /dev/null +++ b/sbt-app/src/sbt-test/project/common-settings-synthetic-root/test @@ -0,0 +1 @@ +> check diff --git a/sbt-app/src/sbt-test/project/common-settings/baz/build.sbt b/sbt-app/src/sbt-test/project/common-settings/baz/build.sbt new file mode 100644 index 0000000000..ba85cb3d79 --- /dev/null +++ b/sbt-app/src/sbt-test/project/common-settings/baz/build.sbt @@ -0,0 +1 @@ +organization := "com.example.baz" diff --git a/sbt-app/src/sbt-test/project/common-settings/build.sbt b/sbt-app/src/sbt-test/project/common-settings/build.sbt new file mode 100644 index 0000000000..75869076df --- /dev/null +++ b/sbt-app/src/sbt-test/project/common-settings/build.sbt @@ -0,0 +1,33 @@ +lazy val check = taskKey[Unit]("") + +def scala212 = "2.12.19" +scalaVersion := scala212 +val o = "com.example" +organization := o + +lazy val root = (project in file(".")) + .aggregate(foo, bar, baz) + +lazy val foo = project +lazy val bar = project + .settings( + name := "bar", + organization := "com.example.bar", + ) + +lazy val baz = project + +check := { + assert((root / scalaVersion).value == scala212) + assert((foo / scalaVersion).value == scala212) + assert((bar / scalaVersion).value == scala212) + assert((baz / scalaVersion).value == scala212) + + assert((root / organization).value == o) + assert((foo / organization).value == o) + // Test that bar can override common setting in settings(...) + assert((bar / organization).value == "com.example.bar") + // Test that baz/build.sbt bare settings get loaded + assert((baz / organization).value == "com.example.baz") +} +check / aggregate := false diff --git a/sbt-app/src/sbt-test/project/common-settings/test b/sbt-app/src/sbt-test/project/common-settings/test new file mode 100644 index 0000000000..15675b1696 --- /dev/null +++ b/sbt-app/src/sbt-test/project/common-settings/test @@ -0,0 +1 @@ +> check diff --git a/sbt-app/src/sbt-test/reporter/nowarn/build.sbt b/sbt-app/src/sbt-test/reporter/nowarn/build.sbt index 67fea2acb2..ecb8c97297 100644 --- a/sbt-app/src/sbt-test/reporter/nowarn/build.sbt +++ b/sbt-app/src/sbt-test/reporter/nowarn/build.sbt @@ -1,13 +1,19 @@ -ThisBuild / scalaVersion := "2.12.17" +scalaVersion := "2.12.19" lazy val sub1 = project lazy val sub2 = project val assertNoWarning = taskKey[Unit]("checks warning *is not* emitted") - val assertWarning = taskKey[Unit]("checks warning *is* emitted") +lazy val root = (project in file(".")) + .aggregate(sub1, sub2) + .settings( + assertWarning := check(true).value, + assertNoWarning := check(false).value, + ) + def check(expectation: Boolean) = Def.task[Unit] { val lastLog: File = BuiltinCommands.lastLogFile(state.value).get val last: String = IO.read(lastLog) @@ -20,7 +26,3 @@ def check(expectation: Boolean) = Def.task[Unit] { IO.write(lastLog, "") // clear the backing log for for 'last'. } } - -assertWarning := check(true).value - -assertNoWarning := check(false).value