mirror of https://github.com/sbt/sbt.git
addPluginSbtFile command fixes
Ref #4211 Fixes #4395 Fixes #4600 This is a reimplementation of `--addPluginSbtFile`. #4211 implemented the command to load extra `*.sbt` files as part of the global plugin subproject. That had the unwanted side effects of not working when `.sbt/1.0/plugins` directory does not exist. This changes the strategy to load the `*.sbt` files as part of the meta build. ``` $ sbt -Dsbt.global.base=/tmp/hello/global --addPluginSbtFile=/tmp/plugins/plugin.sbt [info] Loading settings for project hello-build from plugin.sbt ... [info] Loading project definition from /private/tmp/hello/project sbt:hello> plugins In file:/private/tmp/hello/ sbt.plugins.IvyPlugin: enabled in root sbt.plugins.JvmPlugin: enabled in root sbt.plugins.CorePlugin: enabled in root sbt.ScriptedPlugin sbt.plugins.SbtPlugin sbt.plugins.SemanticdbPlugin: enabled in root sbt.plugins.JUnitXmlReportPlugin: enabled in root sbt.plugins.Giter8TemplatePlugin: enabled in root sbtvimquit.VimquitPlugin: enabled in root ```
This commit is contained in:
parent
e17c64dfb6
commit
033601c393
|
|
@ -789,6 +789,9 @@ lazy val mainProj = (project in file("main"))
|
||||||
exclude[IncompatibleSignatureProblem]("sbt.ProjectExtra.inConfig"),
|
exclude[IncompatibleSignatureProblem]("sbt.ProjectExtra.inConfig"),
|
||||||
exclude[IncompatibleSignatureProblem]("sbt.ProjectExtra.inTask"),
|
exclude[IncompatibleSignatureProblem]("sbt.ProjectExtra.inTask"),
|
||||||
exclude[IncompatibleSignatureProblem]("sbt.ProjectExtra.inScope"),
|
exclude[IncompatibleSignatureProblem]("sbt.ProjectExtra.inScope"),
|
||||||
|
|
||||||
|
exclude[MissingTypesProblem]("sbt.internal.Load*"),
|
||||||
|
exclude[IncompatibleSignatureProblem]("sbt.internal.Load*"),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.configure(
|
.configure(
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,15 @@ import java.io.File
|
||||||
sealed abstract class AddSettings
|
sealed abstract class AddSettings
|
||||||
|
|
||||||
object AddSettings {
|
object AddSettings {
|
||||||
private[sbt] final class Sequence(val sequence: Seq[AddSettings]) extends AddSettings
|
private[sbt] final class Sequence(val sequence: Seq[AddSettings]) extends AddSettings {
|
||||||
|
override def toString: String = s"Sequence($sequence)"
|
||||||
|
}
|
||||||
private[sbt] final object User extends AddSettings
|
private[sbt] final object User extends AddSettings
|
||||||
private[sbt] final class AutoPlugins(val include: AutoPlugin => Boolean) extends AddSettings
|
private[sbt] final class AutoPlugins(val include: AutoPlugin => Boolean) extends AddSettings
|
||||||
private[sbt] final class DefaultSbtFiles(val include: File => Boolean) extends AddSettings
|
private[sbt] final class DefaultSbtFiles(val include: File => Boolean) extends AddSettings
|
||||||
private[sbt] final class SbtFiles(val files: Seq[File]) extends AddSettings
|
private[sbt] final class SbtFiles(val files: Seq[File]) extends AddSettings {
|
||||||
|
override def toString: String = s"SbtFiles($files)"
|
||||||
|
}
|
||||||
private[sbt] final object BuildScalaFiles extends AddSettings
|
private[sbt] final object BuildScalaFiles extends AddSettings
|
||||||
|
|
||||||
/** Adds all settings from autoplugins. */
|
/** Adds all settings from autoplugins. */
|
||||||
|
|
|
||||||
|
|
@ -875,10 +875,12 @@ private[sbt] object Load {
|
||||||
def discover(base: File): DiscoveredProjects = {
|
def discover(base: File): DiscoveredProjects = {
|
||||||
val auto =
|
val auto =
|
||||||
if (base == buildBase) AddSettings.allDefaults
|
if (base == buildBase) AddSettings.allDefaults
|
||||||
else if (context.globalPluginProject)
|
|
||||||
AddSettings.seq(AddSettings.defaultSbtFiles, AddSettings.sbtFiles(extraSbtFiles: _*))
|
|
||||||
else AddSettings.defaultSbtFiles
|
else AddSettings.defaultSbtFiles
|
||||||
discoverProjects(auto, base, plugins, eval, memoSettings)
|
|
||||||
|
val extraFiles =
|
||||||
|
if (base == buildBase && isMetaBuildContext(context)) extraSbtFiles
|
||||||
|
else Nil
|
||||||
|
discoverProjects(auto, base, extraFiles, plugins, eval, memoSettings)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step two:
|
// Step two:
|
||||||
|
|
@ -888,6 +890,7 @@ private[sbt] object Load {
|
||||||
def finalizeProject(
|
def finalizeProject(
|
||||||
p: Project,
|
p: Project,
|
||||||
files: Seq[File],
|
files: Seq[File],
|
||||||
|
extraFiles: Seq[File],
|
||||||
expand: Boolean
|
expand: Boolean
|
||||||
): (Project, Seq[Project]) = {
|
): (Project, Seq[Project]) = {
|
||||||
val configFiles = files.flatMap(f => memoSettings.get(f))
|
val configFiles = files.flatMap(f => memoSettings.get(f))
|
||||||
|
|
@ -895,8 +898,8 @@ private[sbt] object Load {
|
||||||
val autoPlugins: Seq[AutoPlugin] =
|
val autoPlugins: Seq[AutoPlugin] =
|
||||||
try plugins.detected.deducePluginsFromProject(p1, log)
|
try plugins.detected.deducePluginsFromProject(p1, log)
|
||||||
catch { case e: AutoPluginException => throw translateAutoPluginException(e, p) }
|
catch { case e: AutoPluginException => throw translateAutoPluginException(e, p) }
|
||||||
val extra = if (context.globalPluginProject) extraSbtFiles else Nil
|
val p2 =
|
||||||
val p2 = resolveProject(p1, autoPlugins, plugins, injectSettings, memoSettings, extra, log)
|
resolveProject(p1, autoPlugins, plugins, injectSettings, memoSettings, extraFiles, log)
|
||||||
val projectLevelExtra =
|
val projectLevelExtra =
|
||||||
if (expand) {
|
if (expand) {
|
||||||
autoPlugins.flatMap(
|
autoPlugins.flatMap(
|
||||||
|
|
@ -908,12 +911,15 @@ private[sbt] object Load {
|
||||||
|
|
||||||
// Discover any new project definition for the base directory of this project, and load all settings.
|
// Discover any new project definition for the base directory of this project, and load all settings.
|
||||||
def discoverAndLoad(p: Project, rest: Seq[Project]): LoadedProjects = {
|
def discoverAndLoad(p: Project, rest: Seq[Project]): LoadedProjects = {
|
||||||
val DiscoveredProjects(rootOpt, discovered, files, generated) = discover(p.base)
|
val DiscoveredProjects(rootOpt, discovered, files, extraFiles, generated) = discover(
|
||||||
|
p.base
|
||||||
|
)
|
||||||
|
|
||||||
// TODO: We assume here the project defined in a build.sbt WINS because the original was a
|
// 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
|
// phony. However, we may want to 'merge' the two, or only do this if the original was a
|
||||||
// default generated project.
|
// default generated project.
|
||||||
val root = rootOpt.getOrElse(p)
|
val root = rootOpt.getOrElse(p)
|
||||||
val (finalRoot, projectLevelExtra) = finalizeProject(root, files, true)
|
val (finalRoot, projectLevelExtra) = finalizeProject(root, files, extraFiles, true)
|
||||||
val newProjects = rest ++ discovered ++ projectLevelExtra
|
val newProjects = rest ++ discovered ++ projectLevelExtra
|
||||||
val newAcc = acc :+ finalRoot
|
val newAcc = acc :+ finalRoot
|
||||||
val newGenerated = generated ++ generatedConfigClassFiles
|
val newGenerated = generated ++ generatedConfigClassFiles
|
||||||
|
|
@ -928,7 +934,9 @@ private[sbt] object Load {
|
||||||
discoverAndLoad(next, rest)
|
discoverAndLoad(next, rest)
|
||||||
case Nil if makeOrDiscoverRoot =>
|
case Nil if makeOrDiscoverRoot =>
|
||||||
log.debug(s"[Loading] Scanning directory $buildBase")
|
log.debug(s"[Loading] Scanning directory $buildBase")
|
||||||
val DiscoveredProjects(rootOpt, discovered, files, generated) = discover(buildBase)
|
val DiscoveredProjects(rootOpt, discovered, files, extraFiles, generated) = discover(
|
||||||
|
buildBase
|
||||||
|
)
|
||||||
val discoveredIdsStr = discovered.map(_.id).mkString(",")
|
val discoveredIdsStr = discovered.map(_.id).mkString(",")
|
||||||
val (root, expand, moreProjects, otherProjects) = rootOpt match {
|
val (root, expand, moreProjects, otherProjects) = rootOpt match {
|
||||||
case Some(root) =>
|
case Some(root) =>
|
||||||
|
|
@ -950,7 +958,7 @@ private[sbt] object Load {
|
||||||
}
|
}
|
||||||
val (finalRoot, projectLevelExtra) =
|
val (finalRoot, projectLevelExtra) =
|
||||||
timed(s"Load.loadTransitive: finalizeProject($root)", log) {
|
timed(s"Load.loadTransitive: finalizeProject($root)", log) {
|
||||||
finalizeProject(root, files, expand)
|
finalizeProject(root, files, extraFiles, expand)
|
||||||
}
|
}
|
||||||
val newProjects = moreProjects ++ projectLevelExtra
|
val newProjects = moreProjects ++ projectLevelExtra
|
||||||
val newAcc = finalRoot +: (acc ++ otherProjects.projects)
|
val newAcc = finalRoot +: (acc ++ otherProjects.projects)
|
||||||
|
|
@ -983,6 +991,7 @@ private[sbt] object Load {
|
||||||
root: Option[Project],
|
root: Option[Project],
|
||||||
nonRoot: Seq[Project],
|
nonRoot: Seq[Project],
|
||||||
sbtFiles: Seq[File],
|
sbtFiles: Seq[File],
|
||||||
|
extraSbtFiles: Seq[File],
|
||||||
generatedFiles: Seq[File]
|
generatedFiles: Seq[File]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -1017,6 +1026,7 @@ private[sbt] object Load {
|
||||||
val allSettings = {
|
val allSettings = {
|
||||||
// TODO - This mechanism of applying settings could be off... It's in two places now...
|
// TODO - This mechanism of applying settings could be off... It's in two places now...
|
||||||
lazy val defaultSbtFiles = configurationSources(p.base)
|
lazy val defaultSbtFiles = configurationSources(p.base)
|
||||||
|
lazy val sbtFiles = defaultSbtFiles ++ extraSbtFiles
|
||||||
// Filter the AutoPlugin settings we included based on which ones are
|
// Filter the AutoPlugin settings we included based on which ones are
|
||||||
// intended in the AddSettings.AutoPlugins filter.
|
// intended in the AddSettings.AutoPlugins filter.
|
||||||
def autoPluginSettings(f: AutoPlugins) =
|
def autoPluginSettings(f: AutoPlugins) =
|
||||||
|
|
@ -1038,23 +1048,14 @@ private[sbt] object Load {
|
||||||
case BuildScalaFiles => p.settings
|
case BuildScalaFiles => p.settings
|
||||||
case User => globalUserSettings.cachedProjectLoaded(loadedPlugins.loader)
|
case User => globalUserSettings.cachedProjectLoaded(loadedPlugins.loader)
|
||||||
case sf: SbtFiles => settings(sf.files.map(f => IO.resolve(p.base, f)))
|
case sf: SbtFiles => settings(sf.files.map(f => IO.resolve(p.base, f)))
|
||||||
case sf: DefaultSbtFiles => settings(defaultSbtFiles.filter(sf.include))
|
case sf: DefaultSbtFiles => settings(sbtFiles.filter(sf.include))
|
||||||
case p: AutoPlugins => autoPluginSettings(p)
|
case p: AutoPlugins => autoPluginSettings(p)
|
||||||
case q: Sequence =>
|
case q: Sequence =>
|
||||||
q.sequence.foldLeft(Seq.empty[Setting[_]]) { (b, add) =>
|
q.sequence.foldLeft(Seq.empty[Setting[_]]) { (b, add) =>
|
||||||
b ++ expandSettings(add)
|
b ++ expandSettings(add)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val auto =
|
val auto = AddSettings.allDefaults
|
||||||
if (extraSbtFiles.nonEmpty)
|
|
||||||
AddSettings.seq(
|
|
||||||
AddSettings.autoPlugins,
|
|
||||||
AddSettings.buildScalaFiles,
|
|
||||||
AddSettings.userSettings,
|
|
||||||
AddSettings.defaultSbtFiles,
|
|
||||||
AddSettings.sbtFiles(extraSbtFiles: _*),
|
|
||||||
)
|
|
||||||
else AddSettings.allDefaults
|
|
||||||
expandSettings(auto)
|
expandSettings(auto)
|
||||||
}
|
}
|
||||||
// Finally, a project we can use in buildStructure.
|
// Finally, a project we can use in buildStructure.
|
||||||
|
|
@ -1074,6 +1075,7 @@ private[sbt] object Load {
|
||||||
private[this] def discoverProjects(
|
private[this] def discoverProjects(
|
||||||
auto: AddSettings,
|
auto: AddSettings,
|
||||||
projectBase: File,
|
projectBase: File,
|
||||||
|
extraSbtFiles: Seq[File],
|
||||||
loadedPlugins: LoadedPlugins,
|
loadedPlugins: LoadedPlugins,
|
||||||
eval: () => Eval,
|
eval: () => Eval,
|
||||||
memoSettings: mutable.Map[File, LoadedSbtFile]
|
memoSettings: mutable.Map[File, LoadedSbtFile]
|
||||||
|
|
@ -1081,6 +1083,7 @@ private[sbt] object Load {
|
||||||
|
|
||||||
// Default sbt files to read, if needed
|
// Default sbt files to read, if needed
|
||||||
lazy val defaultSbtFiles = configurationSources(projectBase)
|
lazy val defaultSbtFiles = configurationSources(projectBase)
|
||||||
|
lazy val sbtFiles = defaultSbtFiles ++ extraSbtFiles
|
||||||
|
|
||||||
// Classloader of the build
|
// Classloader of the build
|
||||||
val loader = loadedPlugins.loader
|
val loader = loadedPlugins.loader
|
||||||
|
|
@ -1117,7 +1120,7 @@ private[sbt] object Load {
|
||||||
import AddSettings.{ DefaultSbtFiles, SbtFiles, Sequence }
|
import AddSettings.{ DefaultSbtFiles, SbtFiles, Sequence }
|
||||||
def associatedFiles(auto: AddSettings): Seq[File] = auto match {
|
def associatedFiles(auto: AddSettings): Seq[File] = auto match {
|
||||||
case sf: SbtFiles => sf.files.map(f => IO.resolve(projectBase, f)).filterNot(_.isHidden)
|
case sf: SbtFiles => sf.files.map(f => IO.resolve(projectBase, f)).filterNot(_.isHidden)
|
||||||
case sf: DefaultSbtFiles => defaultSbtFiles.filter(sf.include).filterNot(_.isHidden)
|
case sf: DefaultSbtFiles => sbtFiles.filter(sf.include).filterNot(_.isHidden)
|
||||||
case q: Sequence =>
|
case q: Sequence =>
|
||||||
q.sequence.foldLeft(Seq.empty[File]) { (b, add) =>
|
q.sequence.foldLeft(Seq.empty[File]) { (b, add) =>
|
||||||
b ++ associatedFiles(add)
|
b ++ associatedFiles(add)
|
||||||
|
|
@ -1129,7 +1132,13 @@ private[sbt] object Load {
|
||||||
val rawProjects = loadedFiles.projects
|
val rawProjects = loadedFiles.projects
|
||||||
val (root, nonRoot) = rawProjects.partition(_.base == projectBase)
|
val (root, nonRoot) = rawProjects.partition(_.base == projectBase)
|
||||||
// TODO - good error message if more than one root project
|
// TODO - good error message if more than one root project
|
||||||
DiscoveredProjects(root.headOption, nonRoot, rawFiles, loadedFiles.generatedFiles)
|
DiscoveredProjects(
|
||||||
|
root.headOption,
|
||||||
|
nonRoot,
|
||||||
|
rawFiles,
|
||||||
|
extraSbtFiles,
|
||||||
|
loadedFiles.generatedFiles
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
def globalPluginClasspath(globalPlugin: Option[GlobalPlugin]): Seq[Attributed[File]] =
|
def globalPluginClasspath(globalPlugin: Option[GlobalPlugin]): Seq[Attributed[File]] =
|
||||||
|
|
@ -1184,11 +1193,19 @@ private[sbt] object Load {
|
||||||
case None => config
|
case None => config
|
||||||
}
|
}
|
||||||
|
|
||||||
def plugins(dir: File, s: State, config: LoadBuildConfiguration): LoadedPlugins =
|
def plugins(dir: File, s: State, config: LoadBuildConfiguration): LoadedPlugins = {
|
||||||
if (hasDefinition(dir))
|
val context = config.pluginManagement.context
|
||||||
|
val extraSbtFiles: Seq[File] =
|
||||||
|
if (isMetaBuildContext(context)) s.get(BasicKeys.extraMetaSbtFiles).getOrElse(Nil)
|
||||||
|
else Nil
|
||||||
|
if (hasDefinition(dir) || extraSbtFiles.nonEmpty)
|
||||||
buildPlugins(dir, s, enableSbtPlugin(activateGlobalPlugin(config)))
|
buildPlugins(dir, s, enableSbtPlugin(activateGlobalPlugin(config)))
|
||||||
else
|
else
|
||||||
noPlugins(dir, config)
|
noPlugins(dir, config)
|
||||||
|
}
|
||||||
|
|
||||||
|
private def isMetaBuildContext(context: PluginManagement.Context): Boolean =
|
||||||
|
!context.globalPluginProject && context.pluginProjectDepth == 1
|
||||||
|
|
||||||
def hasDefinition(dir: File): Boolean = {
|
def hasDefinition(dir: File): Boolean = {
|
||||||
import sbt.io.syntax._
|
import sbt.io.syntax._
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue