mirror of https://github.com/sbt/sbt.git
expand input task documentation. ref #407
This commit is contained in:
parent
387f06e73a
commit
114cf2dbd8
|
|
@ -102,6 +102,8 @@ A similar method ``parsed`` is defined on ``Parser[T]``, ``Initialize[Parser[T]]
|
||||||
for(arg <- args) println(" " + arg)
|
for(arg <- args) println(" " + arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
For details, see :doc:`Extending/Input-Tasks`.
|
||||||
|
|
||||||
To expect a task to fail and get the failing exception, use the ``failure`` method instead of ``value``. This provides an ``Incomplete`` value, which wraps the exception. To get the result of a task whether or not it succeeds, use ``result``, which provides a ``Result[T]``.
|
To expect a task to fail and get the failing exception, use the ``failure`` method instead of ``value``. This provides an ``Incomplete`` value, which wraps the exception. To get the result of a task whether or not it succeeds, use ``result``, which provides a ``Result[T]``.
|
||||||
|
|
||||||
Dynamic settings and tasks (``flatMap``) have been cleaned up. Use the ``Def.taskDyn`` and ``Def.settingDyn`` methods to define them (better name suggestions welcome). These methods expect the result to be a task and setting, respectively.
|
Dynamic settings and tasks (``flatMap``) have been cleaned up. Use the ``Def.taskDyn`` and ``Def.settingDyn`` methods to define them (better name suggestions welcome). These methods expect the result to be a task and setting, respectively.
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ represents a task. Define a new input task key using the
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
// goes in <base>/project/Build.scala or in <base>/build.sbt
|
// goes in project/Build.scala or in build.sbt
|
||||||
val demo = inputKey[Unit]("A demo input task.")
|
val demo = inputKey[Unit]("A demo input task.")
|
||||||
|
|
||||||
The definition of an input task is similar to that of a normal task, but it can
|
The definition of an input task is similar to that of a normal task, but it can
|
||||||
|
|
@ -53,7 +53,7 @@ Input Task using Parsers
|
||||||
========================
|
========================
|
||||||
|
|
||||||
The Parser provided by the ``spaceDelimited`` method does not provide
|
The Parser provided by the ``spaceDelimited`` method does not provide
|
||||||
any flexibility in defining the input syntax. , but using a custom parser
|
any flexibility in defining the input syntax. Using a custom parser
|
||||||
is just a matter of defining your own ``Parser`` as described on the
|
is just a matter of defining your own ``Parser`` as described on the
|
||||||
:doc:`/Detailed-Topics/Parsing-Input` page.
|
:doc:`/Detailed-Topics/Parsing-Input` page.
|
||||||
|
|
||||||
|
|
@ -120,3 +120,126 @@ print some information to the screen.
|
||||||
println("Value: " + value)
|
println("Value: " + value)
|
||||||
println("Packaged: " + packageBin.value.getAbsolutePath)
|
println("Packaged: " + packageBin.value.getAbsolutePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
The InputTask type
|
||||||
|
==================
|
||||||
|
|
||||||
|
It helps to look at the ``InputTask`` type to understand more advanced usage of input tasks.
|
||||||
|
The core input task type is:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
class InputTask[T](val parser: State => Parser[Task[T]])
|
||||||
|
|
||||||
|
Normally, an input task is assigned to a setting and you work with ``Initialize[InputTask[T]]``.
|
||||||
|
|
||||||
|
Breaking this down,
|
||||||
|
|
||||||
|
1. You can use other settings (via ``Initialize``) to construct an input task.
|
||||||
|
2. You can use the current ``State`` to construct the parser.
|
||||||
|
3. The parser accepts user input and provides tab completion.
|
||||||
|
4. The parser produces the task to run.
|
||||||
|
|
||||||
|
So, you can use settings or ``State`` to construct the parser that defines an input task's command line syntax.
|
||||||
|
This was described in the previous section.
|
||||||
|
You can then use settings, ``State``, or user input to construct the task to run.
|
||||||
|
This is implicit in the input task syntax.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Using other input tasks
|
||||||
|
=======================
|
||||||
|
|
||||||
|
The types involved in an input task are composable, so it is possible to reuse input tasks.
|
||||||
|
The ``.parsed`` and ``.value`` methods are defined on InputTasks to make this more convenient in common situations:
|
||||||
|
|
||||||
|
* Call ``.parsed`` on an ``InputTask[T]`` or ``Initialize[InputTask[T]]`` to get the ``Task[T]`` created by that input task
|
||||||
|
* Call ``.value`` on an ``InputTask[T]`` or ``Initialize[InputTask[T]]`` to get the final value of type ``T`` for that input task
|
||||||
|
|
||||||
|
In both situations, the underlying ``Parser`` is sequenced with other parsers in the input task definition.
|
||||||
|
In the case of ``.value``, the generated task is evaluated.
|
||||||
|
|
||||||
|
The following example applies the ``run`` input task, a literal separator parser ``--``, and ``run`` again.
|
||||||
|
The parsers are sequenced in order of syntactic appearance,
|
||||||
|
so that the arguments before ``--`` are passed to the first ``run`` and the ones after are passed to the second.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
val run2 = inputKey[Unit](
|
||||||
|
"Runs the main class twice with different argument lists separated by ---")
|
||||||
|
|
||||||
|
val separator: Parser[String] = "--"
|
||||||
|
|
||||||
|
run2 := {
|
||||||
|
val one = (run in Compile).value
|
||||||
|
val sep = separator.parsed
|
||||||
|
val two = (run in Compile).value
|
||||||
|
}
|
||||||
|
|
||||||
|
For a main class Demo that echoes its arguments, this looks like:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
$ sbt
|
||||||
|
> run2 a b -- c d
|
||||||
|
[info] Running Demo c d
|
||||||
|
[info] Running Demo a b
|
||||||
|
c
|
||||||
|
d
|
||||||
|
a
|
||||||
|
b
|
||||||
|
|
||||||
|
|
||||||
|
Preapplying input
|
||||||
|
=================
|
||||||
|
|
||||||
|
Because ``InputTasks`` are built from ``Parsers``, it is possible to generate a new ``InputTask`` by applying some input programmatically.
|
||||||
|
Two convenience methods are provided on ``InputTask[T]`` and ``Initialize[InputTask[T]]`` that accept the String to apply.
|
||||||
|
|
||||||
|
* ``partialInput`` applies the input and allows further input, such as from the command line
|
||||||
|
* ``fullInput`` applies the input and terminates parsing, so that further input is not accepted
|
||||||
|
|
||||||
|
In each case, the input is applied to the input task's parser.
|
||||||
|
Because input tasks handle all input after the task name, they usually require initial whitespace to be provided in the input.
|
||||||
|
|
||||||
|
Consider the example in the previous section.
|
||||||
|
We can modify it so that we:
|
||||||
|
|
||||||
|
* Explicitly specify all of the arguments to the first ``run``. We use ``name`` and ``version`` to show that settings can be used to define and modify parsers.
|
||||||
|
* Define the initial arguments passed to the second ``run``, but allow further input on the command line.
|
||||||
|
|
||||||
|
NOTE: the current implementation of ``:=`` doesn't actually support applying input derived from settings yet.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
val run2 = inputKey[Unit]("Runs the main class twice: " +
|
||||||
|
"once with the project name and version as arguments"
|
||||||
|
"and once with command line arguments preceded by hard coded values.")
|
||||||
|
|
||||||
|
// The argument string for the first run task is ' <name> <version>'
|
||||||
|
val firstInput: Initialize[String] =
|
||||||
|
Def.setting(s" ${name.value} ${version.value}")
|
||||||
|
|
||||||
|
// Make the first arguments to the second run task ' red blue'
|
||||||
|
val secondInput: String = " red blue"
|
||||||
|
|
||||||
|
val separator: Parser[String] = "--"
|
||||||
|
|
||||||
|
run2 := {
|
||||||
|
val one = (run in Compile).fullInput(firstInput.value).value
|
||||||
|
val two = (run in Compile).partialInput(secondInput).value
|
||||||
|
}
|
||||||
|
|
||||||
|
For a main class Demo that echoes its arguments, this looks like:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
$ sbt
|
||||||
|
> run2 green
|
||||||
|
[info] Running Demo demo 1.0
|
||||||
|
[info] Running Demo red blue green
|
||||||
|
demo
|
||||||
|
1.0
|
||||||
|
red
|
||||||
|
blue
|
||||||
|
green
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue