Using Package Definitions¶
A package is defined as a collection of common commands and environment variables. The package definition is a JSON file.
Here is an example of package definition:
{
"identifier": "foo",
"version": "0.1.0",
"description": "Foo Application.",
"system": {
"os": "el >= 7, <8",
"arch": "x86_64"
},
"command": {
"app": "App0.1",
"app-py": "AppPython"
},
"environ": {
"LICENSE": "port@licence-server.com",
"PATH": "/path/to/application:${PATH}",
"PYTHONPATH": "/path/to/application/python:${PYTHONPATH}",
"LD_LIBRARY_PATH": "/path/to/application:${LD_LIBRARY_PATH}"
},
"requirements": [
"python > 2.7, < 3"
]
}
See also
Follow these Guidelines for writing proper package definitions.
Identifier¶
At minimum a package definition contains an identifier
, which has to be
unique. If an identifier is found in multiple registries, the
last sourced registry will define the package.
{
"identifier": "maya"
}
Version¶
The optional version
keyword eases the package selection when a specific
range of version is required.
{
"version": "0.1.0"
}
The same version specifiers defined in PEP 440 are used:
>>> wiz use "app-package >=0.1.0, <2"
The version could also be specified when running a command directly:
>>> wiz run "app == 0.1.*"
See also
If no version is requested, the latest version is automatically fetched.
Namespace¶
the optional namespace
keyword can be used to provides a scope to a
package definition.
{
"namespace": "maya"
}
It can be used to organize packages into logical groups and prevent name collisions that can occur, especially for plugins.
>>> wiz use maya::xmlf
>>> wiz use houdini::xmlf
When a package identifier only exists under one namespace, it can be called without it. For instance, if “foo” only exists under the “bar” namespace, then both commands will be correct:
>>> wiz use bar::foo
>>> wiz use foo
If many namespaces are available for one package identifier, it must be specified in the command line. However, namespaces from packages previously fetched, as well as package names that were part of the original request, can be used as a hint to guess the namespace of the following requests if only the identifier is used:
>>> wiz use maya xmlf
>>> wiz use xmlf maya
>>> wiz use maya::maya maya::xmlf
Note
Only one namespace per definition can be setup at this point. A hyphen can be used in the namespace if necessary (e.g. “A-B::foo”).
Note
A package without namespace can be called explicitely as follows:
>>> wiz use ::foo
Description¶
An optional package description
.
{
"description": "Foo Application."
}
It is useful when searching for packages using:
>>> wiz search app
System¶
An optional system
keyword can be used to limit the scope of a package
definition to a particular:
- Platform (e.g. Linux, Windows)
- Architecture (e.g. x86_64, i386)
- Operating System (e.g. CentOS 7.3, CentOS 6.5, MacOS, Windows)
{
"system": {
"platform": "linux",
"os": "el >= 7, < 8",
"arch": "x86_64"
}
}
The version specifiers defined PEP 440 are used to identify the operating system version.
If no system keyword is provided, the definition could be fetched and loaded from any platform.
Environment¶
The optional environ
keyword defines the environment mapping.
The resolved environment combines all environment variable mappings from all package definitions required to form the resolved context.
In order to combine two environment mappings, each variable value can be augmented by referencing any variable names already included in the resolved mapping.
If a variable value does not reference its variable name within its value, it can override any precedent value.
{
"environ": {
"LICENSE": "port@licence-server.com",
"PATH": "/path/to/application:${PATH}",
"PYTHONPATH": "/path/to/application/python:${PYTHONPATH}",
"LD_LIBRARY_PATH": "/path/to/application:${LD_LIBRARY_PATH}"
}
}
Note
To help debug any accidental overwrites, a warning is being displayed each time a variable is overwriting another one.
Commands¶
The optional command
keyword contains a mapping of commands that serves as
aliases when running within the resolved context.
{
"command": {
"nuke": "Nuke11.1",
"nukex": "Nuke11.1 --nukex",
"studio": "Nuke11.1 --studio",
"hiero": "Nuke11.1 --hiero"
}
}
It can be used to run a command within a resolved environment (with or without additional arguments):
>>> wiz use nuke plugin-nuke -- nukex
>>> wiz use nuke plugin-nuke -- hiero
>>> wiz use nuke plugin-nuke -- nuke /path/to/script
The command mappings are parsed when the package definitions are discovered so
that each command is associated with the definition package it is in. This
let the user call the command directly with the run
command:
>>> wiz run nuke
>>> wiz run nuke==10.5.*
>>> wiz run nukex -- /path/to/script
Warning
Each command must be unique within a Using Registries and could be overwritten by another package definition in another registry.
Requirements¶
the optional requirements
keyword can be used to reference other package
definitions. This indicates that the resulting context has to be composed of
other package definitions and thereby eases the creation of reliable context.
By default, the latest versions of definitions will be fetched, but specific versions can be required. The same version specifiers defined in PEP 440 are use:
{
"requirements": [
"python > 2.7, < 3"
]
}
When several requirements are specified, the order will define the priority of each required package definition. In case of conflict, the first requirement will have priority over the latest.
Warning
A definition and its requirements would be resolved into one context with a common environment variable mapping. Therefore it would not be safe to mix several DCCs into one context to prevent clashes:
"requirement": [
"nuke",
"maya"
]
Conditions¶
The optional conditions
keyword can be used to reference a list of package
definitions which should be in the resolution graph for the package to be
included. If not all conditions are fulfilled, the package will be ignored.
The same version specifiers defined in PEP 440 can be used:
{
"conditions": [
"houdini",
"python >= 2, < 3"
]
}
Warning
Packages will be silently ignored when conditions are not met. For an error to be raised, requirements should be used instead.
Important
conditions
only operate on the entire definition and can not be scoped
to variants.
Variants¶
When different environment mappings are available for one definition version,
the optional variants
keyword can be used in order to define an array of
sub-definitions:
{
"variants": [
{
"identifier": "variant1",
"environ": {
"KEY": "A_VALUE"
},
"requirements": [
"env >= 1, < 2"
]
},
{
"identifier": "variant2",
"environ": {
"KEY": "ANOTHER_VALUE"
},
"requirements": [
"env >= 2, < 3"
]
}
]
}
The environ
and requirements
value will be combined with the global
environ
and requirements
values if necessary.
By default the first variant that leads to a resolution of the graph will be returned. However, a variant can also be requested individually:
>>> wiz use foo[variant1]
Important
conditions only operate on the entire definition and can not be scoped to variants.
While it is in theory possible to combine these features, it adds complexity to the system which could increase human error when setting up definitions. As there is no currently known case that would use a setup that would require this combination of features, it is not supported.
Auto Use¶
The optional auto-use
boolean keyword can be used to always include the
definition in the resolution graph, even when it isn’t explicitly called.
By default this keyword is set to false.
{
"auto-use": true
}
Warning
This keyword should be used carefully as it could potentially pollute all other requests.
Disabled¶
The optional disabled
boolean keyword can be used to prevent a definition
from being used. By default this keyword is set to false.
{
"disabled": true
}
Install Location¶
If a package definition is referencing data on the file system it can be useful
to define the install-location
which would indicate the location for that
data:
{
"install-location": "/path/to/data"
}
This location can be referenced within each environ
value (including the
variants
) using the INSTALL_LOCATION
environment variable:
{
"definition": "foo",
"install-location": "/path/to/data",
"environ": {
"PATH": "${INSTALL_LOCATION}/bin:${PATH}",
"PYTHONPATH": "${INSTALL_LOCATION}/lib/python2.7/site-packages:${PYTHONPATH}"
}
}
When the context is resolved, the INSTALL_LOCATION
environment
variable is replaced by the install-location
value within the definition.
Install Root¶
If a package definition is referencing data on the file system it can be useful
to define the install-root
which would indicate the root location for that
data:
{
"install-root": "/path/to/root"
}
The value behind this keyword can be referenced within the
install-location value using the
INSTALL_ROOT
environment variable:
{
"definition": "foo",
"install-root": "/path/to/root",
"install-location": "${INSTALL_ROOT}/data"
}
This keyword offers greater flexibility as to where the data is located or moved to on the file system, especially when several package definitions share a common root path.