4 KiB
This page provides information for developers.
Tasks
What is a task ?
A task is the basic execution unit in provs. When executed, each task produces exactly one result (line) with either success or failure.
The success or failure is computed automatically in the following way:
- a task fails if it calls subtasks and if at least one subtask has failed
- a taskWithResult works the same except that it requires an additional result to be returned which is also included in the success calculation
- a task defined with optional (i.e.
= optional { /* ... */ }
always returns success (even if there are failing subtasks) - requireLast defines a task which must provide an explicit result and solely this result counts for success calculation
Task declaration
Recommended way
A task can be declared by
fun Prov.myCustomTask() = task { /* ... code and subtasks come here ... */ }
// e.g.
fun Prov.myEchoTask() = task {
cmd("echo hello world!")
}
The task will succeed if all sub-tasks (called tasks during execution) have succeeded resp. if no sub-task was called.
Alternative ways
The following ways are equivalent but are more verbose:
// Redundant declaration of the return type (ProvResult), which is already declared by task
fun Prov.myCustomTask(): ProvResult = task { /* ... code and subtasks come here ... */ }
// Redundant parentheses behind task
fun Prov.myCustomTask() = task() { /* ... code and subtasks come here ... */ }
// Redundant definition of the task name, but could be used to output a different task name
fun Prov.myCustomTask() = task("myCustomTask") { /* ... code and subtasks come here ... */ }
// Functionally equal, but with additional curly brackets
fun Prov.myCustomTask() { task { /* ... code and subtasks come here ... */ } }
Btw, the following lines and WILL NOT work as expected. Due to too much lamda nesting, the code within the task is NOT executed:
fun Prov.myCustomTask() = { task { /* ... code and subtasks come here ... */ } }
fun Prov.myCustomTask() {{ task { /* ... code and subtasks come here ... */ } }}
Add custom results
If you want to add a result explicitly, you can use method addResultToEval
.
This maxy be used e.g. to add explicitly an error line, like in:
fun Prov.myCustomTask() = task {
/* some other code ... */
addResultToEval(ProvResult(false, err = "my error msg"))
/* some other code ... */
}
or alternatively you can use taskWithResult
.
TaskWithResult
In case you want to include the return value (of type ProvResult
) of a task to be added to the evaluation,
you can use taskWithResult
instead of task
and return the value, e.g. like
fun Prov.myEchoTask() = taskWithResult {
cmd("echo hello world!")
// ...
ProvResult(false, "Error: ... error message ...") // will be the returned as return value and included in the evaluation
}
IMPORTANT: the value you want to return must be placed at the end of the lambda code (as usual in functional programming)! The following will NOT work as expected:
fun Prov.myEchoTask() = taskWithResult {
ProvResult(false, "Error: ... error message ...") // will be ignored
// the result from the call below (i.e. from task "cmd") will be returned by myEchoTask,
// which is redundant as its result is already included in the evaluation anyway.
cmd("echo hello world!")
}
Task output
If a task is run e.g. with local().myEchoTask()
, it will produce output like
> Success -- myEchoTask
---> Success -- cmd [/bin/bash, -c, echo hello world!]
Call hierarchy
In the following link you can find an example of a sequence diagram when provisioning a desktop:
Create a provs jar-file
- Clone this repo
- Build the jar-file by
./gradlew uberjarDesktop
- In folder build/libs you'll find the file
provs-desktop.jar
This uberjar is a Java jar-file including all required dependencies.