====== JSON Package Definition Files ====== {{:software:valet:valet-icon.png?128 |}}In version 2 of VALET, packages (and their versions) can also defined in JSON files. JSON -- short for JavaScript Object Notation -- is an open standard format that uses human-readable text to represent structured data, just as XML does. XML carries with it a heavy amount of additional formatting surrounding the data, which some people find makes the data itself less visible when inspected. JSON uses far less formatting around the data. VALET package definitions in the JSON format use the file extension ''.vpkg_json''. Comments can be included in the files using the hash character: # # This is a comment. # { "matlab": { } } The JSON standard does //not// include a comment syntax; since having comments in VALET configuration files is very necessary, VALET augments the JSON standard with shell-style comments. ===== File Format ===== The JSON package file consists minimally of a dictionary containing a single key-value pair: { "<>": { } } The ''<>'' must match with the name of the file itself. For example, ''mathematica.vpkg_json'' would contain: { "mathematica": { "description": "Wolfram Mathematica", "url": "http://www.wolfram.com/", "prefix": "/opt/mathematica" } } A package can optionally have a human-readable description and a reference URL (e.g. the vendor/product web site) as shown in this example. Ideally, all versions of a package are installed in unique directories under a common parent directory. If this is indeed the case, then a ''prefix'' key-value pair can be used as shown above. When the individual package versions are later defined, they can provide a relative path in their own ''prefix'' key-value pair which VALET takes as being relative to the package's ''prefix'' path. ==== Versions ==== All versions of a package are contained within a dictionary keyed by the string ''versions'': { "mathematica": { "description": "Wolfram Mathematica", "url": "http://www.wolfram.com/", "prefix": "/opt/mathematica", "versions": { "6": { "description": "Wolfram Mathematica version 6", "url": "http://www.wolfram.com/6", "prefix": "6.0.1", "dependencies": [ "pgi/10" ], "incompatibilities": [ "matlab/^^.*$" ], "actions": [ { "bindir": "Executables" } ] } } } } The optional ''description'' and ''url'' key-value pairs override the value presented in the parent ''package'' element. As mentioned earlier, the ''prefix'' value specified here is a relative path that VALET assumes is relative to the ''prefix'' provided by the parent ''package''. In this case ''/opt/mathematica/6.0.1'' would be the full path. For version definitions lacking an explicit ''prefix'', the version id will be used in its stead as a path component relative to the parent package's ''prefix''. In this example if the ''6.0.1'' prefix had not been specified then it would have been implicitly set to ''/opt/mathematica/6''. The ''actions'' key-value pair defines the changes that accompany package inclusion. The simplest actions involve the addition of filesystem paths to various environment variables. In this example, the ''bindir'' action specifies a path that should be added to the ''PATH'' environment variable. Relative paths are taken to be relative to the ''prefix'' directory. Besides ''bindir'' there are several other special directory-related actions: ^Element Name^Env Var Affected^Description^Defaults^ |''bindir''|''PATH''|Directories containing executables|''bin'', ''sbin''| |''libdir''|''LD_LIBRARY_PATH'', ''LDFLAGS''|Directories containing libraries|''lib'', ''libso''| |''mandir''|''MANPATH''|Directories containing manual pages|''man'', ''share/man''| |''infodir''|''INFOPATH''|Directories containing manual pages|''share/info''| |''incdir''|''CPPFLAGS''|Directories containing header files|''include''| |''pkgconfigdir''|''PKG_CONFIG_PATH''|Directories containing .pc files for ''pkg-config''|''lib/pkgconfig'', ''share/pkgconfig''| By default VALET will also automatically check for the default directory(s) associated with each of the special actions listed above in addition to any that are specified explicitly (this behavior can be disabled on a per-package and per-version basis). In all cases, only directories that actually exist will be setup in the environment. The ''LDFLAGS'' and ''CPPFLAGS'' environment variables are set to affect software compilation and linking. The user must explicitly request their inclusion in the environment setup. For software packages that are built using other packages managed by VALET, a list of ''dependencies'' can be specified. Each item in the ''depencencies'' array can be: - A versioned package id, e.g. ''openmpi/1.8.2'' - A versioned package regular expression, e.g. ''openmpi/^^1\\.[0-9]*[02468]\\.'' - A [[#predicates|predicate]] The regular expression format and predicates will be covered later in this document. When configuring the environment, VALET will automatically attempt to include all dependency packages' configuration details, as well. A list of ''incompatibilities'' can be included to express that a versioned package conflicts with some other versioned package. Just like dependencies, the ''incompatibilities'' array can contain - Versioned package ids, e.g. ''openmpi/1.8.2'' - Versioned package regular expressions, e.g. ''openmpi/^^1\\.[0-9]*[02468]\\.'' - [[#predicates|Predicates]] In the example above Mathematica 6 conflicts (somehow) with //any// version of Matlab: the ''^^.*$'' regular expression matches any version id associated with the ''matlab'' package. Inclusion of any version of Matlab either prior to or after this versioned package's inclusion will yield an error. Multiple version dictionaries (keyed by their version id) may be present in a package's ''versions'' dictionary. A ''default-version'' element in the ''package'' indicates which version should be considered the default; omitting the ''default-version'' element, the first version dictionary will be the default for the package (the ''{ ... }'' has been used to shorten the lengthy version dictionaries for illustrative purposes): { "mathematica": { "description": "Wolfram Mathematica", "url": "http://www.wolfram.com/", "prefix": "/opt/mathematica", "default-version": "7", "versions": { "6": { ... }, "7": { ... }, "8": { ... } } } } ==== Aliases ==== A version //alias// is a unique package version that points to a sibling version. For example, Gaussian releases their G09 product and its incremental updates as a series, e.g. ''g09a01'', ''g09a02'', ''g09b03'', etc. Most users probably don't care what revision of G09 they are using, so long as they are using G09. By specifying a version alias { "gaussian": { "versions": { "g09a01": { ... }, "g09a02": { ... }, "g09b03": { ... }, "g09": { "alias-to": "g09b03" } } } } users can always just request ''gaussian/g09'' and the system administrator can change the alias target as future incremental updates are installed on the system. As illustrated, a version alias dictionary has no content other than the ''alias-to'' key-value pair. ==== Static Exports ==== In some cases there may be additional environment variables that need to be modified for a package/version. To facilitate this, zero or more ''variable'' actions can be added to a package or version dictionary: { "mathematica": { "description": "Wolfram Mathematica", "url": "http://www.wolfram.com/", "prefix": "/opt/mathematica", "default-version": "7", "actions": [ { "variable": "MATHEMATICA_IN_USE", "value": 1 } ], "versions": { "6": { ... }, "7": { ... }, "8": { ... "actions": [ { "variable": "MATHEMATICA_DOCS", "action": "path-prepend", "value": "${HOME}/mma_8" } ] } } } } The ''action'' can be: ^Action^Description^ |''set''|Sets the value| |''unset''|Removed the variable from the environment| |''prepend''|Sets or prefixes the new value to the variable's value| |''append''|Sets or suffixes the new value to the variable's value| |''prepend-path''|Sets or prefixes (with a colon separator) the value to the variable's value| |''append-path''|Sets or suffixes (with a colon separator) the value to the variable's value| |''prepend-space''|Sets or prefixes (with a single space character) the value to the variable's value| |''append-space''|Sets or suffixes (with a single space character) the value to the variable's value| |''scrub''|Removes all occurrences of the new value from the variable's value| |''scrub-path''|Treat the new value as a path and remove all occurrences of that path from the variable's value| If no ''action'' attribute is specified the ''set'' action is assumed. To embed references to the value of other environment variables in an ''export'' element the ''${VAR-NAME}'' syntax //must// be used. VALET will not recognize ''$VAR-NAME'' style references in values! VALET defines some environment variables that variable actions may reference: ^Variable^Description^ |''VALET_PKG_ID''|The package id associated with the version for which the script was invoked.| |''VALET_PATH_PREFIX''|The path prefix associated with the version for which the script was invoked.| ==== Scripts ==== If there is additional "work" that cannot be encapsulated in VALET configuration directives, the system administrator can write an external script that will be sourced into the user's shell. A ''script'' action provides the path to each such script and directives that control how that path is used: ... "actions": [ { "variable": "MATHEMATICA_DOCS", "action": "path-prepend", "value": "${HOME}/mma_8" }, { "action": "source", "script": { "sh": "/opt/mathematica/bin/remote_kernel.sh", "csh": "/opt/mathematica/bin/remote_kernel.csh" }, "order": "failure-first", "success": 0 } ] ... VALET includes a ''libexec'' directory into which you can install helper scripts; relative script paths are taken to be relative to the ''libexec'' directory. The same VALET-defined variables available to variable actions can be used by scripts (e.g. using ''VALET_PATH_PREFIX'' to find the software's installed location). Scripts (or binary executables) can be forked-and-executed (''"action": "exec"'') while scripts can be sourced into the shell, as in the example above. Shell-specific paths can be specified. An integer value for ''success'' and/or ''failure'' can be provided that will be compared against the return code after source'ing/execution of the appropriate path. The ''order'' determines which is tested first: ''failure-first'' or ''success-first''. A script action that fails its succeed/failure test causes VALET to discard the current configuration changes and return in error. ==== Predicates ==== In some cases it may be necessary to test the value of one or more environment variables to determine whether or not the package setup should succeed or fail. For example, if the user has no ''GAUSS_SCRDIR'' defined then Gaussian will have no directory in which to write scratch files. This could be described as either a dependency or an incompatibility. Such tests are modeled with a predicate. A predicate can be specified inside the ''dependencies'' and ''incompatibilities'' dictionaries of a package or a version. A predicate is defined similarly to a variable action: ... "dependencies": [ { "variable": "GAUSS_SCRDIR", "operator": "is-set", "stage": "post-condition" } } ... In this case, the predicate could also be configured as an incompatibility: ... "incompatibilities": [ { "variable": "GAUSS_SCRDIR", "operator": "not-is-set", "stage": "post-condition" } } ... The ''stage'' key-value pair dictates whether the test should be performed //before// (''pre-condition'') or //after// (''post-condition'') VALET makes changes to the environment on behalf of the package. If no ''stage'' attribute is specified, the predicate is a pre-condition. Valid operators are: ^Short ^Long Name ^Meaning ^ Unary/Binary ^ | |''is-set''|Non-empty value|unary| | |''is-not-set''|Empty value|unary| |''==''|''eq''|Equivalent to the given string|binary| |''!=''|''ne''|Not equivalent to the given string|binary| |''<''|''lt''|Lexigraphically less-than the given string|binary| |''%%<=%%''|''le''|Lexigraphically less-than or equivalent to the given string|binary| |''>''|''gt''|Lexigraphically greater-than the given string|binary| |''%%>=%%''|''ge''|Lexigraphically greater-than or equivalent to the given string|binary| |''%%<<%%''|''starts-with''|Starts with the given string|binary| |''!%%<<%%''|''not-starts-with''|Does not start with the given string|binary| |''%%>>%%''|''ends-with''|Ends with the given string|binary| |''!%%>>%%''|''not-ends-with''|Does not end with the given string|binary| |''%%<>%%''|''contains''|Contains the given string|binary| |''!%%<>%%''|''not-contains''|Does not contain the given string|binary| |''~''|''matches''|Matches the given Python regular expression|binary| |''!~''|''not-matches''|Does not match the given Python regular expression|binary| A set of file-testing operators exist, as well. For these operators, the ''variable'' key may be replaced by the ''path'' key in the predicate specification. Tests include existence/non-existence of a filesystem entity at the ''path''; read/write/execute access checks; and file type introspection (directory, regular file, socket, etc.). The value of the ''path'' key can contain both environment variable references (as ''${VARIABLE}'') and user home directory macros (e.g. ''~professorx''). For example, ''~professorx/${DEFAULTS}/info.txt'' is implicitly expanded by replacing ''~professorx'' with that user's home directory path and ''${DEFAULTS}'' with the value of that environment variable. The expanded path is then used for the test. ^Short ^Long Name ^Meaning ^ Unary/Binary ^ |''-e''|''exists''|Filesystem entity exists at ''path''|unary| |''!-e''|'' not-exists''|Filesystem entity does not exist at ''path''|unary| |''-r''|''is-readable''|Filesystem entity at ''path'' is readable|unary| |''!-r''|'' not-is-readable''|Filesystem entity at ''path'' is not readable|unary| |''-w''|''is-writable''|Filesystem entity at ''path'' is writable|unary| |''!-w''|'' not-is-writable''|Filesystem entity at ''path'' is not writable|unary| |''-x''|''is-executable''|Filesystem entity at ''path'' is executable|unary| |''!-x''|'' not-is-executable''|Filesystem entity at ''path'' is not executable|unary| |''-t''|''is-file-type''|Filesystem entity at ''path'' is of the given type|binary| |''!-t''|''not-is-file-type''|Filesystem entity at ''path'' is not of the given type|binary| |''-st''|''is-strict-file-type''|Filesystem entity at ''path'' is of the given type; symlinks are not followed|binary| |''!-st''|''not-is-strict-file-type''|Filesystem entity at ''path'' is not of the given type; symlinks are not followed|binary| For binary operators, the required argument is provided in a ''value'' key-value pair. For example, to ensure that setup does not proceed if a user has pre-set ''GAUSS_SCRDIR'' to a filesystem that should not be used as scratch, the following incompatibility predicate might be used: ... "incompatibilities": [ { "variable": "GAUSS_SCRDIR", "operator": "matches", "value": "^/(home|archive)/", "message": "Storing Gaussian scratch files on /home or /archive is forbidden." } } ... If a user subsequently attempts to ''vpkg_require gaussian'' the ''message'' will be displayed if they have ''GAUSS_SCRDIR'' misconfigured: ERROR: an error occurred while altering your environment REASON: Storing Gaussian scratch files on /home or /archive is forbidden. All predicates must pass in order for environment configuration to succeed; essentially, success is the logical AND of all predicates specified. Like package/version dependencies and incompatibilities, predicates are preserved across calls to ''vpkg_require''. If a later ''vpkg_require'' produces changes to the environment that conflict with any predicates, old or new, the changes will be reverted and an error message displayed. ===== Grammar ===== A VALET package is represented in JSON as a dictionary containing a single key-value pair: ^Key^Value^ |<>|a dictionary containing configuration directives global to the package and all defined versions of the package| Example: { "gaussian": { : "versions": { : } } } A set of scalar properties can be used both in the global and per-version areas of the configuration. Scalar properties are: ^Key^Value^ |''description''|Human-readable description of the software package| |''url''|A web site documenting the package, for example| |''prefix''|A filesystem path containing the package or the version of the package| |''development-env''|Set to boolean ''true'' if VALET should emit ''LDFLAGS'' and ''CPPFLAGS''| |''standard-paths''|Set to boolean ''false'' if 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'' or ''standard-paths'' flag inherit the value of their parent package. Example: { "gaussian": { "description": "Gaussian Quantum Chemistry Suite", "url": "http://gaussian.com/", "prefix": "/opt/shared/gaussian", "development-env": false, "standard-paths": false, "versions": { "g09": { "prefix": "g09d01" }, "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: "versions": { "g09": { "alias-to": "g09d01" }, "g09d01": { } } 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| All three are represented as JSON arrays. 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": { "description": "Gaussian Quantum Chemistry Suite", "url": "http://gaussian.com/", "prefix": "/opt/shared/gaussian", "development-env": false, "standard-paths": false, "dependencies": [ { "variable": "GAUSS_SCRDIR", "operator": "not-is-set", "stage": "pre-condition", "message": "If GAUSS_SCRDIR is not set, the working directory will be used; you do not want that." } ], "actions": [ { "action": "exec", "script": { "all": "mk-gaussian-scrdir" }, "order": "success-first", "success": 0 } ], "versions": { "g09": { "alias-to": "g09d01" }, "g09d01": { "dependencies": [ "pgi/14" ], "actions": [ { "variable": "GAUSSIAN_VERSION", "action": "set", "value": "G09" }, { "action": "source", "script": { "sh": "g09.sh" } } ] } } } } 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 ''actions'' array can be specified either in a package or in a version of a package and contains zero or more action objects: * //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 a JSON dictionary . 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 array. Example: "actions": [ { "incdir": "/opt/include" }, { "variable": "PATH", "action": "scrub-path", "value": "/opt/bin" }, { "bindir": "/opt/bin", "libdir": [ "/opt/lib", "/opt/lib64" ], "mandir": "/opt/share/man" }, { "variable": "USER_SW_PATH", "value": "/opt/bin" }, { "variable": "CFLAGS", "action": "append-space", "value": "-O3 -g", "development-env": true } ] === Variable action === Variable actions alter the value of an environment variable. A variable action is a JSON dictionary with the following key-value pairs: ^Key^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''| |''value''|New value to introduce by means of the action|unused if ''action'' = ''unset''| |''development-env''|Only set this variable when ''vpkg_devrequire'' is used|default = no| The actions are self-explanatory for the most part. The ''scrub'' action removes all occurrences of ''value'' from the variables 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: { "variable": "PATH", "action": "scrub-path", "value": "/opt/bin" } === Special directories === All special-directory actions are enclosed in a JSON dictionary within the ''actions'' array. These actions are shortcuts that produce variable actions that affect standard environment variables (like ''PATH'' or ''LD_LIBRARY_PATH''). The dictionary can contain the following key-value pairs; for each, the value can be either a single string or an array of strings: ^Key^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''| Example: { "bindir": "/opt/bin", "libdir": [ "/opt/lib", "/opt/lib64" ], "mandir": "/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 a JSON dictionary containing the following key-value pairs: ^Key^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| |''script''|dictionary of paths keyed by shell id| The ''script'' dictionary provides alternative paths for each different shell supported by VALET. 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: { "action": "source", "script": { "sh": "/opt/mathematica/bin/remote_kernel.sh", "csh": "/opt/mathematica/bin/remote_kernel.csh" }, "order": "success-first", "success": 0 } === 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 a JSON dictionary containing the following key-value pairs: ^Key^Value^ |''shell-alias''|the name of the alias, e.g. ''lll''| |''development-env''|set to boolean ''true'' to restrict this alias to only be set on ''vpkg_devrequire''| |''command''|dictionary of command strings keyed by shell id| The ''command'' dictionary provides alternative commands for each different shell supported by VALET. For simple commands that do not use shell-specific syntax, the shell id ''any'' (or ''*'') can be used. A blank command implies that the named alias should be removed from the environment if it exists. Example: { # Add 'lll' alias: "shell-alias": "lll", "command": { "any": "/bin/ls -l | /usr/bin/less" } }, { # Remove 'll' alias: "shell-alias": "ll", "command": { "*": "" } } === Warning Messages === A warning message is quite simply that: a textual message that is written to stdout when the user configures the package into his/her environment. A warning might be used to notify the user that s/he is using an unsupported version of a product, for example. A warning message action is a JSON dictionary containing the following key-value pairs: ^Key^Value^ |''warning''|the message to display, e.g. ''This software is not officially supported.''| |''development-env''|set to boolean ''true'' to restrict this alias to only be set on ''vpkg_devrequire''| Example: { # Mention that we don't support PGI on this cluster: "warning": "The Portland compiler suite is not officially supported on this cluster." } ==== Dependencies & Incompatibilities ==== Dependencies and incompatibilities are JSON arrays of 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. Examples: "dependencies": [ "pgi/14", "fftw/^^3\\." ], "incompatibilities": [ { "variable": "GAUSS_SCRDIR", "operator": "starts-with", "value": "/home", "stage": "post-condition", "message": "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. JSON treats the backslash as an escape character, hence the reason it must be escaped itself in the regular expression string. 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 dictionary 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, a predicate dictionary 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'', ''not-is-set'', ''exists'', ''not-exists'', ''is-readable'', ''not-is-readable'', ''is-writable'', ''not-is-writable'', ''is-executable'', and ''not-is-executable'' operators are unary and take no additional test value. There are several predicate operators used to examine filesystem paths. The ''is-file-type'' operator uses the ''stat()'' system call on the given path; if the path is a symbolic link, then the type refers to the target of the link, not the link itself. Use the ''is-strict-file-type'' operator to not follow symbolic links. The right-hand-side of this kind of predicate (its ''value'') should be one of the following strings: ^value^Description^ |''file''|regular file| |''directory''|directory| |''link''|symbolic link| |''fifo''|filesystem pipe (FIFO)| |''socket''|socket file| ^Key^Value^Optional^ |''variable'', ''path''|Environment variable name or file system path to test|required| |''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''|:::| |:::|''exists'', ''-e'': path specified exists on system|:::| |:::|''not-exists'', ''!-e'': path specified does not exist on system|:::| |:::|''is-file-type'', ''-t'': path specified is of ''value'' file type|:::| |:::|''not-is-file-type'', ''!-t'': path specified is not of ''value'' file type|:::| |:::|''is-strict-file-type'', ''-st'': path specified is of ''value'' file type (symlinks not followed)|:::| |:::|''not-is-strict-file-type'', ''!-st'': path specified is not of ''value'' file type (symlinks not followed)|:::| |:::|''is-readable'', ''-r'': path specified is readable by current user|:::| |:::|''not-is-readable'', ''!-r'': path specified is not readable by current user|:::| |:::|''is-writable'', ''-w'': path specified is writable by current user|:::| |:::|''not-is-writable'', ''!-w'': path specified is not writable by current user|:::| |:::|''is-executable'', ''-x'': path specified is executable by current user|:::| |:::|''not-is-executable'', ''!-x'': path specified is not executable by current user|:::| |''value''|Value to compare against for binary operators|required except for ''operator'' = ''is-set'' or ''not-is-set''| |''stage''|''pre-condition''|default = ''pre-condition''| |:::|''post-condition''|:::| |''message''|String that will be displayed if the predicate is not satisfied| | Examples: { "variable": "GAUSS_SCRDIR", "operator": "starts-with", "value": "/home", "stage": "post-condition", "message": "Home directories should not be used as scratch for Gaussian." }, { "path": "/tmp/.pgSQL", "operator": "is-file-type", "value": "socket", "message": "Gaussian database access expects a PostgreSQL socket at /tmp/.pgSQL for connections." }, { "path": "/opt/shared/gaussian", "operator": "is-readable", "message": "Gaussian software is only licensed to UD users." }