Lmod Tcl modulefile compatibility¶
Goal is to be able to evaluate with modulecmd.tcl a Tcl modulefile generated for Lmod
- No evaluation error
- Be as close as possible to the behavior of Lmod
As of Modules v5.0, the following Tcl modulefile command of Lmod are not supported:
add-property
remove-property
extensions
depends-on
prereq-any
always-load
module load-any
pushenv
require-fullname
family
add-property
/remove-property
¶
Property mechanism of Lmod does not completely fit into Modules tag mechanism:
- Property are first defined in a global RC file
- Then associated to a given modulefile with
add-property
command - Could be unset with
remove-property
- Defined as a key-value
These commands will be first implemented as a no-operation command (
nop
)- No error raised if used
- And no warning message to avoid polluting output
These commands are intended for use only within modulefile evaluation context (not within modulerc)
FUTURE: it could be interesting to map some properties on tags like the
lmod:sticky
property which corresponds to thesticky
tag
extensions
¶
Extension mechanism is an additional information added on
avail
andspider
sub-command output- Requires to evaluate modulefile on
avail
processing - Not used to load the modulefile declaring them when an extension name is
passed to
load
sub-command ordepends-on
modulefile command
- Requires to evaluate modulefile on
This command will be first implemented as a no-operation command (
nop
)- No error raised if used
- And no warning message to avoid polluting output
This command is intended for use only within modulefile evaluation context (not within modulerc)
FUTURE: may be interesting to improve the concept by making the extension names an alias on the modulefile declaring them
- Will automatically achieve dependency consistency this way
- Could resolve dependencies based on extension names if modulefile is
evaluated during an
avail
prereq-any
¶
This command is an alias over
prereq
command- In Lmod,
prereq
acts as a prereq-all - Whereas on Modules
prereq
acts already as a prereq-any
- In Lmod,
This command is intended for use only within modulefile evaluation context (not within modulerc)
require-fullname
¶
Raise an error if modulefile has been designed with implicit or explicit default name
- This error aborts modulefile evaluation
- Occurs for instance if
foo/1.0
is loaded withfoo
orfoo/default
name - Which means
require-fullname
has precedence over explicitly set default version - If an alias or a symbolic version (other than
default
) point to the modulefile, no error occurs if modulefile is designated using these alternative names.
require-fullname
is implemented to only apply on load evaluation mode- On Lmod, it applies on load, unload, and display modes
- It seems important not to apply the constraint on unload and display modes to ease user's experience
This command is intended for use only within modulefile evaluation context (not within modulerc)
depends-on
¶
Auto load one or more modules said as dependencies when modulefile is evaluated in load mode
- Corresponds to the Requirement Load module auto handling mechanism.
- Semantically this command corresponds to a requirement declaration.
- Make it an alias over
prereq
but with each argument set as a prereq*all not a prereq-any. - If
auto_handling
option is disabled, requirement will not be loaded and an error is raised. This will be different than Lmod as with Modules the modulefile commands defines the semantic (this is a dependency) then the automation is defined by the module command configuration, not by the modulefile like done in Lmod.
Auto unload the dependency modules when modulefile is unloaded if no other loaded module depends on them
- Corresponds to the Useless Requirement Unload module auto handling mechanism
- Like for load evaluation, automation is configured at the module command level, not by individual modulefiles
This command is intended for use only within modulefile evaluation context (not within modulerc)
always-load
¶
Auto load on or more modules said as dependencies when modulefile is evaluated in load mode
- Semantically this command corresponds to a requirement declaration.
- Make it an alias over
module load
- Add
keep-loaded
tag to the modules loaded this way - When several modules are specified, it acts as an AND operation, which means all specified modules are required
When modulefile is unloaded, the always-load modules are not automatically unloaded as they own the
keep-loaded
tagThis command is intended for use only within modulefile evaluation context (not within modulerc)
module load-any
¶
Auto load first valid module in a list when modulefile is evaluated in load mode
Semantically this command corresponds to a requirement declaration.
Acting as an OR operation
Evaluation stops after first module in list loaded
- Whether called from a modulefile evaluation context or from top evaluation context
- Different than Lmod that apply the
load
sub-command behavior when called from top evaluation context and does not stop after first modulefile loaded
If the evaluation of first module to load in list ends in error
When called from a modulefile evaluation context
- Error is silenced
- Next module in list is tried
- It behaves this way like a
prereq
command with auto_handling mode enabled - Proceed this way whatever the auto_handling state
- Different than Lmod that aborts modulefile evaluation
Otherwise when called from top evaluation context
- Error message is reported
- Next module in list is tried
- Different than Lmod that aborts processing
If first modules to load are unknown
- No message reported
load-any
continues until finding a module in the specified list
If a module in the list is already loaded
When called from a modulefile evaluation context
load-any
is not performed as requirement is considered already satisfied- Better cope this way with the expressed requirement
- It behaves this way like a
prereq
command - Proceed this way whatever the auto_handling state
- Different behavior than Lmod that still proceed to load the module in the list from the left to the right until loading one or finding one loaded
Otherwise when called from top evaluation context
- An attempt to load first module in list is still issued
- And pursued from left to right until loading one module or finding one loaded
load-any
acts similarly totry-load
but with an OR operation behavior instead of an AND operationAn error is obtained if none of the listed modules can be loaded if none of their load attempt generated an error message
If no argument is provided an error is obtained, like done for
try-load
When modulefile is unloaded, an attempt to unload all specified module is made
- Correspond to the behavior of a
module unload
- Modules which are still depended by other loaded modules will not be unloaded
- Correspond to the behavior of a
This command is intended for use only within modulefile evaluation context (not within modulerc)
family
¶
Defines membership in family name and ensures that only one member of a given family is currently loaded.
Semantically this command corresponds to the definition of both:
- a conflict on family name
- a module alias name over currently loading module
Also defines the
MODULES_FAMILY_<NAME>
environment variable set to the currently loading module name minus its version number.- As family name is used in environment variable name, it requires that name should only use characters that are accepted there
- Accepted characters for family name are [a-zA-Z0-9_]
- An error is generated in case other kind of characters are found in specified family name
The
LMOD_FAMILY_<NAME>
environment variable is also set in addition toMODULES_FAMILY_<NAME>
and set to the same value. This way existing scripts or modulefiles relying on this variable do not need to be changed to be compatible with Modules.When modulefile is unloaded, the
MODULES_FAMILY_<NAME>
andLMOD_FAMILY_<NAME>
environment variables are unsetThis command is intended for use only within modulefile evaluation context (not within modulerc)
pushenv
¶
Sets an environment variable with a value specified as argument but saves the previous value set to restore it when modulefile is unloaded.
Use a
__MODULES_PUSHENV_<VAR>
environment variable as a stack to record the previous values of environment variable<VAR>
.Each element in this Modules-specific variable is the combination of the currently evaluating modulename and pushed value.
- Combination joined with the ampersand character
- Each element in variable separated by colon character
When unloading, the value set by this module is removed not the value on top of the list.
Different than Lmod that restores the value on top of the stack even if unloading module were not the one defining the top value currently in use.
When saving value set before any module
- An empty module name is used to push to the stack.
- When restoring this initial value, initial entry in stack is also cleared (as no other module unload will unset it).
It is not expected that for the same environment variable,
pushenv
is mixed with:setenv
,unsetenv
append-path
,prepend-path
,remove-path
- These other modulefile commands clear the pushenv stack environment
variable (like
setenv
/unsetenv
clear the reference counter environment variable of the*-path
commands)
It is not expected that
pushenv
is called multiple times for the same environment variable in the same modulefile- Inconsistent results may be obtained if environment variable value is used in modulefile to set other variables.
- Especially that unload evaluation of modulefile will not process the
pushenv
commands in the reverse order but in the script order. - When checked during modulefile evaluation, lastly defined value remains
- However the operation is consistent at the end of modulefile evaluation, as all values are withdrawn from stack and a value defined somewhere else is restored.
- pushenv stack environment variable correctly handles multiple entries coming from same modulefile, even multiple identical values.
For Lua modulefiles, Lmod handles a specific
false
value which clears environment variable- Lmod does not implement this for Tcl modulefile
- Maybe because
false
cannot be distinguished from any other value - So this specific behavior is also not supported on Modules
This command is intended for use only within modulefile evaluation context (not within modulerc)