mirror of https://github.com/sbt/sbt.git
Docs: more 0.13 cleanup
* Drop dependOn, dependsOn. These are rarely the right method to call. * Drop references to ~= in favor of just :=. * Drop a .scala example where a .sbt example suffices.
This commit is contained in:
parent
718fa91772
commit
27a630e0d0
|
|
@ -29,12 +29,9 @@ There are several features of the task system:
|
||||||
|
|
||||||
1. By integrating with the settings system, tasks can be added, removed,
|
1. By integrating with the settings system, tasks can be added, removed,
|
||||||
and modified as easily and flexibly as settings.
|
and modified as easily and flexibly as settings.
|
||||||
2. :doc:`Input Tasks <TaskInputs>`, the successor to method tasks, use
|
2. :doc:`Input Tasks <TaskInputs>`, use :doc:`parser combinators <Parsing-Input>` to define the syntax for their arguments.
|
||||||
:doc:`parser combinators <Parsing-Input>` to define the syntax for their
|
This allows flexible syntax and tab-completions in the same way as :doc:`/Extending/Commands`.
|
||||||
arguments. This allows flexible syntax and tab-completions in the
|
3. Tasks produce values. Other tasks can access a task's value by calling ``value`` on it within a task definition.
|
||||||
same way as :doc:`/Extending/Commands`.
|
|
||||||
3. Tasks produce values. Other tasks can access a task's value by calling
|
|
||||||
``value`` on it within a task definition.
|
|
||||||
4. Dynamically changing the structure of the task graph is possible.
|
4. Dynamically changing the structure of the task graph is possible.
|
||||||
Tasks can be injected into the execution graph based on the result of another task.
|
Tasks can be injected into the execution graph based on the result of another task.
|
||||||
5. There are ways to handle task failure, similar to ``try/catch/finally``.
|
5. There are ways to handle task failure, similar to ``try/catch/finally``.
|
||||||
|
|
@ -61,52 +58,21 @@ build.sbt
|
||||||
|
|
||||||
hello := println("hello world!")
|
hello := println("hello world!")
|
||||||
|
|
||||||
Hello World example (scala)
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
project/Build.scala
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
|
|
||||||
import sbt._
|
|
||||||
import Keys._
|
|
||||||
|
|
||||||
object HelloBuild extends Build {
|
|
||||||
val hwsettings = Defaults.defaultSettings ++ Seq(
|
|
||||||
organization := "hello",
|
|
||||||
name := "world",
|
|
||||||
version := "1.0-SNAPSHOT",
|
|
||||||
scalaVersion := "2.9.0-1"
|
|
||||||
)
|
|
||||||
|
|
||||||
val hello = taskKey[Unit]("Prints 'Hello World'")
|
|
||||||
|
|
||||||
val helloTask = hello := {
|
|
||||||
println("Hello World")
|
|
||||||
}
|
|
||||||
|
|
||||||
lazy val project = Project (
|
|
||||||
"project",
|
|
||||||
file ("."),
|
|
||||||
settings = hwsettings ++ Seq(helloTask)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Run "sbt hello" from command line to invoke the task. Run "sbt tasks" to
|
Run "sbt hello" from command line to invoke the task. Run "sbt tasks" to
|
||||||
see this task listed.
|
see this task listed.
|
||||||
|
|
||||||
Define the key
|
Define the key
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
To declare a new task, define a val of type ``TaskKey``, either in ``.sbt`` or ``.scala``:
|
To declare a new task, define a val of type ``TaskKey``:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
val sampleTask = taskKey[Int]("A sample task.")
|
val sampleTask = taskKey[Int]("A sample task.")
|
||||||
|
|
||||||
The name of the ``val`` is used when referring to the task in Scala
|
The name of the ``val`` is used when referring to the task in Scala code and at the command line.
|
||||||
code and at the command line. The string passed to the ``TaskKey`` method is a description of the task. The type parameter passed to ``TaskKey`` (here, ``Int``) is the type of value produced by the task.
|
The string passed to the ``taskKey`` method is a description of the task.
|
||||||
|
The type parameter passed to ``taskKey`` (here, ``Int``) is the type of value produced by the task.
|
||||||
|
|
||||||
We'll define a couple of other of tasks for the examples:
|
We'll define a couple of other of tasks for the examples:
|
||||||
|
|
||||||
|
|
@ -260,22 +226,15 @@ only print ``#3``.
|
||||||
sampleTask.value - 3
|
sampleTask.value - 3
|
||||||
}
|
}
|
||||||
|
|
||||||
To apply a transformation to a single task, without using additional
|
|
||||||
tasks as inputs, use ``~=``. This accepts the function to apply to the
|
|
||||||
task's result:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
intTask := 3
|
|
||||||
|
|
||||||
// increment the value returned by intTask
|
|
||||||
intTask ~= { (x: Int) => x + 1 }
|
|
||||||
|
|
||||||
Advanced Task Operations
|
Advanced Task Operations
|
||||||
========================
|
========================
|
||||||
|
|
||||||
The previous sections demonstrated the most common way to define a task.
|
The examples in this section use the task keys defined in the previous section.
|
||||||
Advanced task definitions require the implementation to be separate from the binding.
|
|
||||||
|
Separating implementations
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
The implementation of a task can be separated from the binding.
|
||||||
For example, a basic separate definition looks like:
|
For example, a basic separate definition looks like:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
@ -289,46 +248,6 @@ For example, a basic separate definition looks like:
|
||||||
Note that whenever ``.value`` is used, it must be within a task definition, such as
|
Note that whenever ``.value`` is used, it must be within a task definition, such as
|
||||||
within ``Def.task`` above or as an argument to ``:=``.
|
within ``Def.task`` above or as an argument to ``:=``.
|
||||||
|
|
||||||
The examples in this section use the task keys defined in the previous section.
|
|
||||||
|
|
||||||
Dependencies
|
|
||||||
------------
|
|
||||||
|
|
||||||
To depend on the side effect of some tasks without using their values
|
|
||||||
and without doing additional work, use ``dependOn`` on a sequence of
|
|
||||||
tasks. The defining task key (the part on the left side of ``:=``) must
|
|
||||||
be of type ``Unit``, since no value is returned.
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
val unitTaskImpl: Initialize[Task[Unit]] = Seq(stringTask, sampleTask).dependOn
|
|
||||||
|
|
||||||
unitTask := unitTaskImpl.value
|
|
||||||
|
|
||||||
To add dependencies to an existing task without using their values, call
|
|
||||||
``dependsOn`` on the task and provide the tasks to depend on. For
|
|
||||||
example, the second task definition here modifies the original to
|
|
||||||
require that ``stringTask`` and ``sampleTask`` run first:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
intTask := 4
|
|
||||||
|
|
||||||
val intTaskImpl = intTask.dependsOn(stringTask, sampleTask)
|
|
||||||
|
|
||||||
intTask := intTaskImpl.value
|
|
||||||
|
|
||||||
Note that you can sometimes use the usual syntax:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
intTask := 4
|
|
||||||
|
|
||||||
intTask := {
|
|
||||||
val ignore = (stringTask.value, sampleTask.value)
|
|
||||||
intTask.value // use the original result
|
|
||||||
}
|
|
||||||
|
|
||||||
Streams: Per-task logging
|
Streams: Per-task logging
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,8 +52,7 @@ Implementing a task
|
||||||
|
|
||||||
Once you've defined a key, you'll need to use it in some task. You could
|
Once you've defined a key, you'll need to use it in some task. You could
|
||||||
be defining your own task, or you could be planning to redefine an
|
be defining your own task, or you could be planning to redefine an
|
||||||
existing task. Either way looks the same; if the task has no
|
existing task. Either way looks the same; use ``:=`` to associate some
|
||||||
dependencies on other settings or tasks, use ``:=`` to associate some
|
|
||||||
code with the task key:
|
code with the task key:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
@ -80,20 +79,6 @@ sbt has some utility libraries and convenience functions, in particular
|
||||||
you can often use the convenient APIs in
|
you can often use the convenient APIs in
|
||||||
`IO <../../api/index.html#sbt.IO$>`_ to manipulate files and directories.
|
`IO <../../api/index.html#sbt.IO$>`_ to manipulate files and directories.
|
||||||
|
|
||||||
Extending but not replacing a task
|
|
||||||
----------------------------------
|
|
||||||
|
|
||||||
If you want to run an existing task while also taking another action,
|
|
||||||
use ``:=`` or ``~=`` to take the existing task as input (which will
|
|
||||||
imply running that task), and then do whatever else you like after the
|
|
||||||
previous implementation completes.
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
// These two settings are equivalent
|
|
||||||
intTask := intTask.value + 1
|
|
||||||
intTask ~= { (value: Int) => value + 1 }
|
|
||||||
|
|
||||||
Use plugins!
|
Use plugins!
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ creating a ``Setting`` without putting it where sbt will find it).
|
||||||
Appending to previous values: ``+=`` and ``++=``
|
Appending to previous values: ``+=`` and ``++=``
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
Replacement with ``:=`` is the simplest transformation, but keys have
|
Assignment with ``:=`` is the simplest transformation, but keys have
|
||||||
other methods as well. If the ``T`` in ``SettingKey[T]`` is a sequence,
|
other methods as well. If the ``T`` in ``SettingKey[T]`` is a sequence,
|
||||||
i.e. the key's value type is a sequence, you can append to the sequence
|
i.e. the key's value type is a sequence, you can append to the sequence
|
||||||
rather than replacing it.
|
rather than replacing it.
|
||||||
|
|
@ -72,49 +72,10 @@ course:
|
||||||
|
|
||||||
sourceDirectories in Compile := Seq(file("sources1"), file("sources2"))
|
sourceDirectories in Compile := Seq(file("sources1"), file("sources2"))
|
||||||
|
|
||||||
Transforming a value: ``~=``
|
|
||||||
----------------------------
|
|
||||||
|
|
||||||
What happens if you want to *prepend* to
|
|
||||||
``sourceDirectories in Compile``, or filter out one of the default
|
|
||||||
directories?
|
|
||||||
|
|
||||||
You can create a ``Setting`` that depends on the previous value of a
|
|
||||||
key.
|
|
||||||
|
|
||||||
- ``~=`` applies a function to the setting's previous value, producing
|
|
||||||
a new value of the same type.
|
|
||||||
|
|
||||||
To modify ``sourceDirectories in Compile``, you could use ``~=`` as
|
|
||||||
follows:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
// filter out src/main/scala
|
|
||||||
sourceDirectories in Compile ~= { srcDirs => srcDirs filter(!_.getAbsolutePath.endsWith("src/main/scala")) }
|
|
||||||
|
|
||||||
Here, ``srcDirs`` is a parameter to an anonymous function, and the old
|
|
||||||
value of ``sourceDirectories in Compile`` gets passed in to the
|
|
||||||
anonymous function. The result of this function becomes the new value of
|
|
||||||
``sourceDirectories in Compile``.
|
|
||||||
|
|
||||||
Or a simpler example:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
// make the project name upper case
|
|
||||||
name ~= { _.toUpperCase }
|
|
||||||
|
|
||||||
The function you pass to the ``~=`` method will always have type
|
|
||||||
``T => T``, if the key has type ``SettingKey[T]`` or ``TaskKey[T]``. The
|
|
||||||
function transforms the key's value into another value of the same type.
|
|
||||||
|
|
||||||
Computing a value based on other keys' values
|
Computing a value based on other keys' values
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
|
||||||
``~=`` defines a new value in terms of a key's previously-associated
|
Reference the value of another task or setting by calling ``value``
|
||||||
value. But what if you want to define a value in terms of *other* keys'
|
|
||||||
values? Reference the value of another task or setting by calling ``value``
|
|
||||||
on the key for the task or setting. The ``value`` method is special and may
|
on the key for the task or setting. The ``value`` method is special and may
|
||||||
only be called in the argument to ``:=``, ``+=``, or ``++=``.
|
only be called in the argument to ``:=``, ``+=``, or ``++=``.
|
||||||
|
|
||||||
|
|
@ -176,7 +137,7 @@ then the computation depends on that key. It just works!
|
||||||
When settings are undefined
|
When settings are undefined
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Whenever a setting uses ``~=`` or ``:=`` to create a dependency on
|
Whenever a setting uses ``:=``, ``+=``, or ``++=`` to create a dependency on
|
||||||
itself or another key's value, the value it depends on must exist. If it
|
itself or another key's value, the value it depends on must exist. If it
|
||||||
does not, sbt will complain. It might say *"Reference to undefined
|
does not, sbt will complain. It might say *"Reference to undefined
|
||||||
setting"*, for example. When this happens, be sure you're using the key
|
setting"*, for example. When this happens, be sure you're using the key
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue