variants.rst (modules-5.1.1.tar.bz2) | : | variants.rst (modules-5.2.0.tar.bz2) | ||
---|---|---|---|---|
.. _variants: | .. _variants: | |||
Variants | Variants | |||
======== | ======== | |||
Configuration | Configuration | |||
------------- | ------------- | |||
- Variant mechanism requires the :mconfig:`advanced_version_spec` option to be e nabled | - Variant mechanism requires the :mconfig:`advanced_version_spec` option to be e nabled | |||
- Variants can be seen as an extension of the advanced module version specif iers | - Variants can be seen as an extension of the advanced module version specifie rs | |||
Specification | Specification | |||
------------- | ------------- | |||
Defining | Defining | |||
^^^^^^^^ | ^^^^^^^^ | |||
- variants are defined for modulefiles within concerned modulefiles with the :mf cmd:`variant` modulefile command | - variants are defined for modulefiles within concerned modulefiles with the :mf cmd:`variant` modulefile command | |||
- variants are bound to the modulefile they target | - variants are bound to the modulefile they target | |||
- especially modulefile evaluation may be guided by the value selected for t | - especially modulefile evaluation may be guided by the value selected for the | |||
he variants | variants | |||
- so it makes more sense to have variants defined within modulefiles rather | - so it makes more sense to have variants defined within modulefiles rather in | |||
in modulercs | modulercs | |||
- ``variant --default? defaultval? --alias? {aliasname...?} name value? ...?`` | - ``variant --default? defaultval? --alias? {aliasname...?} name value? ...?`` | |||
- ``name`` restrained to the accepted variable name | - ``name`` restrained to the accepted variable name | |||
- which should correspond to a sequence of one or more characters that are a | - which should correspond to a sequence of one or more characters that are a l | |||
letter, digit or underscore | etter, digit or underscore | |||
- if we want to match Spack here also: ``[A-Za-z0-9_][A-Za-z0-9_.-]*`` | - if we want to match Spack here also: ``[A-Za-z0-9_][A-Za-z0-9_.-]*`` | |||
- raise error otherwise | - raise error otherwise | |||
- a variant ``name`` that has already been defined as variant or variant alias f or this modulefile evaluation overwrites previous definition | - a variant ``name`` that has already been defined as variant or variant alias f or this modulefile evaluation overwrites previous definition | |||
- it is up to modulefile author to ensure there is no duplicate | - it is up to modulefile author to ensure there is no duplicate | |||
- no need this way to check in ``modulecmd.tcl`` code if variant has already | - no need this way to check in ``modulecmd.tcl`` code if variant has already b | |||
been defined | een defined | |||
- may have a default value (when ``--default`` argument is passed) | - may have a default value (when ``--default`` argument is passed) | |||
- if not, variant is undefined | - if not, variant is undefined | |||
- argument ``--default`` should be associated a *defaultval* argument | - argument ``--default`` should be associated a *defaultval* argument | |||
- raise error otherwise | - raise error otherwise | |||
- default value should be part of possible value list if value list provided | - default value should be part of possible value list if value list provided | |||
- error is raised otherwise when default value is used, as it does not c orrespond to an accepted value | - error is raised otherwise when default value is used, as it does not corre spond to an accepted value | |||
- ex: ``variant name --default 1.8 1.0 2.0`` | - ex: ``variant name --default 1.8 1.0 2.0`` | |||
- when no list of accepted value is provided, default value could be any value | - when no list of accepted value is provided, default value could be any val ue | |||
- may be set as a Boolean variant (when ``--boolean`` argument is passed) | - may be set as a Boolean variant (when ``--boolean`` argument is passed) | |||
- a Boolean variant may equal *true* or *false* | - a Boolean variant may equal *true* or *false* | |||
- may have a list of accepted values | - may have a list of accepted values | |||
- unless if defined as a Boolean variant | - unless if defined as a Boolean variant | |||
- passed value(s) must correspond to those accepted | - passed value(s) must correspond to those accepted | |||
- raise error otherwise | - raise error otherwise | |||
- raised error is a global error to signal specification issue, not a mo | - raised error is a global error to signal specification issue, not a module | |||
dulefile error | file error | |||
- an error is raised if one or more accepted values are defined on a Boolean variant | - an error is raised if one or more accepted values are defined on a Boolean v ariant | |||
- non-Boolean variants cannot define Boolean value in their accepted value l ist | - non-Boolean variants cannot define Boolean value in their accepted value lis t | |||
- as Boolean values are translated to their canonical form (*0* or *1*) | - as Boolean values are translated to their canonical form (*0* or *1*) when | |||
when specified | specified | |||
- an error is raised otherwise | - an error is raised otherwise | |||
- exception made for the *0* and *1* integers | - exception made for the *0* and *1* integers | |||
- when no list of accepted value is provided it means any value is accepted | - when no list of accepted value is provided it means any value is accepted | |||
- it is up to the modulefile author to write the appropriate test after variant declaration to check that the value provided is acceptable | - it is up to the modulefile author to write the appropriate test after vari ant declaration to check that the value provided is acceptable | |||
- may be aliased (when argument ``--alias`` is passed) in which case: | - may be aliased (when argument ``--alias`` is passed) in which case: | |||
- argument ``--alias`` should be associated one or a list of alias names | - argument ``--alias`` should be associated one or a list of alias names | |||
- raise error otherwise | - raise error otherwise | |||
- defined alias names should be valid variant name (i.e.: ``[A-Za-z0-9_][A-Z a-z0-9_.-]*``) | - defined alias names should be valid variant name (i.e.: ``[A-Za-z0-9_][A-Za- z0-9_.-]*``) | |||
- raise error otherwise | - raise error otherwise | |||
- should not be already defined as variant or variant alias | - should not be already defined as variant or variant alias | |||
- raise error otherwise | - raise error otherwise | |||
- variant alias could negate its target (when alias name is prefixed by ``-` `) | - variant alias could negate its target (when alias name is prefixed by ``-``) | |||
- meaning if alias variant is set to ``false`` its target is set to ``tr | - meaning if alias variant is set to ``false`` its target is set to ``true`` | |||
ue`` | - only possible if targeted variant is Boolean | |||
- only possible if targeted variant is Boolean | ||||
- raise error otherwise | - raise error otherwise | |||
- no support of ``~`` as an alternative negated prefix to only get one w ay to write negation | - no support of ``~`` as an alternative negated prefix to only get one way t o write negation | |||
- require a value to be set | - require a value to be set | |||
- raise error if no value set for variant (no value specified and no defined default) | - raise error if no value set for variant (no value specified and no defined d efault) | |||
- to validate variant value is coherent against other variant values or any othe r test | - to validate variant value is coherent against other variant values or any othe r test | |||
- it is up to the modulefile author to write the appropriate test after all | - it is up to the modulefile author to write the appropriate test after all va | |||
variant declaration | riant declaration | |||
- and then raise error if variant combination is not appropriate | - and then raise error if variant combination is not appropriate | |||
- as there is no way to automatically determine when all variants are declar | - as there is no way to automatically determine when all variants are declared | |||
ed | ||||
Evaluating | Evaluating | |||
^^^^^^^^^^ | ^^^^^^^^^^ | |||
- when reaching ``variant`` command in modulefile | - when reaching ``variant`` command in modulefile | |||
- set a key ``name`` in array ``ModuleVariant`` if variant ``name`` has been spe cified or if it owns a default value | - set a key ``name`` in array ``ModuleVariant`` if variant ``name`` has been spe cified or if it owns a default value | |||
- variable ``ModuleVariant($name)`` is not defined if variant not specified and no default for it | - variable ``ModuleVariant($name)`` is not defined if variant not specified an d no default for it | |||
- error is raised if used in this case | - error is raised if used in this case | |||
- if variant ``name`` can be aliased, if alias is set it specifies the value of variant ``name`` | - if variant ``name`` can be aliased, if alias is set it specifies the value of variant ``name`` | |||
- evaluated from left to right, in case variant is set and also its aliases | - evaluated from left to right, in case variant is set and also its aliases | |||
- negating aliases sets its reversed value to Boolean variant | - negating aliases sets its reversed value to Boolean variant | |||
- variant alias is not instantiated in ``ModuleVariant`` array | - variant alias is not instantiated in ``ModuleVariant`` array | |||
- therefore accessing ``$ModuleVariant($aliasname)`` will raise an error | - therefore accessing ``$ModuleVariant($aliasname)`` will raise an error | |||
- raise error if variant ``name``: | - raise error if variant ``name``: | |||
- has been specified but passed value is incorrect | - has been specified but passed value is incorrect | |||
- is wrongly declared in modulefile | - is wrongly declared in modulefile | |||
- then variable ``$ModuleVariant(name)`` could be used to adapt modulefile evalu ation | - then variable ``$ModuleVariant(name)`` could be used to adapt modulefile evalu ation | |||
- to know all variant currently set, use ``[array names ModuleVariant]`` | - to know all variant currently set, use ``[array names ModuleVariant]`` | |||
- but beware that only the variant already evaluated will be set in array | - but beware that only the variant already evaluated will be set in array | |||
- must use after all the ``variant`` to be set in the modulefile to accurate | - must use after all the ``variant`` to be set in the modulefile to accurately | |||
ly get all variant defined | get all variant defined | |||
- if variant accepted values are Booleans, variable could be directly used in co nditional tests | - if variant accepted values are Booleans, variable could be directly used in co nditional tests | |||
- like ``if {$ModuleVariant($name)} {...`` | - like ``if {$ModuleVariant($name)} {...`` | |||
- quoting Tcl doc, Booleans could have many forms: | - quoting Tcl doc, Booleans could have many forms: | |||
- If string is any of *0*, *false*, *no*, or *off*, then Tcl_GetBoolean stor | - If string is any of *0*, *false*, *no*, or *off*, then Tcl_GetBoolean stores | |||
es a zero value at ``*boolPtr``. | a zero value at ``*boolPtr``. | |||
- If string is any of *1*, *true*, *yes*, or *on*, then 1 is stored at ``*bo | - If string is any of *1*, *true*, *yes*, or *on*, then 1 is stored at ``*bool | |||
olPtr``. | Ptr``. | |||
- Any of these values may be abbreviated, and upper-case spellings are also | - Any of these values may be abbreviated, and upper-case spellings are also ac | |||
acceptable | ceptable | |||
- variants with a :ref:`shortcut <variant-shortcut>` defined for them, are resol ved to their full name and transmitted this way to the modulefile | - variants with a :ref:`shortcut <variant-shortcut>` defined for them, are resol ved to their full name and transmitted this way to the modulefile | |||
- therefore no entry in ``ModuleVariant`` array is made for the shortcut nam e | - therefore no entry in ``ModuleVariant`` array is made for the shortcut name | |||
- as special variant ``version`` will not be implemented on Modules 4.8, an erro r is raised if a variant is named ``version`` | - as special variant ``version`` will not be implemented on Modules 4.8, an erro r is raised if a variant is named ``version`` | |||
- to ensure no usage of this variant name will be made before its special me chanism availability | - to ensure no usage of this variant name will be made before its special mech anism availability | |||
- special variant ``version`` is instantiated as variable ``ModuleVariant(versio n)`` if declared | - special variant ``version`` is instantiated as variable ``ModuleVariant(versio n)`` if declared | |||
- will be set to value that may be specified with the ``@`` shortcut | - will be set to value that may be specified with the ``@`` shortcut | |||
- will initially work as any other variant (accepted list of value, default | - will initially work as any other variant (accepted list of value, default va | |||
value) | lue) | |||
- using ``variant version --default 1.8 1.8 1.10`` | - using ``variant version --default 1.8 1.8 1.10`` | |||
- is equivalent of having two modulefiles *mod/1.8* and *mod/1.10* | - is equivalent of having two modulefiles *mod/1.8* and *mod/1.10* | |||
- with a default defined: ``module-version mod/1.8 default`` | - with a default defined: ``module-version mod/1.8 default`` | |||
- FUTURE: could be refined later on to accept range then select latest versi | - FUTURE: could be refined later on to accept range then select latest version | |||
on or defined default if in range | or defined default if in range | |||
- note that ``ModuleVariant(version)`` is set only if a ``version`` variant | - note that ``ModuleVariant(version)`` is set only if a ``version`` variant is | |||
is declared in modulefile | declared in modulefile | |||
- querying ``[module-info name]`` returns modulefile designation appended by | - querying ``[module-info name]`` returns modulefile designation appended by t | |||
the version variant: ``@versionvalue`` | he version variant: ``@versionvalue`` | |||
- at the end of the modulefile evaluation, if module specification contains a va riant which is not defined in modulefile | - at the end of the modulefile evaluation, if module specification contains a va riant which is not defined in modulefile | |||
- an error is raised | - an error is raised | |||
- for the different evaluation modes: | - for the different evaluation modes: | |||
- *load*, *help* and *test* apply evaluation mechanism described above | - *load*, *help* and *test* apply evaluation mechanism described above | |||
- for the *help* and *test* modes it helps to see how the modulefile rea cts to the different variant value | - for the *help* and *test* modes it helps to see how the modulefile reacts to the different variant value | |||
- *display* applies evaluation mechanism described above but allow variant t o be unspecified | - *display* applies evaluation mechanism described above but allow variant to be unspecified | |||
- to help learning all the variant defined by the modulefile | - to help learning all the variant defined by the modulefile | |||
- as a result unspecified variant is not instantiated in the ``ModuleVar | - as a result unspecified variant is not instantiated in the ``ModuleVariant | |||
iant`` array variable | `` array variable | |||
- with unspecified variant a user will not accurately see how the module | - with unspecified variant a user will not accurately see how the modulefile | |||
file reacts to the different variant value | reacts to the different variant value | |||
- evaluation error is obtained if accessing the ``ModuleVariant`` ar ray variable for an unspecified variant | - evaluation error is obtained if accessing the ``ModuleVariant`` array va riable for an unspecified variant | |||
- on *display* mode, the ``variant`` command is reported in addition of its evaluation | - on *display* mode, the ``variant`` command is reported in addition of its evaluation | |||
- *unload* evaluates the mechanism described above but the specified variant s are fetched from loaded module persistent information | - *unload* evaluates the mechanism described above but the specified variants are fetched from loaded module persistent information | |||
- ``version`` variant value is fetched from the module specification to | - ``version`` variant value is fetched from the module specification to iden | |||
identify the module to unload | tify the module to unload | |||
- other variant specification on the unload command are dropped once mat | - other variant specification on the unload command are dropped once matchin | |||
ching loaded module is identified | g loaded module is identified | |||
- however this specification remains available when querying ``[modu le-info specified]`` | - however this specification remains available when querying ``[module-inf o specified]`` | |||
- variant values are defined within modulefile context by the evaluation of the ``variant`` modulefile commands | - variant values are defined within modulefile context by the evaluation of the ``variant`` modulefile commands | |||
- like it is done during a *load* modulefile evaluation | - like it is done during a *load* modulefile evaluation | |||
- this way variables related to variant are instantiated the same wa | - this way variables related to variant are instantiated the same way whet | |||
y whether module is loading or unloading | her module is loading or unloading | |||
- so it is easier for modulefile author to understand how the module | - so it is easier for modulefile author to understand how the modulefile c | |||
file code is evaluated | ode is evaluated | |||
- variant evaluated during modulefile unload may produce an error | - variant evaluated during modulefile unload may produce an error | |||
- if variant value not found defined or if value recorded in persist | - if variant value not found defined or if value recorded in persistency d | |||
ency does not match an allowed value | oes not match an allowed value | |||
- should encourage variants to be consistent between the load and un | - should encourage variants to be consistent between the load and unload e | |||
load evaluation phases | valuation phases | |||
- *whatis* ignores all variants from the module specification (only the modu le names are retained) | - *whatis* ignores all variants from the module specification (only the module names are retained) | |||
- like for ``setenv`` or ``*-path`` modulefile commands on this mode, `` | - like for ``setenv`` or ``*-path`` modulefile commands on this mode, ``vari | |||
variant`` will set the ``ModuleVariant`` array with a empty string for each vari | ant`` will set the ``ModuleVariant`` array with a empty string for each variant | |||
ant defined in the modulefile | defined in the modulefile | |||
- this is done to avoid the *undefined variable* error if these variable | - this is done to avoid the *undefined variable* error if these variables ar | |||
s are used later in the modulefile | e used later in the modulefile | |||
- FUTURE: if the different ``version`` variant values are considered as | - FUTURE: if the different ``version`` variant values are considered as diff | |||
different modulefiles in the future, then *whatis* may evaluates the ``version`` | erent modulefiles in the future, then *whatis* may evaluates the ``version`` var | |||
variant from module specification | iant from module specification | |||
getvariant | getvariant | |||
"""""""""" | """""""""" | |||
- A :mfcmd:`getvariant` modulefile command is added following the same principle than :mfcmd:`getenv` | - A :mfcmd:`getvariant` modulefile command is added following the same principle than :mfcmd:`getenv` | |||
- A variant name is passed as argument | - A variant name is passed as argument | |||
- Corresponding variant value is returned if it is defined | - Corresponding variant value is returned if it is defined | |||
- If not defined the *value if not defined* argument is returned | - If not defined the *value if not defined* argument is returned | |||
- By default *value if not defined* argument equals to the empty string | - By default *value if not defined* argument equals to the empty string | |||
- ``getvariant`` should be preferred to accessing variant value in ``ModuleVaria nt`` array | - ``getvariant`` should be preferred to accessing variant value in ``ModuleVaria nt`` array | |||
- On display evaluation mode, ``getvariant`` returns the variant name enclosed i n curly braces | - On display evaluation mode, ``getvariant`` returns the variant name enclosed i n curly braces | |||
- Which helps to report where the variant is used in environment variable co | - Which helps to report where the variant is used in environment variable cont | |||
ntent | ent | |||
- The variant name and enclosing curly braces are graphically enhanced with | - The variant name and enclosing curly braces are graphically enhanced with `` | |||
``va`` SGR code | va`` SGR code | |||
Persistency | Persistency | |||
^^^^^^^^^^^ | ^^^^^^^^^^^ | |||
- once a module is loaded its defined variants are made persistent in user envir onment | - once a module is loaded its defined variants are made persistent in user envir onment | |||
- to keep track of how loaded modules were evaluated | - to keep track of how loaded modules were evaluated | |||
- and enable query commands on these loaded modules without need to reevalua | - and enable query commands on these loaded modules without need to reevaluate | |||
te modulefile | modulefile | |||
- variants defined are made persistent in :envvar:`__MODULES_LMVARIANT` environm ent variable | - variants defined are made persistent in :envvar:`__MODULES_LMVARIANT` environm ent variable | |||
- following same approach than for :envvar:`__MODULES_LMPREREQ` | - following same approach than for :envvar:`__MODULES_LMPREREQ` | |||
- each loaded module with defined variants (default value or specifically se | - each loaded module with defined variants (default value or specifically set) | |||
t) will expose: | will expose: | |||
- these variants value | - these variants value | |||
- and if the value is the default one and if this default was specifical | - and if the value is the default one and if this default was specifically a | |||
ly asked | sked | |||
- in a record with following syntax: | - in a record with following syntax: | |||
- ``loadedmodule&boolvariantname1|isbooleanvariant|isdefaultvalue&varian | - ``loadedmodule&boolvariantname1|isbooleanvariant|isdefaultvalue&variantnam | |||
tname2|value2|value3...|isbooleanvariant|isdefaultvalue`` | e2|value2|value3...|isbooleanvariant|isdefaultvalue`` | |||
- for each variant it is recorded if the variant is a Boolean variant | - for each variant it is recorded if the variant is a Boolean variant | |||
- which enables to compare value in a Boolean way | - which enables to compare value in a Boolean way | |||
- and to report variant value with the *+variant* or *-variant* syntax | - and to report variant value with the *+variant* or *-variant* syntax | |||
- for each variant it is recorded if the value set corresponds to the varian t default value or not | - for each variant it is recorded if the value set corresponds to the variant default value or not | |||
- such information is useful to save collection when pin version mechani | - such information is useful to save collection when pin version mechanism i | |||
sm is disabled | s disabled | |||
- on such setup the variant definition should not recorded in collection | - on such setup the variant definition should not recorded in collection if | |||
if this is the default value which is set | this is the default value which is set | |||
- in addition to know if the variant value is default or not, it is recorded if the default value was: | - in addition to know if the variant value is default or not, it is recorded i f the default value was: | |||
- specifically asked (*isdefaultvalue=1*) | - specifically asked (*isdefaultvalue=1*) | |||
- or automatically set (*isdefaultvalue=2*) | - or automatically set (*isdefaultvalue=2*) | |||
- this information will be useful in the FUTURE to determine if a varian | - this information will be useful in the FUTURE to determine if a variant ma | |||
t may be automatically swapped by another | y be automatically swapped by another | |||
- each *loadedmodule* record are joined in ``__MODULES_LMVARIANT`` separated by ``:`` character | - each *loadedmodule* record are joined in ``__MODULES_LMVARIANT`` separated b y ``:`` character | |||
- variant alias are also made persistent in :envvar:`__MODULES_LMVARIANTALTNAME` environment variable | - variant alias are also made persistent in :envvar:`__MODULES_LMVARIANTALTNAME` environment variable | |||
- each loaded module with defined variants (default value or specifically se t) which could be aliased will expose their aliases in a record with following s yntax | - each loaded module with defined variants (default value or specifically set) which could be aliased will expose their aliases in a record with following syn tax | |||
- ``loadedmodule&variantname1|aliasname1|-aliasname2&variant2|aliasname3 ...`` | - ``loadedmodule&variantname1|aliasname1|-aliasname2&variant2|aliasname3...` ` | |||
- each loadedmodule record are joined in ``__MODULES_LMVARIANTALTNAME`` sepa rated by ``:`` character | - each loadedmodule record are joined in ``__MODULES_LMVARIANTALTNAME`` separa ted by ``:`` character | |||
- when persistency information is corrupted | - when persistency information is corrupted | |||
- a missing or non Boolean ``isdefaultvalue`` information means variant valu | - a missing or non Boolean ``isdefaultvalue`` information means variant value | |||
e is not the default | is not the default | |||
- a missing or non Boolean ``isbooleanvariant`` information means variant is | - a missing or non Boolean ``isbooleanvariant`` information means variant is n | |||
not a Boolean variant | ot a Boolean variant | |||
- a non-Boolean value set on a Boolean variant means variant equals *0* | - a non-Boolean value set on a Boolean variant means variant equals *0* | |||
- Boolean variants are stored in the form ``+name`` or ``-name`` | - Boolean variants are stored in the form ``+name`` or ``-name`` | |||
- which enables to determine this variant is of Boolean type | - which enables to determine this variant is of Boolean type | |||
- and check against query using different Boolean representations | - and check against query using different Boolean representations | |||
- like ``serial=0``, ``serial=on``, ``serial=false``, etc. | - like ``serial=0``, ``serial=on``, ``serial=false``, etc. | |||
- when the special variant ``version`` is defined for a loaded module | - when the special variant ``version`` is defined for a loaded module | |||
- the value of this variant is part of loaded module identification | - the value of this variant is part of loaded module identification | |||
- ``@versionvalue`` is appended to the module name, for instance ``mod@1.2`` | - ``@versionvalue`` is appended to the module name, for instance ``mod@1.2`` | |||
- such identification is then recorded in persistency variables to designate | - such identification is then recorded in persistency variables to designate l | |||
loaded module (like ``LOADEDMODULES``, ``__MODULES_LMPREREQ``, ``__MODULES_LMVA | oaded module (like ``LOADEDMODULES``, ``__MODULES_LMPREREQ``, ``__MODULES_LMVARI | |||
RIANT``, etc) | ANT``, etc) | |||
- this way in case a modulefile allows the load of two of its versions in th | - this way in case a modulefile allows the load of two of its versions in the | |||
e user environment, it is possible to distinguish these two loaded versions (to | user environment, it is possible to distinguish these two loaded versions (to un | |||
unload one of them for instance) | load one of them for instance) | |||
- with this identification, it is possible to distinguish a traditional modu | - with this identification, it is possible to distinguish a traditional module | |||
le (identified by ``mod/version``) from a module using ``version`` variant (iden | (identified by ``mod/version``) from a module using ``version`` variant (identi | |||
tified by ``mod@version``) | fied by ``mod@version``) | |||
- note that if a modulefile ``mod/1.2`` defines a ``version`` variant, it wi | - note that if a modulefile ``mod/1.2`` defines a ``version`` variant, it will | |||
ll be identified as ``mod/1.2@versionvalue`` | be identified as ``mod/1.2@versionvalue`` | |||
- so the ``version`` variant should not be defined if each version of th | - so the ``version`` variant should not be defined if each version of the mo | |||
e module has its own modulefile | dule has its own modulefile | |||
- ``version`` variant is useful if a single modulefile is used to instan | - ``version`` variant is useful if a single modulefile is used to instantiat | |||
tiate every version of the module | e every version of the module | |||
- FUTURE: when it will be possible to override the shortcut for ``version`` | - FUTURE: when it will be possible to override the shortcut for ``version`` va | |||
variant it will be important to identify version value in loaded module identifi | riant it will be important to identify version value in loaded module identifica | |||
cation string | tion string | |||
with a designation that is not dependent of the selected shortcut | with a designation that is not dependent of the selected shortcut | |||
- loaded module identification stops at the module name and ``version`` variant (if defined) | - loaded module identification stops at the module name and ``version`` variant (if defined) | |||
- other variants are not considered as part of the identification | - other variants are not considered as part of the identification | |||
- as it is not foreseen useful to have the same module loaded multiple times | - as it is not foreseen useful to have the same module loaded multiple times w | |||
with different variant values, unless for ``version`` variant | ith different variant values, unless for ``version`` variant | |||
Specifying | Specifying | |||
^^^^^^^^^^ | ^^^^^^^^^^ | |||
- following Spack spec | - following Spack spec | |||
- see https://github.com/spack/spack/blob/develop/lib/spack/spack/spec.py | - see https://github.com/spack/spack/blob/develop/lib/spack/spack/spec.py | |||
- or https://spack.readthedocs.io/en/latest/basic_usage.html#variants | - or https://spack.readthedocs.io/en/latest/basic_usage.html#variants | |||
- this specs covers all needs to specify variant on Modules | - this specs covers all needs to specify variant on Modules | |||
- Spack users are already familiar with it, | - Spack users are already familiar with it, | |||
- it copes very well with command-line typing, avoiding most problematic cha | - it copes very well with command-line typing, avoiding most problematic chara | |||
racters | cters | |||
- that are interpreted by shells (like < or >) | - that are interpreted by shells (like < or >) | |||
- specification for one module could | - specification for one module could | |||
- be almost condensed into one word *hdf5@1.8+debug* | - be almost condensed into one word *hdf5@1.8+debug* | |||
- or be expanded into multiple *hdf5 @1.8 +debug* | - or be expanded into multiple *hdf5 @1.8 +debug* | |||
- same grammar used whatever the context | - same grammar used whatever the context | |||
- command-line or as argument to modulefile command (like command) | - command-line or as argument to modulefile command (like command) | |||
- variants are specified whether | - variants are specified whether | |||
- as specific words (separated by " ") | - as specific words (separated by " ") | |||
- or as suffix to module name | - or as suffix to module name | |||
- change command specifications which were previously accepting list of modules | - change command specifications which were previously accepting list of modules | |||
- like *module1 module2 module3* | - like *module1 module2 module3* | |||
- now these modules could express variants appended to their name | - now these modules could express variants appended to their name | |||
- like *module1@1.8+debug module2~shared module3* | - like *module1@1.8+debug module2~shared module3* | |||
- or these variants could be defined as words next to module name | - or these variants could be defined as words next to module name | |||
- like *module1@1.8 +debug module2 shared=false module3* | - like *module1@1.8 +debug module2 shared=false module3* | |||
- as a consequence it denies: | - as a consequence it denies: | |||
- use of *+*, *~* and *=* in module names | - use of *+*, *~* and *=* in module names | |||
- and use of *-* as first character of module names | - and use of *-* as first character of module names | |||
- also a command-line argument starting with the *-* character is not anymor e considered as an invalid option | - also a command-line argument starting with the *-* character is not anymore considered as an invalid option | |||
- it is considered as an element of the module specification (potential | - it is considered as an element of the module specification (potential nega | |||
negated boolean variant) | ted boolean variant) | |||
- unless if set prior the sub-command designation | - unless if set prior the sub-command designation | |||
- or set on sub-commands that do not accept module specification as argu | - or set on sub-commands that do not accept module specification as argument | |||
ment | ||||
- such change requires an option to be enabled to avoid breaking compat | - such change requires an option to be enabled to avoid breaking compat | |||
- this is why to enable variant, the ``advanced_version_spec`` option ha s to be enabled | - this is why to enable variant, the ``advanced_version_spec`` option has to be enabled | |||
- a valued-variant is specified by *name=value* | - a valued-variant is specified by *name=value* | |||
- this kind of variant cannot be directly appended to module name | - this kind of variant cannot be directly appended to module name | |||
- thus it must be specified as a separate word | - thus it must be specified as a separate word | |||
- a Boolean variant can be specified with its bare name prefixed by *+*, *-* or *~* | - a Boolean variant can be specified with its bare name prefixed by *+*, *-* or *~* | |||
- when directly appended to module name string (no space) only *+* and *~* a re recognized | - when directly appended to module name string (no space) only *+* and *~* are recognized | |||
- *-* in this case is retained as part of previous name/value | - *-* in this case is retained as part of previous name/value | |||
- the negation prefix *-* is not supported on the :command:`ml` command | - the negation prefix *-* is not supported on the :command:`ml` command | |||
- as this *-* prefix means to unload a module on this command | - as this *-* prefix means to unload a module on this command | |||
- negation prefix plus Boolean variant name should not equal a command-line option short form | - negation prefix plus Boolean variant name should not equal a command-line op tion short form | |||
- command-line option takes precedence | - command-line option takes precedence | |||
- for instance the ``-t`` will always be treated as ``--terse`` and not | - for instance the ``-t`` will always be treated as ``--terse`` and not the | |||
the negation of a ``t`` variant | negation of a ``t`` variant | |||
- beware that the negation prefix *~* when used as a separate word may trigg er the tilde resolution of the currently running shell | - beware that the negation prefix *~* when used as a separate word may trigger the tilde resolution of the currently running shell | |||
- if a username matches a Boolean variant name, using the ``~name`` form on the shell command-line will leads to the resolution of the HOME directory pa th of user ``name`` | - if a username matches a Boolean variant name, using the ``~name`` form on the shell command-line will leads to the resolution of the HOME directory path o f user ``name`` | |||
- module name could end with one or more *+* characters | - module name could end with one or more *+* characters | |||
- it could be distinguished from a Boolean variant specification as no c haracter should follow these trailing *+* | - it could be distinguished from a Boolean variant specification as no chara cter should follow these trailing *+* | |||
- Boolean variant could also be specified using the *name=value* form | - Boolean variant could also be specified using the *name=value* form | |||
- in which case, it should be written as a separate word | - in which case, it should be written as a separate word | |||
- value could be any syntax recognized as a true or false string | - value could be any syntax recognized as a true or false string | |||
- false: *0*, *false*, *no*, or *off* | - false: *0*, *false*, *no*, or *off* | |||
- true: *1*, *true*, *yes*, or *on* | - true: *1*, *true*, *yes*, or *on* | |||
- Any of these values may be abbreviated, and upper-case spellings a | - Any of these values may be abbreviated, and upper-case spellings are als | |||
re also acceptable. | o acceptable. | |||
- when specified Boolean value is translated to its canonical form (*0* or * 1*) | - when specified Boolean value is translated to its canonical form (*0* or *1* ) | |||
- variant may be specified with a shortcut if any set (see :ref:`variant-shortcu t`) | - variant may be specified with a shortcut if any set (see :ref:`variant-shortcu t`) | |||
- a shortcut is appended to the module designation word or specified as sepa rate word, combined or not with other variant | - a shortcut is appended to the module designation word or specified as separa te word, combined or not with other variant | |||
- for instance for the ``@`` shortcut: *module@versspec+boolvar*, *modul e+boolvar@versspec*, *module +boolvar@versspec* | - for instance for the ``@`` shortcut: *module@versspec+boolvar*, *module+bo olvar@versspec*, *module +boolvar@versspec* | |||
- even if a shortcut is set, the variant could also be expressed as valued v ariant name | - even if a shortcut is set, the variant could also be expressed as valued var iant name | |||
- in case variant is specified multiple times | - in case variant is specified multiple times | |||
- lastly mentioned (read from left to right) value is retained (it overwrite s previous values) | - lastly mentioned (read from left to right) value is retained (it overwrites previous values) | |||
- a *merge all passed values in list* is not the methodology retained he re | - a *merge all passed values in list* is not the methodology retained here | |||
- same handling way whatever the variant properties | - same handling way whatever the variant properties | |||
- like *name=value1 name=value2* | - like *name=value1 name=value2* | |||
- or *name=value name=value* | - or *name=value name=value* | |||
- or *name=value1,value2 name=value3* | - or *name=value1,value2 name=value3* | |||
- or *name=value1 name=value2,value3* | - or *name=value1 name=value2,value3* | |||
- or *@vers1 version=vers2* | - or *@vers1 version=vers2* | |||
- or for boolean *+name~name* | - or for boolean *+name~name* | |||
- or *~name -name* | - or *~name -name* | |||
- or *~name name=value1 name=value2,value3* | - or *~name name=value1 name=value2,value3* | |||
- or in case of variant aliases *+name~aliastoname* | - or in case of variant aliases *+name~aliastoname* | |||
- at the specification time variant aliases are not known | - at the specification time variant aliases are not known | |||
- so the full module specification has to be transmitted toward the modu | - so the full module specification has to be transmitted toward the modulefi | |||
lefile to determine what is the value at the most right position | le to determine what is the value at the most right position | |||
- for instance *name=value1 aliasname=value2* with *aliasname* being an | - for instance *name=value1 aliasname=value2* with *aliasname* being an alia | |||
alias of *name* | s of *name* | |||
- specification can just be cleared from the obvious duplicates (same va | - specification can just be cleared from the obvious duplicates (same varian | |||
riant name defined multiple times on the line) | t name defined multiple times on the line) | |||
- when special characters like *?* or \* are used in variant name or value | - when special characters like *?* or \* are used in variant name or value | |||
- they are treated literally, no wildcard meaning is applied | - they are treated literally, no wildcard meaning is applied | |||
- like currently done when specifying module version on command-line | - like currently done when specifying module version on command-line | |||
- which leads to errors as no corresponding module is found:: | - which leads to errors as no corresponding module is found:: | |||
$ module load loc_dv6/* | $ module load loc_dv6/* | |||
ERROR: Unable to locate a modulefile for 'loc_dv6/*' | ERROR: Unable to locate a modulefile for 'loc_dv6/*' | |||
- when a variant is specified but it does not correspond to a variant defined in the evaluated modulefile | - when a variant is specified but it does not correspond to a variant defined in the evaluated modulefile | |||
- an error is raised at the end of modulefile evaluation | - an error is raised at the end of modulefile evaluation | |||
- need to wait for the end of modulefile evaluation to be sure the variant i | - need to wait for the end of modulefile evaluation to be sure the variant is | |||
s defined nowhere in modulefile code | defined nowhere in modulefile code | |||
- special variant ``version`` has to be specified with ``@`` shortcut or by its full variant name (``version=value``) | - special variant ``version`` has to be specified with ``@`` shortcut or by its full variant name (``version=value``) | |||
- traditional separator character ``/`` cannot be used to specify variant ve | - traditional separator character ``/`` cannot be used to specify variant vers | |||
rsion | ion | |||
- if used, a modulefile named ``mod/version`` will be searched and a *module | - if used, a modulefile named ``mod/version`` will be searched and a *module n | |||
not found* error will be raised | ot found* error will be raised | |||
- specification may be passed to commands to verify a given module and variant c ombination is loaded | - specification may be passed to commands to verify a given module and variant c ombination is loaded | |||
- which should be performed without evaluating modulefiles | - which should be performed without evaluating modulefiles | |||
- like for ``is-loaded`` sub-command: | - like for ``is-loaded`` sub-command: | |||
- ``module is-loaded hdf5+parallel`` | - ``module is-loaded hdf5+parallel`` | |||
- or ``hdf5@1.8 parallel=true`` | - or ``hdf5@1.8 parallel=true`` | |||
- or ``hdf5 -serial`` | - or ``hdf5 -serial`` | |||
- or ``hdf5 serial=0`` | - or ``hdf5 serial=0`` | |||
- checks rely on the content of the ``__MODULES_LMVARIANT`` and ``__MODULES_ LMVARIANTALTNAME`` variables | - checks rely on the content of the ``__MODULES_LMVARIANT`` and ``__MODULES_LM VARIANTALTNAME`` variables | |||
- which store variants set for loaded modules and eventual variant alias es of variant set | - which store variants set for loaded modules and eventual variant aliases o f variant set | |||
- with this information it is possible to compare query against what is load ed | - with this information it is possible to compare query against what is loaded | |||
- a variant specified on query which is not part of the variables means a different module/variant combination | - a variant specified on query which is not part of the variables means a di fferent module/variant combination | |||
- even if variant from query is not valid for module, which cannot b e known | - even if variant from query is not valid for module, which cannot be know n | |||
- verification mechanism of a sub-command like ``is-loaded`` should be prese rved | - verification mechanism of a sub-command like ``is-loaded`` should be preserv ed | |||
- which means a query not mentioning a specific value for a variant shou ld match a loaded module which specify a variant value that differs from this va riant default | - which means a query not mentioning a specific value for a variant should m atch a loaded module which specify a variant value that differs from this varian t default | |||
- the module identification part in specification may be resolved from a sym bolic version or a module alias to an actual modulefile | - the module identification part in specification may be resolved from a symbo lic version or a module alias to an actual modulefile | |||
- the ``@loaded`` specification is translated into the name, version and variant list of corresponding loaded module | - the ``@loaded`` specification is translated into the name, version and variant list of corresponding loaded module | |||
- for instance ``mod/3.0 foo=val1`` is loaded so ``mod@loaded`` is translate | - for instance ``mod/3.0 foo=val1`` is loaded so ``mod@loaded`` is translated | |||
d into ``mod/3.0 foo=val1`` | into ``mod/3.0 foo=val1`` | |||
- in case the ``@loaded`` specification is followed by variant specified, th | - in case the ``@loaded`` specification is followed by variant specified, thos | |||
ose variant specifications are ignored | e variant specifications are ignored | |||
- following the above example, ``mod@loaded foo=val2`` is translated into `` | - following the above example, ``mod@loaded foo=val2`` is translated into ``mo | |||
mod/3.0 foo=val1`` | d/3.0 foo=val1`` | |||
- variant can also be specified to designate module on :mfcmd:`module-tag`, :mfc md:`module-hide` or :mfcmd:`module-forbid` commands | - variant can also be specified to designate module on :mfcmd:`module-tag`, :mfc md:`module-hide` or :mfcmd:`module-forbid` commands | |||
- tags may only apply when a given variant of a module is loaded | - tags may only apply when a given variant of a module is loaded | |||
- it may be useful to decommission a given variant of a module prior others | - it may be useful to decommission a given variant of a module prior others | |||
- or to forbid the use of a given variant to some users | - or to forbid the use of a given variant to some users | |||
- variants specified on search context are ignored | - variants specified on search context are ignored | |||
- search context taking a module specification as argument only look for mod ule name and version | - search context taking a module specification as argument only look for modul e name and version | |||
- no variant evaluation occurs on such context | - no variant evaluation occurs on such context | |||
- it concerns the ``avail``, ``whatis``, ``is-avail``, ``path`` and ``pa | - it concerns the ``avail``, ``whatis``, ``is-avail``, ``path`` and ``paths` | |||
ths`` sub-commands | ` sub-commands | |||
- if variants are defined within module specification, they are not taken in | - if variants are defined within module specification, they are not taken into | |||
to account by search commands | account by search commands | |||
- for instance ``avail mod foo=var`` returns all versions of *foo* module wh | - for instance ``avail mod foo=var`` returns all versions of *foo* module whet | |||
ether they support the foo variant or not | her they support the foo variant or not | |||
- FUTURE: may be revised if variants are evaluated on search context | - FUTURE: may be revised if variants are evaluated on search context | |||
- variant cannot be specified over the :mfcmd:`module-alias`, :mfcmd:`module-ver sion`, :mfcmd:`module-virtual` commands | - variant cannot be specified over the :mfcmd:`module-alias`, :mfcmd:`module-ver sion`, :mfcmd:`module-virtual` commands | |||
- variant passed as argument to :mfcmd:`module-info` ``alias``, ``version`` or ` `symbols`` will not match anything | - variant passed as argument to :mfcmd:`module-info` ``alias``, ``version`` or ` `symbols`` will not match anything | |||
- ``module-info loaded`` only accepts modulefile as argument, not variant specif ication | - ``module-info loaded`` only accepts modulefile as argument, not variant specif ication | |||
- it also only return loaded module name and version, without the variant se t | - it also only return loaded module name and version, without the variant set | |||
Variant in requirement specification | Variant in requirement specification | |||
"""""""""""""""""""""""""""""""""""" | """""""""""""""""""""""""""""""""""" | |||
- :mfcmd:`prereq`/:mfcmd:`conflict` specification | - :mfcmd:`prereq`/:mfcmd:`conflict` specification | |||
- could consolidate different variation set for same module on the same prer eq/conflict list | - could consolidate different variation set for same module on the same prereq /conflict list | |||
- to indicate a preferred order (if available) | - to indicate a preferred order (if available) | |||
- like ``prereq netcdf -debug netcdf +debug`` | - like ``prereq netcdf -debug netcdf +debug`` | |||
- or ``prereq netcdf var=val1 netcdf var=val2 netcdf`` | - or ``prereq netcdf var=val1 netcdf var=val2 netcdf`` | |||
- in last example, could not currently consolidate definition into ``prereq netcdf var=val1,val2,default`` | - in last example, could not currently consolidate definition into ``prereq ne tcdf var=val1,val2,default`` | |||
- in case of requirement alternatives, all possibilities should be writt en as independent | - in case of requirement alternatives, all possibilities should be written a s independent | |||
- like ``prereq module@vers variant=val1 module@vers variant=val2`` | - like ``prereq module@vers variant=val1 module@vers variant=val2`` | |||
- to clearly indicate a priority order to apply when for instance attemp | - to clearly indicate a priority order to apply when for instance attempting | |||
ting to load these requirements | to load these requirements | |||
- FUTURE: a value selection mechanism, like when selecting a module vers | - FUTURE: a value selection mechanism, like when selecting a module version | |||
ion among others, would help here | among others, would help here | |||
- prereq/conflict persistency | - prereq/conflict persistency | |||
- :envvar:`__MODULES_LMPREREQ` and :envvar:`__MODULES_LMCONFLICT` content sh ould reflect specified variant constraint | - :envvar:`__MODULES_LMPREREQ` and :envvar:`__MODULES_LMCONFLICT` content shou ld reflect specified variant constraint | |||
- it could be expressed in these variables as it is specified over the prere q/conflict modulefile commands | - it could be expressed in these variables as it is specified over the prereq/ conflict modulefile commands | |||
- for instance ``__MODULES_LMPREREQ=hdf5/1.10&mpi@1.8 +shared variant=na | - for instance ``__MODULES_LMPREREQ=hdf5/1.10&mpi@1.8 +shared variant=name&n | |||
me&netcdf`` | etcdf`` | |||
- use of characters `` ``, ``+``, ``~``, ``,`` is not an issue | - use of characters `` ``, ``+``, ``~``, ``,`` is not an issue | |||
- as delimiters characters in these environment variables are ``:``, ``&`` and ``|`` | - as delimiters characters in these environment variables are ``:``, ``&`` and ``|`` | |||
.. _variant-shortcut: | .. _variant-shortcut: | |||
Variant shortcut | Variant shortcut | |||
"""""""""""""""" | """""""""""""""" | |||
- shortcuts can be set to abbreviate variant names and simplify their specificat ion | - shortcuts can be set to abbreviate variant names and simplify their specificat ion | |||
- a shortcut abbreviates ``name=`` into a unique character | - a shortcut abbreviates ``name=`` into a unique character | |||
- when using shortcut, variant value is specified as ``<shortcut>value`` | - when using shortcut, variant value is specified as ``<shortcut>value`` | |||
- for instance, if the ``%`` is set as the shortcut for a ``toolchain`` vari | - for instance, if the ``%`` is set as the shortcut for a ``toolchain`` varian | |||
ant, value ``foss21a`` is specified as ``%foss21a`` | t, value ``foss21a`` is specified as ``%foss21a`` | |||
- shortcut can be set through the :mconfig:`variant_shortcut` configuration opti on | - shortcut can be set through the :mconfig:`variant_shortcut` configuration opti on | |||
- this option holds a colon separated list of shortcut definitions | - this option holds a colon separated list of shortcut definitions | |||
- each definition have the following form: ``variantname=shortcut_character` | - each definition have the following form: ``variantname=shortcut_character`` | |||
` | - for instance: ``toolchain=%:foo=^`` | |||
- for instance: ``toolchain=%:foo=^`` | ||||
- shortcut must be: | - shortcut must be: | |||
- a single character | - a single character | |||
- excluding characters already used for other concerns or in module names (* | - excluding characters already used for other concerns or in module names (*-* | |||
-*, *+*, *~*, */*, *@*, *=*, *[a-zA-Z0-9]*) | , *+*, *~*, */*, *@*, *=*, *[a-zA-Z0-9]*) | |||
- when set through ``config`` sub-command or ``--with-variant-shortcut`` ins | - when set through ``config`` sub-command or ``--with-variant-shortcut`` insta | |||
tallation option: an error is raised when a shortcut is badly specified | llation option: an error is raised when a shortcut is badly specified | |||
- if a badly specified shortcut ends up in modulecmd configuration, it is pu | - if a badly specified shortcut ends up in modulecmd configuration, it is pure | |||
rely ignored | ly ignored | |||
- shortcut does not apply to Boolean variants | - shortcut does not apply to Boolean variants | |||
- as shortcuts are intended to be a prefix, they do not add benefit compared | - as shortcuts are intended to be a prefix, they do not add benefit compared t | |||
to *-*, *+* or *~* Boolean prefixes | o *-*, *+* or *~* Boolean prefixes | |||
- however a shortcut could be defined on a boolean variant (e.g., ``%true`` | - however a shortcut could be defined on a boolean variant (e.g., ``%true`` or | |||
or ``%0``) | ``%0``) | |||
- by default, when ``advanced_version_spec`` is enabled, the ``@`` character is set as a shortcut for the ``version`` variant | - by default, when ``advanced_version_spec`` is enabled, the ``@`` character is set as a shortcut for the ``version`` variant | |||
- this shortcut is not referred in ``MODULES_VARIANT_SHORTCUT`` thus it cann | - this shortcut is not referred in ``MODULES_VARIANT_SHORTCUT`` thus it cannot | |||
ot be unset | be unset | |||
- FUTURE: superseding of this ``@`` shortcut in ``MODULES_VARIANT_SHORTCUT`` | - FUTURE: superseding of this ``@`` shortcut in ``MODULES_VARIANT_SHORTCUT`` m | |||
may be introduced in the future | ay be introduced in the future | |||
- but currently entries in ``MODULES_VARIANT_SHORTCUT`` for ``version`` variant are ignored | - but currently entries in ``MODULES_VARIANT_SHORTCUT`` for ``version`` vari ant are ignored | |||
- variant shortcuts could be used on the command-line or within modulefiles even if it is not recommended to use them in the latter case | - variant shortcuts could be used on the command-line or within modulefiles even if it is not recommended to use them in the latter case | |||
- as if user updates the ``variant_shortcut`` configuration option, it will broke underlying modulefiles using a de-configured shortcuts | - as if user updates the ``variant_shortcut`` configuration option, it will br oke underlying modulefiles using a de-configured shortcuts | |||
- module designation in collection does not use variant shortcuts | - module designation in collection does not use variant shortcuts | |||
- when shortcut configuration is changed it should not impact collection def inition | - when shortcut configuration is changed it should not impact collection defin ition | |||
Reporting | Reporting | |||
^^^^^^^^^ | ^^^^^^^^^ | |||
- Defined variants are reported on ``list`` sub-command results | - Defined variants are reported on ``list`` sub-command results | |||
- Reported joined to modulefile name, within curly braces | - Reported joined to modulefile name, within curly braces | |||
- Each variant definition separated by a colon | - Each variant definition separated by a colon | |||
- For instance ``module/version{vr=val:+boolvr}`` | - For instance ``module/version{vr=val:+boolvr}`` | |||
- Variants are reported by default on ``list`` sub-command | - Variants are reported by default on ``list`` sub-command | |||
- as they qualify what exact flavor of the module is loaded | - as they qualify what exact flavor of the module is loaded | |||
- so it enables users to really catch what has been loaded exactly | - so it enables users to really catch what has been loaded exactly | |||
- They can be removed from output using the :ref:`output configuration<outpu | - They can be removed from output using the :ref:`output configuration<output- | |||
t-configuration>` mechanism | configuration>` mechanism | |||
- Variants defined by modulefiles are not reported currently on ``avail`` sub-co mmand as it requires to evaluate the modulefiles | - Variants defined by modulefiles are not reported currently on ``avail`` sub-co mmand as it requires to evaluate the modulefiles | |||
- FUTURE: this could be implemented later on, but such evaluation of all mod | - FUTURE: this could be implemented later on, but such evaluation of all modul | |||
ulefiles would be really expensive | efiles would be really expensive | |||
- it will take a lot more time to get ``avail`` results (unless a valid cach | - it will take a lot more time to get ``avail`` results (unless a valid cache | |||
e is found) | is found) | |||
- A specific color key is defined to highlight variants: ``va`` | - A specific color key is defined to highlight variants: ``va`` | |||
- Variant report depends on variant type | - Variant report depends on variant type | |||
- valued variant: ``variant=value`` | - valued variant: ``variant=value`` | |||
- boolean variant: ``+variant`` or ``-variant`` | - boolean variant: ``+variant`` or ``-variant`` | |||
- valued variant with shortcut set: ``<shortcut>value`` (for instance if ``% | - valued variant with shortcut set: ``<shortcut>value`` (for instance if ``%`` | |||
`` is a defined shortcut: ``%value``) | is a defined shortcut: ``%value``) | |||
- in case a shortcut is defined over a Boolean variant, Boolean report preva | - in case a shortcut is defined over a Boolean variant, Boolean report prevail | |||
ils over shortcut | s over shortcut | |||
- Variant aliases are not reported | - Variant aliases are not reported | |||
- to keep output tight | - to keep output tight | |||
- Special variant ``version`` is reported right after the module name | - Special variant ``version`` is reported right after the module name | |||
- with ``@`` shortcut | - with ``@`` shortcut | |||
- using variant highlight color if any | - using variant highlight color if any | |||
- for instance: ``module@version{othervariant=value}`` | - for instance: ``module@version{othervariant=value}`` | |||
- Variants are reported on the *Loading*, *Unloading* and *Switching* informatio nal messages | - Variants are reported on the *Loading*, *Unloading* and *Switching* informatio nal messages | |||
- As they qualify what exact flavor of the module is loaded, unloaded or swi | - As they qualify what exact flavor of the module is loaded, unloaded or switc | |||
tched | hed | |||
- They are put along the module name and version designation | - They are put along the module name and version designation | |||
- They are reported using their short form, like for ``list`` sub-command to | - They are reported using their short form, like for ``list`` sub-command to k | |||
keep output tight | eep output tight | |||
- Separated between each other by space character | - Separated between each other by space character | |||
- Each variant specification is enclosed between single quotes if it contain | - Each variant specification is enclosed between single quotes if it contains | |||
s a space character | a space character | |||
- The whole variant specification is enclosed between curly braces (``{}``) | - The whole variant specification is enclosed between curly braces (``{}``) an | |||
and separated from module name version by space character | d separated from module name version by space character | |||
- Easier this way to distinguish variant specification from module name version on informational messages where multiple module designation are reported | - Easier this way to distinguish variant specification from module name vers ion on informational messages where multiple module designation are reported | |||
- These designations have to be recorded | - These designations have to be recorded | |||
- prior module evaluation and based on variant specification (passed as | - prior module evaluation and based on variant specification (passed as argu | |||
argument) in order to be ready for any report prior the end of modulefile evalua | ment) in order to be ready for any report prior the end of modulefile evaluation | |||
tion (in case of error for instance) | (in case of error for instance) | |||
- then refined after module evaluation with the variant accurately set i | - then refined after module evaluation with the variant accurately set in lo | |||
n loaded environment | aded environment | |||
- Variants are also reported along module name and version in the :mconfig:`auto _handling` informational messages | - Variants are also reported along module name and version in the :mconfig:`auto _handling` informational messages | |||
Recording collection | Recording collection | |||
^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^ | |||
- The variant specification set for loaded modules has to be recorded when savin g it in a collection | - The variant specification set for loaded modules has to be recorded when savin g it in a collection | |||
- Restoring such environment should apply the variant specified on the modul | - Restoring such environment should apply the variant specified on the module | |||
e to load | to load | |||
- Lines like the following one could now be found in collection: ``module lo | - Lines like the following one could now be found in collection: ``module load | |||
ad hdf5@1.10 +parallel`` | hdf5@1.10 +parallel`` | |||
- Important to distinguish multiple modules specified on a single line from | - Important to distinguish multiple modules specified on a single line from a | |||
a module specified with variant defined | module specified with variant defined | |||
- In case the :mconfig:`collection_pin_version` configuration option is disabled variant set to their default value should not be recorded in collection | - In case the :mconfig:`collection_pin_version` configuration option is disabled variant set to their default value should not be recorded in collection | |||
- Following the same scheme than for module version | - Following the same scheme than for module version | |||
- When saving collection, the *is-default-value* information stored in persi | - When saving collection, the *is-default-value* information stored in persist | |||
stency variable (``__MODULES_LMVARIANT``) helps to know whether the value set to | ency variable (``__MODULES_LMVARIANT``) helps to know whether the value set to a | |||
a variant is or not the default one | variant is or not the default one | |||
- The save mechanism will rely on this information to exclude or not the var | - The save mechanism will rely on this information to exclude or not the varia | |||
iant specification in the generated collection output | nt specification in the generated collection output | |||
- Within this *is-default-value* hint, the *was-this-default-specified-by-us | - Within this *is-default-value* hint, the *was-this-default-specified-by-user | |||
er* sub-information is not preserved when saving collection | * sub-information is not preserved when saving collection | |||
- if collection is not pinned, default value is excluded whether it was specifically set by user or not | - if collection is not pinned, default value is excluded whether it was spec ifically set by user or not | |||
Comparing module specification including variants | Comparing module specification including variants | |||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |||
- When a module specification has to be compared on a non-loaded or non-loading modules context | - When a module specification has to be compared on a non-loaded or non-loading modules context | |||
- If this specification contains variants | - If this specification contains variants | |||
- There is no variant set on non-loaded or non-loading modules we are co | - There is no variant set on non-loaded or non-loading modules we are compar | |||
mparing to | ing to | |||
- Specified variants are ignored, match is only performed over module na | - Specified variants are ignored, match is only performed over module name a | |||
me and version | nd version | |||
- Applies especially to the search commands taking a module specificatio | - Applies especially to the search commands taking a module specification as | |||
n as argument | argument | |||
- no variant evaluation occurs on such context | - no variant evaluation occurs on such context | |||
- Namely the ``avail``, ``whatis``, ``is-avail``, ``path`` and ``pat | - Namely the ``avail``, ``whatis``, ``is-avail``, ``path`` and ``paths`` s | |||
hs`` sub-commands | ub-commands | |||
- If this specification does not contain variant | - If this specification does not contain variant | |||
- There is no variant set on non-loaded or non-loading modules we are co | - There is no variant set on non-loaded or non-loading modules we are compar | |||
mparing to | ing to | |||
- Match is performed over module name and version | - Match is performed over module name and version | |||
- When a module specification has to be compared against loaded or loading modul es | - When a module specification has to be compared against loaded or loading modul es | |||
- If this specification contains variants | - If this specification contains variants | |||
- It should be matched against the variants set on loaded or loading mod | - It should be matched against the variants set on loaded or loading modules | |||
ules | - No variant set for loaded or loading module means no match | |||
- No variant set for loaded or loading module means no match | ||||
- If this specification does not contain variant | - If this specification does not contain variant | |||
- Loaded or loading modules match is only made on their name | - Loaded or loading modules match is only made on their name | |||
- No comparison occurs over the variants set on loaded or loading module | - No comparison occurs over the variants set on loaded or loading modules | |||
s | ||||
- To compare variant set on loaded or loading modules | - To compare variant set on loaded or loading modules | |||
- A ``ismodlo`` flag is added to the ``modEq`` procedure | - A ``ismodlo`` flag is added to the ``modEq`` procedure | |||
- With this flag it is known if ``modEq`` operates on a: | - With this flag it is known if ``modEq`` operates on a: | |||
- non-loaded or non-loading context (0), | - non-loaded or non-loading context (0), | |||
- loading context (1) | - loading context (1) | |||
- loaded context (2) | - loaded context (2) | |||
- Variants set on loading or loaded modules will be fetched in case ``ismodl | - Variants set on loading or loaded modules will be fetched in case ``ismodlo` | |||
o`` is equal to 1 or 2 | ` is equal to 1 or 2 | |||
- Loaded or loading modules are passed to ``modEq`` by their name/version de | - Loaded or loading modules are passed to ``modEq`` by their name/version desi | |||
signation | gnation | |||
- No change here | - No change here | |||
- And no change required in all procedures that perform such comparison | - And no change required in all procedures that perform such comparison | |||
- Alternative names should also be tested like main module name with variant s set | - Alternative names should also be tested like main module name with variants set | |||
- As the alternative names currently apply to module name and version on | - As the alternative names currently apply to module name and version only | |||
ly | - Name and version could be compared on their own | |||
- Name and version could be compared on their own | - Then variants could be compared | |||
- Then variants could be compared | - Which means all applying names are compared then if a match is found varia | |||
- Which means all applying names are compared then if a match is found v | nts are compared | |||
ariants are compared | ||||
- Specific comparison occurs when restoring collection | - Specific comparison occurs when restoring collection | |||
- When a collection is restored an unspecified variant for a given module to | - When a collection is restored an unspecified variant for a given module to l | |||
load means this variant has to be set at its default value | oad means this variant has to be set at its default value | |||
- So when comparing against loaded environment, an unspecified variant in co | - So when comparing against loaded environment, an unspecified variant in coll | |||
llection only matches if variant set on loaded environment is the default one | ection only matches if variant set on loaded environment is the default one | |||
- Collection procedures now rely on the ``modEq`` procedure | - Collection procedures now rely on the ``modEq`` procedure | |||
- ``ismodlo`` flag is set to ``3`` to indicate a collection context | - ``ismodlo`` flag is set to ``3`` to indicate a collection context | |||
- This collection context leads to also compare simplified module names | - This collection context leads to also compare simplified module names (in | |||
(in addition to alternative names) | addition to alternative names) | |||
- And to treat an unspecified variant on tested pattern as a default var | - And to treat an unspecified variant on tested pattern as a default variant | |||
iant value | value | |||
- There is no need to compare variants on following procedures | - There is no need to compare variants on following procedures | |||
- ``getLoadedWithClosestName`` | - ``getLoadedWithClosestName`` | |||
- Find a loaded module whose name and version is the closest to passed s | - Find a loaded module whose name and version is the closest to passed speci | |||
pecification | fication | |||
- Variant specified on loaded modules or on specification is ignored her | - Variant specified on loaded modules or on specification is ignored here | |||
e | ||||
- ``modStartNb`` | - ``modStartNb`` | |||
- Only used to compare module name and versions | - Only used to compare module name and versions | |||
- Used by ``getLoadedWithClosestName`` and ``isModuleHidden`` | - Used by ``getLoadedWithClosestName`` and ``isModuleHidden`` | |||
- ``modEqStatic`` | - ``modEqStatic`` | |||
- Always used over non-loaded or non-loading context | - Always used over non-loaded or non-loading context | |||
- Used by ``findModules`` and ``getModules`` | - Used by ``findModules`` and ``getModules`` | |||
- ``getEqArrayKey`` | - ``getEqArrayKey`` | |||
- ``cmdModuleSearch`` | - ``cmdModuleSearch`` | |||
- ``cmdModuleSwitch`` | - ``cmdModuleSwitch`` | |||
- ``getModules`` | - ``getModules`` | |||
- Used by ``cmdModuleAvail``, ``getPathToModule``, ``isStickinessReloadi | - Used by ``cmdModuleAvail``, ``getPathToModule``, ``isStickinessReloading`` | |||
ng``, | , | |||
``cmdModulePaths``, ``cmdModuleSearch`` and ``cmdModuleAliases`` | ``cmdModulePaths``, ``cmdModuleSearch`` and ``cmdModuleAliases`` | |||
- ``getPathToModule`` | - ``getPathToModule`` | |||
- Which calls to ``getModules`` | - Which calls to ``getModules`` | |||
- Used by ``cmdModulePath``, ``cmdModuleSearch``, ``cmdModuleSwitch``, ` | - Used by ``cmdModulePath``, ``cmdModuleSearch``, ``cmdModuleSwitch``, ``cmd | |||
`cmdModuleLoad``, | ModuleLoad``, | |||
``cmdModuleUnload``, ``cmdModuleTest``, ``cmdModuleHelp``, ``getAllMod | ``cmdModuleUnload``, ``cmdModuleTest``, ``cmdModuleHelp``, ``getAllModuleR | |||
uleResolvedName``, | esolvedName``, | |||
``is-avail``, ``getSimplifiedLoadedModuleList`` and ``cmdModuleDisplay | ``is-avail``, ``getSimplifiedLoadedModuleList`` and ``cmdModuleDisplay`` | |||
`` | ||||
- ``getAllModuleResolvedName`` | - ``getAllModuleResolvedName`` | |||
- Variant comparison is needed on following procedures | - Variant comparison is needed on following procedures | |||
- ``setModuleDependency`` | - ``setModuleDependency`` | |||
- ``getUnmetDependentLoadedModuleList`` | - ``getUnmetDependentLoadedModuleList`` | |||
- ``getDirectDependentList`` | - ``getDirectDependentList`` | |||
- ``cmdModuleLoad`` | - ``cmdModuleLoad`` | |||
- ``conflict`` | - ``conflict`` | |||
- ``getLoadedMatchingName`` | - ``getLoadedMatchingName`` | |||
- ``doesModuleConflict`` | - ``doesModuleConflict`` | |||
- ``getModuleTag`` | - ``getModuleTag`` | |||
- Useful when a tag is defined only when a specific variant is set | - Useful when a tag is defined only when a specific variant is set | |||
- ``collectModuleTag`` | - ``collectModuleTag`` | |||
- Useful when a tag is defined only when a specific variant is set | - Useful when a tag is defined only when a specific variant is set | |||
- ``getModuleHidingLevel`` | - ``getModuleHidingLevel`` | |||
- Useful when a module with a specific variant value set is defined hidd | - Useful when a module with a specific variant value set is defined hidden | |||
en | - FUTURE: if variants are reported on ``avail``, hiding a variant specific v | |||
- FUTURE: if variants are reported on ``avail``, hiding a variant specif | alue | |||
ic value | would have an effect on this sub-command | |||
would have an effect on this sub-command | ||||
- ``isModuleHidden`` | - ``isModuleHidden`` | |||
- Useful when a module with a specific variant value set is defined hidd | - Useful when a module with a specific variant value set is defined hidden | |||
en | - FUTURE: if variants are reported on ``avail``, hiding a variant specific v | |||
- FUTURE: if variants are reported on ``avail``, hiding a variant specif | alue | |||
ic value | would have an effect on this sub-command | |||
would have an effect on this sub-command | ||||
Specific impact | Specific impact | |||
^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^ | |||
- When loading a module with variant, if this module is already loaded but with a different variant set an error is raised | - When loading a module with variant, if this module is already loaded but with a different variant set an error is raised | |||
- Tags applying specifically on variants do not appear over ``avail`` result | - Tags applying specifically on variants do not appear over ``avail`` result | |||
- As variant are not treated on ``avail`` mode | - As variant are not treated on ``avail`` mode | |||
- However if a module is loaded and tags apply to the variant selected, thes | - However if a module is loaded and tags apply to the variant selected, these | |||
e tags will appear on the module designation within ``avail`` result | tags will appear on the module designation within ``avail`` result | |||
- Variant specification is ignored on ``avail`` and ``whatis`` sub-commands | - Variant specification is ignored on ``avail`` and ``whatis`` sub-commands | |||
- If a forbidden tag applies to a specific module variant | - If a forbidden tag applies to a specific module variant | |||
- If this variant is the one specified as argument to ``avail`` or ``whatis` | - If this variant is the one specified as argument to ``avail`` or ``whatis`` | |||
` sub-command | sub-command | |||
- The module will still be reported on ``avail`` or evaluated on ``whatis`` | - The module will still be reported on ``avail`` or evaluated on ``whatis`` | |||
- Hiding a specific variant of a module will not hide the module from search res ults | - Hiding a specific variant of a module will not hide the module from search res ults | |||
- As variant are not treated on search context like on ``avail`` sub-command | - As variant are not treated on search context like on ``avail`` sub-command | |||
- Sticky modules can be swapped by another sticky modules if the stickiness appl ies to the generic module name | - Sticky modules can be swapped by another sticky modules if the stickiness appl ies to the generic module name | |||
- It stays true even if module has variants | - It stays true even if module has variants | |||
- Which means if stickiness designate module version or several versions, st | - Which means if stickiness designate module version or several versions, stic | |||
icky module cannot be changed once loaded | ky module cannot be changed once loaded | |||
- Variant change cannot either occur | - Variant change cannot either occur | |||
- FUTURE: this may be revised to allow variant change if needs arise | - FUTURE: this may be revised to allow variant change if needs arise | |||
- Stickiness can be defined over specific variant value, like any other tag | - Stickiness can be defined over specific variant value, like any other tag | |||
- In case stickiness applies to the default value of a variant | - In case stickiness applies to the default value of a variant | |||
- When swapping sticky modules by another still matching the sticky rule | - When swapping sticky modules by another still matching the sticky rule | |||
- The variant with default value has to be explicitly specified for the swap | - The variant with default value has to be explicitly specified for the swap t | |||
to be allowed | o be allowed | |||
- As it cannot be guessed prior loading module that the default value of | - As it cannot be guessed prior loading module that the default value of the | |||
the variant will match the sticky rule | variant will match the sticky rule | |||
- It applies to both sticky module swap context: ``restore`` and ``switc | - It applies to both sticky module swap context: ``restore`` and ``switch`` | |||
h`` | ||||
- On ``module-info tags``, currently defined tags need to get fetched when calle d | - On ``module-info tags``, currently defined tags need to get fetched when calle d | |||
- As variant specified prior ``module-info tags`` call may change the list o | - As variant specified prior ``module-info tags`` call may change the list of | |||
f tags that apply | tags that apply | |||
- Especially when a variant inherits its default value as it is not specifie | - Especially when a variant inherits its default value as it is not specified | |||
d when loading module | when loading module | |||
- ``module-info specified`` returns module name version and variants specified t o designate the currently evaluating module | - ``module-info specified`` returns module name version and variants specified t o designate the currently evaluating module | |||
- ``module-info name`` only returns module name and version, variants are not pa rt of the result | - ``module-info name`` only returns module name and version, variants are not pa rt of the result | |||
- Variants can be fetched in the ``ModuleVariant`` array within evaluation c ontext | - Variants can be fetched in the ``ModuleVariant`` array within evaluation con text | |||
Corner cases | Corner cases | |||
------------ | ------------ | |||
- When loading a variant which is an optional requirement for an already loaded module | - When loading a variant which is an optional requirement for an already loaded module | |||
- If this optional requirement is loaded without specifying its variant valu | - If this optional requirement is loaded without specifying its variant value | |||
e to get the default variant value | to get the default variant value | |||
- Currently it is not seen as an optional requirement at the load time | - Currently it is not seen as an optional requirement at the load time | |||
- Thus dependent module is not reloaded | - Thus dependent module is not reloaded | |||
- FUTURE: the *deps* evaluation mode that will be triggered prior module loa | - FUTURE: the *deps* evaluation mode that will be triggered prior module load | |||
d may fix this current limitation | may fix this current limitation | |||
.. vim:set tabstop=2 shiftwidth=2 expandtab autoindent: | ||||
End of changes. 218 change blocks. | ||||
531 lines changed or deleted | 519 lines changed or added |