sbt/main/src/test
Ethan Atkins 3319423369 Add full support for managing file task io
This commit unifies my previous work for automatically watching the
input files for a task with support for automatically tracking and
cleaning up the output files of a task. The big idea is that users may
want to define tasks that depend on the file outputs of other tasks and
we may not want to run the dependent tasks if the output files of the
parent tasks are unmodified.

For example, suppose we wanted to make a plugin for managing typescript
files. There may be, say, two tasks with the following inputs and
outputs:

compileTypescript = taskKey[Unit]("shells out to compile typescript files")
  fileInputs -- sourceDirectory / ** / "*.ts"
  fileOutputs -- target / "generated-js" / ** / "*.js"

minifyGeneratedJS = taskKey[Path]("minifies the js files generated by compileTypescript to a single combined js file.")
  dependsOn: compileTypeScript / fileOutputs

Given a clean build, the following should happen
> minifyGeneratedJS
// compileTypescript is run
// minifyGeneratedJS is run

> minifyGeneratedJS
// no op because nothing changed

> minifyGeneratedJS / clean
// removes the file returned by minifyGeneratedJS.previous

> minifyGeneratedJS
// re-runs minifyGeneratedJS with the previously compiled js artifacts

> compileTypescript / clean
// removes the generated js files

> minifyGeneratedJS
// compileTypescript is run because the previous clean removed the generated js files
// minifyGeneratedJS runs because the artifacts have changed

> clean
// removes the generated js files and the minified js file

> minifyGeneratedJS
// compileTypescript is run because the generated js files were
// minifyGeneratedJS is run both because it was removed and

Moreover, if compileTypescript fails, we want minifyGeneratedJS to fail
as well.

This commit makes this all possible. It adds a number of tasks to
sbt.nio.Keys that deal with the output files. When injecting settings, I
now identify all tasks that return Seq[File], File, Seq[Path] and Path
and create a hidden special task: dynamicFileOutputs: TaskKey[Seq[Path]]
This special task runs the underlying task and converts the result to
Seq[Path]. From there, we can have the tasks like changedOutputPaths
delegate to dynamicFileOutputs which, by proxy, runs the underlying
task. If any task in the input / output chain fails, the entire sequence
fails.

Unlike the fileInputs, we do not register the dynamicFileOutputs or
fileOutputs with continuous watch service so these paths will not
trigger a continuous build if they are modified. Only explicit unmanaged
input sources should should do that.

As part of this, I also added automatic generation of a custom clean task for
any task that returns Seq[File], File, Seq[Path] or Path. I also added
aggregation so that clean can be defined in a configuration or project
and it will automatically run clean for all of the tasks that have a
custom clean implementation in that task or project. The automatic clean
task will only delete files that are in the task target directory to
avoid accidentally deleting unmanaged files.
2019-05-02 14:36:08 -07:00
..
resources Use Scala 2.12.1 2017-01-15 20:49:14 -05:00
scala Add full support for managing file task io 2019-05-02 14:36:08 -07:00