mirror of https://github.com/sbt/sbt.git
Control over automatically added settings.
Project.autoSettings accepts a sequence of AddSettings, instances of which are constructed from methods in AddSettings. The configurable settings are per-user settings (from ~/.sbt, for example), settings from .sbt files, and plugin settings (project-level only). The order in which these instances are provided to autoSettings determines the order in which they are appended to the settings explicitly provided in Project.settings. For .sbt files, defaultSbtFiles adds the settings from all .sbt files in the project's base directory as usual. AddSettings.sbtFiles accepts a sequence of Files that will be loaded according to the standard .sbt format. Relative Files are resolved against the project's base directory. Plugin settings may be included on a per-Plugin basis by using the plugins method and passing a Plugin => Boolean. The settings controlled here are only the automatic per-project settings. Per-build and global settings will always be included.
This commit is contained in:
parent
1bc26fa488
commit
f99ba44703
|
|
@ -0,0 +1,38 @@
|
|||
package sbt
|
||||
|
||||
import Types.const
|
||||
import java.io.File
|
||||
|
||||
/** Represents how settings from various sources are automatically merged into a Project's settings.
|
||||
* This only configures per-project settings and not global or per-build settings. */
|
||||
sealed abstract class AddSettings
|
||||
|
||||
object AddSettings
|
||||
{
|
||||
private[sbt] final class Sequence(val sequence: Seq[AddSettings]) extends AddSettings
|
||||
private[sbt] final object User extends AddSettings
|
||||
private[sbt] final class Plugins(val include: Plugin => 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
|
||||
|
||||
/** Adds all settings from a plugin to a project. */
|
||||
val allPlugins: AddSettings = plugins(const(true))
|
||||
|
||||
/** Allows the plugins whose names match the `names` filter to automatically add settings to a project. */
|
||||
def plugins(include: Plugin => Boolean): AddSettings = new Plugins(include)
|
||||
|
||||
/** Includes user settings in the project. */
|
||||
val userSettings: AddSettings = User
|
||||
|
||||
/** Includes the settings from all .sbt files in the project's base directory. */
|
||||
val defaultSbtFiles: AddSettings = new DefaultSbtFiles(const(true))
|
||||
|
||||
/** Includes the settings from the .sbt files given by `files`. */
|
||||
def sbtFiles(files: File*): AddSettings = new SbtFiles(files)
|
||||
|
||||
/** Includes settings automatically*/
|
||||
def seq(autos: AddSettings*): AddSettings = new Sequence(autos)
|
||||
|
||||
val allDefaults: AddSettings = seq(userSettings, allPlugins, defaultSbtFiles)
|
||||
}
|
||||
|
||||
|
|
@ -195,19 +195,25 @@ object Load
|
|||
loaded.units.toSeq.flatMap { case (uri, build) =>
|
||||
val eval = if(uri == loaded.root) rootEval else lazyEval(build.unit)
|
||||
val plugins = build.unit.plugins.plugins
|
||||
val (pluginSettings, pluginProjectSettings, pluginBuildSettings) = extractSettings(plugins)
|
||||
val (pluginThisProject, pluginNotThis) = pluginSettings partition isProjectThis
|
||||
val pluginBuildSettings = plugins.flatMap(_.buildSettings)
|
||||
val pluginNotThis = plugins.flatMap(_.settings) filterNot isProjectThis
|
||||
val projectSettings = build.defined flatMap { case (id, project) =>
|
||||
val srcs = configurationSources(project.base)
|
||||
val ref = ProjectRef(uri, id)
|
||||
val defineConfig = for(c <- project.configurations) yield ( (configuration in (ref, ConfigKey(c.name))) :== c)
|
||||
val loader = build.unit.definitions.loader
|
||||
val settings =
|
||||
(thisProject :== project) +:
|
||||
(thisProjectRef :== ref) +:
|
||||
(defineConfig ++ project.settings ++ injectSettings.projectLoaded(loader) ++ pluginThisProject ++
|
||||
pluginProjectSettings ++ configurations(srcs, eval, build.imports)(loader) ++ injectSettings.project)
|
||||
|
||||
lazy val defaultSbtFiles = configurationSources(project.base)
|
||||
|
||||
import AddSettings.{User,SbtFiles,DefaultSbtFiles,Plugins,Sequence}
|
||||
def expand(auto: AddSettings): Seq[Setting[_]] = auto match {
|
||||
case User => injectSettings.projectLoaded(loader)
|
||||
case sf: SbtFiles => configurations( sf.files.map(f => IO.resolve(project.base, f)), eval, build.imports )(loader)
|
||||
case sf: DefaultSbtFiles => configurations( defaultSbtFiles.filter(sf.include), eval, build.imports )(loader)
|
||||
case f: Plugins => plugins.filter(f.include).flatMap(p => p.settings.filter(isProjectThis) ++ p.projectSettings)
|
||||
case q: Sequence => q.sequence.flatMap(expand)
|
||||
}
|
||||
|
||||
val ref = ProjectRef(uri, id)
|
||||
val defineConfig: Seq[Setting[_]] = for(c <- project.configurations) yield ( (configuration in (ref, ConfigKey(c.name))) :== c)
|
||||
val builtin: Seq[Setting[_]] = (thisProject :== project) +: (thisProjectRef :== ref) +: defineConfig
|
||||
val settings = builtin ++ project.settings ++ expand(project.auto) ++ injectSettings.project
|
||||
// map This to thisScope, Select(p) to mapRef(uri, rootProject, p)
|
||||
transformSettings(projectScope(ref), uri, rootProject, settings)
|
||||
}
|
||||
|
|
@ -221,8 +227,11 @@ object Load
|
|||
loaded.units.toSeq flatMap { case (_, build) =>
|
||||
build.unit.plugins.plugins flatMap { _.globalSettings }
|
||||
}
|
||||
|
||||
@deprecated("No longer used.", "0.13.0")
|
||||
def extractSettings(plugins: Seq[Plugin]): (Seq[Setting[_]], Seq[Setting[_]], Seq[Setting[_]]) =
|
||||
(plugins.flatMap(_.settings), plugins.flatMap(_.projectSettings), plugins.flatMap(_.buildSettings))
|
||||
|
||||
def transformProjectOnly(uri: URI, rootProject: URI => String, settings: Seq[Setting[_]]): Seq[Setting[_]] =
|
||||
Project.transform(Scope.resolveProject(uri, rootProject), settings)
|
||||
def transformSettings(thisScope: Scope, uri: URI, rootProject: URI => String, settings: Seq[Setting[_]]): Seq[Setting[_]] =
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ sealed trait ProjectDefinition[PR <: ProjectReference]
|
|||
def dependencies: Seq[ClasspathDep[PR]]
|
||||
def uses: Seq[PR] = aggregate ++ dependencies.map(_.project)
|
||||
def referenced: Seq[PR] = delegates ++ uses
|
||||
def auto: AddSettings
|
||||
|
||||
override final def hashCode: Int = id.hashCode ^ base.hashCode ^ getClass.hashCode
|
||||
override final def equals(o: Any) = o match {
|
||||
|
|
@ -34,23 +35,24 @@ sealed trait ProjectDefinition[PR <: ProjectReference]
|
|||
}
|
||||
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[Project.Setting[_]] = settings, configurations: Seq[Configuration] = configurations): Project =
|
||||
Project(id, base, aggregate = aggregate, dependencies = dependencies, delegates = delegates, settings, configurations)
|
||||
def copy(id: String = id, base: File = base, aggregate: => Seq[ProjectReference] = aggregate, dependencies: => Seq[ClasspathDep[ProjectReference]] = dependencies,
|
||||
delegates: => Seq[ProjectReference] = delegates, settings: => Seq[Project.Setting[_]] = settings, configurations: Seq[Configuration] = configurations,
|
||||
auto: AddSettings = auto): Project =
|
||||
Project(id, base, aggregate = aggregate, dependencies = dependencies, delegates = delegates, settings, configurations, auto)
|
||||
|
||||
def resolve(resolveRef: ProjectReference => ProjectRef): ResolvedProject =
|
||||
{
|
||||
def resolveRefs(prs: Seq[ProjectReference]) = prs map resolveRef
|
||||
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)
|
||||
resolved(id, base, aggregate = resolveRefs(aggregate), dependencies = resolveDeps(dependencies), delegates = resolveRefs(delegates), settings, configurations, auto)
|
||||
}
|
||||
def resolveBuild(resolveRef: ProjectReference => ProjectReference): Project =
|
||||
{
|
||||
def resolveRefs(prs: Seq[ProjectReference]) = prs map resolveRef
|
||||
def resolveDeps(ds: Seq[ClasspathDep[ProjectReference]]) = ds map resolveDep
|
||||
def resolveDep(d: ClasspathDep[ProjectReference]) = ClasspathDependency(resolveRef(d.project), d.configuration)
|
||||
apply(id, base, aggregate = resolveRefs(aggregate), dependencies = resolveDeps(dependencies), delegates = resolveRefs(delegates), settings, configurations)
|
||||
apply(id, base, aggregate = resolveRefs(aggregate), dependencies = resolveDeps(dependencies), delegates = resolveRefs(delegates), settings, configurations, auto)
|
||||
}
|
||||
|
||||
def overrideConfigs(cs: Configuration*): Project = copy(configurations = Defaults.overrideConfigs(cs : _*)(configurations))
|
||||
|
|
@ -60,6 +62,7 @@ sealed trait Project extends ProjectDefinition[ProjectReference]
|
|||
def aggregate(refs: ProjectReference*): Project = copy(aggregate = (aggregate: Seq[ProjectReference]) ++ refs)
|
||||
def configs(cs: Configuration*): Project = copy(configurations = configurations ++ cs)
|
||||
def settings(ss: Project.Setting[_]*): Project = copy(settings = (settings: Seq[Project.Setting[_]]) ++ ss)
|
||||
def autoSettings(select: AddSettings*): Project = copy(auto = AddSettings.seq(select : _*))
|
||||
}
|
||||
sealed trait ResolvedProject extends ProjectDefinition[ProjectRef]
|
||||
|
||||
|
|
@ -138,8 +141,8 @@ object Project extends Init[Scope] with ProjectExtra
|
|||
case _ => display(project) + "/"
|
||||
}
|
||||
|
||||
private abstract class ProjectDef[PR <: ProjectReference](val id: String, val base: File, aggregate0: => Seq[PR], dependencies0: => Seq[ClasspathDep[PR]], delegates0: => Seq[PR],
|
||||
settings0: => Seq[Setting[_]], val configurations: Seq[Configuration]) extends ProjectDefinition[PR]
|
||||
private abstract class ProjectDef[PR <: ProjectReference](val id: String, val base: File, aggregate0: => Seq[PR], dependencies0: => Seq[ClasspathDep[PR]],
|
||||
delegates0: => Seq[PR], settings0: => Seq[Setting[_]], val configurations: Seq[Configuration], val auto: AddSettings) extends ProjectDefinition[PR]
|
||||
{
|
||||
lazy val aggregate = aggregate0
|
||||
lazy val dependencies = dependencies0
|
||||
|
|
@ -149,16 +152,17 @@ object Project extends Init[Scope] with ProjectExtra
|
|||
Dag.topologicalSort(configurations)(_.extendsConfigs) // checks for cyclic references here instead of having to do it in Scope.delegates
|
||||
}
|
||||
|
||||
def apply(id: String, base: File, aggregate: => Seq[ProjectReference] = Nil, dependencies: => Seq[ClasspathDep[ProjectReference]] = Nil, delegates: => Seq[ProjectReference] = Nil,
|
||||
settings: => Seq[Setting[_]] = defaultSettings, configurations: Seq[Configuration] = Configurations.default): Project =
|
||||
def apply(id: String, base: File, aggregate: => Seq[ProjectReference] = Nil, dependencies: => Seq[ClasspathDep[ProjectReference]] = Nil,
|
||||
delegates: => Seq[ProjectReference] = Nil, settings: => Seq[Setting[_]] = defaultSettings, configurations: Seq[Configuration] = Configurations.default,
|
||||
auto: AddSettings = AddSettings.allDefaults): Project =
|
||||
{
|
||||
DefaultParsers.parse(id, DefaultParsers.ID).left.foreach(errMsg => error("Invalid project ID: " + errMsg))
|
||||
new ProjectDef[ProjectReference](id, base, aggregate, dependencies, delegates, settings, configurations) with Project
|
||||
new ProjectDef[ProjectReference](id, base, aggregate, dependencies, delegates, settings, configurations, auto) with Project
|
||||
}
|
||||
|
||||
def resolved(id: String, base: File, aggregate: => Seq[ProjectRef], dependencies: => Seq[ResolvedClasspathDependency], delegates: => Seq[ProjectRef],
|
||||
settings: Seq[Setting[_]], configurations: Seq[Configuration]): ResolvedProject =
|
||||
new ProjectDef[ProjectRef](id, base, aggregate, dependencies, delegates, settings, configurations) with ResolvedProject
|
||||
settings: Seq[Setting[_]], configurations: Seq[Configuration], auto: AddSettings): ResolvedProject =
|
||||
new ProjectDef[ProjectRef](id, base, aggregate, dependencies, delegates, settings, configurations, auto) with ResolvedProject
|
||||
|
||||
def defaultSettings: Seq[Setting[_]] = Defaults.defaultSettings
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
version := "ignored"
|
||||
|
|
@ -0,0 +1 @@
|
|||
version := "1.3"
|
||||
|
|
@ -0,0 +1 @@
|
|||
version := "ignored"
|
||||
|
|
@ -0,0 +1 @@
|
|||
version := "1.4"
|
||||
|
|
@ -0,0 +1 @@
|
|||
version := "1.1"
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
import sbt._
|
||||
import Keys._
|
||||
|
||||
import AddSettings._
|
||||
|
||||
object B extends Build
|
||||
{
|
||||
// version should be from explicit/a.txt
|
||||
lazy val root = project("root", "1.4") autoSettings( userSettings, sbtFiles(file("explicit/a.txt")) )
|
||||
|
||||
// version should be from global/user.sbt
|
||||
lazy val a = project("a", "1.1") autoSettings( userSettings )
|
||||
|
||||
// version should be the default 0.1-SNAPSHOT
|
||||
lazy val b = project("b", "0.1-SNAPSHOT") autoSettings()
|
||||
|
||||
// version should be from the explicit settings call
|
||||
lazy val c = project("c", "0.9") settings(version := "0.9") autoSettings()
|
||||
|
||||
// version should be from d/build.sbt
|
||||
lazy val d = project("d", "1.3") settings(version := "0.9") autoSettings( defaultSbtFiles )
|
||||
|
||||
// version should be from global/user.sbt
|
||||
lazy val e = project("e", "1.1") settings(version := "0.9") autoSettings( defaultSbtFiles, sbtFiles(file("../explicit/a.txt")), userSettings )
|
||||
|
||||
def project(id: String, expectedVersion: String): Project = Project(id, if(id == "root") file(".") else file(id)) settings(
|
||||
TaskKey[Unit]("check") <<= version map { v =>
|
||||
assert(v == expectedVersion, "Expected version '" + expectedVersion + "', got: " + v)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
version := "1.2"
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
> root/check
|
||||
|
||||
> a/check
|
||||
|
||||
> b/check
|
||||
|
||||
> c/check
|
||||
|
||||
> d/check
|
||||
|
||||
> e/check
|
||||
Loading…
Reference in New Issue