gnatsetup
gnatsetup
is a command-line tool that can download and install AdaCore
binary packages. It is designed to be used in conjunction with a manifest
file that describes the set of packages to install.
gnatsetup
is intended to help with the deployment of work environments, typically
in the context of DevOps (CI/CD pipelines, Docker images, etc.) and can be used to
set up a local environment for a developer.
One key feature of gnatsetup
is that it can be extended to integrate into
custom networks and workflows, typically to be able to download packages from a
private registry.
Prerequisites
gnatsetup
requires Python 3.8 or later.
Installation
On Linux: to install gnatsetup, unpack the package using:
tar xzf gnatsetup-<version>.tar.gz
In the directory of your choice, then place <prefix>/bin
in your PATH
.
Usage
The gnatsetup
command line works as follow: some optional parameters,
followed by a command parameter, followed optionally by parameters that
apply to that command.
The following global options are supported:
--help
: print a help message and exit.--manifest <FILE>
: specify an alternate manifest file to use. In the absence of this, the manifest file isgnatsetup.toml
in the current directory.--prefix <DIR>
: specify an alternate installation prefix. In the absence of this, the prefix is read from the manifest file.--root-dir <DIR>
: specify the root directory in whichgnatsetup
will store its internal data, a cache of downloaded packages, and the installed packages. In the absence of this, the root directory is read from the manifest file, defaulting to.gnat
in the user’s home directory.
The following commands are supported:
install
: download and install the packages listed in the manifest file. This supports the following options:package
: the package to install; if this is specified, the manifest file is ignored.version
: the version of the package to install.platform
: the platform for which to install the package, for instancex86_64-linux
oraarch64-linux
.
list-packages
: list the packages available in the manifest file.printenv
: print the environment variables that need to be set to use the installed packages. The output of this is intended to be evaluated by the shell, for instance witheval $(gnatsetup printenv)
.download-packages
: download the packages listed in the manifest file.
Manifest file format
The manifest file is a TOML file which describes the set of packages to install. The syntax is as follows:
######################
# The global section #
######################
# The [variables] and [config] sections contain global settings;
# they are optional.
[variables]
# A place to define custom variables that can be used below.
a_variable = a_value
[config] # Optional: the global configuration section
# The root directory, where the gnatsetup metadata is stored
root_dir = "$(env.GNATSETUP_ROOT_DIR|/home/<user>/.gnat)"
# The default installation prefix for all packages
prefix = "$(root_dir)/install"
# The local cache directory, typically hosting the downloaded packages
cache = "$(root_dir)/cache"
############################
# The dependencies section #
############################
# The [[dependencies]] entries list the packages to install.
# At least one of them is required.
# This represents a specific version of GNATcoll
[[dependencies]]
# The name of the package
name = "gnatcoll"
# The version of the package
version = "20.1"
# This is how to override the default value for the installation prefix
prefix = "/opt/gnatcoll"
# This represents a specific version of GNATcoll Bindings
[[dependencies]]
name = "gnatcoll-bindings"
version = "24.0w-20230224"
prefix = "/opt/gnatcoll-bindings"
platform = "x86_64-linux"
Macro substitutions can be used to provide variability to the manifest file.
The
$(env.<VAR>)
syntax is used to reference an environment variable: the value of the environment variableVAR
will be used, and an error will be raised if the variable is not defined.The
$(env.<VAR>|<value>)
syntax is used to reference an environment variable: the value of the environment variable<VAR>
will be used, and if the variable is not defined, the value<value>
will be used.The
$(<FIELD>)
syntax is used to reference a field defined in the current section of the manifest file.As a special case,
$(MANIFEST_DIR)
is replaced by the directory containing the manifest file.The
$(config.<FIELD>)
syntax is used to reference a field defined in the globalconfig
section of the manifest file.The
$(variable.<FIELD>)
syntax is used to reference a field defined in the globalvariables
section of the manifest file.Inside a macro, the suffix
'slug
can be used to replace all non-alphanumeric characters with-
. For instance$(env.NAME'slug)
will expand tomy-name
if the environment variableNAME
is set tomy name
.
Extending gnatsetup
The mechanism for extending gnatsetup
is through the definition of Python modules
that are loaded dynamically by gnatsetup
and that can define:
How to download packages from a custom location: this is done by implementing a Registry Interface.
How to determine the file name for a package based on a dependency description, and how to install the corresponding packages: this is done by implementing a Recipe.
Predefined recipes and registry interfaces
gnatsetup
is packaged with a set of recipes and registry interfaces that can be used
out of the box. The share/gnatsetup/recipe
directory in the gnatsetup
Installation
contains in particular the following files:
gnatpro.py
: defines Recipes for installing a number of AdaCore packages.
local_folder.py
: defines a Registry Interface that can be used to install packages from a local folder. The folder is provided through theGNATSETUP_CUSTOM_FOLDER
environment variable. The packages are assumed to be available directly in the provided folder.
wget.py
: defines a Registry Interface that can be used to install packages from a custom remote location using thewget
command. Two environment variables are read for this:
GNATSETUP_WGET_URL
: the base URL for the remote location; packages are assumed to be available at<base_url>/<package>
.
GNATSETUP_WGET_HEADERS
: any additional headers to pass towget
.
Feel free to use these for inspiration when writing your own recipes and registry interfaces.
Writing your own recipes and registry interfaces
The API for defining Recipes and Registry Interfaces is described respectively
in recipes.py
and package_registry_interface.py
in the share/gnatsetup/gnatsetup_api
directory of the gnatsetup
installation.
For each, you’ll need to inherit from the base class and implement the required methods. Some methods are optional.
Making your own extensions available to gnatsetup
To make your own extensions available to gnatsetup
, you’ll need to either:
Copy the files to the
share/gnatsetup/recipes
directory of thegnatsetup
installation, orPlace them in a separate folder and point the
GNATSETUP_CUSTOM_RECIPES
environment variable to that folder.