-
-
Notifications
You must be signed in to change notification settings - Fork 60
Incremental Tasks
Incremental tasks are used in order to improve build performance by skipping jobs which output files are created or updated after the last modification of the corresponding input files.
Tasks with one-to-one correspondence between input and output files are called partial incremental and they normally use the build pattern described in Partial Incremental Tasks. A typical example is conversion of files from one format into another.
Other incremental tasks do not have one-to-one input-output correspondence but they still have input files to be converted into one or more output files. For example input is a set of .cs files and the output is an assembly file (.dll or .exe) built from input.
Here is an incremental task template:
task Name -Inputs ... -Outputs ... [-Jobs] { ... }
or using the alternative task syntax:
task Name @{
Inputs = ...
Outputs = ...
Jobs = { ... }
}
It normally defines at least these three pieces: the inputs and outputs expressions and the script that produces the output files from the input.
It is a list of input file items or paths or a script block which gets them. For example, for all .cs files in the build directory it can be:
task ... -Inputs (Get-Item *.cs) -Outputs ...
or almost the same with a script block:
task ... -Inputs {Get-Item *.cs} -Outputs ...
The main difference between the first and the second is that the first input is evaluated on task creation (always) and the second only on task invocation. If a task is not always invoked then the second form may improve performance. But the first form catches potential issues earlier, before any task is invoked.
A fixed list of known absolute or relative file paths will do as well:
task ... -Inputs Class.cs, AssemblyInfo.cs -Outputs ...
The inputs are finally resolved by the engine into the full paths represented
by the automatic variable $Inputs
. All input files must exist, otherwise the
task fails.
It is a list of output file paths or a script block which gets them. A single file path is allowed, too. Empty output is not allowed.
If any of output items is missing then the task scripts are invoked. Otherwise the engine compares timestamps. If the minimum of outputs is less than the maximum of inputs then the task scripts are invoked.
task ... -Inputs ... -Outputs Library.dll
The script builds the output files from the input files. There are two helper
automatic variables defined: the $Inputs
(array of resolved full input paths)
and the $Outputs
(exactly as it was defined or returned by a script block).
Scripts can but do not have to use them, like in this example:
{
exec { csc /optimize /target:library /out:Library.dll *.cs }
}
Here is the build script with an incremental task combined from the pieces above:
# Use the .NET 4.0 compiler
use 4.0 csc
# Build the Library.dll if it is missing or out-of-date
task Build -Inputs { Get-Item *.cs } -Outputs Library.dll {
exec { csc /optimize /target:library /out:Library.dll *.cs }
}
Inputs and outputs are often not trivial script blocks and normal task syntax may be hard to compose and read. If this is the case use a hashtable to define task parameters in addition to the task name:
# Synopsis: Complex task with parameters as a hashtable.
task TestAndAnalyse @{
If = !$SkipAnalyse
Inputs = {
Get-ChildItem . -Recurse -Include *.ps1, *.psm1
}
Outputs = {
'Analyser.log'
}
Jobs = 'Test', {
Invoke-ScriptAnalyzer . > Analyser.log
}
}
# Synopsis: Simple task with usual parameters.
task Test -If (!$SkipTest) {
Invoke-Pester
}
In some scenarios inputs and outputs are not known but discovered by a script. In this case incremental tasks may be created dynamically for each discovered set, see Tasks/Dynamic.
- Concepts
- Script Tutorial
- Incremental Tasks
- Partial Incremental Tasks
- How Build Works
- Special Variables
- Build Failures
- Build Analysis
- Parallel Builds
- Persistent Builds
- Portable Build Scripts
- Using for Test Automation
- Debugging Tips
- VSCode Tips
Helpers
- Invoke Task from VSCode
- Generate VSCode Tasks
- Invoke Task from ISE
- Resolve MSBuild
- Show Build Trees
- Show Build Graph
- Argument Completers
- Invoke-Build.template
Appendix