mirror of https://github.com/sbt/sbt.git
Merge pull request #2717 from eed3si9n/wip/plugin
Add buildExtras and projectExtras
This commit is contained in:
commit
d0ce0cef49
|
|
@ -467,10 +467,13 @@ object Load {
|
|||
val defsScala = timed("Load.loadUnit: defsScala", log) {
|
||||
plugs.detected.builds.values
|
||||
}
|
||||
val buildLevelExtraProjects = plugs.detected.autoPlugins flatMap { d =>
|
||||
d.value.buildExtras map {_.setProjectOrigin(ProjectOrigin.BuildExtra)}
|
||||
}
|
||||
|
||||
// NOTE - because we create an eval here, we need a clean-eval later for this URI.
|
||||
lazy val eval = timed("Load.loadUnit: mkEval", log) { mkEval(plugs.classpath, defDir, plugs.pluginData.scalacOptions) }
|
||||
val initialProjects = defsScala.flatMap(b => projectsFromBuild(b, normBase))
|
||||
val initialProjects = defsScala.flatMap(b => projectsFromBuild(b, normBase)) ++ buildLevelExtraProjects
|
||||
|
||||
val hasRootAlreadyDefined = defsScala.exists(_.rootProject.isDefined)
|
||||
|
||||
|
|
@ -580,10 +583,28 @@ object Load {
|
|||
// load all relevant configuration files (.sbt, as .scala already exists at this point)
|
||||
def discover(auto: AddSettings, base: File): DiscoveredProjects =
|
||||
discoverProjects(auto, base, plugins, eval, memoSettings)
|
||||
// Step two, Finalize a project with all its settings/configuration.
|
||||
def finalizeProject(p: Project, configFiles: Seq[File]): Project = {
|
||||
val loadedFiles = configFiles flatMap { f => memoSettings.get(f) }
|
||||
resolveProject(p, loadedFiles, plugins, injectSettings, memoSettings, 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[File], expand: Boolean): (Project, Seq[Project]) = {
|
||||
val configFiles = files flatMap { f => memoSettings.get(f) }
|
||||
val p1: Project =
|
||||
timed(s"Load.loadTransitive(${p.id}): transformedProject", log) {
|
||||
configFiles.flatMap(_.manipulations).foldLeft(p) { (prev, t) =>
|
||||
t(prev)
|
||||
}
|
||||
}
|
||||
val autoPlugins: Seq[AutoPlugin] =
|
||||
timed(s"Load.loadTransitive(${p.id}): autoPlugins", log) {
|
||||
try plugins.detected.deducePluginsFromProject(p1, log)
|
||||
catch { case e: AutoPluginException => throw translateAutoPluginException(e, p) }
|
||||
}
|
||||
val p2 = this.resolveProject(p1, autoPlugins, plugins, injectSettings, memoSettings, log)
|
||||
val projectLevelExtra =
|
||||
if (expand) autoPlugins flatMap { _.projectExtras(p2) map {_.setProjectOrigin(ProjectOrigin.ProjectExtra)} }
|
||||
else Nil
|
||||
(p2, projectLevelExtra)
|
||||
}
|
||||
// Discover any new project definition for the base directory of this project, and load all settings.
|
||||
// Also return any newly discovered project instances.
|
||||
|
|
@ -596,9 +617,10 @@ object Load {
|
|||
(root, rest, files, generated)
|
||||
case DiscoveredProjects(None, rest, files, generated) => (p, rest, files, generated)
|
||||
}
|
||||
val finalRoot = finalizeProject(root, files)
|
||||
(finalRoot, discovered, generated)
|
||||
val (finalRoot, projectLevelExtra) = finalizeProject(root, files, true)
|
||||
(finalRoot, discovered ++ projectLevelExtra, generated)
|
||||
}
|
||||
|
||||
// Load all config files AND finalize the project at the root directory, if it exists.
|
||||
// Continue loading if we find any more.
|
||||
newProjects match {
|
||||
|
|
@ -611,8 +633,10 @@ object Load {
|
|||
discover(AddSettings.defaultSbtFiles, buildBase) match {
|
||||
case DiscoveredProjects(Some(root), discovered, files, generated) =>
|
||||
log.debug(s"[Loading] Found root project ${root.id} w/ remaining ${discovered.map(_.id).mkString(",")}")
|
||||
val finalRoot = timed(s"Load.loadTransitive: finalizeProject($root)", log) { finalizeProject(root, files) }
|
||||
loadTransitive(discovered, buildBase, plugins, eval, injectSettings, finalRoot +: acc, memoSettings, log, false, buildUri, context, generated ++ generatedConfigClassFiles)
|
||||
val (finalRoot, projectLevelExtra) = timed(s"Load.loadTransitive: finalizeProject($root)", log) {
|
||||
finalizeProject(root, files, true)
|
||||
}
|
||||
loadTransitive(discovered ++ projectLevelExtra, buildBase, plugins, eval, injectSettings, finalRoot +: acc, memoSettings, log, false, buildUri, context, generated ++ generatedConfigClassFiles)
|
||||
// Here we need to create a root project...
|
||||
case DiscoveredProjects(None, discovered, files, generated) =>
|
||||
log.debug(s"[Loading] Found non-root projects ${discovered.map(_.id).mkString(",")}")
|
||||
|
|
@ -624,7 +648,9 @@ object Load {
|
|||
val defaultID = autoID(buildBase, context, existingIds)
|
||||
val root0 = if (discovered.isEmpty || java.lang.Boolean.getBoolean("sbt.root.ivyplugin")) Build.defaultAggregatedProject(defaultID, buildBase, refs)
|
||||
else Build.generatedRootWithoutIvyPlugin(defaultID, buildBase, refs)
|
||||
val root = timed(s"Load.loadTransitive: finalizeProject2($root0)", log) { finalizeProject(root0, files) }
|
||||
val (root, _) = timed(s"Load.loadTransitive: finalizeProject2($root0)", log) {
|
||||
finalizeProject(root0, files, false)
|
||||
}
|
||||
val result = root +: (acc ++ otherProjects.projects)
|
||||
log.debug(s"[Loading] Done in ${buildBase}, returning: ${result.map(_.id).mkString("(", ", ", ")")}")
|
||||
LoadedProjects(result, generated ++ otherGenerated ++ generatedConfigClassFiles)
|
||||
|
|
@ -656,13 +682,11 @@ object Load {
|
|||
/**
|
||||
* This method attempts to resolve/apply all configuration loaded for a project. It is responsible for the following:
|
||||
*
|
||||
* 1. Apply any manipulations defined in .sbt files.
|
||||
* 2. Detecting which autoPlugins are enabled for the project.
|
||||
* 3. Ordering all Setting[_]s for the project
|
||||
* Ordering all Setting[_]s for the project
|
||||
*
|
||||
*
|
||||
* @param rawProject The original project, with nothing manipulated since it was evaluated/discovered.
|
||||
* @param configFiles All configuration files loaded for this project. Used to discover project manipulations
|
||||
* @param transformedProject The project with manipulation.
|
||||
* @param projectPlugins The deduced list of plugins for the given project.
|
||||
* @param loadedPlugins The project definition (and classloader) of the build.
|
||||
* @param globalUserSettings All the settings contributed from the ~/.sbt/<version> directory
|
||||
* @param memoSettings A recording of all loaded files (our files should reside in there). We should need not load any
|
||||
|
|
@ -670,48 +694,35 @@ object Load {
|
|||
* @param log A logger to report auto-plugin issues to.
|
||||
*/
|
||||
private[this] def resolveProject(
|
||||
rawProject: Project,
|
||||
configFiles: Seq[LoadedSbtFile],
|
||||
p: Project,
|
||||
projectPlugins: Seq[AutoPlugin],
|
||||
loadedPlugins: sbt.LoadedPlugins,
|
||||
globalUserSettings: InjectSettings,
|
||||
memoSettings: mutable.Map[File, LoadedSbtFile],
|
||||
log: Logger): Project =
|
||||
timed(s"Load.resolveProject(${rawProject.id})", log) {
|
||||
timed(s"Load.resolveProject(${p.id})", log) {
|
||||
import AddSettings._
|
||||
// 1. Apply all the project manipulations from .sbt files in order
|
||||
val transformedProject =
|
||||
timed(s"Load.resolveProject(${rawProject.id}): transformedProject", log) {
|
||||
configFiles.flatMap(_.manipulations).foldLeft(rawProject) { (prev, t) =>
|
||||
t(prev)
|
||||
}
|
||||
}
|
||||
// 2. Discover all the autoplugins and contributed configurations.
|
||||
val autoPlugins =
|
||||
timed(s"Load.resolveProject(${rawProject.id}): autoPlugins", log) {
|
||||
try loadedPlugins.detected.deducePluginsFromProject(transformedProject, log)
|
||||
catch { case e: AutoPluginException => throw translateAutoPluginException(e, transformedProject) }
|
||||
}
|
||||
val autoConfigs = autoPlugins.flatMap(_.projectConfigurations)
|
||||
val autoConfigs = projectPlugins.flatMap(_.projectConfigurations)
|
||||
|
||||
// 3. Use AddSettings instance to order all Setting[_]s appropriately
|
||||
val allSettings = {
|
||||
// TODO - This mechanism of applying settings could be off... It's in two places now...
|
||||
lazy val defaultSbtFiles = configurationSources(transformedProject.base)
|
||||
lazy val defaultSbtFiles = configurationSources(p.base)
|
||||
// Grabs the plugin settings for old-style sbt plugins.
|
||||
def pluginSettings(f: Plugins) =
|
||||
timed(s"Load.resolveProject(${rawProject.id}): expandSettings(...): pluginSettings($f)", log) {
|
||||
timed(s"Load.resolveProject(${p.id}): expandSettings(...): pluginSettings($f)", log) {
|
||||
val included = loadedPlugins.detected.plugins.values.filter(f.include) // don't apply the filter to AutoPlugins, only Plugins
|
||||
included.flatMap(p => p.settings.filter(isProjectThis) ++ p.projectSettings)
|
||||
}
|
||||
// Filter the AutoPlugin settings we included based on which ones are
|
||||
// intended in the AddSettings.AutoPlugins filter.
|
||||
def autoPluginSettings(f: AutoPlugins) =
|
||||
timed(s"Load.resolveProject(${rawProject.id}): expandSettings(...): autoPluginSettings($f)", log) {
|
||||
autoPlugins.filter(f.include).flatMap(_.projectSettings)
|
||||
timed(s"Load.resolveProject(${p.id}): expandSettings(...): autoPluginSettings($f)", log) {
|
||||
projectPlugins.filter(f.include).flatMap(_.projectSettings)
|
||||
}
|
||||
// Grab all the settigns we already loaded from sbt files
|
||||
def settings(files: Seq[File]): Seq[Setting[_]] =
|
||||
timed(s"Load.resolveProject(${rawProject.id}): expandSettings(...): settings($files)", log) {
|
||||
timed(s"Load.resolveProject(${p.id}): expandSettings(...): settings($files)", log) {
|
||||
for {
|
||||
file <- files
|
||||
config <- (memoSettings get file).toSeq
|
||||
|
|
@ -720,20 +731,20 @@ object Load {
|
|||
}
|
||||
// Expand the AddSettings instance into a real Seq[Setting[_]] we'll use on the project
|
||||
def expandSettings(auto: AddSettings): Seq[Setting[_]] = auto match {
|
||||
case BuildScalaFiles => rawProject.settings
|
||||
case BuildScalaFiles => p.settings
|
||||
case User => globalUserSettings.cachedProjectLoaded(loadedPlugins.loader)
|
||||
case sf: SbtFiles => settings(sf.files.map(f => IO.resolve(rawProject.base, f)))
|
||||
case sf: SbtFiles => settings(sf.files.map(f => IO.resolve(p.base, f)))
|
||||
case sf: DefaultSbtFiles => settings(defaultSbtFiles.filter(sf.include))
|
||||
case p: Plugins => pluginSettings(p)
|
||||
case p: AutoPlugins => autoPluginSettings(p)
|
||||
case q: Sequence => (Seq.empty[Setting[_]] /: q.sequence) { (b, add) => b ++ expandSettings(add) }
|
||||
}
|
||||
timed(s"Load.resolveProject(${rawProject.id}): expandSettings(...)", log) {
|
||||
expandSettings(transformedProject.auto)
|
||||
timed(s"Load.resolveProject(${p.id}): expandSettings(...)", log) {
|
||||
expandSettings(p.auto)
|
||||
}
|
||||
}
|
||||
// Finally, a project we can use in buildStructure.
|
||||
transformedProject.copy(settings = allSettings).setAutoPlugins(autoPlugins).prefixConfigs(autoConfigs: _*)
|
||||
p.copy(settings = allSettings).setAutoPlugins(projectPlugins).prefixConfigs(autoConfigs: _*)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -90,6 +90,12 @@ abstract class AutoPlugin extends Plugins.Basic with PluginsFunctions {
|
|||
|
||||
// TODO?: def commands: Seq[Command]
|
||||
|
||||
/** The [[Project]]s to add to the current build. */
|
||||
def buildExtras: Seq[Project] = Nil
|
||||
|
||||
/** The [[Project]]s to add to the current build based on an existing project. */
|
||||
def projectExtras(proj: ProjectDefinition[_]): Seq[Project] = Nil
|
||||
|
||||
private[sbt] def unary_! : Exclude = Exclude(this)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -64,6 +64,9 @@ sealed trait ProjectDefinition[PR <: ProjectReference] {
|
|||
*/
|
||||
def plugins: Plugins
|
||||
|
||||
/** Indicates whether the project was created organically, or was generated synthetically. */
|
||||
def projectOrigin: ProjectOrigin
|
||||
|
||||
/** The [[AutoPlugin]]s enabled for this project. This value is only available on a loaded Project. */
|
||||
private[sbt] def autoPlugins: Seq[AutoPlugin]
|
||||
|
||||
|
|
@ -88,7 +91,7 @@ sealed trait Project extends ProjectDefinition[ProjectReference] {
|
|||
def copy(id: String = id, base: File = base, aggregate: => Seq[ProjectReference] = aggregate, dependencies: => Seq[ClasspathDep[ProjectReference]] = dependencies,
|
||||
delegates: => Seq[ProjectReference] = delegates, settings: => Seq[Setting[_]] = settings, configurations: Seq[Configuration] = configurations,
|
||||
auto: AddSettings = auto): Project =
|
||||
unresolved(id, base, aggregate = aggregate, dependencies = dependencies, delegates = delegates, settings, configurations, auto, plugins, autoPlugins)
|
||||
unresolved(id, base, aggregate = aggregate, dependencies = dependencies, delegates = delegates, settings, configurations, auto, plugins, autoPlugins, projectOrigin)
|
||||
|
||||
def resolve(resolveRef: ProjectReference => ProjectRef): ResolvedProject =
|
||||
{
|
||||
|
|
@ -96,7 +99,7 @@ sealed trait Project extends ProjectDefinition[ProjectReference] {
|
|||
def resolveDeps(ds: Seq[ClasspathDep[ProjectReference]]) = ds map resolveDep
|
||||
def resolveDep(d: ClasspathDep[ProjectReference]) = ResolvedClasspathDependency(resolveRef(d.project), d.configuration)
|
||||
resolved(id, base, aggregate = resolveRefs(aggregate), dependencies = resolveDeps(dependencies), delegates = resolveRefs(delegates),
|
||||
settings, configurations, auto, plugins, autoPlugins)
|
||||
settings, configurations, auto, plugins, autoPlugins, projectOrigin)
|
||||
}
|
||||
def resolveBuild(resolveRef: ProjectReference => ProjectReference): Project =
|
||||
{
|
||||
|
|
@ -104,7 +107,7 @@ sealed trait Project extends ProjectDefinition[ProjectReference] {
|
|||
def resolveDeps(ds: Seq[ClasspathDep[ProjectReference]]) = ds map resolveDep
|
||||
def resolveDep(d: ClasspathDep[ProjectReference]) = ClasspathDependency(resolveRef(d.project), d.configuration)
|
||||
unresolved(id, base, aggregate = resolveRefs(aggregate), dependencies = resolveDeps(dependencies), delegates = resolveRefs(delegates),
|
||||
settings, configurations, auto, plugins, autoPlugins)
|
||||
settings, configurations, auto, plugins, autoPlugins, projectOrigin)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -174,13 +177,19 @@ sealed trait Project extends ProjectDefinition[ProjectReference] {
|
|||
|
||||
private[this] def setPlugins(ns: Plugins): Project = {
|
||||
// TODO: for 0.14.0, use copy when it has the additional `plugins` parameter
|
||||
unresolved(id, base, aggregate = aggregate, dependencies = dependencies, delegates = delegates, settings, configurations, auto, ns, autoPlugins)
|
||||
unresolved(id, base, aggregate = aggregate, dependencies = dependencies, delegates = delegates, settings, configurations, auto, ns, autoPlugins, projectOrigin)
|
||||
}
|
||||
|
||||
/** Definitively set the [[AutoPlugin]]s for this project. */
|
||||
private[sbt] def setAutoPlugins(autos: Seq[AutoPlugin]): Project = {
|
||||
// TODO: for 0.14.0, use copy when it has the additional `autoPlugins` parameter
|
||||
unresolved(id, base, aggregate = aggregate, dependencies = dependencies, delegates = delegates, settings, configurations, auto, plugins, autos)
|
||||
unresolved(id, base, aggregate = aggregate, dependencies = dependencies, delegates = delegates, settings, configurations, auto, plugins, autos, projectOrigin)
|
||||
}
|
||||
|
||||
/** Definitively set the [[ProjectOrigin]] for this project. */
|
||||
private[sbt] def setProjectOrigin(origin: ProjectOrigin): Project = {
|
||||
// TODO: for 1.0.x, use withProjectOrigin.
|
||||
unresolved(id, base, aggregate = aggregate, dependencies = dependencies, delegates = delegates, settings, configurations, auto, plugins, autoPlugins, origin)
|
||||
}
|
||||
}
|
||||
sealed trait ResolvedProject extends ProjectDefinition[ProjectRef] {
|
||||
|
|
@ -192,6 +201,18 @@ sealed trait ClasspathDep[PR <: ProjectReference] { def project: PR; def configu
|
|||
final case class ResolvedClasspathDependency(project: ProjectRef, configuration: Option[String]) extends ClasspathDep[ProjectRef]
|
||||
final case class ClasspathDependency(project: ProjectReference, configuration: Option[String]) extends ClasspathDep[ProjectReference]
|
||||
|
||||
/**
|
||||
* Indicate whether the project was created organically, synthesized by a plugin,
|
||||
* or is a "generic root" project supplied by sbt when a project doesn't exist for `file(".")`.
|
||||
*/
|
||||
sealed trait ProjectOrigin
|
||||
object ProjectOrigin {
|
||||
case object Organic extends ProjectOrigin
|
||||
case object BuildExtra extends ProjectOrigin
|
||||
case object ProjectExtra extends ProjectOrigin
|
||||
case object GenericRoot extends ProjectOrigin
|
||||
}
|
||||
|
||||
object Project extends ProjectExtra {
|
||||
@deprecated("Use Def.Setting", "0.13.0")
|
||||
type Setting[T] = Def.Setting[T]
|
||||
|
|
@ -219,7 +240,7 @@ object Project extends ProjectExtra {
|
|||
|
||||
private abstract class ProjectDef[PR <: ProjectReference](val id: String, val base: File, aggregate0: => Seq[PR], dependencies0: => Seq[ClasspathDep[PR]],
|
||||
delegates0: => Seq[PR], settings0: => Seq[Def.Setting[_]], val configurations: Seq[Configuration], val auto: AddSettings,
|
||||
val plugins: Plugins, val autoPlugins: Seq[AutoPlugin]) extends ProjectDefinition[PR] {
|
||||
val plugins: Plugins, val autoPlugins: Seq[AutoPlugin], val projectOrigin: ProjectOrigin) extends ProjectDefinition[PR] {
|
||||
lazy val aggregate = aggregate0
|
||||
lazy val dependencies = dependencies0
|
||||
lazy val delegates = delegates0
|
||||
|
|
@ -228,18 +249,18 @@ object Project extends ProjectExtra {
|
|||
Dag.topologicalSort(configurations)(_.extendsConfigs) // checks for cyclic references here instead of having to do it in Scope.delegates
|
||||
}
|
||||
|
||||
// TODO: add parameter for plugins in 0.14.0
|
||||
// TODO: add parameter for plugins and projectOrigin in 1.0
|
||||
// TODO: Modify default settings to be the core settings, and automatically add the IvyModule + JvmPlugins.
|
||||
def apply(id: String, base: File, aggregate: => Seq[ProjectReference] = Nil, dependencies: => Seq[ClasspathDep[ProjectReference]] = Nil,
|
||||
delegates: => Seq[ProjectReference] = Nil, settings: => Seq[Def.Setting[_]] = Nil, configurations: Seq[Configuration] = Nil,
|
||||
auto: AddSettings = AddSettings.allDefaults): Project =
|
||||
unresolved(id, base, aggregate, dependencies, delegates, settings, configurations, auto, Plugins.empty, Nil) // Note: JvmModule/IvyModule auto included...
|
||||
unresolved(id, base, aggregate, dependencies, delegates, settings, configurations, auto, Plugins.empty, Nil, ProjectOrigin.Organic) // Note: JvmModule/IvyModule auto included...
|
||||
|
||||
/** This is a variation of def apply that mixes in GeneratedRootProject. */
|
||||
private[sbt] def mkGeneratedRoot(id: String, base: File, aggregate: => Seq[ProjectReference]): Project =
|
||||
{
|
||||
validProjectID(id).foreach(errMsg => sys.error("Invalid project ID: " + errMsg))
|
||||
new ProjectDef[ProjectReference](id, base, aggregate, Nil, Nil, Nil, Nil, AddSettings.allDefaults, Plugins.empty, Nil) with Project with GeneratedRootProject
|
||||
new ProjectDef[ProjectReference](id, base, aggregate, Nil, Nil, Nil, Nil, AddSettings.allDefaults, Plugins.empty, Nil, ProjectOrigin.GenericRoot) with Project with GeneratedRootProject
|
||||
}
|
||||
|
||||
/** Returns None if `id` is a valid Project ID or Some containing the parser error message if it is not.*/
|
||||
|
|
@ -267,19 +288,19 @@ object Project extends ProjectExtra {
|
|||
@deprecated("Will be removed.", "0.13.2")
|
||||
def resolved(id: String, base: File, aggregate: => Seq[ProjectRef], dependencies: => Seq[ResolvedClasspathDependency], delegates: => Seq[ProjectRef],
|
||||
settings: Seq[Def.Setting[_]], configurations: Seq[Configuration], auto: AddSettings): ResolvedProject =
|
||||
resolved(id, base, aggregate, dependencies, delegates, settings, configurations, auto, Plugins.empty, Nil)
|
||||
resolved(id, base, aggregate, dependencies, delegates, settings, configurations, auto, Plugins.empty, Nil, ProjectOrigin.Organic)
|
||||
|
||||
private def resolved(id: String, base: File, aggregate: => Seq[ProjectRef], dependencies: => Seq[ClasspathDep[ProjectRef]],
|
||||
delegates: => Seq[ProjectRef], settings: Seq[Def.Setting[_]], configurations: Seq[Configuration], auto: AddSettings,
|
||||
plugins: Plugins, autoPlugins: Seq[AutoPlugin]): ResolvedProject =
|
||||
new ProjectDef[ProjectRef](id, base, aggregate, dependencies, delegates, settings, configurations, auto, plugins, autoPlugins) with ResolvedProject
|
||||
plugins: Plugins, autoPlugins: Seq[AutoPlugin], origin: ProjectOrigin): ResolvedProject =
|
||||
new ProjectDef[ProjectRef](id, base, aggregate, dependencies, delegates, settings, configurations, auto, plugins, autoPlugins, origin) with ResolvedProject
|
||||
|
||||
private def unresolved(id: String, base: File, aggregate: => Seq[ProjectReference], dependencies: => Seq[ClasspathDep[ProjectReference]],
|
||||
delegates: => Seq[ProjectReference], settings: => Seq[Def.Setting[_]], configurations: Seq[Configuration], auto: AddSettings,
|
||||
plugins: Plugins, autoPlugins: Seq[AutoPlugin]): Project =
|
||||
plugins: Plugins, autoPlugins: Seq[AutoPlugin], origin: ProjectOrigin): Project =
|
||||
{
|
||||
validProjectID(id).foreach(errMsg => sys.error("Invalid project ID: " + errMsg))
|
||||
new ProjectDef[ProjectReference](id, base, aggregate, dependencies, delegates, settings, configurations, auto, plugins, autoPlugins) with Project
|
||||
new ProjectDef[ProjectReference](id, base, aggregate, dependencies, delegates, settings, configurations, auto, plugins, autoPlugins, origin) with Project
|
||||
}
|
||||
|
||||
@deprecated("Use Defaults.coreDefaultSettings instead, combined with AutoPlugins.", "0.13.2")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
|
||||
### Synthetic subprojects
|
||||
|
||||
sbt 0.13.13 adds support for `AutoPlugin`s to generate
|
||||
synthetic subprojects. To generate subprojects, override `buildExtras`
|
||||
method as follows:
|
||||
|
||||
import sbt._
|
||||
import Keys._
|
||||
|
||||
object BuildExtrasPlugin extends AutoPlugin {
|
||||
override def buildExtras: Seq[Project] =
|
||||
List("foo", "bar", "baz") map generateProject
|
||||
|
||||
def generateProject(id: String): Project =
|
||||
Project(id, file(id)).
|
||||
settings(
|
||||
name := id
|
||||
)
|
||||
}
|
||||
|
||||
In addition, subprojects may be derived from an existing subproject
|
||||
by overriding `projectExtras`.
|
||||
|
||||
import sbt._
|
||||
import Keys._
|
||||
|
||||
object ProjectExtrasPlugin extends AutoPlugin {
|
||||
// Enable this plugin by default
|
||||
override def requires: Plugins = sbt.plugins.CorePlugin
|
||||
override def trigger = allRequirements
|
||||
|
||||
override def projectExtras(proj: ProjectDefinition[_]): Seq[Project] =
|
||||
// Make sure to exclude project extras to avoid recursive generation
|
||||
if (proj.projectOrigin != ProjectOrigin.ProjectExtra) {
|
||||
val id = proj.id + "1"
|
||||
Seq(
|
||||
Project(id, file(id)).
|
||||
enablePlugins(DatabasePlugin)
|
||||
)
|
||||
}
|
||||
else Nil
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
import sbt._
|
||||
import Keys._
|
||||
|
||||
object BuildExtrasPlugin extends AutoPlugin {
|
||||
override def buildExtras: Seq[Project] =
|
||||
List("foo", "bar", "baz") map generateProject
|
||||
|
||||
def generateProject(id: String): Project =
|
||||
Project(id, file(id)).
|
||||
settings(
|
||||
name := id
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
import sbt._
|
||||
import Keys._
|
||||
|
||||
object DatabasePlugin extends AutoPlugin {
|
||||
override def requires: Plugins = sbt.plugins.JvmPlugin
|
||||
override def trigger = noTrigger
|
||||
|
||||
object autoImport {
|
||||
lazy val databaseName = settingKey[String]("name of the database")
|
||||
}
|
||||
import autoImport._
|
||||
override def projectSettings: Seq[Setting[_]] =
|
||||
Seq(
|
||||
databaseName := "something"
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
import sbt._
|
||||
import Keys._
|
||||
|
||||
object ProjectExtrasPlugin extends AutoPlugin {
|
||||
// Enable this plugin by default
|
||||
override def requires: Plugins = sbt.plugins.CorePlugin
|
||||
override def trigger = allRequirements
|
||||
|
||||
override def projectExtras(proj: ProjectDefinition[_]): Seq[Project] =
|
||||
// Make sure to exclude project extras to avoid recursive generation
|
||||
if (proj.projectOrigin != ProjectOrigin.ProjectExtra) {
|
||||
val id = proj.id + "1"
|
||||
Seq(
|
||||
Project(id, file(id)).
|
||||
enablePlugins(DatabasePlugin)
|
||||
)
|
||||
}
|
||||
else Nil
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
> bar/compile
|
||||
|
||||
> foo1/compile
|
||||
|
||||
> foo1/databaseName
|
||||
Loading…
Reference in New Issue