How do I...
You can set up default arguments in Configuration files.
(for example, when I have set nested to true/a task/virtualenv/etc in the Dovetail configuration file)
All the Dovetail configuration file options (except clear) can be disabled from the command line:
- Use -nn to disable nesting
- -e '' or --virtualenv '' to disable virtualenv
- dovetail '' will print the list of tasks in the build file (you must include the '' otherwise the default task will run)
Set up a configuration file and set them in the [Environment] section. See configuration-files.
The Dovetail command line process returns the following value as it exits:
0: Successful build/print warranty/print license
- 1: Build failed due to an error in the build, for example:
- Task raising an exception or
- a directive failing a Task (e.g. @fail_if_skipped)
2: Invalid command line options (syntax error)
32-63: Semantic error or environment error in command line options
32: General error; no task specified
33: Invalid build file - it does not exist, is not a Python file or is otherwise invalid
34: Invalid virtual environment specified (doesn’t exist or cannot be created)
35: Invalid Task specified. Doesn’t exist in the build file
254: Bootstrap failure: unable to start dovetail in a virtual environment
255: System failure running build
How do I...
Check if environment variable DOVETAIL_VERSION is set.
Dovetail sets a number of Environment variables that can be interrogated with the Env predicate in a @do_if or @skip_if
How do I...
Dovetail does not support function arguments in tasks.
Instead we recommend passing values between tasks:
- within the same file - use global variables
- between different build files - use environment variables.
Yes - that is a great way of failing the task. Remember to include a descriptive error message. This is discussed in Exception thrown within a task.
You can also build logic into a @fail_if directive, but this will run only after your function has completed.
How do I...
You cannot - it’s a rule in Python that all Python source files must have the .py extension. Since a build file is just a Python script, Dovetail inherits this rule.
Simple answer: The design of the build requires that the entire build occurs in or under the directory of the main build file. This is a design limitation to ensure that all loaded tasks have valid, non-conflicting Python package names.
Complex answer: You can still import python files from the Python system path, and these will be recognized by Dovetail for basic functions. However:
These imports do require that there is an __init__.py file present which make the directory look like package source.
BuildModule (the Dovetail loader) will not load tasks from such files
And therefore, to use functions in the import, you would need to wrap them in a function in the build file that is doing the import, eg:
import my_package @task def imported_task(): return my_package.my_task()
When a build is started, the build root is set in the environment variable DOVETAIL_BUILD_ROOT.
The build may be different from the parent directory of __file__ if the build script is loaded by a master build script (either in the same directory or perhaps in a parent directory). So, given on which script is run, the build root for a given task may be different. Beware!
Just before the main body of a task is run, Dovetail ensures that the current working directory (:func:os.getcwd) is the directory in which the build script is located (__file__).
You can modify this behaviour with the @cwd directive.
Add the directive: @cwd(None)
This tells Dovetail to switch off the working directory functionality for that task.
How do I...
Dovetail has direct support for only the --clear parameter of virtualenv. If you need to pass more specific parameters, you can use one of several techniques documented by virtualenv:
- Environment variables , eg VIRTUALENV_USE_DISTRIBUTE=true is exactly the same as using the --distribute command line option.
- virtualenv.ini configuration file containing the settings.
This is not yet implemented.
Dovetail’s @do_if, @skip_if and @fail_if directives take an optional extra argument - message - for this purpose. For example:
@skip_if(predicate_1, predicate_2, …, message="Zorg application is partially installed")
Alternatively, you can define your own Predicate callable and customize the __str__ method, e.g.:
class ZorgFullyInstalled(object):
def __call__(self):
# Your logic here
def __str__(self):
return "Zorg is installed"
If you want to fail a task, you can throw an exception in the task. However, if you have written your own predicate or directive, there are two types of error condition:
Normal condition: Where the system meets a condition expected by the developer or the predicate or directive, and the predicate or directive can’t continue, but this situation is expected. For example, the directive needs a file in a particular location, but it’s missing.
In this case, call Execution.fail() to mark the task as failed. The current task will be marked as FAILED, and the build will fail in the normal manner.
Do not throw an exception.
Fatal error: Where there is an unexpected exception, that is the developer of the predicate or directive did not know that this condition would happen, by definition it’s not going to be handled. Let this exception propagate. This will cause Dovetail to fail with a system exception as described in Errors in Dovetail or third-party decorators or predicates. Note that, in this case, the post-actions of the task and parent tasks will not be called.