====== XML Package Definition Files ======
{{:software:valet:valet-icon.png?128 |}}In version 2 of VALET, packages (and their versions) can still be defined in XML files (with an augmented grammar for new features). VALET 2 can use ''.vpkg'' files from version 1 for backward compatibility, but many version 2 features are only available using the newer XML grammar.
VALET package definitions in the XML format use the file extension ''.vpkg'' or ''.vpkg_xml''.
===== Grammar =====
A VALET package is represented in XML as a document with the following overall structure:
:
:
A set of scalar properties can be used both in the ''package'' and ''version'' elements of the configuration. Scalar properties are:
^Element^Value^
|''text...''|Human-readable description of the software package|
|''hyperlink''|A web site documenting the package, for example|
|''path''|A filesystem path containing the package or the version of the package|
|''''|VALET should emit ''LDFLAGS'' and ''CPPFLAGS''|
|''''|VALET should not emit ''LDFLAGS'' and ''CPPFLAGS''|
|''''|VALET should check for standard sub-paths like ''bin'' and ''lib'' under the ''prefix'' directory|
|''''|VALET should not check for standard sub-paths like ''bin'' and ''lib'' under the ''prefix'' directory|
Typically, the package-global ''prefix'' is set to a directory containing each version of the package, and each versioned package defines a ''prefix'' relative to that directory:
$ ls -l /opt/shared/openmpi
total 14
drwxr-sr-x 8 user sysadmin 8 Aug 27 16:10 1.8.2
drwxr-sr-x 8 user sysadmin 8 Aug 27 16:10 1.8.2-gcc-4.8.3
drwxr-sr-x 8 user sysadmin 8 Aug 28 09:26 1.8.2-intel64
drwxrwsr-x 2 user sysadmin 3 Aug 27 17:10 attic
The package's ''prefix'' = ''/opt/shared/openmpi'' and versions would use e.g. ''prefix'' = ''1.8.2-intel64''. If no ''prefix'' is provided for a versioned package, then VALET implicitly uses the version id.
Versioned packages that do not specify the ''development-env'', ''no-development-env'', ''standard-paths'', or ''no-standard-paths'' properties inherit the value of their parent package.
Example:
Gaussian Quantum Chemistry Suite
http://gaussian.com/
/opt/shared/gaussian
g09d01
In this example, version ''g09d01'' has a prefix path of ''/opt/shared/gaussian/g09d01'' since it did not specify a ''prefix''. Version ''g09'' provided a relative path that is appended to the prefix of its parent package to also yield ''/opt/shared/gaussian/g09d01''. Both versions inherit the ''development-env'' and ''standard-paths'' behavior of the parent package.
The full versioned package identifiers available in the ''gaussian'' package defined above would be:
* ''gaussian/g09''
* ''gaussian/g09d01''
Since the ''g09'' version targets the same executables as ''g09d01'', the ''g09'' version can be considered to be an //alias// of ''g09d01''. VALET allows for aliased versions of packages:
Once the overall versioning structure of a package has been created, the environment tests and changes associated with the package and versions of the package can be added. The three kinds of tests/changes are:
|''dependencies''|other packages that must be present or loaded into the environment; environment variable tests that must evaluate to true for configuration to happen|
|''incompatibilities''|other packages that must NOT be present in the environment; environment variable tests that must evaluate to false for configuration to happen|
|''actions''|changes to be made to the environment if all ''dependencies'' and ''incompatibilities'' are satisfied|
If present in the package-global area of the configuration, the tests/changes affect all versions of the package and are satisfied/applied before version-specific ''dependencies''/''incompatibilities'' and ''actions''.
Example:
Gaussian Quantum Chemistry Suite
http://gaussian.com/
/opt/shared/gaussian
GAUSS_SCRDIR
not-is-set
If GAUSS_SCRDIR is not set, the working directory will be used; you do not want that.
G09
Given the package definition above, typing ''vpkg_require gaussian/g09'' yields the following course of events:
- ''g09'' is an alias to ''g09d01'', so version ''g09d01'' becomes the target versioned package being configured
- Has the ''pgi/14'' package been loaded into the environment yet?
* If not, do all of its tests and attempt to affect all of its environment changes before proceeding
* If that fails, this configuration fails and must exit immediately
- The installation prefix for the software is constructed as ''/opt/shared/gaussian/g09d01''
- The ''GAUSS_SCRDIR'' environment variable is examined
* If it does not exist in the environment the configuration fails and the ''message'' text is printed to stdout
- The ''mk-gaussian-scrdir'' program found in VALET's ''libexec'' directory is executed
* If the result code returned by ''mk-gaussian-scrdir'' is zero, continue
* Otherwise, the configuration fails and exits
- The ''GAUSSIAN_VERSION'' environment variable is assigned the value ''G09''
- For Bash and other sh-like shells, the script ''g09.sh'' in VALET's ''libexec'' directory is sourced
* The return code is not checked for success or failure
If control reaches the end of this pseudo-code, then the ''gaussian/g09'' package has been successfully configured in the environment.
==== Actions ====
An XML ''actions'' element can be specified either in a package or in a version of a package and contains zero or more action elements of the following kinds:
* //variable// -- make changes to environment variables
* //special directories// -- shorthand for alterations to ''PATH'', ''LD_LIBRARY_PATH'', etc.
* //script// -- source/execute a script
* //shell alias// -- set/unset an alias
Each action is represented as an XML element. Actions attached to the package itself will be performed when //any// version of the package is selected for addition to the environment, and in addition to actions associated with the version itself.
Actions will be performed in the order they are specified in the block.
Example:
/opt/include
/opt/bin
/opt/bin
/opt/lib
/opt/lib64
/opt/share/man
/opt/bin
-O3 -g
=== Variable action ===
Variable actions alter the value of an environment variable. A variable action is an XML ''export'' element with the following attributes:
^Attribute^Value^Optional^
|''variable''|Environment variable name|required|
|''action''|''set'' ''unset'' ''append'' ''prepend'' ''append-path'' ''prepend-path'' ''append-space'' ''prepend-space'' ''scrub'' ''scrub-path''|default = ''set''|
|''development-env''|Only set this variable when ''vpkg_devrequire'' is used|default = no|
The text inside the ''export'' element is the //value// to add/remove/etc.
The actions are self-explanatory for the most part. The ''scrub'' action removes all occurrences of //value// from the variable's current value in the environment. The ''scrub-path'' action treats the value of ''variable'' as a search path and removes from that search path all occurrences (by exact match) of //value//.
The //value// may contain references to other environment variables using the syntax ''${ENV VAR NAME}''.
Example:
/opt/bin
=== Special directories ===
All special-directory actions are enclosed in an XML element within the ''actions'' element. These actions are shortcuts that produce variable actions that affect standard environment variables (like ''PATH'' or ''LD_LIBRARY_PATH''). The following XML element tags are available:
^Element Tag^Value^
|''bindir''|Paths to add to ''PATH''|
|''libdir''|Paths to add to ''LD_LIBRARY_PATH'' (and ''LDFLAGS'' under ''vpkg_devrequire'')|
|''incdir''|Paths to add to ''CPPFLAGS'' under ''vpkg_devrequire''|
|''mandir''|Paths to add to ''MANPATH''|
|''infodir''|Paths to add to ''INFOPATH''|
|''pkgconfigdir''|Paths to add to ''PKG_CONFIG_PATH''|
The text inside the XML element is the path to be added to the variable in question. Multiple elements of the same tag are allowed.
Example:
/opt/bin
/opt/lib
/opt/lib64
/opt/share/man
=== Scripts ===
At times VALET may not be able to fully express the modifications necessary for a package, or the package includes its own extensive environment configuration scripts. In such instances, a VALET package can be configured to simply execute (or source) that external script. A script action is an XML ''script'' element with the following attributes:
^Attribute^Value^
|''action''|''source'' or ''exec''|
|''order''|''failure-first'' or ''success-first''|
|''success''|integer return code indicating successful execution/sourcing|
|''failure''|integer return code indicating failed execution/sourcing|
|''shell''|shell type for which this script is executed|
The text inside the XML ''script'' element is the path to the script to be sourced/executed. Multiple ''script'' elements are allowed.
The ''order'' determines which is tested first, the success return code or the failure return code. If no ''success'' or ''failure'' are specified, then the return code is not tested. Many shell scripts return code 0 on success and a non-zero value in case of a failure; this could be tested by supplying ''order'' = ''success_first'' and ''success'' = 0.
Example:
=== Shell Aliases ===
An //alias// is a word that represents an arbitrarily complex command in the shell environment. Rather than typing the command ''ls -l | less'' repeatedly, a user might create an alias named ''lll'' that when typed yields the same results as if ''ls -l | less'' had been typed. A shell alias action is an XML ''shell-alias'' element with the following attributes:
^Attribute^Value^
|''shell''|shell type for which this alias is valid|
|''development-env''|set to boolean ''true'' to restrict this alias to only be set on ''vpkg_devrequire''|
The text inside the XML ''shell-alias'' element is the command to be executed for the alias. A blank command implies that the named alias should be removed from the environment if it exists. Multiple ''shell-alias'' elements are allowed.
Example:
/bin/ls -l | /usr/bin/less
==== Dependencies & Incompatibilities ====
Dependencies and incompatibilities are XML elements that contain one or more package identifiers, package identifier pattern matches, or predicates that must:
* dependencies:
* package id/pattern must be satisfied (present in environment or successfully loads and configures)
* predicate evaluates to true
* incompatibilities:
* package id/pattern must not be configured in the current environment
* prediate evaluates to false
A ''pre-condition'' is tested //before// any environment changes are made for the sake of the package. A ''post-condition'' is tested //after// all environment changes have been made for the sake of the package.
Example:
GAUSS_SCRDIR
starts-with
/home
Home directories should not be used as scratch for Gaussian.
=== Package Id Patterns ===
A package id pattern is a string that is similar in construction to a regular package id but contains a regular expression for the package side, version side, or both sides of the versioned package id. A regular expression is indicated in either half by prefixing with a carat (^) character. For example, the pattern
> ''openmpi/^^1\.[0-9]*[02468]\.''
includes a regular expression in the version half of the id. Discarding the leading carat, the regular expression is
> ''^1\.[0-9]*[02468]\.''
This pattern will match with any even-numbered release of the ''openmpi'' package in the 1.x series: 1.4.4, 1.6.3, 1.8.2 would all be matches, but 1.5.1 would not.
As a dependency, id patterns are tested against packages that have already been loaded into the environment. If no matching package has been loaded, VALET locates an available package that matches the pattern and attempts to load it into the environment. Note that VALET simply chooses the first versioned package it finds as a match, which may or may not be a new enough version, etc. Ideally, the user will have loaded an appropriate version of the package prior to loading the package that uses an id pattern dependency.
Using a regular expression that is the negation of what you would use for a dependency and employing an incompatibility forces the user to load the dependency prior to loading this package. After all, package ids and id patterns inside an incompatibilities element do not cause VALET to attempt to load a package into the environment.
=== Predicates ===
A predicate is a test performed against an environment variable's value to determine whether package configuration should succeed or fail. Minimally, an XML ''predicate'' element must contain an environment variable name and an //operator// that specifies what test is to be performed. Most operators are binary and thus require a value against which to test; the ''is-set'' and ''not-is-set'' operators are unary and take no additional test value.
^Attribute^Value^Optional^
|''operator''|''is-set'': has a value|required|
|:::|''is-not-set'': does not have a value|:::|
|:::|''eq'', ''=='': lexigraphically equivalent to ''value''|:::|
|:::|''ne'', ''!='': not lexigraphically equivalent to ''value''|:::|
|:::|''lt'', ''%%<%%'': lexigraphically less-than ''value''|:::|
|:::|''le'', ''%%<=%%'': lexigraphically less-than or equivalent to ''value''|:::|
|:::|''gt'', ''%%>%%'': lexigraphically greater-than ''value''|:::|
|:::|''ge'', ''%%>=%%'': lexigraphically greater-than or equivalent to ''value''|:::|
|:::|''starts-with'', ''%%<<%%'': ''value'' as prefix|:::|
|:::|''not-starts-with'', ''!%%<<%%'': not ''value'' as prefix|:::|
|:::|''ends-with'', ''%%>>%%'': ''value'' as suffix|:::|
|:::|''not-ends-with'', ''!%%>>%%'': not ''value'' as suffix|:::|
|:::|''contains'', ''%%<>%%'': contains ''value''|:::|
|:::|''not-contains'', ''!%%<>%%'': does not contain ''value''|:::|
|:::|''matches'', ''~'': matches regular expression in ''value''|:::|
|:::|''not-matches'', ''!~'': does not match regular expression in ''value''|:::|
|''stage''|''pre-condition''|default = ''pre-condition''|
|:::|''post-condition''|:::|
The ''predicate'' element may contain the following child elements:
^Element Tag^Purpose^ Optional^
|''variable''|Environment variable name|required|
|''operator''|The attribute can instead be specified as a child element||
|''value''|Value to compare against for binary operators|required except for operator = ''is-set'' or ''not-is-set''|
|''message''|String that will be displayed if the predicate is not satisfied||
Example:
GAUSS_SCRDIR
starts-with
/home
Home directories should not be used as scratch for Gaussian.
----
[[software:valet:03_packagefile|Prev: XML Package Files]] | [[software:valet:04_snapshot|Next: JSON/YAML Package Files]]