diff --git a/src/sphinx/Community/Community-Plugins.rst b/src/sphinx/Community/Community-Plugins.rst index c0550c327..07045638e 100644 --- a/src/sphinx/Community/Community-Plugins.rst +++ b/src/sphinx/Community/Community-Plugins.rst @@ -38,9 +38,9 @@ To automatically deploy snapshot/release versions of your plugin use the followi :: - publishTo <<= (version) { version: String => + publishTo := { val scalasbt = "http://repo.scala-sbt.org/scalasbt/" - val (name, url) = if (version.contains("-SNAPSHOT")) + val (name, url) = if (version.value.contains("-SNAPSHOT")) ("sbt-plugin-snapshots", scalasbt+"sbt-plugin-snapshots") else ("sbt-plugin-releases", scalasbt+"sbt-plugin-releases") diff --git a/src/sphinx/Community/Using-Sonatype.rst b/src/sphinx/Community/Using-Sonatype.rst index 20a9d6dc6..aadf28029 100644 --- a/src/sphinx/Community/Using-Sonatype.rst +++ b/src/sphinx/Community/Using-Sonatype.rst @@ -32,9 +32,9 @@ the same URLs for everyone: :: - publishTo <<= version { (v: String) => + publishTo := { val nexus = "https://oss.sonatype.org/" - if (v.trim.endsWith("SNAPSHOT")) + if (version.value.trim.endsWith("SNAPSHOT")) Some("snapshots" at nexus + "content/repositories/snapshots") else Some("releases" at nexus + "service/local/staging/deploy/maven2") @@ -226,9 +226,9 @@ others: :: - publishTo <<= version { v: String => + publishTo := { val nexus = "https://oss.sonatype.org/" - if (v.trim.endsWith("SNAPSHOT")) + if (version.value.trim.endsWith("SNAPSHOT")) Some("snapshots" at nexus + "content/repositories/snapshots") else Some("releases" at nexus + "service/local/staging/deploy/maven2") diff --git a/src/sphinx/Detailed-Topics/Artifacts.rst b/src/sphinx/Detailed-Topics/Artifacts.rst index 383a56cc3..0eca6f8b6 100644 --- a/src/sphinx/Detailed-Topics/Artifacts.rst +++ b/src/sphinx/Detailed-Topics/Artifacts.rst @@ -46,7 +46,7 @@ Modifying default artifacts =========================== Each built-in artifact has several configurable settings in addition to -``publish-artifact``. The basic ones are ``artifact`` (of type +``publishArtifact``. The basic ones are ``artifact`` (of type ``SettingKey[Artifact]``), ``mappings`` (of type ``TaskKey[(File,String)]``), and ``artifactPath`` (of type ``SettingKey[File]``). They are scoped by ``(, )`` as @@ -60,7 +60,7 @@ To modify the type of the main artifact, for example: art.copy(`type` = "bundle") } -The generated artifact name is determined by the ``artifact-name`` +The generated artifact name is determined by the ``artifactName`` setting. This setting is of type ``(ScalaVersion, ModuleID, Artifact) => String``. The ScalaVersion argument provides the full Scala version String and the binary @@ -83,9 +83,9 @@ path: (Note that in practice you rarely want to drop the classifier.) Finally, you can get the ``(Artifact, File)`` pair for the artifact by -mapping the ``packaged-artifact`` task. Note that if you don't need the +mapping the ``packagedArtifact`` task. Note that if you don't need the ``Artifact``, you can get just the File from the package task -(``package``, ``package-doc``, or ``package-src``). In both cases, +(``package``, ``packageDoc``, or ``packageSrc``). In both cases, mapping the task to get the file ensures that the artifact is generated first and so the file is guaranteed to be up-to-date. @@ -93,7 +93,8 @@ For example: :: - myTask <<= packagedArtifact in (Compile, packageBin) map { case (art: Artifact, file: File) => + myTask := { + val (art, file) = packagedArtifact.in(Compile, packageBin).value println("Artifact definition: " + art) println("Packaged file: " + file.getAbsolutePath) } diff --git a/src/sphinx/Detailed-Topics/Best-Practices.rst b/src/sphinx/Detailed-Topics/Best-Practices.rst index eb5cf8409..ecb9dbd36 100644 --- a/src/sphinx/Detailed-Topics/Best-Practices.rst +++ b/src/sphinx/Detailed-Topics/Best-Practices.rst @@ -26,9 +26,9 @@ beginning of the resolvers list: :: - resolvers <<= resolvers {rs => + resolvers := { val localMaven = "Local Maven Repository" at "file://"+Path.userHome.absolutePath+"/.m2/repository" - localMaven +: rs + localMaven +: resolvers.value } 1. Put settings specific to a user in a global ``.sbt`` file, such as @@ -68,7 +68,7 @@ respect that. Instead, use the setting, like: :: - myDirectory <<= target(_ / "sub-directory") + myDirectory := target.value / "sub-directory" Don't "mutate" files ~~~~~~~~~~~~~~~~~~~~ @@ -92,7 +92,7 @@ For example: :: - lazy val makeFile = TaskKey[File]("make-file") + lazy val makeFile = TaskKey[File]("makeFile") // define a task that creates a file, // writes some content, and returns the File @@ -106,9 +106,8 @@ For example: // The result of makeFile is the constructed File, // so useFile can map makeFile and simultaneously // get the File and declare the dependency on makeFile - useFile <<= makeFile map { (f: File) => - doSomething( f ) - } + useFile := + doSomething( makeFile.value ) This arrangement is not always possible, but it should be the rule and not the exception. @@ -135,7 +134,7 @@ directory. :: - myPath <<= baseDirectory(_ / "licenses") + myPath := baseDirectory.value / "licenses" In Java (and thus in Scala), a relative File is relative to the current working directory. The working directory is not always the same as the diff --git a/src/sphinx/Detailed-Topics/Classpaths.rst b/src/sphinx/Detailed-Topics/Classpaths.rst index 7a226c50c..cac5e11ce 100644 --- a/src/sphinx/Detailed-Topics/Classpaths.rst +++ b/src/sphinx/Detailed-Topics/Classpaths.rst @@ -53,32 +53,24 @@ Tasks that produce managed files should be inserted as follows: :: - sourceGenerators in Compile <+= sourceManaged in Compile map { out => - generate(out / "some_directory") - } + sourceGenerators in Compile += + generate( (sourceManaged in Compile).value / "some_directory") In this example, ``generate`` is some function of type -``File => Seq[File]`` that actually does the work. The ``<+=`` method is -like ``+=``, but allows the right hand side to have inputs (like the -difference between ``:=`` and ``<<=``). So, we are appending a new task +``File => Seq[File]`` that actually does the work. So, we are appending a new task to the list of main source generators (``sourceGenerators in Compile``). To insert a named task, which is the better approach for plugins: :: - - sourceGenerators in Compile <+= (mySourceGenerator in Compile).task - - mySourceGenerator in Compile <<= sourceManaged in Compile map { out => - generate(out / "some_directory") - } - -where ``mySourceGenerator`` is defined as: - -:: - val mySourceGenerator = TaskKey[Seq[File]](...) + mySourceGenerator in Compile := + generate( (sourceManaged in Compile).value / "some_directory") + + sourceGenerators in Compile += (mySourceGenerator in Compile).task + + The ``task`` method is used to refer to the actual task instead of the result of the task. @@ -115,33 +107,33 @@ Keys For classpaths, the relevant keys are: -- ``unmanaged-classpath`` -- ``managed-classpath`` -- ``external-dependency-classpath`` -- ``internal-dependency-classpath`` +- ``unmanagedClasspath`` +- ``managedClasspath`` +- ``externalDependencyClasspath`` +- ``internalDependencyClasspath`` For sources: -- ``unmanaged-sources`` These are by default built up from - ``unmanaged-source-directories``, which consists of ``scala-source`` - and ``java-source``. -- ``managed-sources`` These are generated sources. -- ``sources`` Combines ``managed-sources`` and ``unmanaged-sources``. -- ``source-generators`` These are tasks that generate source files. +- ``unmanagedSources`` These are by default built up from + ``unmanagedSourceDirectories``, which consists of ``scalaSource`` + and ``javaSource``. +- ``managedSources`` These are generated sources. +- ``sources`` Combines ``managedSources`` and ``unmanagedSources``. +- ``sourceGenerators`` These are tasks that generate source files. Typically, these tasks will put sources in the directory provided by - ``source-managed``. + ``sourceManaged``. For resources -- ``unmanaged-resources`` These are by default built up from - ``unmanaged-resource-directories``, which by default is - ``resource-directory``, excluding files matched by - ``default-excludes``. -- ``managed-resources`` By default, this is empty for standard +- ``unmanagedResources`` These are by default built up from + ``unmanagedResourceDirectories``, which by default is + ``resourceDirectory``, excluding files matched by + ``defaultExcludes``. +- ``managedResources`` By default, this is empty for standard projects. sbt plugins will have a generated descriptor file here. -- ``resource-generators`` These are tasks that generate resource files. +- ``resourceGenerators`` These are tasks that generate resource files. Typically, these tasks will put resources in the directory provided - by ``resource-managed``. + by ``resourceManaged``. Use the :doc:`inspect command ` for more details. @@ -158,10 +150,4 @@ in classpath. :: - unmanagedClasspath in Runtime <<= (unmanagedClasspath in Runtime, baseDirectory) map { (cp, bd) => cp :+ Attributed.blank(bd / "config") } - -Or shorter: - -:: - - unmanagedClasspath in Runtime <+= (baseDirectory) map { bd => Attributed.blank(bd / "config") } + unmanagedClasspath in Runtime += baseDirectory.value / "config" diff --git a/src/sphinx/Detailed-Topics/Command-Line-Reference.rst b/src/sphinx/Detailed-Topics/Command-Line-Reference.rst index bef6d568b..3592473b7 100644 --- a/src/sphinx/Detailed-Topics/Command-Line-Reference.rst +++ b/src/sphinx/Detailed-Topics/Command-Line-Reference.rst @@ -28,10 +28,10 @@ Project-level tasks ------------------- - ``clean`` Deletes all generated files (the ``target`` directory). -- ``publish-local`` Publishes artifacts (such as jars) to the local Ivy +- ``publishLocal`` Publishes artifacts (such as jars) to the local Ivy repository as described in :doc:`Publishing`. - ``publish`` Publishes artifacts (such as jars) to the repository - defined by the ``publish-to`` setting, described in :doc:`Publishing`. + defined by the ``publishTo`` setting, described in :doc:`Publishing`. - ``update`` Resolves and retrieves external dependencies as described in :doc:`library dependencies `. @@ -54,14 +54,14 @@ equivalent in the ``test`` configuration that can be run using a libraries. To return to sbt, type ``:quit``, Ctrl+D (Unix), or Ctrl+Z (Windows). Similarly, ``test:console`` starts the interpreter with the test classes and classpath. -- ``console-quick`` Starts the Scala interpreter with the project's - compile-time dependencies on the classpath. ``test:console-quick`` +- ``consoleQuick`` Starts the Scala interpreter with the project's + compile-time dependencies on the classpath. ``test:consoleQuick`` uses the test dependencies. This task differs from ``console`` in that it does not force compilation of the current project's sources. -- ``console-project`` Enters an interactive session with sbt and the +- ``consoleProject`` Enters an interactive session with sbt and the build definition on the classpath. The build definition and related values are bound to variables and common packages and values are - imported. See the :doc:`console-project documentation ` for more information. + imported. See the :doc:`consoleProject documentation ` for more information. - ``doc`` Generates API documentation for Scala source files in ``src/main/scala`` using scaladoc. ``test:doc`` generates API documentation for source files in ``src/test/scala``. @@ -70,13 +70,13 @@ equivalent in the ``test`` configuration that can be run using a ``src/main/scala``. ``test:package`` creates a jar containing the files in ``src/test/resources`` and the class compiled from ``src/test/scala``. -- ``package-doc`` Creates a jar file containing API documentation +- ``packageDoc`` Creates a jar file containing API documentation generated from Scala source files in ``src/main/scala``. - ``test:package-doc`` creates a jar containing API documentation for + ``test:packageDoc`` creates a jar containing API documentation for test sources files in ``src/test/scala``. -- ``package-src``: Creates a jar file containing all main source files +- ``packageSrc``: Creates a jar file containing all main source files and resources. The packaged paths are relative to ``src/main/scala`` - and ``src/main/resources``. Similarly, ``test:package-src`` operates + and ``src/main/resources``. Similarly, ``test:packageSrc`` operates on test source files and resources. - ``run *`` Runs the main class for the project in the same virtual machine as ``sbt``. The main class is passed the @@ -84,18 +84,18 @@ equivalent in the ``test`` configuration that can be run using a details on the use of ``System.exit`` and multithreading (including GUIs) in code run by this action. ``test:run`` runs a main class in the test code. -- ``run-main *`` Runs the specified main class +- ``runMain *`` Runs the specified main class for the project in the same virtual machine as ``sbt``. The main class is passed the ``argument``\ s provided. Please see :doc:`Running-Project-Code` for details on the use of ``System.exit`` and multithreading (including GUIs) in code run by this action. - ``test:run-main`` runs the specified main class in the test code. + ``test:runMain`` runs the specified main class in the test code. - ``test`` Runs all tests detected during test compilation. See :doc:`Testing` for details. -- ``test-only *`` Runs the tests provided as arguments. ``*`` +- ``testOnly *`` Runs the tests provided as arguments. ``*`` (will be) interpreted as a wildcard in the test name. See :doc:`Testing` for details. -- ``test-quick *`` Runs the tests specified as arguments (or all +- ``testQuick *`` Runs the tests specified as arguments (or all tests if no arguments are given) that: 1. have not been run yet OR @@ -130,7 +130,7 @@ General commands should be on its own line. Empty lines and lines beginning with '#' are ignored - ``+ `` Executes the project specified action or method for - all versions of Scala defined in the ``cross-scala-versions`` + all versions of Scala defined in the ``crossScalaVersions`` setting. - ``++ `` Temporarily changes the version of Scala building the project and executes the provided command. ```` diff --git a/src/sphinx/Detailed-Topics/Compiler-Plugins.rst b/src/sphinx/Detailed-Topics/Compiler-Plugins.rst index f137c5ad9..0642e5c52 100644 --- a/src/sphinx/Detailed-Topics/Compiler-Plugins.rst +++ b/src/sphinx/Detailed-Topics/Compiler-Plugins.rst @@ -3,7 +3,7 @@ Compiler Plugin Support ======================= There is some special support for using compiler plugins. You can set -``auto-compiler-plugins`` to ``true`` to enable this functionality. +``autoCompilerPlugins`` to ``true`` to enable this functionality. :: @@ -18,7 +18,7 @@ for specifying ``plugin`` as the configuration for a dependency: addCompilerPlugin("org.scala-tools.sxr" %% "sxr" % "0.2.7") -The ``compile`` and ``test-compile`` actions will use any compiler +The ``compile`` and ``testCompile`` actions will use any compiler plugins found in the ``lib`` directory or in the ``plugin`` configuration. You are responsible for configuring the plugins as necessary. For example, Scala X-Ray requires the extra option: @@ -26,9 +26,8 @@ necessary. For example, Scala X-Ray requires the extra option: :: // declare the main Scala source directory as the base directory - scalacOptions <<= (scalacOptions, scalaSource in Compile) { (options, base) => - options :+ ("-Psxr:base-directory:" + base.getAbsolutePath) - } + scalacOptions := + scalacOptions.value :+ ("-Psxr:base-directory:" + (scalaSource in Compile).value.getAbsolutePath) You can still specify compiler plugins manually. For example: @@ -59,8 +58,7 @@ Adding a version-specific compiler plugin can be done as follows: autoCompilerPlugins := true - libraryDependencies <<= (scalaVersion, libraryDependencies) { (ver, deps) => - deps :+ compilerPlugin("org.scala-lang.plugins" % "continuations" % ver) - } + libraryDependencies += + compilerPlugin("org.scala-lang.plugins" % "continuations" % scalaVersion.value) scalacOptions += "-P:continuations:enable" diff --git a/src/sphinx/Detailed-Topics/Console-Project.rst b/src/sphinx/Detailed-Topics/Console-Project.rst index 9c877d0b4..3f1c996b6 100644 --- a/src/sphinx/Detailed-Topics/Console-Project.rst +++ b/src/sphinx/Detailed-Topics/Console-Project.rst @@ -5,7 +5,7 @@ Console Project Description =========== -The ``console-project`` task starts the Scala interpreter with access to +The ``consoleProject`` task starts the Scala interpreter with access to your project definition and to ``sbt``. Specifically, the interpreter is started up with these commands already executed: @@ -29,7 +29,7 @@ be included in the standard library in Scala 2.9): > "grep -r null src" #|| "echo null-free" ! > uri("http://databinder.net/dispatch/About").toURL #> file("About.html") ! -``console-project`` can be useful for creating and modifying your build +``consoleProject`` can be useful for creating and modifying your build in the same way that the Scala interpreter is normally used to explore writing code. Note that this gives you raw access to your build. Think about what you pass to ``IO.delete``, for example. @@ -93,8 +93,8 @@ Show the classpaths used for compilation and testing: > evalTask( fullClasspath in Test, currentState ).files foreach println Show the remaining commands to be executed in the build (more -interesting if you invoke ``console-project`` like -``; console-project ; clean ; compile``): +interesting if you invoke ``consoleProject`` like +``; consoleProject ; clean ; compile``): .. code-block:: scala diff --git a/src/sphinx/Detailed-Topics/Dependency-Management-Flow.rst b/src/sphinx/Detailed-Topics/Dependency-Management-Flow.rst index ab408b0d6..1e6c63bdb 100644 --- a/src/sphinx/Detailed-Topics/Dependency-Management-Flow.rst +++ b/src/sphinx/Detailed-Topics/Dependency-Management-Flow.rst @@ -63,7 +63,7 @@ B. If a file cannot be C. ``last update`` contains more information about the most recent resolution and download. The amount of debugging output from Ivy is - high, so you may want to use ``last-grep`` (run ``help last-grep`` for + high, so you may want to use ``lastGrep`` (run ``help lastGrep`` for usage). D. Run ``clean`` and then ``update``. If this works, it could diff --git a/src/sphinx/Detailed-Topics/Forking.rst b/src/sphinx/Detailed-Topics/Forking.rst index 4bf611507..88f37dac4 100644 --- a/src/sphinx/Detailed-Topics/Forking.rst +++ b/src/sphinx/Detailed-Topics/Forking.rst @@ -19,8 +19,8 @@ The ``fork`` setting controls whether forking is enabled (true) or not (false). It can be set in the ``run`` scope to only fork ``run`` commands or in the ``test`` scope to only fork ``test`` commands. -To fork all test tasks (``test``, ``test-only``, and ``test-quick``) and -run tasks (``run``, ``run-main``, ``test:run``, and ``test:run-main``), +To fork all test tasks (``test``, ``testOnly``, and ``testQuick``) and +run tasks (``run``, ``runMain``, ``test:run``, and ``test:runMain``), :: @@ -33,14 +33,14 @@ To enable forking ``run`` tasks only, set ``fork`` to ``true`` in the fork in run := true -To only fork ``test:run`` and ``test:run-main``: +To only fork ``test:run`` and ``test:runMain``: :: fork in (Test,run) := true Similarly, set ``fork in (Compile,run) := true`` to only fork the main -``run`` tasks. ``run`` and ``run-main`` share the same configuration and +``run`` tasks. ``run`` and ``runMain`` share the same configuration and cannot be configured separately. To enable forking all ``test`` tasks only, set ``fork`` to ``true`` in @@ -64,13 +64,13 @@ To change the working directory when forked, set // sets the working directory for all `run`-like tasks baseDirectory in run := file("/path/to/working/directory/") - // sets the working directory for `run` and `run-main` only + // sets the working directory for `run` and `runMain` only baseDirectory in (Compile,run) := file("/path/to/working/directory/") - // sets the working directory for `test:run` and `test:run-main` only + // sets the working directory for `test:run` and `test:runMain` only baseDirectory in (Test,run) := file("/path/to/working/directory/") - // sets the working directory for `test`, `test-quick`, and `test-only` + // sets the working directory for `test`, `testQuick`, and `testOnly` baseDirectory in test := file("/path/to/working/directory/") Forked JVM options @@ -99,7 +99,7 @@ or only affect the ``test`` tasks: Java Home ========= -Select the Java installation to use by setting the ``java-home`` +Select the Java installation to use by setting the ``javaHome`` directory: :: @@ -122,7 +122,7 @@ Configuring output By default, forked output is sent to the Logger, with standard output logged at the ``Info`` level and standard error at the ``Error`` level. -This can be configured with the ``output-strategy`` setting, which is of +This can be configured with the ``outputStrategy`` setting, which is of type `OutputStrategy <../../api/sbt/OutputStrategy.html>`_. diff --git a/src/sphinx/Detailed-Topics/Inspecting-Settings.rst b/src/sphinx/Detailed-Topics/Inspecting-Settings.rst index d7c42a6dd..37bfb4c68 100644 --- a/src/sphinx/Detailed-Topics/Inspecting-Settings.rst +++ b/src/sphinx/Detailed-Topics/Inspecting-Settings.rst @@ -59,7 +59,7 @@ like ``test:run``. Some other examples that require the explicit .. code-block:: console - > test:console-quick + > test:consoleQuick > test:console > test:doc > test:package @@ -68,8 +68,8 @@ Task-specific Settings ---------------------- Some settings are defined per-task. This is used when there are several -related tasks, such as ``package``, ``package-src``, and -``package-doc``, in the same configuration (such as ``compile`` or +related tasks, such as ``package``, ``packageSrc``, and +``packageDoc``, in the same configuration (such as ``compile`` or ``test``). For package tasks, their settings are the files to package, the options to use, and the output file to produce. Each package task should be able to have different values for these settings. @@ -80,16 +80,16 @@ different package tasks. .. code-block:: console - > package::artifact-path + > package::artifactPath [info] /home/user/sample/target/scala-2.8.1.final/demo_2.8.1-0.1.jar - > package-src::artifact-path + > packageSrc::artifactPath [info] /home/user/sample/target/scala-2.8.1.final/demo_2.8.1-0.1-src.jar - > package-doc::artifact-path + > packageDoc::artifactPath [info] /home/user/sample/target/scala-2.8.1.final/demo_2.8.1-0.1-doc.jar - > test:package::artifact-path + > test:package::artifactPath [info] /home/user/sample/target/scala-2.8.1.final/root_2.8.1-0.1-test.jar Note that a single colon ``:`` follows a configuration axis and a double @@ -113,13 +113,13 @@ is defined. For example, .. code-block:: console - > inspect library-dependencies + > inspect libraryDependencies [info] Setting: scala.collection.Seq[sbt.ModuleID] = List(org.scalaz:scalaz-core:6.0-SNAPSHOT, org.scala-tools.testing:scalacheck:1.8:test) [info] Provided by: - [info] {file:/home/user/sample/}root/*:library-dependencies + [info] {file:/home/user/sample/}root/*:libraryDependencies ... -This shows that ``library-dependencies`` has been defined on the current +This shows that ``libraryDependencies`` has been defined on the current project (``{file:/home/user/sample/}root``) in the global configuration (``*:``). For a task like ``update``, the output looks like: @@ -168,23 +168,23 @@ As an example, we'll look at ``console``: > inspect console ... [info] Dependencies: - [info] compile:console::full-classpath - [info] compile:console::scalac-options - [info] compile:console::initial-commands - [info] compile:console::cleanup-commands + [info] compile:console::fullClasspath + [info] compile:console::scalacOptions + [info] compile:console::initialCommands + [info] compile:console::cleanupCommands [info] compile:console::compilers - [info] compile:console::task-temporary-directory - [info] compile:console::scala-instance + [info] compile:console::taskTemporary-directory + [info] compile:console::scalaInstance [info] compile:console::streams ... This shows the inputs to the ``console`` task. We can see that it gets -its classpath and options from ``full-classpath`` and -``scalac-options(for console)``. The information provided by the +its classpath and options from ``fullClasspath`` and +``scalacOptions(for console)``. The information provided by the ``inspect`` command can thus assist in finding the right setting to change. The convention for keys, like ``console`` and -``full-classpath``, is that the Scala identifier is camel case, while +``fullClasspath``, is that the Scala identifier is camel case, while the String representation is lowercase and separated by dashes. The Scala identifier for a configuration is uppercase to distinguish it from tasks like ``compile`` and ``test``. For example, we can infer from the @@ -200,12 +200,12 @@ starts up: ... ``inspect`` showed that ``console`` used the setting -``compile:console::initial-commands``. Translating the -``initial-commands`` string to the Scala identifier gives us +``compile:console::initialCommands``. Translating the +``initialCommands`` string to the Scala identifier gives us ``initialCommands``. ``compile`` indicates that this is for the main sources. ``console::`` indicates that the setting is specific to ``console``. Because of this, we can set the initial commands on the -``console`` task without affecting the ``console-quick`` task, for +``console`` task without affecting the ``consoleQuick`` task, for example. Actual Dependencies @@ -224,28 +224,28 @@ Dependencies, > inspect actual console ... [info] Dependencies: - [info] compile:scalac-options - [info] compile:full-classpath - [info] *:scala-instance - [info] */*:initial-commands - [info] */*:cleanup-commands - [info] */*:task-temporary-directory + [info] compile:scalacOptions + [info] compile:fullClasspath + [info] *:scalaInstance + [info] */*:initialCommands + [info] */*:cleanupCommands + [info] */*:taskTemporaryDirectory [info] *:console::compilers [info] compile:console::streams ... -For ``initial-commands``, we see that it comes from the global scope +For ``initialCommands``, we see that it comes from the global scope (``*/*:``). Combining this with the relevant output from ``inspect console``: .. code-block:: console - compile:console::initial-commands + compile:console::initialCommands -we know that we can set ``initial-commands`` as generally as the global +we know that we can set ``initialCommands`` as generally as the global scope, as specific as the current project's ``console`` task scope, or anything in between. This means that we can, for example, set -``initial-commands`` for the whole project and will affect ``console``: +``initialCommands`` for the whole project and will affect ``console``: .. code-block:: console @@ -258,19 +258,19 @@ looking at the reverse dependencies output of ``inspect actual``: .. code-block:: console - > inspect actual initial-commands + > inspect actual initialCommands ... [info] Reverse dependencies: [info] test:console - [info] compile:console-quick + [info] compile:consoleQuick [info] compile:console - [info] test:console-quick - [info] *:console-project + [info] test:consoleQuick + [info] *:consoleProject ... -We now know that by setting ``initial-commands`` on the whole project, +We now know that by setting ``initialCommands`` on the whole project, we affect all console tasks in all configurations in that project. If we -didn't want the initial commands to apply for ``console-project``, which +didn't want the initial commands to apply for ``consoleProject``, which doesn't have our project's classpath available, we could use the more specific task axis: @@ -299,17 +299,17 @@ As an example, consider the initial commands for ``console`` again: .. code-block:: console - > inspect console::initial-commands + > inspect console::initialCommands ... [info] Delegates: - [info] *:console::initial-commands - [info] *:initial-commands - [info] {.}/*:console::initial-commands - [info] {.}/*:initial-commands - [info] */*:console::initial-commands - [info] */*:initial-commands + [info] *:console::initialCommands + [info] *:initialCommands + [info] {.}/*:console::initialCommands + [info] {.}/*:initialCommands + [info] */*:console::initialCommands + [info] */*:initialCommands ... This means that if there is no value specifically for -``*:console::initial-commands``, the scopes listed under Delegates will +``*:console::initialCommands``, the scopes listed under Delegates will be searched in order until a defined value is found. diff --git a/src/sphinx/Detailed-Topics/Java-Sources.rst b/src/sphinx/Detailed-Topics/Java-Sources.rst index 47c4083c1..61aa45ee9 100644 --- a/src/sphinx/Detailed-Topics/Java-Sources.rst +++ b/src/sphinx/Detailed-Topics/Java-Sources.rst @@ -11,10 +11,10 @@ Usage - ``compile`` will compile the sources under ``src/main/java`` by default. -- ``test-compile`` will compile the sources under ``src/test/java`` by +- ``testCompile`` will compile the sources under ``src/test/java`` by default. -Pass options to the Java compiler by setting ``javac-options``: +Pass options to the Java compiler by setting ``javacOptions``: :: @@ -28,7 +28,7 @@ sbt. Multi-element options, such as ``-source 1.5``, are specified like: javacOptions ++= Seq("-source", "1.5") You can specify the order in which Scala and Java sources are built with -the ``compile-order`` setting. Possible values are from the +the ``compileOrder`` setting. Possible values are from the ``CompileOrder`` enumeration: ``Mixed``, ``JavaThenScala``, and ``ScalaThenJava``. If you have circular dependencies between Scala and Java sources, you need the default, ``Mixed``, which passes both Java @@ -68,10 +68,10 @@ unnecessary Scala directories can be ignored by modifying :: // Include only src/main/java in the compile configuration - unmanagedSourceDirectories in Compile <<= Seq(javaSource in Compile).join + unmanagedSourceDirectories in Compile := (javaSource in Compile).value :: Nil // Include only src/test/java in the test configuration - unmanagedSourceDirectories in Test <<= Seq(javaSource in Test).join + unmanagedSourceDirectories in Test := (javaSource in Test).value :: Nil However, there should not be any harm in leaving the Scala directories if they are empty. diff --git a/src/sphinx/Detailed-Topics/Launcher.rst b/src/sphinx/Detailed-Topics/Launcher.rst index 1775ed3bf..c9eb73050 100644 --- a/src/sphinx/Detailed-Topics/Launcher.rst +++ b/src/sphinx/Detailed-Topics/Launcher.rst @@ -307,7 +307,7 @@ definition would be: libraryDependencies += "org.scala-sbt" % "launcher-interface" % "0.12.0" % "provided" - resolvers <+= sbtResolver + resolvers += sbtResolver.value Make the entry point to your class implement 'xsbti.AppMain'. An example that uses some of the information: @@ -363,7 +363,7 @@ it might look like: [boot] directory: ${user.home}/.myapp/boot -Then, ``publish-local`` or ``+publish-local`` the application to make it +Then, ``publishLocal`` or ``+publishLocal`` the application to make it available. Running an Application diff --git a/src/sphinx/Detailed-Topics/Library-Management.rst b/src/sphinx/Detailed-Topics/Library-Management.rst index ea9968aa8..2bf2e8415 100644 --- a/src/sphinx/Detailed-Topics/Library-Management.rst +++ b/src/sphinx/Detailed-Topics/Library-Management.rst @@ -30,27 +30,28 @@ project definition are required to use this method unless you would like to change the location of the directory you store the jars in. To change the directory jars are stored in, change the -``unmanaged-base`` setting in your project definition. For example, to +``unmanagedBase`` setting in your project definition. For example, to use ``custom_lib/``: :: - unmanagedBase <<= baseDirectory { base => base / "custom_lib" } + unmanagedBase := baseDirectory.value / "custom_lib" If you want more control and flexibility, override the -``unmanaged-jars`` task, which ultimately provides the manual +``unmanagedJars`` task, which ultimately provides the manual dependencies to sbt. The default implementation is roughly: :: - unmanagedJars in Compile <<= baseDirectory map { base => (base ** "*.jar").classpath } + unmanagedJars in Compile := (baseDirectory.value ** "*.jar").classpath If you want to add jars from multiple directories in addition to the default directory, you can do: :: - unmanagedJars in Compile <++= baseDirectory map { base => + unmanagedJars in Compile ++= { + val base = baseDirectory.value val baseDirectories = (base / "libA") +++ (base / "b" / "lib") +++ (base / "libC") val customJars = (baseDirectories ** "*.jar") +++ (base / "d" / "my.jar") customJars.classpath @@ -162,8 +163,8 @@ Override default resolvers ``resolvers`` configures additional, inline user resolvers. By default, ``sbt`` combines these resolvers with default repositories (Maven -Central and the local Ivy repository) to form ``external-resolvers``. To -have more control over repositories, set ``external-resolvers`` +Central and the local Ivy repository) to form ``externalResolvers``. To +have more control over repositories, set ``externalResolvers`` directly. To only specify repositories in addition to the usual defaults, configure ``resolvers``. @@ -178,9 +179,8 @@ To use the local repository, but not the Maven Central repository: :: - externalResolvers <<= resolvers map { rs => - Resolver.withDefaultResolvers(rs, mavenCentral = false) - } + externalResolvers := + Resolver.withDefaultResolvers(resolvers.value, mavenCentral = false) Override all resolvers for all builds ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -257,9 +257,9 @@ For multiple classifiers, use multiple ``classifier`` calls: "org.lwjgl.lwjgl" % "lwjgl-platform" % lwjglVersion classifier "natives-windows" classifier "natives-linux" classifier "natives-osx" To obtain particular classifiers for all dependencies transitively, run -the ``update-classifiers`` task. By default, this resolves all artifacts +the ``updateClassifiers`` task. By default, this resolves all artifacts with the ``sources`` or ``javadoc`` classifier. Select the classifiers -to obtain by configuring the ``transitive-classifiers`` setting. For +to obtain by configuring the ``transitiveClassifiers`` setting. For example, to only retrieve sources: :: @@ -300,8 +300,8 @@ Download Sources ~~~~~~~~~~~~~~~~ Downloading source and API documentation jars is usually handled by an -IDE plugin. These plugins use the ``update-classifiers`` and -``update-sbt-classifiers`` tasks, which produce an :doc:`Update-Report` +IDE plugin. These plugins use the ``updateClassifiers`` and +``updateSbtClassifiers`` tasks, which produce an :doc:`Update-Report` referencing these jars. To have sbt download the dependency's sources without using an IDE @@ -333,7 +333,7 @@ To define extra attributes on the current project: :: - projectID <<= projectID { id => + projectID ~= { id => id extra("color" -> "blue", "component" -> "compiler-interface") } diff --git a/src/sphinx/Detailed-Topics/Local-Scala.rst b/src/sphinx/Detailed-Topics/Local-Scala.rst index 63f15b066..3f8723e51 100644 --- a/src/sphinx/Detailed-Topics/Local-Scala.rst +++ b/src/sphinx/Detailed-Topics/Local-Scala.rst @@ -2,14 +2,14 @@ Local Scala =========== -To use a locally built Scala version, define the ``scala-home`` setting, +To use a locally built Scala version, define the ``scalaHome`` setting, which is of type ``Option[File]``. This Scala version will only be used for the build and not for sbt, which will still use the version it was compiled against. Example: ``scala scalaHome := Some(file("/path/to/scala"))`` -Using a local Scala version will override the ``scala-version`` setting +Using a local Scala version will override the ``scalaVersion`` setting and will not work with :doc:`cross building `. sbt reuses the class loader for the local Scala version. If you diff --git a/src/sphinx/Detailed-Topics/Macro-Projects.rst b/src/sphinx/Detailed-Topics/Macro-Projects.rst index 370ccfac7..0cc3ebc4c 100644 --- a/src/sphinx/Detailed-Topics/Macro-Projects.rst +++ b/src/sphinx/Detailed-Topics/Macro-Projects.rst @@ -29,7 +29,7 @@ This configuration is shown in the following build definition: object MacroBuild extends Build { lazy val main = Project("main", file(".")) dependsOn(macroSub) lazy val macroSub = Project("macro", file("macro")) settings( - libraryDependencies <+= scalaVersion("org.scala-lang" % "scala-compiler" % _) + libraryDependencies += "org.scala-lang" % "scala-compiler" % scalaVersion.value ) } @@ -119,7 +119,7 @@ For example, the project definitions from above would look like: lazy val main = Project("main", file(".")) dependsOn(macroSub, commonSub) lazy val macroSub = Project("macro", file("macro")) dependsOn(commonSub) settings( - libraryDependencies <+= scalaVersion("org.scala-lang" % "scala-compiler" % _) + libraryDependencies += "org.scala-lang" % "scala-compiler" % scalaVersion.value ) lazy val commonSub = Project("common", file("common")) diff --git a/src/sphinx/Detailed-Topics/Parallel-Execution.rst b/src/sphinx/Detailed-Topics/Parallel-Execution.rst index f88a746fb..ab1023ea2 100644 --- a/src/sphinx/Detailed-Topics/Parallel-Execution.rst +++ b/src/sphinx/Detailed-Topics/Parallel-Execution.rst @@ -28,7 +28,7 @@ declaration of the tasks would be: f } - read <<= write map { f => IO.read(f) } + read := IO.read(write.value) This establishes an ordering: ``read`` must run after ``write``. We've also guaranteed that ``read`` will read from the same file that @@ -100,14 +100,18 @@ associates the ``CPU`` and ``Compile`` tags with the ``compile`` task :: - compile <<= myCompileTask tag(Tags.CPU, Tags.Compile) + def myCompileTask = Def.task { ... } tag(Tags.CPU, Tags.Compile) + + compile := myCompileTask.value Different weights may be specified by passing tag/weight pairs to ``tagw``: :: - download <<= downloadImpl.tagw(Tags.Network -> 3) + def downloadImpl = Def.task { ... } tagw(Tags.Network -> 3) + + download := downloadImpl.value Defining Restrictions ~~~~~~~~~~~~~~~~~~~~~ @@ -222,7 +226,7 @@ The tasks that are currently tagged by default are: - ``compile``: ``Compile``, ``CPU`` - ``test``: ``Test`` - ``update``: ``Update``, ``Network`` -- ``publish``, ``publish-local``: ``Publish``, ``Network`` +- ``publish``, ``publishLocal``: ``Publish``, ``Network`` Of additional note is that the default ``test`` task will propagate its tags to each child task created for each test class. @@ -231,9 +235,9 @@ The default rules provide the same behavior as previous versions of sbt: :: - concurrentRestrictions in Global <<= parallelExecution { par => + concurrentRestrictions in Global := { val max = Runtime.getRuntime.availableProcessors - Tags.limitAll(if(par) max else 1) :: Nil + Tags.limitAll(if(parallelExecution.value) max else 1) :: Nil } As before, ``parallelExecution in Test`` controls whether tests are @@ -258,7 +262,9 @@ Then, use this tag as any other tag. For example: :: - aCustomTask <<= aCustomTask.tag(Custom) + def aImpl = Def.task { ... } tag(Custom) + + aCustomTask := aImpl.value concurrentRestrictions in Global += Tags.limit(Custom, 1) @@ -278,7 +284,9 @@ tags applied to it. Only the first computation is labeled. :: - compile <<= myCompileTask tag(Tags.CPU, Tags.Compile) + def myCompileTask = Def.task { ... } tag(Tags.CPU, Tags.Compile) + + compile := myCompileTask.value compile ~= { ... do some post processing ... } @@ -305,16 +313,8 @@ Adjustments to Defaults Rules should be easier to remove or redefine, perhaps by giving them names. As it is, rules must be appended or all rules must be completely -redefined. - -Redefining the tags of a task looks like: - -:: - - compile <<= compile.tag(Tags.Network) - -This will overwrite the previous weight if the tag (Network) was already -defined. +redefined. Also, tags can only be defined for tasks at the original +definition site when using the ``:=`` syntax. For removing tags, an implementation of ``removeTag`` should follow from the implementation of ``tag`` in a straightforward manner. diff --git a/src/sphinx/Detailed-Topics/Paths.rst b/src/sphinx/Detailed-Topics/Paths.rst index fe75e86a4..0ec4e645e 100644 --- a/src/sphinx/Detailed-Topics/Paths.rst +++ b/src/sphinx/Detailed-Topics/Paths.rst @@ -53,13 +53,13 @@ to be the "custom\_lib" directory in a project's base directory: :: - unmanagedBase <<= baseDirectory( (base: File) => base /"custom_lib" ) + unmanagedBase := baseDirectory.value /"custom_lib" Or, more concisely: :: - unmanagedBase <<= baseDirectory( _ /"custom_lib" ) + unmanagedBase := baseDirectory.value /"custom_lib" This setting sets the location of the shell history to be in the base directory of the build, irrespective of the project the setting is @@ -67,7 +67,7 @@ defined in: :: - historyPath <<= (baseDirectory in ThisBuild)(t => Some(t / ".history")), + historyPath := Some( (baseDirectory in ThisBuild).value / ".history"), Path Finders ------------ diff --git a/src/sphinx/Detailed-Topics/Process.rst b/src/sphinx/Detailed-Topics/Process.rst index 24106c9eb..a4edfbfc1 100644 --- a/src/sphinx/Detailed-Topics/Process.rst +++ b/src/sphinx/Detailed-Topics/Process.rst @@ -7,7 +7,7 @@ Usage ``sbt`` includes a process library to simplify working with external processes. The library is available without import in build definitions -and at the interpreter started by the :doc:`console-project ` task. +and at the interpreter started by the :doc:`consoleProject ` task. To run an external command, follow it with an exclamation mark ``!``: diff --git a/src/sphinx/Detailed-Topics/Publishing.rst b/src/sphinx/Detailed-Topics/Publishing.rst index 83fa9da87..6ec4cf4cc 100644 --- a/src/sphinx/Detailed-Topics/Publishing.rst +++ b/src/sphinx/Detailed-Topics/Publishing.rst @@ -12,7 +12,7 @@ repository. To use publishing, you need to specify the repository to publish to and the credentials to use. Once these are set up, you can run ``publish``. -The ``publish-local`` action is used to publish your project to a local +The ``publishLocal`` action is used to publish your project to a local Ivy repository. You can then use this project from other projects on the same machine. @@ -48,9 +48,9 @@ repository. Doing this selection can be done by using the value of the :: - publishTo <<= version { (v: String) => + publishTo := { val nexus = "https://oss.sonatype.org/" - if (v.trim.endsWith("SNAPSHOT")) + if (version.value.trim.endsWith("SNAPSHOT")) Some("snapshots" at nexus + "content/repositories/snapshots") else Some("releases" at nexus + "service/local/staging/deploy/maven2") @@ -100,10 +100,10 @@ for details. Modifying the generated POM --------------------------- -When ``publish-maven-style`` is ``true``, a POM is generated by the -``make-pom`` action and published to the repository instead of an Ivy +When ``publishMavenStyle`` is ``true``, a POM is generated by the +``makePom`` action and published to the repository instead of an Ivy file. This POM file may be altered by changing a few settings. Set -'pom-extra' to provide XML (``scala.xml.NodeSeq``) to insert directly +``pomExtra`` to provide XML (``scala.xml.NodeSeq``) to insert directly into the generated pom. For example: :: @@ -117,8 +117,8 @@ into the generated pom. For example: -``make-pom`` adds to the POM any Maven-style repositories you have -declared. You can filter these by modifying ``pom-repository-filter``, +``makePom`` adds to the POM any Maven-style repositories you have +declared. You can filter these by modifying ``pomRepositoryFilter``, which by default excludes local repositories. To instead only include local repositories: @@ -128,7 +128,7 @@ local repositories: repo.root.startsWith("file:") } -There is also a ``pom-post-process`` setting that can be used to +There is also a ``pomPostProcess`` setting that can be used to manipulate the final XML before it is written. It's type is ``Node => Node``. @@ -141,7 +141,7 @@ manipulate the final XML before it is written. It's type is Publishing Locally ------------------ -The ``publish-local`` command will publish to the local Ivy repository. +The ``publishLocal`` command will publish to the local Ivy repository. By default, this is in ``${user.home}/.ivy2/local``. Other projects on the same machine can then list the project as a dependency. For example, if the SBT project you are publishing has configuration parameters like: diff --git a/src/sphinx/Detailed-Topics/TaskInputs.rst b/src/sphinx/Detailed-Topics/TaskInputs.rst index 2ecfbcce5..e6a223b6e 100644 --- a/src/sphinx/Detailed-Topics/TaskInputs.rst +++ b/src/sphinx/Detailed-Topics/TaskInputs.rst @@ -54,8 +54,7 @@ The first point is like declaring a task dependency, the second is like two tasks modifying the same state (either project variables or files), and the third is a consequence of unsynchronized, shared state. -In Scala, we have the built-in functionality to easily fix this: -``lazy val``. +In Scala, we have the built-in functionality to easily fix this: ``lazy val``. :: @@ -83,26 +82,21 @@ The general form of a task definition looks like: :: - myTask <<= (aTask, bTask) map { (a: A, b: B) => + myTask := { + val a: A = aTask.value + val b: B = bTask.value ... do something with a, b and generate a result ... } (This is only intended to be a discussion of the ideas behind tasks, so see the :doc:`sbt Tasks ` page -for details on usage.) Basically, ``myTask`` is defined by declaring -``aTask`` and ``bTask`` as inputs and by defining the function to apply -to the results of these tasks. Here, ``aTask`` is assumed to produce a +for details on usage.) Here, ``aTask`` is assumed to produce a result of type ``A`` and ``bTask`` is assumed to produce a result of type ``B``. Application ----------- -Apply this in practice: - -1. Determine the tasks that produce the values you need -2. ``map`` the tasks with the function that implements your task. - As an example, consider generating a zip file containing the binary jar, source jar, and documentation jar for your project. First, determine what tasks produce the jars. In this case, the input tasks are @@ -115,8 +109,11 @@ map on the zip task. :: - zip <<= (packageBin in Compile, packageSrc in Compile, packageDoc in Compile, zipPath) map { - (bin: File, src: File, doc: File, out: File) => + zip := { + val bin: File = (packageBin in Compile).value + val src: File = (packageSrc in Compile).value + val doc: File = (packageDoc in Compile).value + val out: File = zipPath.value val inputs: Seq[(File,String)] = Seq(bin, src, doc) x Path.flat IO.zip(inputs, out) out @@ -131,8 +128,6 @@ the zip file. For example: :: - zipPath <<= target map { - (t: File) => - t / "out.zip" - } + zipPath := + target.value / "out.zip" diff --git a/src/sphinx/Detailed-Topics/Tasks.rst b/src/sphinx/Detailed-Topics/Tasks.rst index d8b36e578..8c4665f85 100644 --- a/src/sphinx/Detailed-Topics/Tasks.rst +++ b/src/sphinx/Detailed-Topics/Tasks.rst @@ -21,7 +21,6 @@ differences between them: demand, often in response to a command from the user. 2. At the beginning of project loading, settings and their dependencies are fixed. Tasks can introduce new tasks during execution, however. - (Tasks have flatMap, but Settings do not.) Features ======== @@ -34,13 +33,11 @@ There are several features of the task system: :doc:`parser combinators ` to define the syntax for their arguments. This allows flexible syntax and tab-completions in the same way as :doc:`/Extending/Commands`. -3. Tasks produce values. Other tasks can access a task's value with the - ``map`` and ``flatMap`` methods. -4. The ``flatMap`` method allows dynamically changing the structure of - the task graph. 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``. +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. + 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``. 6. Each task has access to its own Logger that by default persists the logging for that task at a more verbose level than is initially printed to the screen. @@ -60,8 +57,9 @@ build.sbt :: + val hello = TaskKey[Unit]("hello", "Prints 'Hello World'") - TaskKey[Unit]("hello") := println("hello world!") + hello := println("hello world!") Hello World example (scala) --------------------------- @@ -101,17 +99,16 @@ see this task listed. Define the key -------------- -To declare a new task, define a ``TaskKey`` in your -:doc:`Full Configuration `: +To declare a new task, define a val of type ``TaskKey``, either in ``.sbt`` or ``.scala`: :: - val sampleTask = TaskKey[Int]("sample-task") + val sampleTask = TaskKey[Int]("sampleTask") The name of the ``val`` is used when referring to the task in Scala code. The string passed to the ``TaskKey`` method is used at runtime, -such as at the command line. By convention, the Scala identifier is -camelCase and the runtime identifier uses hyphens. The type parameter +such as at the command line. By convention, both the Scala identifier +and the runtime identifier are camelCase. The type parameter passed to ``TaskKey`` (here, ``Int``) is the type of value produced by the task. @@ -119,8 +116,8 @@ We'll define a couple of other of tasks for the examples: :: - val intTask = TaskKey[Int]("int-task") - val stringTask = TaskKey[String]("string-task") + val intTask = TaskKey[Int]("intTask") + val stringTask = TaskKey[String]("stringTask") The examples themselves are valid entries in a ``build.sbt`` or can be provided as part of a sequence to ``Project.settings`` (see @@ -134,15 +131,15 @@ defined: 1. Determine the settings and other tasks needed by the task. They are the task's inputs. -2. Define a function that takes these inputs and produces a value. +2. Define the code that implements the task in terms of these inputs. 3. Determine the scope the task will go in. These parts are then combined like the parts of a setting are combined. -Tasks without inputs -~~~~~~~~~~~~~~~~~~~~ +Defining a basic task +~~~~~~~~~~~~~~~~~~~~~ -A task that takes no arguments can be defined using ``:=`` +A task is defined using ``:=`` :: @@ -157,35 +154,29 @@ A task that takes no arguments can be defined using ``:=`` } As mentioned in the introduction, a task is evaluated on demand. -Each time ``sample-task`` is invoked, for example, it will print the sum. -If the username changes between runs, ``string-task`` will take different values in those separate runs. +Each time ``sampleTask`` is invoked, for example, it will print the sum. +If the username changes between runs, ``stringTask`` will take different values in those separate runs. (Within a run, each task is evaluated at most once.) In contrast, settings are evaluated once on project load and are fixed until the next reload. Tasks with inputs ~~~~~~~~~~~~~~~~~ -Tasks with other tasks or settings as inputs are defined using ``<<=``. -The right hand side will typically call ``map`` or ``flatMap`` on other -settings or tasks. (Contrast this with the ``apply`` method that is used -for settings.) The function argument to ``map`` or ``flatMap`` is the -task body. The following are equivalent ways of defining a task that -adds one to value produced by ``int-task`` and returns the result. +Tasks with other tasks or settings as inputs are also defined using ``:=``. +The values of the inputs are referenced by the ``value`` method. This method +is special syntax and can only be called when defining a task, such as in the +argument to ``:=``. The following defines a task that adds one to the value +produced by ``intTask`` and returns the result. :: - sampleTask <<= intTask map { (count: Int) => count + 1 } + sampleTask := intTask.value + 1 - sampleTask <<= intTask map { _ + 1 } - -Multiple inputs are handled as with settings. The ``map`` and -``flatMap`` are done on a tuple of inputs: +Multiple settings are handled similarly: :: - stringTask <<= (sampleTask, intTask) map { (sample: Int, intValue: Int) => - "Sample: " + sample + ", int: " + intValue - } + stringTask := "Sample: " + sampleTask.value + ", int: " + intValue.value Task Scope ~~~~~~~~~~ @@ -193,36 +184,16 @@ Task Scope As with settings, tasks can be defined in a specific scope. For example, there are separate ``compile`` tasks for the ``compile`` and ``test`` scopes. The scope of a task is defined the same as for a setting. In the -following example, ``test:sample-task`` uses the result of -``compile:int-task``. +following example, ``test:sampleTask`` uses the result of +``compile:intTask``. :: - sampleTask.in(Test) <<= intTask.in(Compile).map { (intValue: Int) => - intValue * 3 - } + sampleTask.in(Test) := + intTask.in(Compile).value * 3 - // more succinctly: - sampleTask in Test <<= intTask in Compile map { _ * 3 } - -Inline task keys -~~~~~~~~~~~~~~~~ - -Although generally not recommended, it is possible to specify the task -key inline: - -:: - - TaskKey[Int]("sample-task") in Test <<= TaskKey[Int]("int-task") in Compile map { _ * 3 } - -The type argument to ``TaskKey`` must be explicitly specified because of -``SI-4653``. It is not recommended because: - -1. Tasks are no longer referenced by Scala identifiers (like - ``sampleTask``), but by Strings (like ``"sample-task"``) -2. The type information must be repeated. -3. Keys should come with a description, which would need to be repeated - as well. + // with a different punctuation style + sampleTask in Test := (intTask in Compile).value * 3 On precedence ~~~~~~~~~~~~~ @@ -243,20 +214,19 @@ the following: :: - (sampleTask in Test) <<= (intTask in Compile map { _ * 3 }) + (sampleTask in Test) := ( (intTask in Compile).value * 3 ) Modifying an Existing Task ========================== The examples in this section use the following key definitions, which -would go in a ``Build`` object in a :doc:`Full Configuration `. -Alternatively, the keys may be specified inline, as discussed above. +would go in a ``Build`` object in a ``.scala`` file or directly in a ``.sbt`` file. :: - val unitTask = TaskKey[Unit]("unit-task") - val intTask = TaskKey[Int]("int-task") - val stringTask = TaskKey[String]("string-task") + val unitTask = TaskKey[Unit]("unitTask") + val intTask = TaskKey[Int]("intTask") + val stringTask = TaskKey[String]("stringTask") The examples themselves are valid settings in a ``build.sbt`` file or as part of a sequence provided to ``Project.settings``. @@ -270,11 +240,11 @@ input. intTask := 3 // overriding definition that references the previous definition - intTask <<= intTask map { (value: Int) => value + 1 } + intTask := intTask.value + 1 Completely override a task by not declaring the previous task as an input. Each of the definitions in the following example completely -overrides the previous one. That is, when ``int-task`` is run, it will +overrides the previous one. That is, when ``intTask`` is run, it will only print ``#3``. :: @@ -289,9 +259,9 @@ only print ``#3``. 5 } - intTask <<= sampleTask map { (value: Int) => + intTask := { println("#3") - value - 3 + sampleTask.value - 3 } To apply a transformation to a single task, without using additional @@ -305,36 +275,63 @@ task's result: // increment the value returned by intTask intTask ~= { (x: Int) => x + 1 } -Task Operations -=============== +Advanced Task Operations +======================== -The previous sections used the ``map`` method to define a task in terms -of the results of other tasks. This is the most common method, but there -are several others. The examples in this section use the task keys -defined in the previous section. +The previous sections demonstrated the most common way to define a task. +Advanced task definitions require the implementation to be separate from the binding. +For example, a basic separate definition looks like: + +:: + + // Define a new, standalone task implemention + val intTaskImpl: Initialize[Task[Int]] = Def.task { sampleTask.value - 3 } + + // Bind the implementation to a specific key + intTask := intTaskImpl.value + +Note that whenever ``.value`` is used, it must be within a task definition, such as +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 +tasks. The defining task key (the part on the left side of ``:=``) must be of type ``Unit``, since no value is returned. :: - unitTask <<= Seq(stringTask, sampleTask).dependOn + 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 ``string-task`` and ``sample-task`` run first: +require that ``stringTask`` and ``sampleTask`` run first: :: intTask := 4 - intTask <<= intTask.dependsOn(stringTask, sampleTask) + 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 ------------------------- @@ -345,7 +342,7 @@ the verbosity of stack traces and logging individually for tasks as well as recalling the last logging for a task. Tasks also have access to their own persisted binary or text data. -To use Streams, ``map`` or ``flatMap`` the ``streams`` task. This is a +To use Streams, get the value of the ``streams`` task. This is a special task that provides an instance of `TaskStreams <../../api/sbt/std/TaskStreams.html>`_ for the defining task. This type provides access to named binary and @@ -356,7 +353,8 @@ method: :: - myTask <<= streams map { (s: TaskStreams) => + myTask := { + val s: TaskStreams = streams.value s.log.debug("Saying hi...") s.log.info("Hello!") } @@ -373,12 +371,12 @@ To obtain the last logging output from a task, use the ``last`` command: .. code-block:: console - $ last my-task + $ last myTask [debug] Saying hi... [info] Hello! The verbosity with which logging is persisted is controlled using the -``persist-log-level`` and ``persist-trace-level`` settings. The ``last`` +``persistLogLevel`` and ``persistTraceLevel`` settings. The ``last`` command displays what was logged according to these levels. The levels do not affect already logged information. @@ -400,7 +398,9 @@ For example: intTask := error("I didn't succeed.") - intTask <<= intTask andFinally { println("andFinally") } + val intTaskImpl = intTask andFinally { println("andFinally") } + + intTask := intTaskImpl.value This modifies the original ``intTask`` to always print "andFinally" even if the task fails. @@ -414,18 +414,20 @@ a task like in the previous example. For example, consider this code: intTask := error("I didn't succeed.") - otherIntTask <<= intTask andFinally { println("andFinally") } + val intTaskImpl = intTask andFinally { println("andFinally") } -If ``int-task`` is run directly, ``other-int-task`` is never involved in + otherIntTask := intTaskImpl.value + +If ``intTask`` is run directly, ``otherIntTask`` is never involved in execution. This case is similar to the following plain Scala code: :: - def intTask: Int = + def intTask(): Int = error("I didn't succeed.") - def otherIntTask: Int = - try { intTask } + def otherIntTask(): Int = + try { intTask() } finally { println("finally") } intTask() @@ -451,12 +453,14 @@ For example: intTask := error("Failed.") - intTask <<= intTask mapFailure { (inc: Incomplete) => + val intTaskImpl = intTask mapFailure { (inc: Incomplete) => println("Ignoring failure: " + inc) 3 } -This overrides the ``int-task`` so that the original exception is printed and the constant ``3`` is returned. + intTask := intTaskImpl.value + +This overrides the ``intTask`` so that the original exception is printed and the constant ``3`` is returned. ``mapFailure`` does not prevent other tasks that depend on the target from failing. Consider the following example: @@ -465,33 +469,37 @@ from failing. Consider the following example: intTask := if(shouldSucceed) 5 else error("Failed.") - // return 3 if int-task fails. if it succeeds, this task will fail - aTask <<= intTask mapFailure { (inc: Incomplete) => 3 } - // a new task that increments the result of int-task - bTask <<= intTask map { \_ + 1 } - cTask <<= (aTask, bTask) map { (a,b) => a + b } + // return 3 if intTask fails. if it succeeds, this task will fail + val aTaskImpl = intTask mapFailure { (inc: Incomplete) => 3 } + + aTask := aTaskImpl.value + + // a new task that increments the result of intTask + bTask := intTask.value + 1 + + cTask := aTask.value + bTask.value The following table lists the results of each task depending on the initially invoked task: ============== =============== ============= ============== ============== ============== -invoked task int-task result a-task result b-task result c-task result overall result +invoked task intTask result aTask result bTask result cTask result overall result ============== =============== ============= ============== ============== ============== -int-task failure not run not run not run failure -a-task failure success not run not run success -b-task failure not run failure not run failure -c-task failure success failure failure failure -int-task success not run not run not run success -a-task success failure not run not run failure -b-task success not run success not run success -c-task success failure success failure failure +intTask failure not run not run not run failure +aTask failure success not run not run success +bTask failure not run failure not run failure +cTask failure success failure failure failure +intTask success not run not run not run success +aTask success failure not run not run failure +bTask success not run success not run success +cTask success failure success failure failure ============== =============== ============= ============== ============== ============== The overall result is always the same as the root task (the directly invoked task). A ``mapFailure`` turns a success into a failure, and a failure into whatever the result of evaluating the supplied function is. -A ``map`` fails when the input fails and applies the supplied function +A normal task definition fails when the input fails and applies the supplied function to a successfully completed input. In the case of more than one input, ``mapFailure`` fails if all inputs @@ -500,14 +508,16 @@ with the list of ``Incomplete``\ s. For example: :: - cTask <<= (aTask, bTask) mapFailure { (incs: Seq[Incomplete]) => 3 } + val cTaskImpl = (aTask, bTask) mapFailure { (incs: Seq[Incomplete]) => 3 } -The following table lists the results of invoking ``c-task``, depending + cTask := cTaskImpl.value + +The following table lists the results of invoking ``cTask``, depending on the success of ``aTask`` and ``bTask``: ============= ============= ============= -a-task result b-task result c-task result +aTask result bTask result cTask result ============= ============= ============= failure failure success failure success success @@ -538,7 +548,7 @@ For example: intTask := error("Failed.") - intTask <<= intTask mapR { + val intTaskImpl = intTask mapR { case Inc(inc: Incomplete) => println("Ignoring failure: " + inc) 3 @@ -547,4 +557,6 @@ For example: v } -This overrides the original ``int-task`` definition so that if the original task fails, the exception is printed and the constant ``3`` is returned. If it succeeds, the value is printed and returned. + intTask := intTaskImpl.value + +This overrides the original ``intTask`` definition so that if the original task fails, the exception is printed and the constant ``3`` is returned. If it succeeds, the value is printed and returned. diff --git a/src/sphinx/Detailed-Topics/Testing.rst b/src/sphinx/Detailed-Topics/Testing.rst index 03bd2e6da..6dfeb1284 100644 --- a/src/sphinx/Detailed-Topics/Testing.rst +++ b/src/sphinx/Detailed-Topics/Testing.rst @@ -34,33 +34,33 @@ to use your library. With the library dependency defined, you can then add test sources in the locations listed above and compile and run tests. The tasks for -running tests are ``test`` and ``test-only``. The ``test`` task accepts +running tests are ``test`` and ``testOnly``. The ``test`` task accepts no command line arguments and runs all tests: .. code-block:: console > test -test-only +testOnly --------- -The ``test-only`` task accepts a whitespace separated list of test names +The ``testOnly`` task accepts a whitespace separated list of test names to run. For example: .. code-block:: console - > test-only org.example.MyTest1 org.example.MyTest2 + > testOnly org.example.MyTest1 org.example.MyTest2 It supports wildcards as well: .. code-block:: console - > test-only org.example.*Slow org.example.MyTest1 + > testOnly org.example.*Slow org.example.MyTest1 -test-quick +testQuick ---------- -The ``test-quick`` task, like ``test-only``, allows to filter the tests +The ``testQuick`` task, like ``testOnly``, allows to filter the tests to run to specific tests or wildcards using the same syntax to indicate the filters. In addition to the explicit filter, only the tests that satisfy one of the following conditions are run: @@ -77,7 +77,7 @@ Tab completion is provided for test names based on the results of the last ``test:compile``. This means that a new sources aren't available for tab completion until they are compiled and deleted sources won't be removed from tab completion until a recompile. A new test source can -still be manually written out and run using ``test-only``. +still be manually written out and run using ``testOnly``. Other tasks ----------- @@ -88,9 +88,9 @@ are referenced in Scala code with ``in Test``. These tasks include: - ``test:compile`` - ``test:console`` -- ``test:console-quick`` +- ``test:consoleQuick`` - ``test:run`` -- ``test:run-main`` +- ``test:runMain`` See :doc:`Running ` for details on these tasks. @@ -111,11 +111,11 @@ Test Framework Arguments ------------------------ Arguments to the test framework may be provided on the command line to -the ``test-only`` tasks following a ``--`` separator. For example: +the ``testOnly`` tasks following a ``--`` separator. For example: .. code-block:: console - > test-only org.example.MyTest -- -d -S + > testOnly org.example.MyTest -- -d -S To specify test framework arguments as part of the build, add options constructed by ``Tests.Argument``: @@ -196,7 +196,7 @@ available with ``testGrouping`` key. For example: tests groupBy (_.name(0)) map { case (letter, tests) => new Group(letter.toString, tests, SubProcess(Seq("-Dfirst.letter"+letter))) } toSeq; - testGrouping <<= definedTests in Test map groupByFirst + testGrouping := groupByFirst( (definedTests in Test).value ) } The tests in a single group are run sequentially. Controlling the number @@ -266,7 +266,7 @@ The standard testing tasks are available, but must be prefixed with .. code-block:: console - > it:test-only org.example.AnIntegrationTest + > it:testOnly org.example.AnIntegrationTest Similarly the standard settings may be configured for the ``IntegrationTest`` configuration. If not specified directly, most @@ -400,7 +400,7 @@ with the configuration name as before: .. code-block:: console > fun:test - > fun:test-only org.example.AFunTest + > fun:testOnly org.example.AFunTest Application to parallel execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/sphinx/Detailed-Topics/Triggered-Execution.rst b/src/sphinx/Detailed-Topics/Triggered-Execution.rst index 64aa1f8fd..0e5e9403d 100644 --- a/src/sphinx/Detailed-Topics/Triggered-Execution.rst +++ b/src/sphinx/Detailed-Topics/Triggered-Execution.rst @@ -5,16 +5,16 @@ Triggered Execution You can make a command run when certain files change by prefixing the command with ``~``. Monitoring is terminated when ``enter`` is pressed. This triggered execution is configured by the ``watch`` setting, but -typically the basic settings ``watch-sources`` and ``poll-interval`` are +typically the basic settings ``watchSources`` and ``pollInterval`` are modified. -- ``watch-sources`` defines the files for a single project that are +- ``watchSources`` defines the files for a single project that are monitored for changes. By default, a project watches resources and Scala and Java sources. -- ``watch-transitive-sources`` then combines the ``watch-sources`` for +- ``watchTransitiveSources`` then combines the ``watchSources`` for the current project and all execution and classpath dependencies (see - :doc:`Full Configuration ` for details on inter-project dependencies). -- ``poll-interval`` selects the interval between polling for changes in + :doc:`Full Configuration ` for details on interProject dependencies). +- ``pollInterval`` selects the interval between polling for changes in milliseconds. The default value is ``500 ms``. Some example usages are described below. @@ -38,11 +38,11 @@ One use is for test driven development, as suggested by Erick on the mailing list. The following will poll for changes to your source code (main or test) -and run ``test-only`` for the specified test. +and run ``testOnly`` for the specified test. .. code-block:: console - > ~ test-only example.TestA + > ~ testOnly example.TestA Running Multiple Commands ========================= diff --git a/src/sphinx/Detailed-Topics/Update-Report.rst b/src/sphinx/Detailed-Topics/Update-Report.rst index 217750ddc..7900058bd 100644 --- a/src/sphinx/Detailed-Topics/Update-Report.rst +++ b/src/sphinx/Detailed-Topics/Update-Report.rst @@ -13,8 +13,8 @@ configuration. Finally, a ``ModuleReport`` lists each successfully retrieved ``Artifact`` and the ``File`` it was retrieved to as well as the ``Artifact``\ s that couldn't be downloaded. This missing ``Arifact`` list is never empty for ``update``, which will fail if it is -non-empty. However, it may be non-empty for ``update-classifiers`` and -``update-sbt-classifers``. +non-empty. However, it may be non-empty for ``updateClassifiers`` and +``updateSbtClassifers``. Filtering a Report and Getting Artifacts ======================================== diff --git a/src/sphinx/Dormant/Basic-Configuration.rst b/src/sphinx/Dormant/Basic-Configuration.rst deleted file mode 100644 index 937d7cb4f..000000000 --- a/src/sphinx/Dormant/Basic-Configuration.rst +++ /dev/null @@ -1,268 +0,0 @@ -*Wiki Maintenance Note:* This page has been replaced most recently by :doc:`/Getting-Started/Basic-Def` and :doc:`/Getting-Started/More-About-Settings/`. It has some obsolete terminology: - -- we now avoid referring to build definition as "configuration" to - avoid confusion with compile configurations -- we now avoid referring to basic/light/quick vs. full configuration, - in favor of ".sbt build definition files" and ".scala build - definition files" - -However, it may still be worth combing this page for examples or points -that are not made in new pages. After doing so, this page could simply -be a redirect (delete the content, link to the new pages about build -definition). - -Configuration -============= - -A build definition is written in Scala. There are two types of -definitions: light and full. A light definition is a quick way of -configuring a build. It consists of a list of Scala expressions -describing project settings in one or more ".sbt" files located in the -base directory of the project. This also applies to sub-projects. - -A full definition is made up of one or more Scala source files that -describe relationships between projects, introduce new configurations -and settings, and define more complex aspects of the build. The -capabilities of a light definition are a proper subset of those of a -full definition. - -Light configuration and full configuration can co-exist. Settings -defined in the light configuration are appended to the settings defined -in the full configuration for the corresponding project. - -Light Configuration -=================== - -By Example ----------- - -Create a file with extension ``.sbt`` in your root project directory -(such as ``/build.sbt``). This file contains Scala -expressions of type ``Setting[T]`` that are separated by blank lines. -Built-in settings typically have reasonable defaults (an exception is -``publishTo``). A project typically redefines at least ``name`` and -``version`` and often ``libraryDependencies``. All built-in settings are -listed in -`Keys <../../sxr/Keys.scala.html>`_. - -A sample ``build.sbt``: - -:: - - // Set the project name to the string 'My Project' - name := "My Project" - - // The := method used in Name and Version is one of two fundamental methods. - // The other method is <<= - // All other initialization methods are implemented in terms of these. - version := "1.0" - - // Add a single dependency - libraryDependencies += "junit" % "junit" % "4.8" % "test" - - // Add multiple dependencies - libraryDependencies ++= Seq( - "net.databinder" %% "dispatch-google" % "0.7.8", - "net.databinder" %% "dispatch-meetup" % "0.7.8" - ) - - // Exclude backup files by default. This uses ~=, which accepts a function of - // type T => T (here T = FileFilter) that is applied to the existing value. - // A similar idea is overriding a member and applying a function to the super value: - // override lazy val defaultExcludes = f(super.defaultExcludes) - // - defaultExcludes ~= (filter => filter || "*~") - /* Some equivalent ways of writing this: - defaultExcludes ~= (_ || "*~") - defaultExcludes ~= ( (_: FileFilter) || "*~") - defaultExcludes ~= ( (filter: FileFilter) => filter || "*~") - */ - - // Use the project version to determine the repository to publish to. - publishTo <<= version { (v: String) => - if(v endsWith "-SNAPSHOT") - Some(ScalaToolsSnapshots) - else - Some(ScalaToolsReleases) - } - -Notes ------ - -- Because everything is parsed as an expression, no semicolons are - allowed at the ends of lines. -- All initialization methods end with ``=`` so that they have the - lowest possible precedence. Except when passing a function literal to - ``~=``, you do not need to use parentheses for either side of the - method. Ok: - -:: - - libraryDependencies += "junit" % "junit" % "4.8" % "test" - - libraryDependencies.+=("junit" % "junit" % "4.8" % "test") - - defaultExcludes ~= (_ || "*~") - - defaultExcludes ~= (filter => filter || "*~") - -Error: - -.. code-block:: console - - error: missing parameter type for expanded function ((x$1) => defaultExcludes.colon$tilde(x$1).$bar("*~")) - defaultExcludes ~= _ || "*~" - ^ - error: value | is not a member of sbt.Project.Setting[sbt.FileFilter] - defaultExcludes ~= _ || "*~" - ^ - -* A block is an expression, with the last statement in the block being the result. For example, the following is an expression: - -:: - - { - val x = 3 - def y = 2 - x + y - } - -An example of using a block to construct a Setting: - -:: - - version := { - // Define a regular expression to match the current branch - val current = """\*\s+(\w+)""".r - // Process the output of 'git branch' to get the current branch - val branch = "git branch --no-color".lines_!.collect { case current(name) => "-" + name } - // Append the current branch to the version. - "1.0" + branch.mkString - } - - - Remember that blank lines are used to clearly delineate expressions. This happens before the expression is sent to the Scala compiler, so no blank lines are allowed within a block. - -More Information ----------------- - -- A ``Setting[T]`` describes how to initialize a value of type T. The - expressions shown in the example are expressions, not statements. In - particular, there is no hidden mutable map that is being modified. - Each ``Setting[T]`` describes an update to a map. The actual map is - rarely directly referenced by user code. It is not the final map that - is important, but the operations on the map. -- There are fundamentally two types of initializations, ``:=`` and - ``<<=``. The methods ``+=``, ``++=``, and ``~=`` are defined in terms - of these. ``:=`` assigns a value, overwriting any existing value. - ``<<=`` uses existing values to initialize a setting. -- ``key ~= f`` is equivalent to ``key <<= key(f)`` -- ``key += value`` is equivalent to ``key ~= (_ :+ value)`` or - ``key <<= key(_ :+ value)`` -- ``key ++= value`` is equivalent to ``key ~= (_ ++ value)`` or - ``key <<= key(_ ++ value)`` -- There can be multiple ``.sbt`` files per project. This feature can be - used, for example, to put user-specific configurations in a separate - file. -- Import clauses are allowed at the beginning of a ``.sbt`` file. Since - they are clauses, no semicolons are allowed. They need not be - separated by blank lines, but each import must be on one line. For - example, - -:: - - import scala.xml.NodeSeq - import math.{abs, pow} - -- These imports are defined by default in a ``.sbt`` file: - -:: - - import sbt._ - import Process._ - import Keys._ - -In addition, the contents of all public ``Build`` and ``Plugin`` -objects from the full definition are imported. - -sbt uses the blank lines to separate the expressions and then it sends -them off to the Scala compiler. Each expression is parsed, compiled, and -loaded independently. The settings are combined into a -``Seq[Setting[_]]`` and passed to the settings engine. The engine groups -the settings by key, preserving order per key though, and then computes -the order in which each setting needs to be evaluated. Cycles and -references to uninitialized settings are detected here and dead settings -are dropped. Finally, the settings are transformed into a function that -is applied to an initially empty map. - -Because the expressions can be separated before the compiler, sbt only -needs to recompile expressions that change. So, the work to respond to -changes is proportional to the number of settings that changed and not -the number of settings defined in the build. If imports change, all -expression in the ``.sbt`` file need to be recompiled. - -Implementation Details (even more information) ----------------------------------------------- - -Each expression describes an initialization operation. The simplest -operation is context-free assignment using ``:=``. That is, no outside -information is used to determine the setting value. Operations other -than ``:=`` are implemented in terms of ``<<=``. The ``<<=`` method -specifies an operation that requires other settings to be initialized -and uses their values to define a new setting. - -The target (left side value) of a method like ``:=`` identifies one of -the constructs in sbt: settings, tasks, and input tasks. It is not an -actual setting or task, but a key representing a setting or task. A -setting is a value assigned when a project is loaded. A task is a unit -of work that is run on-demand zero or more times after a project is -loaded and also produces a value. An input task, previously known as a -Method Task in 0.7 and earlier, accepts an input string and produces a -task to be run. The renaming is because it can accept arbitrary input in -0.10 and not just a space-delimited sequence of arguments like in 0.7. - -A construct (setting, task, or input task) is identified by a scoped -key, which is a pair ``(Scope, AttributeKey[T])``. An ``AttributeKey`` -associates a name with a type and is a typesafe key for use in an -``AttributeMap``. Attributes are best illustrated by the ``get`` and -``put`` methods on ``AttributeMap``: - -:: - - def get[T](key: AttributeKey[T]): Option[T] - def put[T](key: AttributeKey[T], value: T): AttributeMap - -For example, given a value ``k: AttributeKey[String]`` and a value -``m: AttributeMap``, ``m.get(k)`` has type ``Option[String]``. - -In sbt, a Scope is mainly defined by a project reference and a -configuration (such as 'test' or 'compile'). Project data is stored in a -Map[Scope, AttributeMap]. Each Scope identifies a map. You can sort of -compare a Scope to a reference to an object and an AttributeMap to the -object's data. - -In order to provide appropriate convenience methods for constructing an -initialization operation for each construct, an AttributeKey is -constructed through either a SettingKey, TaskKey, or InputKey: - -:: - - // underlying key: AttributeKey[String] - val name = SettingKey[String]("name") - - // underlying key: AttributeKey[Task[String]] - val hello = TaskKey[String]("hello") - - // underlying key: AttributeKey[InputTask[String]] - val helloArgs = InputKey[String]("hello-with-args") - -In the basic expression ``name := "asdf"``, the ``:=`` method is -implicitly available for a ``SettingKey`` and accepts an argument that -conforms to the type parameter of name, which is String. - -The high-level API for constructing settings is defined in -`Scoped <../../api/sbt/Scoped$.html>`_. Scopes are defined in `Scope <../../api/sbt/Scope$.html>`_. -The underlying engine is in `Settings <../../sxr/Settings.scala.html>`_ -and the heterogeneous map is in `Attributes <../../sxr/Attributes.scala.html>`_. - -Built-in keys are in `Keys <../../sxr/Keys.scala.html>`_ and -default settings are defined in `Defaults <../../sxr/Defaults.scala.html>`_. diff --git a/src/sphinx/Dormant/Configurations.rst b/src/sphinx/Dormant/Configurations.rst index 2bbec6b38..9245e65e1 100644 --- a/src/sphinx/Dormant/Configurations.rst +++ b/src/sphinx/Dormant/Configurations.rst @@ -61,9 +61,7 @@ it in your jar by modifying ``resources``. For example: libraryDependencies += "jquery" % "jquery" % "1.3.2" % "js->default" from "http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js" - resources <<= (resources, update) { (rs, report) => - rs ++ report.select( configurationFilter("js") ) - } + resources ++= update.value.select( configurationFilter("js") ) The ``config`` method defines a new configuration with name ``"js"`` and makes it private to the project so that it is not used for publishing. diff --git a/src/sphinx/Dormant/Needs-New-Home.rst b/src/sphinx/Dormant/Needs-New-Home.rst index cf4de044e..97a9df3ba 100644 --- a/src/sphinx/Dormant/Needs-New-Home.rst +++ b/src/sphinx/Dormant/Needs-New-Home.rst @@ -52,7 +52,7 @@ use ``custom_lib/``: :: - unmanagedBase <<= baseDirectory { base => base / "custom_lib" } + unmanagedBase := baseDirectory.value / "custom_lib" If you want more control and flexibility, override the ``unmanaged-jars`` task, which ultimately provides the manual @@ -60,14 +60,15 @@ dependencies to sbt. The default implementation is roughly: :: - unmanagedJars in Compile <<= baseDirectory map { base => (base ** "*.jar").classpath } + unmanagedJars in Compile := (baseDirectory.value ** "*.jar").classpath If you want to add jars from multiple directories in addition to the default directory, you can do: :: - unmanagedJars in Compile <++= baseDirectory map { base => + unmanagedJars in Compile ++= { + val base = baseDirectory.value val baseDirectories = (base / "libA") +++ (base / "b" / "lib") +++ (base / "libC") val customJars = (baseDirectories ** "*.jar") +++ (base / "d" / "my.jar") customJars.classpath @@ -83,9 +84,8 @@ releases repository: :: - externalResolvers <<= resolvers map { rs => - Resolver.withDefaultResolvers(rs, mavenCentral = true, scalaTools = false) - } + externalResolvers := + Resolver.withDefaultResolvers(resolvers.value, mavenCentral = true, scalaTools = false) Explicit URL ~~~~~~~~~~~~ @@ -153,7 +153,7 @@ To define extra attributes on the current project: :: - projectID <<= projectID { id => + projectID ~= { id => id extra("color" -> "blue", "component" -> "compiler-interface") } diff --git a/src/sphinx/Examples/Quick-Configuration-Examples.rst b/src/sphinx/Examples/Quick-Configuration-Examples.rst index a8b7d041a..f98d62514 100644 --- a/src/sphinx/Examples/Quick-Configuration-Examples.rst +++ b/src/sphinx/Examples/Quick-Configuration-Examples.rst @@ -24,10 +24,10 @@ setting is otherwise a normal Scala expression with expected type scalaVersion := "2.9.0-SNAPSHOT" // set the main Scala source directory to be /src - scalaSource in Compile <<= baseDirectory(_ / "src") + scalaSource in Compile := baseDirectory.value / "src" // set the Scala test source directory to be /test - scalaSource in Test <<= baseDirectory(_ / "test") + scalaSource in Test := baseDirectory.value / "test" // add a test dependency on ScalaCheck libraryDependencies += "org.scala-tools.testing" %% "scalacheck" % "1.8" % "test" @@ -56,7 +56,7 @@ setting is otherwise a normal Scala expression with expected type // append -deprecation to the options passed to the Scala compiler scalacOptions += "-deprecation" - // define the statements initially evaluated when entering 'console', 'console-quick', or 'console-project' + // define the statements initially evaluated when entering 'console', 'consoleQuick', or 'consoleProject' initialCommands := """ import System.{currentTimeMillis => now} def time[T](f: => T): T = { @@ -65,7 +65,7 @@ setting is otherwise a normal Scala expression with expected type } """ - // set the initial commands when entering 'console' or 'console-quick', but not 'console-project' + // set the initial commands when entering 'console' or 'consoleQuick', but not 'consoleProject' initialCommands in console := "import myproject._" // set the main class for packaging the main jar @@ -78,7 +78,7 @@ setting is otherwise a normal Scala expression with expected type mainClass in (Compile, run) := Some("myproject.MyMain") // add /input to the files that '~' triggers on - watchSources <+= baseDirectory map { _ / "input" } + watchSources += baseDirectory.value / "input" // add a maven-style repository resolvers += "name" at "url" diff --git a/src/sphinx/Extending/Build-State.rst b/src/sphinx/Extending/Build-State.rst index 8421388d8..14fdf79b1 100644 --- a/src/sphinx/Extending/Build-State.rst +++ b/src/sphinx/Extending/Build-State.rst @@ -123,7 +123,7 @@ other parts of the settings interface are defined. Some examples: // get name of current project val nameOpt: Option[String] = name in currentRef get structure.data - // get the package options for the `test:package-src` task or Nil if none are defined + // get the package options for the `test:packageSrc` task or Nil if none are defined val pkgOpts: Seq[PackageOption] = packageOptions in (currentRef, Test, packageSrc) get structure.data getOrElse Nil `BuildStructure <../../api/sbt/Load$$BuildStructure.html>`_ contains diff --git a/src/sphinx/Extending/Command-Line-Applications.rst b/src/sphinx/Extending/Command-Line-Applications.rst index 724b1ad88..3f0674f18 100644 --- a/src/sphinx/Extending/Command-Line-Applications.rst +++ b/src/sphinx/Extending/Command-Line-Applications.rst @@ -27,7 +27,7 @@ There are three files in this example: To try out this example: 1. Put the first two files in a new directory -2. Run ``sbt publish-local`` in that directory +2. Run ``sbt publishLocal`` in that directory 3. Run ``sbt @path/to/hello.build.properties`` to run the application. Like for sbt itself, you can specify commands from the command line diff --git a/src/sphinx/Extending/Commands.rst b/src/sphinx/Extending/Commands.rst index d75407747..62f77734e 100644 --- a/src/sphinx/Extending/Commands.rst +++ b/src/sphinx/Extending/Commands.rst @@ -109,8 +109,8 @@ commands to a project. To try it out: 1. Copy the following build definition into ``project/Build.scala`` for a new project. 2. Run sbt on the project. -3. Try out the ``hello``, ``hello-all``, ``fail-if-true``, ``color``, - and ``print-state`` commands. +3. Try out the ``hello``, ``helloAll``, ``failIfTrue``, ``color``, + and ``printState`` commands. 4. Use tab-completion and the code below as guidance. :: @@ -139,14 +139,14 @@ commands to a project. To try it out: // A simple, multiple-argument command that prints "Hi" followed by the arguments. // Again, it leaves the current state unchanged. - def helloAll = Command.args("hello-all", "") { (state, args) => + def helloAll = Command.args("helloAll", "") { (state, args) => println("Hi " + args.mkString(" ")) state } // A command that demonstrates failing or succeeding based on the input - def failIfTrue = Command.single("fail-if-true") { + def failIfTrue = Command.single("failIfTrue") { case (state, "true") => state.fail case (state, _) => state } @@ -168,7 +168,7 @@ commands to a project. To try it out: // A command that demonstrates getting information out of State. - def printState = Command.command("print-state") { state => + def printState = Command.command("printState") { state => import state._ println(definedCommands.size + " registered commands") println("commands to run: " + show(remainingCommands)) diff --git a/src/sphinx/Extending/Input-Tasks.rst b/src/sphinx/Extending/Input-Tasks.rst index 9be7a6890..599c11034 100644 --- a/src/sphinx/Extending/Input-Tasks.rst +++ b/src/sphinx/Extending/Input-Tasks.rst @@ -18,88 +18,95 @@ represents a task. Define a new input task key using the :: - // goes in /project/Build.scala + // goes in /project/Build.scala or in /build.sbt val demo = InputKey[Unit]("demo") +The definition of an input task is similar to that of a normal task, but it can +also use the result of a `Parser `_ applied to +user input. Just as the special ``value`` method gets the value of a +setting or task, the special ``parsed`` method gets the result of a ``Parser``. + Basic Input Task Definition =========================== The simplest input task accepts a space-delimited sequence of arguments. -It does not provide useful tab completion and parsing is basic. Such a -task may be defined using the ``inputTask`` method, which accepts a -single function of type ``TaskKey[Seq[String]] => Initialize[Task[O]]`` -for some parse result type ``O``. The input to this function is a -``TaskKey`` for a task that will provide the parsed ``Seq[String]``. The -function should return a task that uses that parsed input. For example: +It does not provide useful tab completion and parsing is basic. The built-in +parser for space-delimited arguments is constructed via the ``spaceDelimited`` +method, which accepts as its only argument the label to present to the user +during tab completion. + +For example, the following task prints the current Scala version and then echoes +the arguments passed to it on their own line. :: - demo <<= inputTask { (argTask: TaskKey[Seq[String]]) => - // Here, we map the argument task `argTask` - // and a normal setting `scalaVersion` - (argTask, scalaVersion) map { (args: Seq[String], sv: String) => - println("The current Scala version is " + sv) - println("The arguments to demo were:") - args foreach println - } + demo := { + // get the result of parsing + val args: Seq[String] = spaceDelimited("").parsed + // Here, we also use the value of the `scalaVersion` setting + println("The current Scala version is " + scalaVersion.value) + println("The arguments to demo were:") + args foreach println } Input Task using Parsers ======================== -The ``inputTask`` method does not provide any flexibility in defining -the input syntax. To use an arbitrary ``Parser`` described on the -:doc:`/Detailed-Topics/Parsing-Input` page for parsing your input -task's command line, use the more advanced -`InputTask.apply <../../api/sbt/InputTask$.html>`_ factory method. This -method accepts two arguments, which will be described in the following -two sections. +The Parser provided by the ``spaceDelimited`` method does not provide +any flexibility in defining the input syntax. , but using a custom parser +is just a matter of defining your own ``Parser`` as described on the +:doc:`/Detailed-Topics/Parsing-Input` page. Constructing the Parser ----------------------- The first step is to construct the actual ``Parser`` by defining a value -of type ``Initialize[State => Parser[I]]`` for some parse result type -``I`` that you decide on. ``Initialize`` is the type that results from -using other settings and the ``State => Parser[I]`` function provides -access to the :doc:`Build-State` when constructing the parser. As an -example, the following defines a contrived ``Parser`` that uses the -project's Scala and sbt version settings as well as the state. +of one of the following types: + +* ``Parser[I]``: a basic parser that does not use any settings +* ``Initialize[Parser[I]]``: a parser whose definition depends on one or more settings +* ``Initialize[State => Parser[I]]``: a parser that is defined using both settings and the current :doc:`state ` + +We already saw an example of the first case with ``spaceDelimited``, which doesn't use any settings in its definition. +As an example of the third case, the following defines a contrived ``Parser`` that uses the +project's Scala and sbt version settings as well as the state. To use these settings, we +need to wrap the Parser construction in ``Def.setting`` and get the setting values with the +special ``value`` method: :: import complete.DefaultParsers._ val parser: Initialize[State => Parser[(String,String)]] = - (scalaVersion, sbtVersion) { (scalaV: String, sbtV: String) => + Def.setting { (state: State) => - ( token("scala" <~ Space) ~ token(scalaV) ) | - ( token("sbt" <~ Space) ~ token(sbtV) ) | + ( token("scala" <~ Space) ~ token(scalaVersion.value) ) | + ( token("sbt" <~ Space) ~ token(sbtVersion.value) ) | ( token("commands" <~ Space) ~ token(state.remainingCommands.size.toString) ) - } + } This Parser definition will produce a value of type ``(String,String)``. -The input syntax isn't very flexible; it is just a demonstration. It +The input syntax defined isn't very flexible; it is just a demonstration. It will produce one of the following values for a successful parse -(assuming the current Scala version is 2.9.2, the current sbt version is -0.12.0, and there are 3 commands left to run): +(assuming the current Scala version is 2.10.0, the current sbt version is +0.13.0, and there are 3 commands left to run): .. code-block:: text - ("scala", "2.9.2") - ("sbt", "0.12.0") + ("scala", "2.10.0") + ("sbt", "0.13.0") ("commands", "3") +Again, we were able to access the current Scala and sbt version for the project because +they are settings. Tasks cannot be used to define the parser. + Constructing the Task --------------------- Next, we construct the actual task to execute from the result of the -``Parser``. For this, we construct a value of type -``TaskKey[I] => Initialize[Task[O]]``, where ``I`` is the type returned -by the ``Parser`` we just defined and ``O`` is the type of the ``Task`` -we will produce. The ``TaskKey[I]`` provides a task that will provide -the result of parsing. +``Parser``. For this, we define a task as usual, but we can access the +result of parsing via the special ``parsed`` method on ``Parser``. The following contrived example uses the previous example's output (of type ``(String,String)``) and the result of the ``package`` task to @@ -107,23 +114,9 @@ print some information to the screen. :: - val taskDef = (parsedTask: TaskKey[(String,String)]) => { - // we are making a task, so use 'map' - (parsedTask, packageBin) map { case ( (tpe: String, value: String), pkg: File) => + demo := { + val (tpe, value) = parser.parsed println("Type: " + tpe) println("Value: " + value) - println("Packaged: " + pkg.getAbsolutePath) - } + println("Packaged: " + packageBin.value.getAbsolutePath) } - -Putting it together -------------------- - -To construct the input task, combine the key, the parser, and the task -definition in a setting that goes in ``build.sbt`` or in the -``settings`` member of a ``Project`` in ``project/Build.scala``: - -:: - - demo <<= InputTask(parser)(taskDef) - diff --git a/src/sphinx/Extending/Plugins-Best-Practices.rst b/src/sphinx/Extending/Plugins-Best-Practices.rst index a67d5c966..4250604d8 100644 --- a/src/sphinx/Extending/Plugins-Best-Practices.rst +++ b/src/sphinx/Extending/Plugins-Best-Practices.rst @@ -39,7 +39,7 @@ Where possible, reuse them in your plugin. For instance, don't define: :: - val sourceFiles = SettingKey[Seq[File]]("source-files") + val sourceFiles = SettingKey[Seq[File]]("sourceFiles") Instead, simply reuse SBT's existing ``sources`` key. @@ -58,7 +58,7 @@ Just use a ``val`` prefix package sbtobfuscate object Plugin extends sbt.Plugin { - val obfuscateStylesheet = SettingKey[File]("obfuscate-stylesheet") + val obfuscateStylesheet = SettingKey[File]("obfuscateStylesheet") } In this approach, every ``val`` starts with ``obfuscate``. A user of the @@ -66,7 +66,7 @@ plugin would refer to the settings like this: :: - obfuscateStylesheet <<= ... + obfuscateStylesheet := ... Use a nested object ~~~~~~~~~~~~~~~~~~~ @@ -76,7 +76,7 @@ Use a nested object package sbtobfuscate object Plugin extends sbt.Plugin { object ObfuscateKeys { - val stylesheet = SettingKey[File]("obfuscate-stylesheet") + val stylesheet = SettingKey[File]("obfuscateStylesheet") } } @@ -87,7 +87,7 @@ of the plugin would refer to the settings like this: import ObfuscateKeys._ // place this at the top of build.sbt - stylesheet <<= ... + stylesheet := ... Configuration Advice -------------------- @@ -118,15 +118,15 @@ the same *key*, but they represent distinct *values*. So, in a user's :: - target in PDFPlugin <<= baseDirectory(_ / "mytarget" / "pdf") - target in Compile <<= baseDirectory(_ / "mytarget") + target in PDFPlugin := baseDirectory.value / "mytarget" / "pdf" + target in Compile := baseDirectory.value / "mytarget" In the PDF plugin, this is achieved with an ``inConfig`` definition: :: val settings: Seq[sbt.Project.Setting[_]] = inConfig(LWM)(Seq( - target <<= baseDirectory(_ / "target" / "docs") # the default value + target := baseDirectory.value / "target" / "docs" # the default value )) When *not* to define your own configuration. @@ -139,10 +139,10 @@ task (see below). :: val akka = config("akka") // This isn't needed. - val akkaStartCluster = TaskKey[Unit]("akka-start-cluster") + val akkaStartCluster = TaskKey[Unit]("akkaStartCluster") - target in akkaStartCluster <<= ... // This is ok. - akkaStartCluster in akka <<= ... // BAD. No need for a Config for plugin-specific task. + target in akkaStartCluster := ... // This is ok. + akkaStartCluster in akka := ... // BAD. No need for a Config for plugin-specific task. Configuration Cat says "Configuration is for configuration" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -168,8 +168,8 @@ Configurations should *not* be used to namespace keys for a plugin. e.g. :: val Config = config("my-plugin") - val pluginKey = SettingKey[String]("plugin-specific-key") - val settings = plugin-key in Config // DON'T DO THIS! + val pluginKey = SettingKey[String]("pluginSpecificKey") + val settings = pluginKey in Config // DON'T DO THIS! Playing nice with configurations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -191,8 +191,8 @@ Split your settings by the configuration axis like so: val obfuscate = TaskKey[Seq[File]]("obfuscate") val obfuscateSettings = inConfig(Compile)(baseObfuscateSettings) val baseObfuscateSettings: Seq[Setting[_]] = Seq( - obfuscate <<= (sources in obfuscate) map { s => ... }, - sources in obfuscate <<= (sources).identity + obfuscate := ... (sources in obfuscate).value ..., + sources in obfuscate := sources.value ) The ``baseObfuscateSettings`` value provides base configuration for the @@ -232,8 +232,8 @@ task itself. val obfuscate = TaskKey[Seq[File]]("obfuscate") val obfuscateSettings = inConfig(Compile)(baseObfuscateSettings) val baseObfuscateSettings: Seq[Setting[_]] = Seq( - obfuscate <<= (sources in obfuscate) map { s => ... }, - sources in obfuscate <<= (sources).identity + obfuscate := ... (sources in obfuscate).value ..., + sources in obfuscate := sources.value ) In the above example, ``sources in obfuscate`` is scoped under the main @@ -245,7 +245,7 @@ Mucking with Global build state There may be times when you need to muck with global build state. The general rule is *be careful what you touch*. -First, make sure your user do not include global build configuration in +First, make sure your user does not include global build configuration in *every* project but rather in the build itself. e.g. :: @@ -266,8 +266,8 @@ removed. object MyPlugin extends Plugin { val globalSettigns: Seq[Setting[_]] = Seq( - onLoad in Global <<= onLoad in Global apply (_ andThen { state => + onLoad in Global := (onLoad in Global).value andThen { state => ... return new state ... - }) + } ) } diff --git a/src/sphinx/Extending/Plugins.rst b/src/sphinx/Extending/Plugins.rst index c48cf28b9..b8fa7d9f3 100644 --- a/src/sphinx/Extending/Plugins.rst +++ b/src/sphinx/Extending/Plugins.rst @@ -177,7 +177,7 @@ If sbt is running, run ``reload``. Note that this approach can be useful used when developing a plugin. A project that uses the plugin will rebuild the plugin on ``reload``. This -saves the intermediate steps of ``publish-local`` and ``clean-plugins`` +saves the intermediate steps of ``publishLocal`` and ``cleanPlugins`` required in 0.7. It can also be used to work with the development version of a plugin from its repository. @@ -269,14 +269,14 @@ An example of a typical plugin: { // configuration points, like the built in `version`, `libraryDependencies`, or `compile` // by implementing Plugin, these are automatically imported in a user's `build.sbt` - val newTask = TaskKey[Unit]("new-task") - val newSetting = SettingKey[String]("new-setting") + val newTask = TaskKey[Unit]("newTask") + val newSetting = SettingKey[String]("newSetting") // a group of settings ready to be added to a Project // to automatically add them, do val newSettings = Seq( newSetting := "test", - newTask <<= newSetting map { str => println(str) } + newTask := println(newSetting.value) ) // alternatively, by overriding `settings`, they could be automatically added to a Project @@ -382,7 +382,7 @@ In addition: 3. sbt will rebuild the plugin and use it for the project. Additionally, the plugin will be available in other projects on the machine without recompiling again. This approach skips the - overhead of ``publish-local`` and cleaning the plugins directory + overhead of ``publishLocal`` and cleaning the plugins directory of the project using the plugin. These are all consequences of ``~/.sbt/plugins/`` being a standard diff --git a/src/sphinx/Extending/Settings-Core.md b/src/sphinx/Extending/Settings-Core.md deleted file mode 100644 index a5eb3b70b..000000000 --- a/src/sphinx/Extending/Settings-Core.md +++ /dev/null @@ -1,170 +0,0 @@ -[Global]: ../../api/sbt/Global$.html -[This]: ../../api/sbt/This$.html -[Select]: ../../api/sbt/Select.html -[main/Structure.scala]: https://github.com/harrah/xsbt/blob/0.12/main/Structure.scala - -# Settings Core - -This page describes the core settings engine a bit. This may be useful for using it outside of sbt. It may also be useful for understanding how sbt works internally. - -The documentation is comprised of two parts. The first part shows an example settings system built on top of the settings engine. The second part comments on how sbt's settings system is built on top of the settings engine. This may help illuminate what exactly the core settings engine provides and what is needed to build something like the sbt settings system. - -## Example - -### Setting up - -To run this example, first create a new project with the following build.sbt file: - -```scala -libraryDependencies <+= sbtVersion("org.scala-sbt" %% "collections" % _) - -resolvers <+= sbtResolver -``` - -Then, put the following examples in source files `SettingsExample.scala` and `SettingsUsage.scala`. Finally, run sbt and enter the REPL using `console`. To see the output described below, enter `SettingsUsage`. - -### Example Settings System - -The first part of the example defines the custom settings system. There are three main parts: - -1. Define the Scope type. -2. Define a function that converts that Scope (plus an AttributeKey) to a String. -3. Define a delegation function that defines the sequence of Scopes in which to look up a value. - -There is also a fourth, but its usage is likely to be specific to sbt at this time. The example uses a trivial implementation for this part. - -`SettingsExample.scala` - -```scala - import sbt._ - -/** Define our settings system */ - -// A basic scope indexed by an integer. -final case class Scope(index: Int) - -// Extend the Init trait. -// (It is done this way because the Scope type parameter is used everywhere in Init. -// Lots of type constructors would become binary, which as you may know requires lots of type lambdas -// when you want a type function with only one parameter. -// That would be a general pain.) -object SettingsExample extends Init[Scope] -{ - // Provides a way of showing a Scope+AttributeKey[_] - val showFullKey: Show[ScopedKey[_]] = new Show[ScopedKey[_]] { - def apply(key: ScopedKey[_]) = key.scope.index + "/" + key.key.label - } - - // A sample delegation function that delegates to a Scope with a lower index. - val delegates: Scope => Seq[Scope] = { case s @ Scope(index) => - s +: (if(index <= 0) Nil else delegates(Scope(index-1)) ) - } - - // Not using this feature in this example. - val scopeLocal: ScopeLocal = _ => Nil - - // These three functions + a scope (here, Scope) are sufficient for defining our settings system. -} -``` - -### Example Usage - -This part shows how to use the system we just defined. The end result is a `Settings[Scope]` value. This type is basically a mapping `Scope -> AttributeKey[T] -> Option[T]`. See the [Settings API documentation](../../api/sbt/Settings.html) for details. - -`SettingsUsage.scala` - -```scala -/** Usage Example **/ - - import sbt._ - import SettingsExample._ - import Types._ - -object SettingsUsage -{ - - // Define some keys - val a = AttributeKey[Int]("a") - val b = AttributeKey[Int]("b") - - // Scope these keys - val a3 = ScopedKey(Scope(3), a) - val a4 = ScopedKey(Scope(4), a) - val a5 = ScopedKey(Scope(5), a) - - val b4 = ScopedKey(Scope(4), b) - - // Define some settings - val mySettings: Seq[Setting[_]] = Seq( - setting( a3, value( 3 ) ), - setting( b4, app(a4 :^: KNil) { case av :+: HNil => av * 3 } ), - update(a5)(_ + 1) - ) - - // "compiles" and applies the settings. - // This can be split into multiple steps to access intermediate results if desired. - // The 'inspect' command operates on the output of 'compile', for example. - val applied: Settings[Scope] = make(mySettings)(delegates, scopeLocal, showFullKey) - - // Show results. - for(i <- 0 to 5; k <- Seq(a, b)) { - println( k.label + i + " = " + applied.get( Scope(i), k) ) - } -``` - -This produces the following output when run: -``` -a0 = None -b0 = None -a1 = None -b1 = None -a2 = None -b2 = None -a3 = Some(3) -b3 = None -a4 = Some(3) -b4 = Some(9) -a5 = Some(4) -b5 = Some(9) -``` - -* For the None results, we never defined the value and there was no value to delegate to. -* For a3, we explicitly defined it to be 3. -* a4 wasn't defined, so it delegates to a3 according to our delegates function. -* b4 gets the value for a4 (which delegates to a3, so it is 3) and multiplies by 3 -* a5 is defined as the previous value of a5 + 1 and - since no previous value of a5 was defined, it delegates to a4, resulting in 3+1=4. -* b5 isn't defined explicitly, so it delegates to b4 and is therefore equal to 9 as well - -## sbt Settings Discussion - -### Scopes - -sbt defines a more complicated scope than the one shown here for the standard usage of settings in a build. This scope has four components: the project axis, the configuration axis, the task axis, and the extra axis. Each component may be [Global] (no specific value), [This] (current context), or [Select] (containing a specific value). sbt resolves This to either [Global] or [Select] depending on the context. - -For example, in a project, a [This] project axis becomes a [Select] referring to the defining project. All other axes that are [This] are translated to [Global]. Functions like inConfig and inTask transform This into a [Select] for a specific value. For example, `inConfig(Compile)(someSettings)` translates the configuration axis for all settings in _someSettings_ to be `Select(Compile)` if the axis value is [This]. - -So, from the example and from sbt's scopes, you can see that the core settings engine does not impose much on the structure of a scope. All it requires is a delegates function `Scope => Seq[Scope]` and a `display` function. You can choose a scope type that makes sense for your situation. - -### Constructing settings - -The _app_, _value_, _update_, and related methods are the core methods for constructing settings. -This example obviously looks rather different from sbt's interface because these methods are not typically used directly, but are wrapped in a higher-level abstraction. - -With the core settings engine, you work with HLists to access other settings. In sbt's higher-level system, there are wrappers around HList for TupleN and FunctionN for N = 1-9 (except Tuple1 isn't actually used). When working with arbitrary arity, it is useful to make these wrappers at the highest level possible. This is because once wrappers are defined, code must be duplicated for every N. By making the wrappers at the top-level, this requires only one level of duplication. - -Additionally, sbt uniformly integrates its task engine into the settings system. -The underlying settings engine has no notion of tasks. -This is why sbt uses a `SettingKey` type and a `TaskKey` type. -Methods on an underlying `TaskKey[T]` are basically translated to operating on an underlying `SettingKey[Task[T]]` (and they both wrap an underlying `AttributeKey`). - -For example, `a := 3` for a SettingKey _a_ will very roughly translate to `setting(a, value(3))`. -For a TaskKey _a_, it will roughly translate to `setting(a, value( task { 3 } ) )`. -See [main/Structure.scala] for details. - -### Settings definitions - -sbt also provides a way to define these settings in a file (build.sbt and Build.scala). -This is done for build.sbt using basic parsing and then passing the resulting chunks of code to `compile/Eval.scala`. -For all definitions, sbt manages the classpaths and recompilation process to obtain the settings. -It also provides a way for users to define project, task, and configuration delegation, which ends up being used by the delegates function. diff --git a/src/sphinx/Extending/Settings-Core.rst b/src/sphinx/Extending/Settings-Core.rst index ea7bc8704..ad33457db 100644 --- a/src/sphinx/Extending/Settings-Core.rst +++ b/src/sphinx/Extending/Settings-Core.rst @@ -24,9 +24,9 @@ build.sbt file: :: - libraryDependencies <+= sbtVersion("org.scala-sbt" %% "collections" % _) + libraryDependencies += "org.scala-sbt" %% "collections" % sbtVersion.value - resolvers <+= sbtResolver + resolvers += sbtResolver.value Then, put the following examples in source files ``SettingsExample.scala`` and ``SettingsUsage.scala``. Finally, run sbt diff --git a/src/sphinx/Getting-Started/Basic-Def.rst b/src/sphinx/Getting-Started/Basic-Def.rst index 87bbfeaf1..77a538c53 100644 --- a/src/sphinx/Getting-Started/Basic-Def.rst +++ b/src/sphinx/Getting-Started/Basic-Def.rst @@ -15,10 +15,7 @@ the base directory, and files ending in ``.scala``, located in the You can use either one exclusively, or use both. A good approach is to use ``.sbt`` files for most purposes, and use ``.scala`` files only to -contain what can't be done in ``.sbt``: - -- to customize sbt (add new settings or tasks) -- to define nested sub-projects +contain what can't be done in ``.sbt``. This page discusses ``.sbt`` files. See :doc:`.scala build definition ` (later in Getting Started) for more on ``.scala`` files and how they relate to ``.sbt`` files. @@ -87,11 +84,10 @@ Here's an example: A ``build.sbt`` file is a list of ``Setting``, separated by blank lines. Each ``Setting`` is defined with a Scala expression. - The expressions in ``build.sbt`` are independent of one another, and -they are expressions, rather than complete Scala statements. An -implication of this is that you can't define a top-level ``val``, -``object``, class, or method in ``build.sbt``. +they are expressions, rather than complete Scala statements. These +expressions may be interspersed with ``val``s, ``lazy val``s, and ``def``s, +but top-level ``object``s and classes are not allowed in ``build.sbt``. On the left, ``name``, ``version``, and ``scalaVersion`` are *keys*. A key is an instance of ``SettingKey[T]``, ``TaskKey[T]``, or @@ -116,8 +112,11 @@ key in sbt's map, giving it the value ``"hello"``. If you use the wrong value type, the build definition will not compile: -``scala name := 42 // will not compile`` ### Settings are separated by -blank lines +:: + + name := 42 // will not compile + +### Settings are separated by blank lines You can't write a ``build.sbt`` like this: @@ -225,20 +224,8 @@ If you type the name of a setting key rather than a task key, the value of the setting key will be displayed. Typing a task key name executes the task but doesn't display the resulting value; to see a task's result, use ``show `` rather than plain ````. - -In build definition files, keys are named with ``camelCase`` following -Scala convention, but the sbt command line uses -``hyphen-separated-words`` instead. The hyphen-separated string used in -sbt comes from the definition of the key (see -`Keys <../../sxr/Keys.scala.html>`_). For -example, in ``Keys.scala``, there's this key: - -:: - - val scalacOptions = TaskKey[Seq[String]]("scalac-options", "Options for the Scala compiler.") - -In sbt you type ``scalac-options`` but in a build definition file you -use ``scalacOptions``. +The convention for keys names is to use ``camelCase`` so that the +command line name and the Scala identifiers are the same. To learn more about any key, type ``inspect `` at the sbt interactive prompt. Some of the information ``inspect`` displays won't diff --git a/src/sphinx/Getting-Started/Custom-Settings.rst b/src/sphinx/Getting-Started/Custom-Settings.rst index 5e9c8de85..4eb07797f 100644 --- a/src/sphinx/Getting-Started/Custom-Settings.rst +++ b/src/sphinx/Getting-Started/Custom-Settings.rst @@ -24,11 +24,11 @@ Some examples from `Keys <../../sxr/Keys.scala.html>`_: :: - val scalaVersion = SettingKey[String]("scala-version", "The version of Scala used for building.") + val scalaVersion = SettingKey[String]("scalaVersion", "The version of Scala used for building.") val clean = TaskKey[Unit]("clean", "Deletes files produced by the build, such as generated sources, compiled classes, and task caches.") The key constructors have two string parameters: the name of the key -(``"scala-version"``) and a documentation string +(``"scalaVersion"``) and a documentation string (``"The version of scala used for building."``). Remember from :doc:`.sbt build definition ` that @@ -66,8 +66,8 @@ code with the task key: sum } -If the task has dependencies, you'd use ``<<=`` instead of course, as -discussed in :doc:`more about settings `. +If the task has dependencies, you'd reference their value using +`value`, as discussed in :doc:`more about settings `. The hardest part about implementing tasks is often not sbt-specific; tasks are just Scala code. The hard part could be writing the "meat" of @@ -78,21 +78,20 @@ and write code based on the HTML library, perhaps). sbt has some utility libraries and convenience functions, in particular 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 +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 map { (value: Int) => value + 1 } + intTask := intTask.value + 1 intTask ~= { (value: Int) => value + 1 } Use plugins! diff --git a/src/sphinx/Getting-Started/Full-Def.rst b/src/sphinx/Getting-Started/Full-Def.rst index a3bcf20e0..5e792c95d 100644 --- a/src/sphinx/Getting-Started/Full-Def.rst +++ b/src/sphinx/Getting-Started/Full-Def.rst @@ -103,10 +103,10 @@ The following two files illustrate. First, if your project is in object HelloBuild extends Build { - val sampleKeyA = SettingKey[String]("sample-a", "demo key A") - val sampleKeyB = SettingKey[String]("sample-b", "demo key B") - val sampleKeyC = SettingKey[String]("sample-c", "demo key C") - val sampleKeyD = SettingKey[String]("sample-d", "demo key D") + val sampleKeyA = SettingKey[String]("sampleKeyA", "demo key A") + val sampleKeyB = SettingKey[String]("sampleKeyB", "demo key B") + val sampleKeyC = SettingKey[String]("sampleKeyC", "demo key C") + val sampleKeyD = SettingKey[String]("sampleKeyD", "demo key D") override lazy val settings = super.settings ++ Seq(sampleKeyA := "A: in Build.settings in Build.scala", resolvers := Seq()) @@ -124,22 +124,22 @@ Now, create ``hello/build.sbt`` as follows: sampleKeyD := "D: in build.sbt" -Start up the sbt interactive prompt. Type ``inspect sample-a`` and you +Start up the sbt interactive prompt. Type ``inspect sampleKeyA`` and you should see (among other things): .. code-block:: text [info] Setting: java.lang.String = A: in Build.settings in Build.scala [info] Provided by: - [info] {file:/home/hp/checkout/hello/}/*:sample-a + [info] {file:/home/hp/checkout/hello/}/*:sampleKeyA -and then ``inspect sample-c`` and you should see: +and then ``inspect sampleKeyC`` and you should see: .. code-block:: text [info] Setting: java.lang.String = C: in build.sbt scoped to ThisBuild [info] Provided by: - [info] {file:/home/hp/checkout/hello/}/*:sample-c + [info] {file:/home/hp/checkout/hello/}/*:sampleKeyC Note that the "Provided by" shows the same scope for the two values. That is, ``sampleKeyC in ThisBuild`` in a ``.sbt`` file is equivalent to @@ -147,30 +147,30 @@ placing a setting in the ``Build.settings`` list in a ``.scala`` file. sbt takes build-scoped settings from both places to create the build definition. -Now, ``inspect sample-b``: +Now, ``inspect sampleKeyB``: .. code-block:: text [info] Setting: java.lang.String = B: in the root project settings in Build.scala [info] Provided by: - [info] {file:/home/hp/checkout/hello/}hello/*:sample-b + [info] {file:/home/hp/checkout/hello/}hello/*:sampleKeyB -Note that ``sample-b`` is scoped to the project +Note that ``sampleKeyB`` is scoped to the project (``{file:/home/hp/checkout/hello/}hello``) rather than the entire build (``{file:/home/hp/checkout/hello/}``). -As you've probably guessed, ``inspect sample-d`` matches ``sample-b``: +As you've probably guessed, ``inspect sampleKeyD`` matches ``sampleKeyB``: .. code-block:: text [info] Setting: java.lang.String = D: in build.sbt [info] Provided by: - [info] {file:/home/hp/checkout/hello/}hello/*:sample-d + [info] {file:/home/hp/checkout/hello/}hello/*:sampleKeyD sbt *appends* the settings from ``.sbt`` files to the settings from ``Build.settings`` and ``Project.settings`` which means ``.sbt`` settings take precedence. Try changing ``Build.scala`` so it sets key -``sample-c`` or ``sample-d``, which are also set in ``build.sbt``. The +``sampleC`` or ``sampleD``, which are also set in ``build.sbt``. The setting in ``build.sbt`` should "win" over the one in ``Build.scala``. One other thing you may have noticed: ``sampleKeyC`` and ``sampleKeyD`` @@ -194,19 +194,13 @@ In summary: When to use ``.scala`` files ---------------------------- -In ``.scala`` files, you are not limited to a series of settings -expressions. You can write any Scala code including ``val``, ``object``, +In ``.scala`` files, you can write any Scala code including ``val``, ``object``, and method definitions. *One recommended approach is to define settings in ``.sbt`` files, using ``.scala`` files when you need to factor out a ``val`` or ``object`` or method definition.* -Because the ``.sbt`` format allows only single expressions, it doesn't -give you a way to share code among expressions. When you need to share -code, you need a ``.scala`` file so you can set common variables or -define methods. - There's one build definition, which is a nested project inside your main project. ``.sbt`` and ``.scala`` files are compiled together to create that single definition. diff --git a/src/sphinx/Getting-Started/Hello.rst b/src/sphinx/Getting-Started/Hello.rst index d49cb934f..5f3f194a0 100644 --- a/src/sphinx/Getting-Started/Hello.rst +++ b/src/sphinx/Getting-Started/Hello.rst @@ -81,7 +81,7 @@ You can force a particular version of sbt by creating a file .. code-block:: text - sbt.version=0.12.0 + sbt.version=0.13.0 sbt is 99% source compatible from release to release. Still, setting the sbt version in ``project/build.properties`` avoids diff --git a/src/sphinx/Getting-Started/Library-Dependencies.rst b/src/sphinx/Getting-Started/Library-Dependencies.rst index a64c02359..3aa2e0eb5 100644 --- a/src/sphinx/Getting-Started/Library-Dependencies.rst +++ b/src/sphinx/Getting-Started/Library-Dependencies.rst @@ -35,23 +35,23 @@ filter some entries out, and return a new classpath value. See :doc:`more about for details of ``~=``. There's nothing to add to ``build.sbt`` to use unmanaged dependencies, -though you could change the ``unmanaged-base`` key if you'd like to use +though you could change the ``unmanagedBase`` key if you'd like to use a different directory rather than ``lib``. To use ``custom_lib`` instead of ``lib``: :: - unmanagedBase <<= baseDirectory { base => base / "custom_lib" } + unmanagedBase := baseDirectory.value / "custom_lib" ``baseDirectory`` is the project's root directory, so here you're -changing ``unmanagedBase`` depending on ``baseDirectory``, using ``<<=`` -as explained in :doc:`more about settings `. +changing ``unmanagedBase`` depending on ``baseDirectory`` using the +special ``value`` method as explained in :doc:`more about settings `. -There's also an ``unmanaged-jars`` task which lists the jars from the -``unmanaged-base`` directory. If you wanted to use multiple directories +There's also an ``unmanagedJars`` task which lists the jars from the +``unmanagedBase`` directory. If you wanted to use multiple directories or do something else complex, you might need to replace the whole -``unmanaged-jars`` task with one that does something else. +``unmanagedJars`` task with one that does something else. Managed Dependencies -------------------- @@ -114,8 +114,7 @@ once: groupID % otherID % otherRevision ) -And in rare cases you might find reasons to use ``:=``, ``<<=``, -``<+=``, etc. with ``libraryDependencies`` as well. +In rare cases you might find reasons to use ``:=`` with ``libraryDependencies`` as well. Getting the right Scala version with ``%%`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -206,10 +205,10 @@ Overriding default resolvers ones added by your build definition. ``sbt`` combines ``resolvers`` with some default repositories to form -``external-resolvers``. +``externalResolvers``. Therefore, to change or remove the default resolvers, you would need to -override ``external-resolvers`` instead of ``resolvers``. +override ``externalResolvers`` instead of ``resolvers``. Per-configuration dependencies ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -225,9 +224,9 @@ If you want a dependency to show up in the classpath only for the libraryDependencies += "org.apache.derby" % "derby" % "10.4.1.3" % "test" -Now, if you type ``show compile:dependency-classpath`` at the sbt +Now, if you type ``show compile:dependencyClasspath`` at the sbt interactive prompt, you should not see derby. But if you type -``show test:dependency-classpath``, you should see the derby jar in the +``show test:dependencyClasspath``, you should see the derby jar in the list. Typically, test-related dependencies such as diff --git a/src/sphinx/Getting-Started/More-About-Settings.rst b/src/sphinx/Getting-Started/More-About-Settings.rst index 837222864..d5930a72a 100644 --- a/src/sphinx/Getting-Started/More-About-Settings.rst +++ b/src/sphinx/Getting-Started/More-About-Settings.rst @@ -15,8 +15,7 @@ transformation with sbt's earlier map as input and a new map as output. The new map becomes sbt's new state. Different settings transform the map in different ways. -:doc:`Earlier `, you read about the ``:=`` -method. +:doc:`Earlier `, you read about the ``:=`` method. The ``Setting`` which ``:=`` creates puts a fixed, constant value in the new, transformed map. For example, if you transform a map with the @@ -110,75 +109,44 @@ 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 value. But what if you want to define a value in terms of *other* keys' -values? +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 +only be called in the argument to ``:=``, ``+=``, or ``++=``. -- ``<<=`` lets you compute a new value using the value(s) of arbitrary - other keys. - -``<<=`` has one argument, of type ``Initialize[T]``. An -``Initialize[T]`` instance is a computation which takes the values -associated with a set of keys as input, and returns a value of type -``T`` based on those other values. It initializes a value of type ``T``. - -Given an ``Initialize[T]``, ``<<=`` returns a ``Setting[T]``, of course -(just like ``:=``, ``+=``, ``~=``, etc.). - -Trivial ``Initialize[T]``: depending on one other key with ``<<=`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -All keys extend the ``Initialize`` trait already. So the simplest -``Initialize`` is just a key: - -:: - - // useless but valid - name <<= name - -When treated as an ``Initialize[T]``, a ``SettingKey[T]`` computes its -current value. So ``name <<= name`` sets the value of ``name`` to the -value that ``name`` already had. - -It gets a little more useful if you set a key to a *different* key. The -keys must have identical value types, though. +As a first example, consider defining the project organization to be the same as the project name. :: // name our organization after our project (both are SettingKey[String]) - organization <<= name + organization := name.value -(Note: this is how you alias one key to another.) - -If the value types are not identical, you'll need to convert from -``Initialize[T]`` to another type, like ``Initialize[S]``. This is done -with the ``apply`` method on ``Initialize``, like this: +Or, set the name to the name of the project's directory: :: // name is a Key[String], baseDirectory is a Key[File] // name the project after the directory it's inside - name <<= baseDirectory.apply(_.getName) + name := baseDirectory.value.getName -``apply`` is special in Scala and means you can invoke the object with -function syntax; so you could also write this: +This transforms the value of ``baseDirectory`` using the standard ``getName`` method of ``java.io.File``. + +Using multiple inputs is similar. For example, :: - name <<= baseDirectory(_.getName) + name := "project " + name.value + " from " + organization.value + " version " + version.value -That transforms the value of ``baseDirectory`` using the function -``_.getName``, where the function ``_.getName`` takes a ``File`` and -returns a ``String``. ``getName`` is a method on the standard -``java.io.File`` object. +This sets the name in terms of its previous value as well as the organization and version settings. Settings with dependencies ~~~~~~~~~~~~~~~~~~~~~~~~~~ -In the setting ``name <<= baseDirectory(_.getName)``, ``name`` will have +In the setting ``name := baseDirectory.value.getName``, ``name`` will have a *dependency* on ``baseDirectory``. If you place the above in ``build.sbt`` and run the sbt interactive console, then type ``inspect name``, you should see (in part): @@ -186,14 +154,14 @@ a *dependency* on ``baseDirectory``. If you place the above in .. code-block:: text [info] Dependencies: - [info] *:base-directory + [info] *:baseDirectory This is how sbt knows which settings depend on which other settings. Remember that some settings describe tasks, so this approach also creates dependencies between tasks. For example, if you ``inspect compile`` you'll see it depends on another -key ``compile-inputs``, and if you inspect ``compile-inputs`` it in turn +key ``compileInputs``, and if you inspect ``compileInputs`` it in turn depends on other keys. Keep following the dependency chains and magic happens. When you type ``compile`` sbt automatically performs an ``update``, for example. It Just Works because the values required as @@ -204,83 +172,11 @@ In this way, all build dependencies in sbt are *automatic* rather than explicitly declared. If you use a key's value in another computation, then the computation depends on that key. It just works! -Complex ``Initialize[T]``: depending on multiple keys with ``<<=`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To support dependencies on multiple other keys, sbt adds ``apply`` and -``identity`` methods to tuples of ``Initialize`` objects. In Scala, you -write a tuple like ``(1, "a")`` (that one has type ``(Int, String)``). - -So say you have a tuple of three ``Initialize`` objects; its type would -be ``(Initialize[A], Initialize[B], Initialize[C])``. The ``Initialize`` -objects could be keys, since all ``SettingKey[T]`` are also instances of -``Initialize[T]``. - -Here's a simple example, in this case all three keys are strings: - -:: - - // a tuple of three SettingKey[String], also a tuple of three Initialize[String] - (name, organization, version) - -The ``apply`` method on a tuple of ``Initialize`` takes a function as -its argument. Using each ``Initialize`` in the tuple, sbt computes a -corresponding value (the current value of the key). These values are -passed in to the function. The function then returns *one* value, which -is wrapped up in a new ``Initialize``. If you wrote it out with explicit -types (Scala does not require this), it would look like: - -:: - - val tuple: (Initialize[String], Initialize[String], Initialize[String]) = (name, organization, version) - val combined: Initialize[String] = tuple.apply({ (n, o, v) => - "project " + n + " from " + o + " version " + v }) - val setting: Setting[String] = name <<= combined - -So each key is already an ``Initialize``; but you can combine up to nine -simple ``Initialize`` (such as keys) into one composite ``Initialize`` -by placing them in tuples, and invoking the ``apply`` method. - -The ``<<=`` method on ``SettingKey[T]`` is expecting an -``Initialize[T]``, so you can use this technique to create an -``Initialize[T]`` with multiple dependencies on arbitrary keys. - -Because function syntax in Scala just calls the ``apply`` method, you -could write the code like this, omitting the explicit ``.apply`` and -just treating ``tuple`` as a function: - -:: - - val tuple: (Initialize[String], Initialize[String], Initialize[String]) = (name, organization, version) - val combined: Initialize[String] = tuple({ (n, o, v) => - "project " + n + " from " + o + " version " + v }) - val setting: Setting[String] = name <<= combined - -In a ``build.sbt``, this code using intermediate ``val`` will not work, -since you can only write single expressions in a ``.sbt`` file, not -multiple statements. - -You can use a more concise syntax in ``build.sbt``, like this: - -:: - - name <<= (name, organization, version) { (n, o, v) => "project " + n + " from " + o + " version " + v } - -Here the tuple of ``Initialize`` (also a tuple of ``SettingKey``) works -as a function, taking the anonymous function delimited by ``{}`` as its -argument, and returning an ``Initialize[T]`` where ``T`` is the result -type of the anonymous function. - -Tuples of ``Initialize`` have one other method, ``identity``, which -simply returns an ``Initialize`` with a tuple value. -``(a: Initialize[A], b: Initialize[B]).identity`` would result in a -value of type ``Initialize[(A, B)]``. ``identity`` combines two -``Initialize`` into one, without losing or modifying any of the values. 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 does not, sbt will complain. It might say *"Reference to undefined setting"*, for example. When this happens, be sure you're using the key @@ -294,12 +190,8 @@ Tasks with dependencies As noted in :doc:`.sbt build definition `, task keys create a ``Setting[Task[T]]`` rather than a ``Setting[T]`` when you -build a setting with ``:=``, ``<<=``, etc. Similarly, task keys are -instances of ``Initialize[Task[T]]`` rather than ``Initialize[T]``, and -``<<=`` on a task key takes an ``Initialize[Task[T]]`` parameter. - -The practical importance of this is that you can't have tasks as -dependencies for a non-task setting. +build a setting with ``:=``, etc. Tasks can use settings as inputs, but +settings cannot use tasks as inputs. Take these two keys (from `Keys <../../sxr/Keys.scala.html>`_): @@ -311,122 +203,35 @@ Take these two keys (from `Keys <../../sxr/Keys.scala.html>`_): (``scalacOptions`` and ``checksums`` have nothing to do with each other, they are just two keys with the same value type, where one is a task.) -You cannot compile a ``build.sbt`` that tries to alias one of these to -the other like this: +It is possible to compile a ``build.sbt`` that aliases ``scalacOptions`` to ``checksums``, but not the other way. +For example, this is allowed: :: + // The scalacOptions task may be defined in terms of the checksums setting + scalacOptions := checksums.value - scalacOptions <<= checksums - - checksums <<= scalacOptions - -The issue is that ``scalacOptions.<<=`` expects an -``Initialize[Task[Seq[String]]]`` and ``checksums.<<=`` expects an -``Initialize[Seq[String]]``. There is, however, a way to convert an -``Initialize[T]`` to an ``Initialize[Task[T]]``, called ``map``: - -:: - - scalacOptions <<= checksums map identity - -(``identity`` is a standard Scala function that returns its input as its -result.) - -There is no way to go the *other* direction, that is, a setting key +There is no way to go the *other* direction. That is, a setting key can't depend on a task key. That's because a setting key is only computed once on project load, so the task would not be re-run every time, and tasks expect to re-run every time. -A task can depend on both settings and other tasks, though, just use -``map`` rather than ``apply`` to build an ``Initialize[Task[T]]`` rather -than an ``Initialize[T]``. Remember the usage of ``apply`` with a -non-task setting looks like this: - :: - name <<= (name, organization, version) { (n, o, v) => "project " + n + " from " + o + " version " + v } + // The checksums setting may not be defined in terms of the scalacOptions task + checksums := scalacOptions.value -(``(name, organization, version)`` has an apply method and is thus a -function, taking the anonymous function in ``{}`` braces as a -parameter.) -To create an ``Initialize[Task[T]]`` you need a ``map`` in there rather -than ``apply``: - -:: - - // this WON'T compile because name (on the left of <<=) is not a task and we used map - name <<= (name, organization, version) map { (n, o, v) => "project " + n + " from " + o + " version " + v } - - // this WILL compile because packageBin is a task and we used map - packageBin in Compile <<= (name, organization, version) map { (n, o, v) => file(o + "-" + n + "-" + v + ".jar") } - - // this WILL compile because name is not a task and we used apply - name <<= (name, organization, version) { (n, o, v) => "project " + n + " from " + o + " version " + v } - - // this WON'T compile because packageBin is a task and we used apply - packageBin in Compile <<= (name, organization, version) { (n, o, v) => file(o + "-" + n + "-" + v + ".jar") } - -*Bottom line:* when converting a tuple of keys into an -``Initialize[Task[T]]``, use ``map``; when converting a tuple of keys -into an ``Initialize[T]`` use ``apply``; and you need the -``Initialize[Task[T]]`` if the key on the left side of ``<<=`` is a -``TaskKey[T]`` rather than a ``SettingKey[T]``. - -Remember, aliases use ``<<=`` not ``:=`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If you want one key to be an alias for another, you might be tempted to -use ``:=`` to create the following nonsense alias: - -:: - - // doesn't work, and not useful - packageBin in Compile := packageDoc in Compile - -The problem is that ``:=``'s argument must be a value (or for tasks, a -function returning a value). For ``packageBin`` which is a -``TaskKey[File]``, it must be a ``File`` or a function ``=> File``. -``packageDoc`` is not a ``File``, it's a key. - -The proper way to do this is with ``<<=``, which takes a key (really an -``Initialize``, but keys are instances of ``Initialize``): - -:: - - // works, still not useful - packageBin in Compile <<= packageDoc in Compile - -Here, ``<<=`` expects an ``Initialize[Task[File]]``, which is a -computation that will return a file later, when sbt runs the task. Which -is what you want: you want to alias a task by making it run another -task, not by setting it one time when sbt loads the project. - -(By the way: the ``in Compile`` scope is needed to avoid "undefined" -errors, because the packaging tasks like ``packageBin`` are -per-configuration, not global.) - -Appending with dependencies: ``<+=`` and ``<++=`` +Appending with dependencies: ``+=`` and ``++=`` ------------------------------------------------- -There are a couple more methods for appending to lists, which combine -``+=`` and ``++=`` with ``<<=``. That is, they let you compute a new -list element or new list to concatenate, using dependencies on other -keys in order to do so. - -These methods work exactly like ``<<=``, but for ``<++=``, the function -you write to convert the dependencies' values into a new value should -create a ``Seq[T]`` instead of a ``T``. - -Unlike ``<<=`` of course, ``<+=`` and ``<++=`` will append to the -previous value of the key on the left, rather than replacing it. +Other keys can be used when appending to an existing setting or task, just like they can for assigning with ``:=``. For example, say you have a coverage report named after the project, and you want to add it to the files removed by ``clean``: :: - cleanFiles <+= (name) { n => file("coverage-report-" + n + ".txt") } + cleanFiles += file("coverage-report-" + name.value + ".txt") Next ---- diff --git a/src/sphinx/Getting-Started/Running.rst b/src/sphinx/Getting-Started/Running.rst index 4af5fd882..9e9626261 100644 --- a/src/sphinx/Getting-Started/Running.rst +++ b/src/sphinx/Getting-Started/Running.rst @@ -43,7 +43,7 @@ in quotes. For example, .. code-block:: console - $ sbt clean compile "test-only TestA TestB" + $ sbt clean compile "testOnly TestA TestB" In this example, ``test-only`` has arguments, ``TestA`` and ``TestB``. The commands will be run in sequence (``clean``, ``compile``, then diff --git a/src/sphinx/Getting-Started/Scopes.rst b/src/sphinx/Getting-Started/Scopes.rst index f22fb11ff..e31438f90 100644 --- a/src/sphinx/Getting-Started/Scopes.rst +++ b/src/sphinx/Getting-Started/Scopes.rst @@ -21,9 +21,9 @@ Some concrete examples: have a different value in each project. - the ``compile`` key may have a different value for your main sources and your test sources, if you want to compile them differently. -- the ``package-options`` key (which contains options for creating jar +- the ``packageOptions`` key (which contains options for creating jar packages) may have different values when packaging class files - (``package-bin``) or packaging source code (``package-src``). + (``packageBin``) or packaging source code (``packageSrc``). *There is no single value for a given key name*, because the value may differ according to scope. @@ -81,21 +81,21 @@ By default, all the keys associated with compiling, packaging, and running are scoped to a configuration and therefore may work differently in each configuration. The most obvious examples are the task keys ``compile``, ``package``, and ``run``; but all the keys which *affect* -those keys (such as ``source-directories`` or ``scalac-options`` or -``full-classpath``) are also scoped to the configuration. +those keys (such as ``sourceDirectories`` or ``scalacOptions`` or +``fullClasspath``) are also scoped to the configuration. Scoping by task axis ~~~~~~~~~~~~~~~~~~~~ -Settings can affect how a task works. For example, the ``package-src`` -task is affected by the ``package-options`` setting. +Settings can affect how a task works. For example, the ``packageSrc`` +task is affected by the ``packageOptions`` setting. -To support this, a task key (such as ``package-src``) can be a scope for -another key (such as ``package-options``). +To support this, a task key (such as ``packageSrc``) can be a scope for +another key (such as ``packageOptions``). -The various tasks that build a package (``package-src``, -``package-bin``, ``package-doc``) can share keys related to packaging, -such as ``artifact-name`` and ``package-options``. Those keys can have +The various tasks that build a package (``packageSrc``, +``packageBin``, ``packageDoc``) can share keys related to packaging, +such as ``artifactName`` and ``packageOptions``. Those keys can have distinct values for each packaging task. Global scope @@ -156,73 +156,73 @@ For more details, see :doc:`/Detailed-Topics/Inspecting-Settings`. Examples of scoped key notation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- ``full-classpath``: just a key, so the default scopes are used: +- ``fullClasspath``: just a key, so the default scopes are used: current project, a key-dependent configuration, and global task scope. -- ``test:full-classpath``: specifies the configuration, so this is - ``full-classpath`` in the ``test`` configuration, with defaults for +- ``test:fullClasspath``: specifies the configuration, so this is + ``fullClasspath`` in the ``test`` configuration, with defaults for the other two scope axes. -- ``*:full-classpath``: specifies ``Global`` for the configuration, +- ``*:fullClasspath``: specifies ``Global`` for the configuration, rather than the default configuration. -- ``doc::full-classpath``: specifies the ``full-classpath`` key scoped +- ``doc::fullClasspath``: specifies the ``fullClasspath`` key scoped to the ``doc`` task, with the defaults for the project and configuration axes. -- ``{file:/home/hp/checkout/hello/}default-aea33a/test:full-classpath`` +- ``{file:/home/hp/checkout/hello/}default-aea33a/test:fullClasspath`` specifies a project, ``{file:/home/hp/checkout/hello/}default-aea33a``, where the project is identified with the build ``{file:/home/hp/checkout/hello/}`` and then a project id inside that build ``default-aea33a``. Also specifies configuration ``test``, but leaves the default task axis. -- ``{file:/home/hp/checkout/hello/}/test:full-classpath`` sets the +- ``{file:/home/hp/checkout/hello/}/test:fullClasspath`` sets the project axis to "entire build" where the build is ``{file:/home/hp/checkout/hello/}`` -- ``{.}/test:full-classpath`` sets the project axis to "entire build" +- ``{.}/test:fullClasspath`` sets the project axis to "entire build" where the build is ``{.}``. ``{.}`` can be written ``ThisBuild`` in Scala code. -- ``{file:/home/hp/checkout/hello/}/compile:doc::full-classpath`` sets +- ``{file:/home/hp/checkout/hello/}/compile:doc::fullClasspath`` sets all three scope axes. Inspecting scopes ----------------- In sbt's interactive mode, you can use the ``inspect`` command to -understand keys and their scopes. Try ``inspect test:full-classpath``: +understand keys and their scopes. Try ``inspect test:fullClasspath``: .. code-block:: text $ sbt - > inspect test:full-classpath + > inspect test:fullClasspath [info] Task: scala.collection.Seq[sbt.Attributed[java.io.File]] [info] Description: [info] The exported classpath, consisting of build products and unmanaged and managed, internal and external dependencies. [info] Provided by: - [info] {file:/home/hp/checkout/hello/}default-aea33a/test:full-classpath + [info] {file:/home/hp/checkout/hello/}default-aea33a/test:fullClasspath [info] Dependencies: - [info] test:exported-products - [info] test:dependency-classpath + [info] test:exportedProducts + [info] test:dependencyClasspath [info] Reverse dependencies: - [info] test:run-main + [info] test:runMain [info] test:run - [info] test:test-loader + [info] test:testLoader [info] test:console [info] Delegates: - [info] test:full-classpath - [info] runtime:full-classpath - [info] compile:full-classpath - [info] *:full-classpath - [info] {.}/test:full-classpath - [info] {.}/runtime:full-classpath - [info] {.}/compile:full-classpath - [info] {.}/*:full-classpath - [info] */test:full-classpath - [info] */runtime:full-classpath - [info] */compile:full-classpath - [info] */*:full-classpath + [info] test:fullClasspath + [info] runtime:fullClasspath + [info] compile:fullClasspath + [info] *:fullClasspath + [info] {.}/test:fullClasspath + [info] {.}/runtime:fullClasspath + [info] {.}/compile:fullClasspath + [info] {.}/*:fullClasspath + [info] */test:fullClasspath + [info] */runtime:fullClasspath + [info] */compile:fullClasspath + [info] */*:fullClasspath [info] Related: - [info] compile:full-classpath - [info] compile:full-classpath(for doc) - [info] test:full-classpath(for doc) - [info] runtime:full-classpath + [info] compile:fullClasspath + [info] compile:fullClasspath(for doc) + [info] test:fullClasspath(for doc) + [info] runtime:fullClasspath On the first line, you can see this is a task (as opposed to a setting, as explained in :doc:`.sbt build definition `). @@ -231,8 +231,8 @@ The value resulting from the task will have type "Provided by" points you to the scoped key that defines the value, in this case -``{file:/home/hp/checkout/hello/}default-aea33a/test:full-classpath`` -(which is the ``full-classpath`` key scoped to the ``test`` +``{file:/home/hp/checkout/hello/}default-aea33a/test:fullClasspath`` +(which is the ``fullClasspath`` key scoped to the ``test`` configuration and the ``{file:/home/hp/checkout/hello/}default-aea33a`` project). @@ -241,33 +241,33 @@ project). You can also see the delegates; if the value were not defined, sbt would search through: -- two other configurations (``runtime:full-classpath``, - ``compile:full-classpath``). In these scoped keys, the project is +- two other configurations (``runtime:fullClasspath``, + ``compile:fullClasspath``). In these scoped keys, the project is unspecified meaning "current project" and the task is unspecified meaning ``Global`` -- configuration set to ``Global`` (``*:full-classpath``), since project +- configuration set to ``Global`` (``*:fullClasspath``), since project is still unspecified it's "current project" and task is still unspecified so ``Global`` - project set to ``{.}`` or ``ThisBuild`` (meaning the entire build, no specific project) -- project axis set to ``Global`` (``*/test:full-classpath``) (remember, +- project axis set to ``Global`` (``*/test:fullClasspath``) (remember, an unspecified project means current, so searching ``Global`` here is new; i.e. ``*`` and "no project shown" are different for the project - axis; i.e. ``*/test:full-classpath`` is not the same as - ``test:full-classpath``) + axis; i.e. ``*/test:fullClasspath`` is not the same as + ``test:fullClasspath``) - both project and configuration set to ``Global`` - (``*/*:full-classpath``) (remember that unspecified task means - ``Global`` already, so ``*/*:full-classpath`` uses ``Global`` for all + (``*/*:fullClasspath``) (remember that unspecified task means + ``Global`` already, so ``*/*:fullClasspath`` uses ``Global`` for all three axes) -Try ``inspect full-classpath`` (as opposed to the above example, -``inspect test:full-classpath``) to get a sense of the difference. +Try ``inspect fullClasspath`` (as opposed to the above example, +``inspect test:fullClasspath``) to get a sense of the difference. Because the configuration is omitted, it is autodetected as ``compile``. -``inspect compile:full-classpath`` should therefore look the same as -``inspect full-classpath``. +``inspect compile:fullClasspath`` should therefore look the same as +``inspect fullClasspath``. -Try ``inspect *:full-classpath`` for another contrast. -``full-classpath`` is not defined in the ``Global`` configuration by +Try ``inspect *:fullClasspath`` for another contrast. +``fullClasspath`` is not defined in the ``Global`` configuration by default. Again, for more details, see :doc:`/Detailed-Topics/Inspecting-Settings`. @@ -302,7 +302,7 @@ name scoped to the ``Compile`` configuration: name in Compile := "hello" -or you could set the name scoped to the ``package-bin`` task (pointless! +or you could set the name scoped to the ``packageBin`` task (pointless! just an example): :: diff --git a/src/sphinx/Getting-Started/Summary.rst b/src/sphinx/Getting-Started/Summary.rst index ad4c57028..49974feba 100644 --- a/src/sphinx/Getting-Started/Summary.rst +++ b/src/sphinx/Getting-Started/Summary.rst @@ -23,8 +23,7 @@ sbt: The Core Concepts - your build definition is one big list of ``Setting`` objects, where a ``Setting`` transforms the set of key-value pairs sbt uses to perform tasks. -- to create a ``Setting``, call one of a few methods on a key (the - ``:=`` and ``<<=`` methods are particularly important). +- to create a ``Setting``, call one of a few methods on a key: ``:=``, ``+=``, ``++=``, or ``~=``. - there is no mutable state, only transformation; for example, a ``Setting`` transforms sbt's collection of key-value pairs into a new collection. It doesn't change anything in-place. diff --git a/src/sphinx/Getting-Started/Using-Plugins.rst b/src/sphinx/Getting-Started/Using-Plugins.rst index ffa60a0a7..d8116e099 100644 --- a/src/sphinx/Getting-Started/Using-Plugins.rst +++ b/src/sphinx/Getting-Started/Using-Plugins.rst @@ -89,7 +89,7 @@ You could add this in ``hello/build.sbt``: libraryDependencies += "org.apache.derby" % "derby" % "10.4.1.3" % "test" If you add that and start up the sbt interactive mode and type -``show dependency-classpath``, you should see the derby jar on your +``show dependencyClasspath``, you should see the derby jar on your classpath. To add a plugin, do the same thing but recursed one level. We want the @@ -109,7 +109,7 @@ For example, edit ``hello/project/build.sbt`` and add this line: libraryDependencies += "net.liftweb" % "lift-json" % "2.0" Now, at the sbt interactive prompt, ``reload plugins`` to enter the -build definition project, and try ``show dependency-classpath``. You +build definition project, and try ``show dependencyClasspath``. You should see the lift-json jar on the classpath. This means: you could use classes from lift-json in your ``Build.scala`` or ``build.sbt`` to implement a task. You could parse a JSON file and generate other files @@ -130,14 +130,10 @@ which you'll have to clean up.) :: def addSbtPlugin(dependency: ModuleID): Setting[Seq[ModuleID]] = - libraryDependencies <+= (sbtVersion in update,scalaVersion) { (sbtV, scalaV) => - sbtPluginExtra(dependency, sbtV, scalaV) - } + libraryDependencies += + sbtPluginExtra(dependency, (sbtVersion in update).value, scalaVersion.value) -Remember from :doc:`more about settings ` that -``<+=`` combines ``<<=`` and ``+=``, so this builds a -value based on other settings, and then appends it to -``libraryDependencies``. The value is based on ``sbtVersion in update`` +The appended dependency is based on ``sbtVersion in update`` (sbt's version scoped to the ``update`` task) and ``scalaVersion`` (the version of scala used to compile the project, in this case used to compile the build definition). ``sbtPluginExtra`` adds the sbt and Scala diff --git a/src/sphinx/Howto/generatefiles.rst b/src/sphinx/Howto/generatefiles.rst index abd8d7b69..057e2c734 100644 --- a/src/sphinx/Howto/generatefiles.rst +++ b/src/sphinx/Howto/generatefiles.rst @@ -9,28 +9,28 @@ sbt provides standard hooks for adding source or resource generation tasks. :title: Generate sources :type: setting - sourceGenerators in Compile <+= + sourceGenerators in Compile += A source generation task should generate sources in a subdirectory of ``sourceManaged`` and return a sequence of files generated. The key to add the task to is called ``sourceGenerators``. It should be scoped according to whether the generated files are main (``Compile``) or test (``Test``) sources. This basic structure looks like: :: - sourceGenerators in Compile <+= + sourceGenerators in Compile += For example, assuming a method ``def makeSomeSources(base: File): Seq[File]``, :: - sourceGenerators in Compile <+= sourceManaged in Compile map { outDir: File => - makeSomeSources(outDir / "demo") - } + sourceGenerators in Compile += + Def.task { makeSomeSources( (sourceManaged in Compile).value / "demo" ) } + As a specific example, the following generates a hello world source file: :: - sourceGenerators in Compile <+= sourceManaged in Compile map { dir => - val file = dir / "demo" / "Test.scala" + sourceGenerators in Compile += Def.task { + val file = (sourceManaged in Compile).value / "demo" / "Test.scala" IO.write(file, """object Test extends App { println("Hi") }""") Seq(file) } @@ -44,33 +44,31 @@ By default, generated sources are not included in the packaged source artifact. :title: Generate resources :type: setting - resourceGenerators in Compile <+= + resourceGenerators in Compile += A resource generation task should generate resources in a subdirectory of ``resourceManaged`` and return a sequence of files generated. The key to add the task to is called ``resourceGenerators``. It should be scoped according to whether the generated files are main (``Compile``) or test (``Test``) resources. This basic structure looks like: :: - resourceGenerators in Compile <+= + resourceGenerators in Compile += For example, assuming a method ``def makeSomeResources(base: File): Seq[File]``, :: - resourceGenerators in Compile <+= resourceManaged in Compile map { outDir: File => - makeSomeResources(outDir / "demo") + resourceGenerators in Compile += Def.task { + makeSomeResources( (resourceManaged in Compile).value / "demo") } As a specific example, the following generates a properties file containing the application name and version: :: - resourceGenerators in Compile <+= - (resourceManaged in Compile, name, version) map { (dir, n, v) => - val file = dir / "demo" / "myapp.properties" - val contents = "name=%s\nversion=%s".format(n,v) + resourceGenerators in Compile += { + val file = (resourceManaged in Compile).value / "demo" / "myapp.properties" + val contents = "name=%s\nversion=%s".format(name.value,version.value) IO.write(file, contents) Seq(file) - } } Change ``Compile`` to ``Test`` to make it a test resource. Normally, you would only want to generate resources when necessary and not every run. diff --git a/src/sphinx/Howto/inspect.rst b/src/sphinx/Howto/inspect.rst index 262334794..94a83b039 100644 --- a/src/sphinx/Howto/inspect.rst +++ b/src/sphinx/Howto/inspect.rst @@ -75,15 +75,15 @@ the dependencies of a task/setting as well as the tasks/settings that depend on > inspect test:compile ... [info] Dependencies: - [info] test:compile::compile-inputs + [info] test:compile::compileInputs [info] test:compile::streams [info] Reverse dependencies: - [info] test:defined-test-names - [info] test:defined-sbt-plugins - [info] test:print-warnings - [info] test:discovered-main-classes - [info] test:defined-tests - [info] test:exported-products + [info] test:definedTestNames + [info] test:definedSbtPlugins + [info] test:printWarnings + [info] test:discoveredMainClasses + [info] test:definedTests + [info] test:exportedProducts [info] test:products ... @@ -104,13 +104,13 @@ For example, > inspect tree clean [info] *:clean = Task[Unit] - [info] +-*:clean-files = List(/lib_managed, /target) - [info] | +-{.}/*:managed-directory = lib_managed + [info] +-*:cleanFiles = List(/lib_managed, /target) + [info] | +-{.}/*:managedDirectory = lib_managed [info] | +-*:target = target - [info] | +-*:base-directory = - [info] | +-*:this-project = Project(id: demo, base: , ... + [info] | +-*:baseDirectory = + [info] | +-*:thisProject = Project(id: demo, base: , ... [info] | - [info] +-*:clean-keep-files = List(/target/.history) + [info] +-*:cleanKeepFiles = List(/target/.history) [info] +-*:history = Some(/target/.history) ... @@ -140,7 +140,7 @@ For example: .. code-block:: console - > inspect scala-version + > inspect scalaVersion [info] Setting: java.lang.String = 2.9.2 [info] Description: [info] The version of Scala used for building. @@ -170,13 +170,13 @@ for testing and API documentation generation. .. code-block:: console - > inspect scalac-options + > inspect scalacOptions ... [info] Related: - [info] compile:doc::scalac-options - [info] test:scalac-options - [info] */*:scalac-options - [info] test:doc::scalac-options + [info] compile:doc::scalacOptions + [info] test:scalacOptions + [info] */*:scalacOptions + [info] test:doc::scalacOptions See the :doc:`/Detailed-Topics/Inspecting-Settings` page for details. @@ -277,11 +277,11 @@ which does not execute a task and thus can only display its type and not its gen :title: Show the classpath used for compilation or testing :type: command - show compile:dependency-classpath + show compile:dependencyClasspath .. code-block:: console - > show compile:dependency-classpath + > show compile:dependencyClasspath ... [info] ArrayBuffer(Attributed(~/.sbt/0.12.0/boot/scala-2.9.2/lib/scala-library.jar)) @@ -289,7 +289,7 @@ For the test classpath, .. code-block:: console - > show test:dependency-classpath + > show test:dependencyClasspath ... [info] ArrayBuffer(Attributed(~/code/sbt.github.com/target/scala-2.9.2/classes), Attributed(~/.sbt/0.12.0/boot/scala-2.9.2/lib/scala-library.jar), Attributed(~/.ivy2/cache/junit/junit/jars/junit-4.8.2.jar)) @@ -298,15 +298,15 @@ For the test classpath, :title: Show the main classes detected in a project :type: command - show compile:discovered-main-classes + show compile:discoveredMainClasses -sbt detects the classes with public, static main methods for use by the ``run`` method and to tab-complete the ``run-main`` method. -The ``discovered-main-classes`` task does this discovery and provides as its result the list of class names. +sbt detects the classes with public, static main methods for use by the ``run`` method and to tab-complete the ``runMain`` method. +The ``discoveredMainClasses`` task does this discovery and provides as its result the list of class names. For example, the following shows the main classes discovered in the main sources: .. code-block:: console - > show compile:discovered-main-classes + > show compile:discoveredMainClasses ... ... [info] List(org.example.Main) @@ -315,14 +315,14 @@ For example, the following shows the main classes discovered in the main sources :title: Show the test classes detected in a project :type: command - show defined-test-names + show definedTestNames sbt detects tests according to fingerprints provided by test frameworks. -The ``defined-test-names`` task provides as its result the list of test names detected in this way. +The ``definedTestNames`` task provides as its result the list of test names detected in this way. For example, .. code-block:: console - > show test:defined-test-names + > show test:definedTestNames ... < runs test:compile if out of date > ... [info] List(org.example.TestA, org.example.TestB) diff --git a/src/sphinx/Howto/interactive.rst b/src/sphinx/Howto/interactive.rst index f21881dd7..a9468022c 100644 --- a/src/sphinx/Howto/interactive.rst +++ b/src/sphinx/Howto/interactive.rst @@ -9,7 +9,7 @@ By default, sbt's interactive mode is started when no commands are provided on t :title: Use tab completion :type: command - test-only + testOnly As the name suggests, tab completion is invoked by hitting the tab key. Suggestions are provided that can complete the text entered to the left of the current cursor position. @@ -33,14 +33,14 @@ To get further completions, hit tab again: .. code-block:: console > test - test-frameworks test-listeners test-loader test-only test-options test: + testFrameworks testListeners testLoader testOnly testOptions test: Now, there is more than one possibility for the next character, so sbt prints the available options. -We will select ``test-only`` and get more suggestions by entering the rest of the command and hitting tab twice: +We will select ``testOnly`` and get more suggestions by entering the rest of the command and hitting tab twice: .. code-block:: console - > test-only + > testOnly -- sbt.DagSpecification sbt.EmptyRelationTest sbt.KeyTest sbt.RelationTest sbt.SettingsTest The first tab inserts an unambiguous space and the second suggests names of tests to run. @@ -64,14 +64,14 @@ Some commands have different levels of completion. Hitting tab multiple times i :title: Show JLine keybindings :type: commands - > console-quick + > consoleQuick scala> :keybindings -Both the Scala and sbt command prompts use JLine for interaction. The Scala REPL contains a ``:keybindings`` command to show many of the keybindings used for JLine. For sbt, this can be used by running one of the ``console`` commands (``console``, ``console-quick``, or ``console-project``) and then running ``:keybindings``. For example: +Both the Scala and sbt command prompts use JLine for interaction. The Scala REPL contains a ``:keybindings`` command to show many of the keybindings used for JLine. For sbt, this can be used by running one of the ``console`` commands (``console``, ``consoleQuick``, or ``consoleProject``) and then running ``:keybindings``. For example: .. code-block:: console - > console-project + > consoleProject [info] Starting scala interpreter... ... scala> :keybindings @@ -140,7 +140,7 @@ search history backwards. The following commands are supported: :title: Change the location of the interactive history file :type: setting - historyPath <<= baseDirectory(t => Some(t / ".history")) + historyPath := Some( baseDirectory.value / ".history" ) By default, interactive history is stored in the ``target/`` directory for the current project (but is not removed by a ``clean``). History is thus separate for each subproject. @@ -149,7 +149,7 @@ For example, history can be stored in the root directory for the project instead :: - historyPath <<= baseDirectory(t => Some(t / ".history")) + historyPath := Some(baseDirectory.value / ".history") The history path needs to be set for each project, since sbt will use the value of ``historyPath`` for the current project (as selected by the ``project`` command). @@ -159,7 +159,7 @@ The history path needs to be set for each project, since sbt will use the value :title: Use the same history for all projects :type: setting - historyPath <<= (target in LocalRootProject) { t => Some(t / ".history") } + historyPath := Some( (target in LocalRootProject).value / ".history" ) The previous section describes how to configure the location of the history file. This setting can be used to share the interactive history among all projects in a build instead of using a different history for each project. @@ -167,10 +167,8 @@ The way this is done is to set ``historyPath`` to be the same file, such as a fi :: - historyPath <<= - (target in LocalRootProject) { t => - Some(t / ".history") - } + historyPath := + Some( (target in LocalRootProject).value / ".history") The ``in LocalRootProject`` part means to get the output directory for the root project for the build. diff --git a/src/sphinx/Howto/logging.rst b/src/sphinx/Howto/logging.rst index 6dd57a142..ca9298e29 100644 --- a/src/sphinx/Howto/logging.rst +++ b/src/sphinx/Howto/logging.rst @@ -51,8 +51,8 @@ The details of this execution can be recalled by running ``last``: [debug] Classpath: [debug] /tmp/e/target/scala-2.9.2/classes [debug] /tmp/e/.sbt/0.12.0/boot/scala-2.9.2/lib/scala-library.jar - [debug] Waiting for thread run-main to exit - [debug] Thread run-main exited. + [debug] Waiting for thread runMain to exit + [debug] Thread runMain exited. [debug] Interrupting remaining threads (should be all daemons). [debug] Sandboxed run complete.. [debug] Exited with code 0 @@ -113,7 +113,7 @@ and: :title: Show warnings from the previous compilation :type: command - print-warnings + printWarnings The Scala compiler does not print the full details of warnings by default. Compiling code that uses the deprecated ``error`` method from Predef might generate the following output: @@ -126,13 +126,13 @@ Compiling code that uses the deprecated ``error`` method from Predef might gener [warn] one warning found The details aren't provided, so it is necessary to add ``-deprecation`` to the options passed to the compiler (``scalacOptions``) and recompile. -An alternative when using Scala 2.10 and later is to run ``print-warnings``. +An alternative when using Scala 2.10 and later is to run ``printWarnings``. This task will display all warnings from the previous compilation. For example, .. code-block:: console - > print-warnings + > printWarnings [warn] A.scala:2: method error in object Predef is deprecated: Use sys.error(message) instead [warn] def x = error("Failed.") [warn] ^ @@ -176,9 +176,9 @@ To enable debug logging for all tasks in the current project, A common scenario is that after running a task, you notice that you need more information than was shown by default. A ``logLevel`` based solution typically requires changing the logging level and running a task again. However, there are two cases where this is unnecessary. -First, warnings from a previous compilation may be displayed using ``print-warnings`` for the main sources or ``test:print-warnings`` for test sources. +First, warnings from a previous compilation may be displayed using ``printWarnings`` for the main sources or ``test:printWarnings`` for test sources. Second, output from the previous execution is available either for a single task or for in its entirety. -See the section on `print-warnings <#printwarnings>`_ and the sections on `previous output <#last>`_. +See the section on `printWarnings <#printwarnings>`_ and the sections on `previous output <#last>`_. .. howto:: @@ -252,10 +252,11 @@ The new function prepends our custom logger to the ones provided by the old func :title: Log messages in a task The special task ``streams`` provides per-task logging and I/O via a `Streams <../../api/#sbt.std.Streams>`_ instance. -To log, a task maps the ``streams`` task and uses its ``log`` member: +To log, a task uses the ``log`` member from the ``streams`` task: :: - myTask <<= (..., streams) map { (..., s) => - s.log.warn("A warning.") + myTask := { + val log = streams.value.log + log.warn("A warning.") } diff --git a/src/sphinx/Howto/package.rst b/src/sphinx/Howto/package.rst index 534b09c58..9472d7db8 100644 --- a/src/sphinx/Howto/package.rst +++ b/src/sphinx/Howto/package.rst @@ -68,15 +68,15 @@ The ``artifactName`` setting controls the name of generated packages. See the : :title: Modify the contents of the package :type: setting - mappings in (Compile, packageBin) <+= - baseDirectory { dir => ( dir / "example.txt") -> "out/example.txt" } + mappings in (Compile, packageBin) += + { ( baseDirectory.value / "example.txt") -> "out/example.txt" } The contents of a package are defined by the ``mappings`` task, of type ``Seq[(File,String)]``. The ``mappings`` task is a sequence of mappings from a file to include in the package to the path in the package. See :doc:`/Detailed-Topics/Mapping-Files` for convenience functions for generating these mappings. For example, to add the file ``in/example.txt`` to the main binary jar with the path "out/example.txt", :: - mappings in (Compile, packageBin) <+= baseDirectory { base => - (base / "in" / "example.txt") -> "out/example.txt" + mappings in (Compile, packageBin) += { + (baseDirectory.value / "in" / "example.txt") -> "out/example.txt" } Note that ``mappings`` is scoped by the configuration and the specific package task. For example, the mappings for the test source package are defined by the ``mappings in (Test, packageSrc)`` task. diff --git a/src/sphinx/Howto/runningcommands.rst b/src/sphinx/Howto/runningcommands.rst index 95dd52347..d6949d0b8 100644 --- a/src/sphinx/Howto/runningcommands.rst +++ b/src/sphinx/Howto/runningcommands.rst @@ -7,7 +7,7 @@ :title: Pass arguments to a command or task in batch mode :type: batch - clean "test-only org.example.Test" "run-main demo.Main a b c" + clean "testOnly org.example.Test" "runMain demo.Main a b c" sbt interprets each command line argument provided to it as a command together with the command's arguments. Therefore, to run a command that takes arguments in batch mode, quote the command and its arguments. diff --git a/src/sphinx/Howto/scala.rst b/src/sphinx/Howto/scala.rst index 605034f73..9f2ad0b2c 100644 --- a/src/sphinx/Howto/scala.rst +++ b/src/sphinx/Howto/scala.rst @@ -67,13 +67,13 @@ Defining the ``scalaHome`` setting with the path to the Scala home directory wil See :doc:`cross building `. .. howto:: - :id: console-quick + :id: consoleQuick :title: Enter the Scala REPL with a project's dependencies on the classpath, but not the compiled project classes :type: command - console-quick + consoleQuick -The ``console-quick`` action retrieves dependencies and puts them on the classpath of the Scala REPL. The project's sources are not compiled, but sources of any source dependencies are compiled. To enter the REPL with test dependencies on the classpath but without compiling test sources, run ``test:console-quick``. This will force compilation of main sources. +The ``consoleQuick`` action retrieves dependencies and puts them on the classpath of the Scala REPL. The project's sources are not compiled, but sources of any source dependencies are compiled. To enter the REPL with test dependencies on the classpath but without compiling test sources, run ``test:consoleQuick``. This will force compilation of main sources. .. howto:: :id: console @@ -85,17 +85,17 @@ The ``console-quick`` action retrieves dependencies and puts them on the classpa The ``console`` action retrieves dependencies and compiles sources and puts them on the classpath of the Scala REPL. To enter the REPL with test dependencies and compiled test sources on the classpath, run ``test:console``. .. howto:: - :id: console-project + :id: consoleProject :title: Enter the Scala REPL with plugins and the build definition on the classpath :type: command - console-project + consoleProject .. code-block:: console - > console-project + > consoleProject -For details, see the :doc:`console-project ` page. +For details, see the :doc:`consoleProject ` page. .. howto:: :id: initial @@ -104,20 +104,20 @@ For details, see the :doc:`console-project ` p initialCommands in console := """println("Hi!")""" -Set ``initialCommands in console`` to set the initial statements to evaluate when ``console`` and ``console-quick`` are run. To configure ``console-quick`` separately, use ``initialCommands in consoleQuick``. +Set ``initialCommands in console`` to set the initial statements to evaluate when ``console`` and ``consoleQuick`` are run. To configure ``consoleQuick`` separately, use ``initialCommands in consoleQuick``. For example, :: initialCommands in console := """println("Hello from console")""" - initialCommands in consoleQuick := """println("Hello from console-quick")""" + initialCommands in consoleQuick := """println("Hello from consoleQuick")""" -The ``console-project`` command is configured separately by ``initialCommands in consoleProject``. It does not use the value from ``initialCommands in console`` by default. For example, +The ``consoleProject`` command is configured separately by ``initialCommands in consoleProject``. It does not use the value from ``initialCommands in console`` by default. For example, :: - initialCommands in consoleProject := """println("Hello from console-project")""" + initialCommands in consoleProject := """println("Hello from consoleProject")""" .. howto:: diff --git a/src/sphinx/Howto/triggered.rst b/src/sphinx/Howto/triggered.rst index 579106ada..a2c3e4b6d 100644 --- a/src/sphinx/Howto/triggered.rst +++ b/src/sphinx/Howto/triggered.rst @@ -9,7 +9,7 @@ ~ test -You can make a command run when certain files change by prefixing the command with ``~``. Monitoring is terminated when ``enter`` is pressed. This triggered execution is configured by the ``watch`` setting, but typically the basic settings ``watch-sources`` and ``poll-interval`` are modified as described in later sections. +You can make a command run when certain files change by prefixing the command with ``~``. Monitoring is terminated when ``enter`` is pressed. This triggered execution is configured by the ``watch`` setting, but typically the basic settings ``watchSources`` and ``pollInterval`` are modified as described in later sections. The original use-case for triggered execution was continuous compilation: @@ -19,11 +19,11 @@ The original use-case for triggered execution was continuous compilation: > ~ compile -You can use the triggered execution feature to run any command or task, however. The following will poll for changes to your source code (main or test) and run ``test-only`` for the specified test. +You can use the triggered execution feature to run any command or task, however. The following will poll for changes to your source code (main or test) and run ``testOnly`` for the specified test. :: - > ~ test-only example.TestA + > ~ testOnly example.TestA .. howto:: :id: multi @@ -45,7 +45,7 @@ This runs ``a`` and then ``b`` when sources change. :title: Configure the sources that are checked for changes :type: setting - watchSources <+= baseDirectory { _ / "examples.txt" } + watchSources += baseDirectory.value / "examples.txt" * ``watchSources`` defines the files for a single project that are monitored for changes. By default, a project watches resources and Scala and Java sources. * ``watchTransitiveSources`` then combines the ``watchSources`` for the current project and all execution and classpath dependencies (see :doc:`/Getting-Started/Full-Def` for details on inter-project dependencies). @@ -54,7 +54,7 @@ To add the file ``demo/example.txt`` to the files to watch, :: - watchSources <+= baseDirectory { _ / "demo" / "examples.txt" } + watchSources += baseDirectory.value / "demo" / "examples.txt" .. howto:: :id: interval diff --git a/src/sphinx/Name-Index.rst b/src/sphinx/Name-Index.rst index 14c36418b..84cd997f4 100644 --- a/src/sphinx/Name-Index.rst +++ b/src/sphinx/Name-Index.rst @@ -98,16 +98,13 @@ Settings and Tasks See the :doc:`Getting Started Guide ` for details. -- ``:=``, ``<<=``, ``+=``, ``++=``, ``~=``, ``<+=``, ``<++=`` These - construct a - `Setting <../api/sbt/Init$Setting.html>`_, +- ``:=``, ``+=``, ``++=``, ``~=`` These + construct a `Setting <../api/sbt/Init$Setting.html>`_, which is the fundamental type in the :doc:`settings ` system. -- ``map`` This defines a task initialization that uses other tasks or - settings. See :doc:`more about settings `. - It is a common name used for many other types in Scala, such as collections. -- ``apply`` This defines a setting initialization using other settings. - It is not typically written out. See :doc:`more about settings `. - This is a common name in Scala. +- ``value`` This uses the value of another setting or task in the definition of a new setting or task. + This method is special (it is a macro) and cannot be used except in the argument of one of the setting + definition methods above (``:=``, ...) or in the standalone construction methods ``Def.setting`` and ``Def.task``. + See :doc:`more about settings ` for details. - ``in`` specifies the `Scope <../api/sbt/Scope.html>`_ or part of the `Scope <../api/sbt/Scope.html>`_ of a setting being referenced. See :doc:`scopes `. diff --git a/src/sphinx/faq.rst b/src/sphinx/faq.rst index 024ec776e..7f1ba2438 100644 --- a/src/sphinx/faq.rst +++ b/src/sphinx/faq.rst @@ -88,8 +88,8 @@ The following commands work pretty much as in 0.7 out of the box: update compile test - test-only - publish-local + testOnly + publishLocal exit Why have the resolved dependencies in a multi-module project changed since 0.7? @@ -233,7 +233,7 @@ You may run ``sbt console``. Build definitions ----------------- -What are the ``:=``, ``~=``, ``<<=``, ``+=``, ``++=``, ``<+=``, and ``<++=`` methods? +What are the ``:=``, ``+=``, ``++=```, and ``~=`` methods? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ These are methods on keys used to construct a ``Setting``. The Getting @@ -256,34 +256,6 @@ Also try the :doc:`index ` of commonly used methods, values, and ty the `API Documentation <../api/index>`_ and the `hyperlinked sources <../sxr/index>`_. -How can one key depend on multiple other keys? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -See :doc:`More About Settings ` in the -Getting Started Guide, scroll down to the discussion of ``<<=`` with -multiple keys. - -Briefly: You need to use a tuple rather than a single key by itself. -Scala's syntax for a tuple is with parentheses, like ``(a, b, c)``. - -If you're creating a value for a task key, then you'll use ``map``: - -:: - - packageBin in Compile <<= (name, organization, version) map { (n, o, v) => file(o + "-" + n + "-" + v + ".jar") } - -If you're creating a value for a setting key, then you'll use ``apply``: - -:: - - name <<= (name, organization, version) apply { (n, o, v) => "project " + n + " from " + o + " version " + v } - -Typing ``apply`` is optional in that code, since Scala treats any object -with an ``apply`` method as a function. See :doc:`More About Settings ` -for a longer explanation. - -To learn about task keys vs. setting keys, read :doc:`.sbt build definition `. - How do I add files to a jar package? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -326,15 +298,15 @@ basic structure looks like: :: - sourceGenerators in Compile <+= + sourceGenerators in Compile += For example, assuming a method ``def makeSomeSources(base: File): Seq[File]``, :: - sourceGenerators in Compile <+= sourceManaged in Compile map { outDir: File => - makeSomeSources(outDir / "demo") + sourceGenerators in Compile += Def.task { + makeSomeSources( (sourceManaged in Compile).value / "demo") } As a specific example, the following generates a hello world source @@ -342,8 +314,8 @@ file: :: - sourceGenerators in Compile <+= sourceManaged in Compile map { dir => - val file = dir / "demo" / "Test.scala" + sourceGenerators in Compile += Def.task { + val file = (sourceManaged in Compile) / "demo" / "Test.scala" IO.write(file, """object Test extends App { println("Hi") }""") Seq(file) } @@ -374,16 +346,15 @@ is: // define a task that takes some inputs // and generates files in an output directory - myTask <<= (cacheDirectory, inputs, target) map { - (cache: File, inFiles: Seq[File], outDir: File) => + myTask := { // wraps a function taskImpl in an uptodate check // taskImpl takes the input files, the output directory, // generates the output files and returns the set of generated files - val cachedFun = FileFunction.cached(cache / "my-task") { (in: Set[File]) => - taskImpl(in, outDir) : Set[File] + val cachedFun = FileFunction.cached(cacheDirectory.value / "my-task") { (in: Set[File]) => + taskImpl(in, target.value) : Set[File] } // Applies the cached function to the inputs files - cachedFun(inFiles) + cachedFun(inputs.value) } There are two additional arguments for the first parameter list that @@ -435,50 +406,16 @@ to ``samples``: :: samples:run - samples:run-main + samples:runMain samples:compile samples:console - samples:console-quick - samples:scalac-options - samples:full-classpath + samples:consoleQuick + samples:scalacOptions + samples:fullClasspath samples:package - samples:package-src + samples:packageSrc ... -Example of adding a new configuration -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -``project/Sample.scala`` - -:: - - import sbt._ - import Keys._ - - object Sample extends Build { - // defines a new configuration "samples" that will delegate to "compile" - lazy val Samples = config("samples") extend(Compile) - - // defines the project to have the "samples" configuration - lazy val p = Project("p", file(".")) - .configs(Samples) - .settings(sampleSettings : _*) - - def sampleSettings = - // adds the default compile/run/... tasks in "samples" - inConfig(Samples)(Defaults.configSettings) ++ - Seq( - // (optional) makes "test:compile" depend on "samples:compile" - compile in Test <<= compile in Test dependsOn (compile in Samples) - ) ++ - // (optional) declare that the samples binary and - // source jars should be published - publishArtifact(packageBin) ++ - publishArtifact(packageSrc) - - def publishArtifact(task: TaskKey[File]): Seq[Setting[_]] = - addArtifact(artifact in (Samples, task), task in Samples).settings - } How do I add a test configuration? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -498,7 +435,7 @@ A basic run task is created by: :: // this lazy val has to go in a full configuration - lazy val myRunTask = TaskKey[Unit]("my-run-task") + lazy val myRunTask = TaskKey[Unit]("myRunTask") // this can go either in a `build.sbt` or the settings member // of a Project in a full configuration @@ -509,7 +446,7 @@ file): :: - fullRunTask(TaskKey[Unit]("my-run-task"), Test, "foo.Foo", "arg1", "arg2") + fullRunTask(TaskKey[Unit]("myRunTask"), Test, "foo.Foo", "arg1", "arg2") If you want to be able to supply arguments on the command line, replace ``TaskKey`` with ``InputKey`` and ``fullRunTask`` with @@ -537,10 +474,10 @@ delegate to ``aRun`` :: - val aRun = TaskKey[Unit]("a-run", "A run task.") + val aRun = TaskKey[Unit]("aRun", "A run task.") // The last parameter to TaskKey.apply here is a repeated one - val myRun = TaskKey[Unit]("my-run", "Custom run task.", aRun) + val myRun = TaskKey[Unit]("myRun", "Custom run task.", aRun) In use, this looks like: @@ -593,16 +530,16 @@ the following are settings that implement #2-#4: "net.sf.proguard" % "proguard" % "4.4" % ProguardConfig.name // Extract the dependencies from the UpdateReport. - managedClasspath in proguard <<= - (classpathTypes in proguard, update) map { (ct, report) => - Classpaths.managedJars(proguardConfig, ct, report) - } + managedClasspath in proguard := + Classpaths.managedJars(proguardConfig, (classpathTypes in proguard).value, update.value) + } // Use the dependencies in a task, typically by putting them // in a ClassLoader and reflectively calling an appropriate // method. - proguard <<= managedClasspath in proguard { (cp: Seq[File] => - // ... do something with 'cp', which includes proguard ... + proguard := { + val cp: Seq[File] = (managedClasspath in proguard).value + // ... do something with , which includes proguard ... } How would I change sbt's classpath dynamically? @@ -684,7 +621,7 @@ has been loaded and prints that number: { // the key for the current count - val key = AttributeKey[Int]("load-count") + val key = AttributeKey[Int]("loadCount") // the State transformer val f = (s: State) => { val previous = s get key getOrElse 0 @@ -697,113 +634,12 @@ has been loaded and prints that number: Errors ------ -Type error, found: ``Initialize[Task[String]]``, required: ``Initialize[String]`` or found: ``TaskKey[String]`` required: ``Initialize[String]`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This means that you are trying to supply a task when defining a setting -key. See :doc:`.sbt build definition ` for the -difference between task and setting keys, and -:doc:`more about settings ` -for more on how to define one key in terms of other keys. - -Setting keys are only evaluated once, on project load, while tasks are -evaluated repeatedly. Defining a setting in terms of a task does not -make sense because tasks must be re-evaluated every time. - -One way to get a task when you didn't want one is to use the ``map`` -method instead of the ``apply`` method. -:doc:`More about settings ` covers this topic as well. - -Suppose we define these keys, in ``./project/Build.scala`` (For details, -see :doc:/`.scala build definition `). - -:: - - val baseSetting = SettingKey[String]("base-setting") - val derivedSetting = SettingKey[String]("derived-setting") - val baseTask = TaskKey[Long]("base-task") - val derivedTask = TaskKey[String]("derived-task") - -Let's define an initialization for ``base-setting`` and ``base-task``. -We will then use these as inputs to other setting and task -initializations. - -:: - - baseSetting := "base setting" - - baseTask := { System.currentTimeMillis() } - -Then this will not work: - -:: - - // error: found: Initialize[Task[String]], required: Initialize[String] - derivedSetting <<= baseSetting.map(_.toString), - derivedSetting <<= baseTask.map(_.toString), - derivedSetting <<= (baseSetting, baseTask).map((a, b) => a.toString + b.toString), - -One or more settings can be used as inputs to initialize another -setting, using the ``apply`` method. - -:: - - derivedSetting <<= baseSetting.apply(_.toString) - - derivedSetting <<= baseSetting(_.toString) - - derivedSetting <<= (baseSetting, baseSetting)((a, b) => a.toString + b.toString) - -Both settings and tasks can be used to initialize a task, using the -``map`` method. - -:: - - derivedTask <<= baseSetting.map(_.toString) - - derivedTask <<= baseTask.map(_.toString) - - derivedTask <<= (baseSetting, baseTask).map((a, b) => a.toString + b.toString) - -But, it is a compile time error to use ``map`` to initialize a setting: - -:: - - // error: found: Initialize[Task[String]], required: Initialize[String] - derivedSetting <<= baseSetting.map(_.toString), - derivedSetting <<= baseTask.map(_.toString), - derivedSetting <<= (baseSetting, baseTask).map((a, b) => a.toString + b.toString), - -It is not allowed to use a task as input to a settings initialization -with ``apply``: - -:: - - // error: value apply is not a member of TaskKey[Long] - derivedSetting <<= baseTask.apply(_.toString) - - // error: value apply is not a member of TaskKey[Long] - derivedTask <<= baseTask.apply(_.toString) - - // error: value apply is not a member of (sbt.SettingKey[String], sbt.TaskKey[Long]) - derivedTask <<= (baseSetting, baseTask).apply((a, b) => a.toString + b.toString) - -Finally, it is not directly possible to use ``apply`` to initialize a -task. - -:: - - // error: found String, required Task[String] - derivedTask <<= baseSetting.apply(_.toString) - On project load, "Reference to uninitialized setting" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Setting initializers are executed in order. If the initialization of a setting depends on other settings that has not been initialized, sbt -will stop loading. This can happen using ``+=``, ``++=``, ``<<=``, -``<+=``, ``<++=``, and ``~=``. (To understand those methods, -:doc:`read this `.) +will stop loading. In this example, we try to append a library to ``libraryDependencies`` before it is initialized with an empty sequence. @@ -837,13 +673,13 @@ A more subtle variation of this error occurs when using :doc:`scoped settings