Configuration¶
Roberto uses invoke, amongst other things, to parse its configuration files. For
most projectes, it is sufficient to just write a .roberto.yaml
file in the
root of the project’s source tree. In some cases, environment variables,
prefixed with ROBERTO_
can be useful to extend or override the settings in
the configuration file. All your settings extend the
default configuration file.
Invoke also offers other mechanisms to modify Roberto’s configuration, which is explained here: http://docs.pyinvoke.org/
Basic configuration¶
The configuration file must at least contain the following:
project:
# 'name' is used for package and directory names.
name: your_project_name
# List one or more software packages below.
packages:
# 'dist_name' is required and there is no default value.
# It must be unique in case of multiple package.
- dist_name: 'name_for_distribution_packages'
# An optional package name, must not be unique.
# The default is the project name.
name: 'package_name'
# An optional subdirectory of the source tree.
# Defaults to '.'
path: .
# List one or more tools below.
# Using all tools is probably not sensible
# because some are geared towards CMake
# packages, while others are only
# useful for Python packages.
tools:
- write-py-version
- cardboardlint-static
# ...
# You can add multiple packages.
- dist_name: '...'
# ...
Each tool of each package will be executed in one task in the overall work flow. See section Work flow for a more detailed description. A complete list of the built-in tools and configuration options can be found in the default configuration file.
Other sections can be added as well, e.g. to define new tools as explained below, or to change other settings from default configuration file.
Python example¶
This is a basic configuration for a Python project, e.g. called spammer:
project:
name: spammer
packages:
- dist_name: spammer
tools:
- write-py-version
- cardboardlint-static
- build-py-inplace
- pytest
- upload-codecov
- cardboardlint-dynamic
- build-sphinx-doc
- upload-docs-gh
- build-py-source
- build-conda
- deploy-pypi
- deploy-conda
- deploy-github
This configuration assumes that you have at least the following files in your Git repository:
.cardboardlint.yaml
setup.py
spammer/__init__.py
tools/conda/meta.yaml
CMake and Python wrapper example¶
A basic configuration for a CMake (e.g. C++) project and a Python wrapper, here called bummer can be done as follows:
project:
name: bummer
packages:
- dist_name: bummer
tools:
- write-cmake-version
- cardboardlint-static
- build-cmake-inplace
- maketest
- upload-codecov
- cardboardlint-dynamic
- build-cmake-source
- build-conda
- deploy-conda
- deploy-github
- dist_name: python-bummer
path: python-bummer
tools:
- write-py-version
- cardboardlint-static
- build-py-inplace
- pytest
- upload-codecov
- cardboardlint-dynamic
- build-py-source
- build-conda
- deploy-conda
- deploy-github
This configuration assumes you have at least the following files in your Git repository:
.cardboardlint.yaml
CMakeLists.txt
tools/conda/meta.yaml
python-bummer/setup.py
python-bummer/bummer/__init__.py
python-bummer/tools/conda/meta.yaml
Working with git tag for versions¶
When Roberto starts, it will run git describe --tags
to determine the
version number and add this version information in various forms in the git
section of the
default configuration file.
From there, all tasks
can access version information when they need it. Below the most important of
these tasks are discussed.
Python projects¶
Use the tool write-py-version
to make sure the file _version.py
exists
before setup.py
is called.
In setup.py
, use the following code to derive the version instead of
hard-coding it:
import os NAME = 'spammer' # <-- change this name. def get_version(): """Read __version__ from version.py, with exec to avoid importing it.""" with open(os.path.join(NAME, 'version.py'), 'r') as f: myglobals = {"__name__": f"{NAME}.version"} # pylint: disable=exec-used exec(f.read(), myglobals) return myglobals['__version__'], myglobals['DEV_CLASSIFIER'] VERSION, DEV_CLASSIFIER = get_version_info() setup( name=NAME, version=VERSION, package_dir={NAME: NAME}, packages=[NAME, NAME + '.test'], classifiers=[ DEV_CLASSIFIER, # ... ], # ... )
The file version.py
contains the following
try: # pylint: disable=unused-import from ._version import __version__, DEV_CLASSIFIER except ImportError: __version__ = '0.0.0.post0' DEV_CLASSIFIER = 'Development Status :: 2 - Pre-Alpha'
This is automates all versioning tasks but still works when Roberto has not been used to write the version file.
When the Sphinx documentation is built, one can assume an in-place built has
succeeded and one can simply import the version in doc/conf.py
as follows:
from spammer.version import __version__ # <-- change name spammer # ... release = __version__ version = '.'.join(release.split('.')[:2])
CMake projects¶
With the tool write-cmake-version
, one can generate a file
CMakeListsVersion.txt.in
, which can be included from the main
CMakeLists.txt
file as follows:
include(CMakeListsVersion.txt.in)
Conda package specifications (meta.yaml
)¶
In the file tools/conda.recipe/meta.yaml
, one can make use of Jinja
templating to insert the version number:
package: version: "{{ PROJECT_VERSION }}"
When Roberto sets up a conda environment, environment variable
${PROJECT_VERSION}
will be set.
Adding tools¶
One can add custom tools to the workflow, by adding a tools section to the configuration file:
tools:
<name of the tool>:
cls: <Class name from roberto/tools.py>
# ...
Additional fields can be added after cls
, and the details of these
additional settings depend on the selected cls
.
Filenames and most other fields in the tool settings can make use of
other confiruaton values, e.g. with {config.project.name}
, package-specific
configuration, e.g. {package.dist_name}
, or tool-specific settings, e.g.
{tool.destination}
. These substitutions are not carried out recursively.
The fields in the tool section are (almost) all constructor arguments for a corresponding class in roberto/tools.py. Refer to their docstrings for more details. There are two optional fields not used as constructor arguments:
requirements
: a list of 2-tuples, in which the first string is the conda package name and the second is the pip package name (if available).suported_envs
: present when a tool is only supported by conda, in which case the corresponding value is[conda]
. When not present, the tool is assumed to work for both types of virtual environments.