mirror of https://github.com/sbt/sbt.git
Docs: add section on getting values from multiple scopes
This commit is contained in:
parent
7ad678f4a4
commit
8b68e0f09e
|
|
@ -221,6 +221,195 @@ only print ``#3``.
|
|||
sampleTask.value - 3
|
||||
}
|
||||
|
||||
Getting values from multiple scopes
|
||||
===================================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
The general form of an expression that gets values from multiple scopes is:
|
||||
|
||||
::
|
||||
|
||||
<setting-or-task>.all(<scope-filter>).value
|
||||
|
||||
The ``all`` method is implicitly added to tasks and settings.
|
||||
It accepts a ``ScopeFilter`` that will select the ``Scopes``.
|
||||
The result has type ``Seq[T]``, where ``T`` is the key's underlying type.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
A common scenario is getting the sources for all subprojects for processing all at once, such as passing them to scaladoc.
|
||||
The task that we want to obtain values for is ``sources`` and we want to get the values in all non-root projects and in the ``Compile`` configuration.
|
||||
This looks like:
|
||||
|
||||
::
|
||||
|
||||
val core = project
|
||||
|
||||
val util = project
|
||||
|
||||
val root = project.settings(
|
||||
sources := {
|
||||
val filter = ScopeFilter( inProjects(core, util), inConfigurations(Compile) )
|
||||
// each sources definition is of type Seq[File],
|
||||
// giving us a Seq[Seq[File]] that we then flatten to Seq[File]
|
||||
val allSources: Seq[Seq[File]] = sources.all(filter).value
|
||||
allSources.flatten
|
||||
}
|
||||
)
|
||||
|
||||
The next section describes various ways to construct a ScopeFilter.
|
||||
|
||||
ScopeFilter
|
||||
-----------
|
||||
|
||||
A basic `ScopeFilter <../../api/sbt/ScopeFilter.html>`_ is constructed by the ``ScopeFilter.apply`` method.
|
||||
This method makes a ``ScopeFilter`` from filters on the parts of a ``Scope``: a ``ProjectFilter``, ``ConfigurationFilter``, and ``TaskFilter``.
|
||||
The simplest case is explicitly specifying the values for the parts:
|
||||
|
||||
::
|
||||
|
||||
val filter: ScopeFilter =
|
||||
ScopeFilter(
|
||||
inProjects( core, util ),
|
||||
inConfigurations( Compile, Test )
|
||||
)
|
||||
|
||||
Unspecified filters
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If the task filter is not specified, as in the example above, the default is to select scopes without a specific task (global).
|
||||
Similarly, an unspecified configuration filter will select scopes in the global configuration.
|
||||
The project filter should usually be explicit, but if left unspecified, the current project context will be used.
|
||||
|
||||
More on filter construction
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The example showed the basic methods ``inProjects`` and ``inConfigurations``.
|
||||
This section describes all methods for constructing a ``ProjectFilter``, ``ConfigurationFilter``, or ``TaskFilter``.
|
||||
These methods can be organized into four groups:
|
||||
|
||||
* Explicit member list (``inProjects``, ``inConfigurations``, ``inTasks``)
|
||||
* Global value (``inGlobalProject``, ``inGlobalConfiguration``, ``inGlobalTask``)
|
||||
* Default filter (``inAnyProject``, ``inAnyConfiguration``, ``inAnyTask``)
|
||||
* Project relationships (``inAggregates``, ``inDependencies``)
|
||||
|
||||
See the `API documentation <../../api/sbt/ScopeFilter.html#Make>`_ for details.
|
||||
|
||||
Combining ScopeFilters
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
``ScopeFilters`` may be combined with the ``&&``, ``||``, ``--``, and ``-`` methods:
|
||||
|
||||
a && b
|
||||
Selects scopes that match both ``a`` and ``b``
|
||||
a || b
|
||||
Selects scopes that match either ``a`` or ``b``
|
||||
a -- b
|
||||
Selects scopes that match ``a`` but not ``b``
|
||||
-b
|
||||
Selects scopes that do not match ``b``
|
||||
|
||||
For example, the following selects the scope for the ``Compile`` and ``Test`` configurations of the ``core`` project
|
||||
and the global configuration of the ``util`` project:
|
||||
|
||||
::
|
||||
|
||||
val filter: ScopeFilter =
|
||||
ScopeFilter( inProjects(core), inConfigurations(Compile, Test)) ||
|
||||
ScopeFilter( inProjects(util), inGlobalConfiguration )
|
||||
|
||||
|
||||
More operations
|
||||
---------------
|
||||
|
||||
The ``all`` method applies to both settings (values of type ``Initialize[T]``)
|
||||
and tasks (values of type ``Initialize[Task[T]]``).
|
||||
It returns a setting or task that provides a ``Seq[T]``, as shown in this table:
|
||||
|
||||
==================== =========================
|
||||
Target Result
|
||||
==================== =========================
|
||||
Initialize[T] Initialize[Seq[T]]
|
||||
Initialize[Task[T]] Initialize[Task[Seq[T]]]
|
||||
==================== =========================
|
||||
|
||||
This means that the ``all`` method can be combined with methods that construct tasks and settings.
|
||||
|
||||
Missing values
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Some scopes might not define a setting or task.
|
||||
The ``?`` and ``??`` methods can help in this case.
|
||||
They are both defined on settings and tasks and indicate what to do when a key is undefined.
|
||||
|
||||
``?``
|
||||
On a setting or task with underlying type ``T``, this accepts no arguments and returns a setting or task (respectively) of type ``Option[T]``.
|
||||
The result is ``None`` if the setting/task is undefined and ``Some[T]`` with the value if it is.
|
||||
``??``
|
||||
On a setting or task with underlying type ``T``, this accepts an argument of type ``T`` and uses this argument if the setting/task is undefined.
|
||||
|
||||
The following contrived example sets the maximum errors to be the maximum of all aggregates of the current project.
|
||||
|
||||
::
|
||||
|
||||
maxErrors := {
|
||||
// select the transitive aggregates for this project, but not the project itself
|
||||
val filter: ScopeFilter =
|
||||
ScopeFilter( inAggregates(ThisProject, includeRoot=false) )
|
||||
// get the configured maximum errors in each selected scope,
|
||||
// using 0 if not defined in a scope
|
||||
val allVersions: Seq[Int] =
|
||||
(maxErrors ?? 0).all(filter).value
|
||||
allVersions.max
|
||||
}
|
||||
|
||||
Multiple values from multiple scopes
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The target of ``all`` is any task or setting, including anonymous ones.
|
||||
This means it is possible to get multiple values at once without defining a new task or setting in each scope.
|
||||
A common use case is to pair each value obtained with the project, configuration, or full scope it came from.
|
||||
|
||||
``resolvedScoped``
|
||||
Provides the full enclosing ``ScopedKey`` (which is a ``Scope`` + ``AttributeKey[_]``)
|
||||
``thisProject``
|
||||
Provides the ``Project`` associated with this scope (undefined at the global and build levels)
|
||||
``thisProjectRef``
|
||||
Provides the ``ProjectRef`` for the context (undefined at the global and build levels)
|
||||
``configuration``
|
||||
Provides the ``Configuration`` for the context (undefined for the global configuration)
|
||||
|
||||
For example, the following defines a task that prints non-Compile configurations that define
|
||||
sbt plugins. This might be used to identify an incorrectly configured build (or not, since this is
|
||||
a fairly contrived example):
|
||||
|
||||
::
|
||||
|
||||
// Select all configurations in the current project except for Compile
|
||||
val filter: ScopeFilter = ScopeFilter(
|
||||
inProjects(ThisProject),
|
||||
inAnyConfiguration -- inConfigurations(Compile)
|
||||
)
|
||||
|
||||
// Define a task that provides the name of the current configuration
|
||||
// and the set of sbt plugins defined in the configuration
|
||||
val pluginsWithConfig: Initialize[Task[ (String, Set[String]) ]] =
|
||||
Def.task {
|
||||
( configuration.value.name, definedSbtPlugins.value )
|
||||
}
|
||||
|
||||
checkPluginsTask := {
|
||||
val oddPlugins: Seq[(String, Set[String])] =
|
||||
pluginsWithConfig.all(filter).value
|
||||
// Print each configuration that defines sbt plugins
|
||||
for( (config, plugins) <- oddPlugins if plugins.nonEmpty )
|
||||
println(s"$config defines sbt plugins: ${plugins.mkString(", ")}")
|
||||
}
|
||||
|
||||
|
||||
Advanced Task Operations
|
||||
========================
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue