diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 590e77a22..684fd8008 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -172,6 +172,7 @@ object Defaults extends BuildCommon { testForkedParallel :== false, javaOptions :== Nil, sbtPlugin :== false, + isMetaBuild :== false, crossPaths :== true, sourcePositionMappers :== Nil, artifactClassifier in packageSrc :== Some(SourceClassifier), @@ -1850,11 +1851,19 @@ object Classpaths { fullClasspath := concatDistinct(exportedProducts, dependencyClasspath).value, internalDependencyClasspath := internalDependencies.value, unmanagedClasspath := unmanagedDependencies.value, - managedClasspath := managedJars( - classpathConfiguration.value, - classpathTypes.value, - update.value - ), + managedClasspath := { + val isMeta = isMetaBuild.value + val app = appConfiguration.value + val sbtCp0 = app.provider.mainClasspath.toList + val sbtCp = sbtCp0 map { Attributed.blank(_) } + val mjars = managedJars( + classpathConfiguration.value, + classpathTypes.value, + update.value + ) + if (isMeta) mjars ++ sbtCp + else mjars + }, exportedProducts := trackedExportedProducts(TrackLevel.TrackAlways).value, exportedProductsIfMissing := trackedExportedProducts(TrackLevel.TrackIfMissing).value, exportedProductsNoTracking := trackedExportedProducts(TrackLevel.NoTracking).value, @@ -2067,6 +2076,7 @@ object Classpaths { allDependencies := { projectDependencies.value ++ libraryDependencies.value }, + allExcludeDependencies := excludeDependencies.value, scalaModuleInfo := (scalaModuleInfo or ( Def.setting { Option( @@ -2294,6 +2304,14 @@ object Classpaths { ScalaArtifacts.toolDependencies(sbtOrg, version, isDotty) ++ pluginAdjust } }, + // in case of meta build, exclude sbt from the dependency graph, so we can use the sbt resolved by the launcher + allExcludeDependencies := { + val sbtdeps = sbtDependency.value + val isMeta = isMetaBuild.value + val excludes = excludeDependencies.value + if (isMeta) excludes.toVector :+ ExclusionRule(sbtdeps.organization, sbtdeps.name) + else excludes + }, dependencyOverrides ++= { val isPlugin = sbtPlugin.value val app = appConfiguration.value @@ -2344,7 +2362,7 @@ object Classpaths { .withScalaModuleInfo(scalaModuleInfo.value) .withDependencies(allDependencies.value.toVector) .withOverrides(dependencyOverrides.value.toVector) - .withExcludes(excludeDependencies.value.toVector) + .withExcludes(allExcludeDependencies.value.toVector) .withIvyXML(ivyXML.value) .withConfigurations(ivyConfigurations.value.toVector) .withDefaultConfiguration(defaultConfiguration.value) diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index 6e85a8da5..91c16ecbf 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -234,6 +234,7 @@ object Keys { val classpathOptions = settingKey[ClasspathOptions]("Configures handling of Scala classpaths.").withRank(DSetting) val discoveredSbtPlugins = taskKey[PluginDiscovery.DiscoveredNames]("The names of sbt plugin-related modules (modules that extend Build, Plugin, AutoPlugin) defined by this project.").withRank(CTask) val sbtPlugin = settingKey[Boolean]("If true, enables adding sbt as a dependency and auto-generation of the plugin descriptor file.").withRank(BMinusSetting) + val isMetaBuild = settingKey[Boolean]("If true, this is a metabuild, a project inside project/ directory, and sbt is added to the classpath.").withRank(DSetting) val pluginCrossBuild = taskKey[Unit]("Dummy task to scope `sbtVersion in pluginCrossBuild`, which gets used for plugin compilation.") val crossSbtVersions = settingKey[Seq[String]]("The versions of Sbt used when cross-building an sbt plugin.") val printWarnings = taskKey[Unit]("Shows warnings from compilation, including ones that weren't printed initially.").withRank(BPlusTask) @@ -454,6 +455,7 @@ object Keys { val libraryDependencies = settingKey[Seq[ModuleID]]("Declares managed dependencies.").withRank(APlusSetting) val dependencyOverrides = settingKey[Seq[ModuleID]]("Declares managed dependency overrides.").withRank(BSetting) val excludeDependencies = settingKey[Seq[InclExclRule]]("Declares managed dependency exclusions.").withRank(BSetting) + val allExcludeDependencies = settingKey[Seq[InclExclRule]]("User-defined dependency exclusions and sbt itself in the case of metabuild.").withRank(CTask) val allDependencies = taskKey[Seq[ModuleID]]("Inter-project and library dependencies.").withRank(CTask) val projectDependencies = taskKey[Seq[ModuleID]]("Inter-project dependencies.").withRank(DTask) val ivyXML = settingKey[NodeSeq]("Defines inline Ivy XML for configuring dependency management.").withRank(BSetting) diff --git a/main/src/main/scala/sbt/internal/Load.scala b/main/src/main/scala/sbt/internal/Load.scala index cf62b1fc6..1ca8513f7 100755 --- a/main/src/main/scala/sbt/internal/Load.scala +++ b/main/src/main/scala/sbt/internal/Load.scala @@ -22,6 +22,7 @@ import Keys.{ exportedProducts, fullClasspath, fullResolvers, + isMetaBuild, loadedBuild, onLoadMessage, pluginData, @@ -1180,6 +1181,7 @@ private[sbt] object Load { val autoPluginSettings: Seq[Setting[_]] = inScope(GlobalScope in LocalRootProject)( Seq( sbtPlugin :== true, + isMetaBuild :== true, pluginData := { val prod = (exportedProducts in Configurations.Runtime).value val cp = (fullClasspath in Configurations.Runtime).value