Environment Modules

Welcome to the Environment Modules documentation portal. The Environment Modules package provides for the dynamic modification of a user's environment via modulefiles.

The Modules package is a tool that simplify shell initialization and lets users easily modify their environment during the session with modulefiles.

Each modulefile contains the information needed to configure the shell for an application. Once the Modules package is initialized, the environment can be modified on a per-module basis using the module command which interprets modulefiles. Typically modulefiles instruct the module command to alter or set shell environment variables such as PATH, MANPATH, etc. modulefiles may be shared by many users on a system and users may have their own collection to supplement or replace the shared modulefiles.

Modules can be loaded and unloaded dynamically and atomically, in an clean fashion. All popular shells are supported, including bash, ksh, zsh, sh, csh, tcsh, fish, as well as some scripting languages such as tcl, perl, python, ruby, cmake and r.

Modules are useful in managing different versions of applications. Modules can also be bundled into metamodules that will load an entire suite of different applications.

Quick examples

Here is an example of loading a module on a Linux machine under bash.

$ module load gcc/6.1.1
$ which gcc
$ /usr/local/gcc/6.1.1/linux-x86_64/bin/gcc

Now we'll switch to a different version of the module

$ module switch gcc gcc/6.3.1
$ which gcc
/usr/local/gcc/6.3.1/linux-x86_64/bin/gcc

And now we'll unload the module altogether

$ module unload gcc
$ which gcc
gcc not found

Now we'll log into a different machine, using a different shell (tcsh).

% module load gcc/6.3.1
% which gcc
/usr/local/gcc/6.3.1/linux-aarch64/bin/gcc

Note that the command line is exactly the same, but the path has automatically configured to the correct architecture.

Installing Modules on Unix

This document is an overview of building and installing Modules on a Unix system.

Requirements

Modules consists of one Tcl script so to run it from a user shell the only requirement is to have a working version of tclsh (version 8.4 or later) available on your system. tclsh is a part of Tcl (http://www.tcl.tk/software/tcltk/).

To install Modules from a distribution tarball or a clone of the git repository, a build step is there to adapt the initialization scripts to your configuration and create the documentation files. This build step requires the tools to be found on your system:

  • bash
  • make
  • sed
  • runtest

When also installing Modules Tcl extension library or the bundled compatibility version of Modules (both enabled by default), these additional tools are needed:

  • grep
  • gcc
  • tcl-devel >= 8.4

When installing from a distribution tarball, documentation is pre-built and scripts to configure Modules Tcl extension library and compatibility version builds are already generated. Thus no additional software is required. When installing from a clone of the git repository, documentation and scripts to prepare for compilation have to be built and the following tools are required:

  • autoconf
  • automake
  • autopoint
  • sphinx >= 1.0

Installation instructions

The simplest way to build and install Modules is:

$ ./configure
$ make
$ make install

Some explanation, step by step:

  1. cd to the directory containing the package's source code. Your system must have the above requirements installed to properly build scripts, compatibility version of Modules if enabled, and documentation if build occurs from a clone of the git repository.
  2. Type ./configure to adapt the installation for your system. At this step you can choose the installation paths and the features you want to enable in the initialization scripts (see Build and installation options section below for a complete overview of the available options)
  3. Type make to adapt scripts to the configuration, build Tcl extension library and compatibility version if enabled and build documentation if working from git repository.
  4. Optionally, type make test to run the test suite.
  5. Type make install to install modulecmd.tcl, initialization scripts, compatibility version if built and documentation.
  6. Optionally, type make testinstall to run the installation test suite.
  7. You can remove the built files from the source code directory by typing make clean. To also remove the files that configure created, type make distclean.

A default installation process like described above will install Modules under /usr/local/Modules. You can change this with the --prefix option. By default, /usr/local/Modules/modulefiles will be setup as the default directory containing modulefiles. --modulefilesdir option enables to change this directory location. For example:

$ ./configure --prefix=/usr/share/Modules \
              --modulefilesdir=/etc/modulefiles

See Build and installation options section to discover all ./configure option available.

Note

GNU Make is excepted to be used for this build and installation process. On non-Linux systems, the gmake should be called instead of make.

Configuration

Once installed you should review and adapt the configuration to make it fit your needs. The following steps are provided for example. They are not necessarily mandatory as it depends of the kind of setup you want to achieve.

  1. Tune the initialization scripts. Review of these scripts is highly encouraged as you may add or adapt specific stuff to get Modules initialized the way you want.

  2. Enable Modules initialization at shell startup. An easy way to get module function defined and its associated configuration setup at shell startup is to make the initialization scripts part of the system-wide environment setup in /etc/profile.d. To do so, make a link in this directory to the profile scripts that can be found in your Modules installation init directory:

    $ ln -s PREFIX/init/profile.sh /etc/profile.d/modules.sh
    $ ln -s PREFIX/init/profile.csh /etc/profile.d/modules.csh
    

    These profile scripts will automatically adapt to the kind of sh or csh shell you are running.

    Another approach may be to get the Modules initialization script sourced from the shell configuration startup file. For instance following line could be added to the end of the ~/.bashrc file if running Bash shell:

    source PREFIX/init/bash
    

    Beware that shells have multiple ways to initialize depending if they are a login shell or not and if they are launched in interactive mode or not.

  3. Define module paths to enable by default. Edit modulerc configuration file or .modulespath if you have chosen --enable-dotmodulespath at configure time. If you have set --with-initconf-in to etcdir to install these Modules initialization configurations in the configuration directory designated by the --etcdir option, these configuration files are respectively named initrc and modulespath. If you use .modulespath (or modulespath) configuration file, add one line mentioning each modulefile directory:

    /path/to/regular/modulefiles
    /path/to/other/modulefiles
    

    If you use modulerc (or initrc) configuration file, add one line mentioning each modulefile directory prefixed by the module use command:

    module use /path/to/regular/modulefiles
    module use /path/to/other/modulefiles
    
  4. Define modulefiles to load by default. Edit modulerc (or initrc) configuration file. Modulefiles to load cannot be specified in .modulespath (or modulespath) file. Add there all the modulefiles you want to load by default at Modules initialization time.

    Add one line mentioning each modulefile to load prefixed by the module load command:

    module load foo
    module load bar
    

    In fact you can add to the modulerc (or initrc) configuration file any kind of supported module command, like module config commands to tune module's default behaviors.

If you go through the above steps you should have a valid setup tuned to your needs. After that you still have to write modulefiles to get something to load and unload in your newly configured Modules setup. Please have a look at the doc/example.txt that explains how the user environment is setup with Modules at the University of Minnesota computer science department.

Build and installation options

Options available at the ./configure installation step are described below. These options enable to choose the installation paths and the features to enable or disable. You can also get a description of these options by typing ./configure --help.

Fine tuning of the installation directories (the default value for each option is displayed within brakets):

--prefix=PREFIX
 Installation root directory [/usr/local/Modules]
--bindir=DIR Directory for executables reachable by users [PREFIX/bin]
--libdir=DIR Directory for object code libraries like libtclenvmodules.so [PREFIX/lib]
--libexecdir=DIR
 Directory for executables called by other executables like modulecmd.tcl [PREFIX/libexec]
--etcdir=DIR Directory for the executable configuration scripts [PREFIX/etc]
--initdir=DIR Directory for the per-shell environment initialization scripts [PREFIX/init]
--datarootdir=DIR
 Base directory to set the man and doc directories [PREFIX/share]
--mandir=DIR Directory to host man pages [DATAROOTDIR/man]
--docdir=DIR Directory to host documentation other than man pages like README, license file, etc [DATAROOTDIR/doc]
--vimdatadir=DIR
 Directory to host Vim addon files [DATAROOTDIR/vim/vimfiles]
--modulefilesdir=DIR
 Directory of main modulefiles also called system modulefiles [PREFIX/modulefiles]

Optional Features (the default for each option is displayed within parenthesis, to disable an option replace enable by disable for instance --disable-set-manpath):

--enable-set-manpath
 Prepend man page directory defined by the --mandir option to the MANPATH environment variable in the shell initialization scripts. (default=yes)
--enable-append-manpath
 Append rather prepend man page directory to the MANPATH environment variable when the --enable-set-manpath option is enabled. (default=no)
--enable-set-binpath
 Prepend binary directory defined by the --bindir option to the PATH environment variable in the shell initialization scripts. (default=yes)
--enable-append-binpath
 Append rather prepend binary directory to the PATH environment variable when the --enable-set-binpath option is enabled. (default=no)
--enable-dotmodulespath, --enable-modulespath
 Set the module paths defined by --with-modulepath option in a .modulespath file (following C version fashion) within the initialization directory defined by the --initdir option rather than within the modulerc file. Or respectively, if option --with-initconf-in has been set to etcdir, in a modulespath file within the configuration directory defined by the --etcdir option rather than within the initrc file. (default=no)
--enable-doc-install
 Install the documentation files in the documentation directory defined with the --docdir option. This feature has no impact on manual pages installation. Disabling documentation file installation is useful in case of installation process handled via a package manager which handles by itself the installation of this kind of documents. (default=yes)
--enable-vim-addons
 Install the Vim addon files in the Vim addons directory defined with the --vimdatadir option. (default=yes)
--enable-example-modulefiles
 Install some modulefiles provided as example in the system modulefiles directory defined with the modulefilesdir option. (default=yes)
--enable-compat-version
 Build and install the Modules compatibility (C) version in addition to the main released version. This feature also enables switching capabilities from initialization script between the two installed version of Modules (by setting-up the switchml shell function or alias). (default=yes)
--enable-libtclenvmodules
 Build and install the Modules Tcl extension library which provides optimized Tcl commands for the modulecmd.tcl script.
--enable-versioning
 Append Modules version to installation prefix and deploy a versions modulepath shared between all versioning enabled Modules installation. A modulefile corresponding to Modules version is added to the shared modulepath and enables to switch from one Modules version to another. (default=no)
--enable-silent-shell-debug-support
 Generate code in module function definition and initialization scripts to add support for silencing shell debugging properties (default=yes)
--enable-set-shell-startup
 Set when module function is defined the shell startup file to ensure that the module function is still defined in sub-shells. (default=yes)
--enable-quarantine-support
 Generate code in module function definition and initialization scripts to add support for the environment variable quarantine mechanism (default=yes)
--enable-auto-handling
 Set modulecmd.tcl to automatically apply automated modulefiles handling actions, like loading the pre-requisites of a modulefile when loading this modulefile. (default=no)
--enable-avail-indepth
 When performing an avail sub-command, include in search results the matching modulefiles and directories and recursively the modulefiles and directories contained in these matching directories when enabled or limit search results to the matching modulefiles and directories found at the depth level expressed by the search query if disabled. (default=yes)
--enable-implicit-default
 Define an implicit default version, for modules with none explicitly defined, to select when the name of the module to evaluate is passed without the mention of a specific version. When this option is disabled the name of the module passed for evaluation should be fully qualified elsewhere an error is returned. (default=yes)
--enable-extended-default
 Allow to specify module versions by their starting part, i.e. substring separated from the rest of the version string by a . character. (default=no)
--enable-advanced-version-spec
 Activate the advanced module version specifiers which enables to finely select module versions by specifying after the module name a version constraint prefixed by the @ character. (default=no)
--enable-color Control if output should be colored by default or not. A value of yes equals to the auto color mode. no equals to the never color mode. (default=no)
--enable-wa-277
 Activate workaround for issue #277 related to Tcsh history mechanism which does not cope well with default module alias definition. Note that enabling this workaround solves Tcsh history issue but weakens shell evaluation of the code produced by modulefiles.

Optional Packages (the default for each option is displayed within parenthesis, to disable an option replace with by without for instance --without-modulepath):

--with-bin-search-path=PATHLIST
 List of paths to look at when searching the location of tools required to build and configure Modules (default=/usr/bin:/bin:/usr/local/bin)
--with-moduleshome
 Location of the master Modules package file directory (default=PREFIX)
--with-initconf-in=VALUE
 Location where to install Modules initialization configuration files. Either initdir or etcdir (default=initdir)
--with-tclsh=BIN
 Name or full path of Tcl interpreter shell (default=tclsh)
--with-pager=BIN
 Name or full path of default pager program to use to paginate informational message output (can be superseded at run-time by environment variable) (default=less)
--with-pager-opts=OPTLIST
 Settings to apply to default pager program (default=-eFKRX)
--with-verbosity=VALUE
 Specify default message verbosity. accepted values are silent, concise, normal, verbose and debug. (default=normal)
--with-dark-background-colors=SGRLIST
 Default color set to apply if terminal background color is defined to dark. SGRLIST follows the same syntax than used in LS_COLORS. Each element in SGRLIST is an output item associated to a Select Graphic Rendition (SGR) code. Elements in SGRLIST are separated by :. Output items are designated by keys. Items able to be colorized are: highlighted element (hi), debug information (db), tag separator (se); Error (er), warning (wa), module error (me) and info (in) message prefixes; Modulepath (mp), directory (di), module alias (al), module symbolic version (sy) and module default version (de). For a complete SGR code reference, see https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters. (default=hi=1:db=2:se=2:er=91:wa=93:me=95:in=94:mp=1;94:di=94:al=96:sy=95:de=4:cm=92)
--with-light-background-colors=SGRLIST
 Default color set to apply if terminal background color is defined to light. Expect the same syntax than described for --with-dark-background-colors. (default=hi=1:db=2:se=2:er=31:wa=33:me=35:in=34:mp=1;34:di=34:al=36:sy=35:de=4:cm=32)
--with-terminal-background=VALUE
 The terminal background color that determines the color set to apply by default between the dark background colors or the light background colors (default=dark)
--with-locked-configs=CONFIGLIST
 Ignore environment variable superseding value for the listed configuration options. Accepted option names in CONFIGLIST are extra_siteconfig and implicit_default (each option name should be separated by whitespace character). (default=no)
--with-unload-match-order=VALUE
 When unloading a module if multiple loaded modules match the request, unload module loaded first (returnfirst) or module loaded last (returnlast) (default=returnlast)
--with-search-match=VALUE
 When searching for a module with avail sub-command, match query string against module name start (starts_with) or any part of module name string (contains). (default=starts_with)
--with-icase=VALUE
 Apply a case insensitive match to module specification on avail, whatis and paths sub-commands (when set to search) or on all module sub-commands and modulefile Tcl commands for the module specification they receive as argument (when set to always). Case insensitive match is disabled when this option is set to never. (default=never)
--with-modulepath=PATHLIST
 Default path list to setup as the default modulepaths. Each path in this list should be separated by :. Defined value is registered in the modulerc or .modulespath configuration file, depending on the --enable-dotmodulespath option. These files are respectively called initrc and modulespath if --with-initconf-in is set to etcdir. The path list value is read at initialization time to populate the MODULEPATH environment variable. By default, this modulepath is composed of the directory set for the system modulefiles (default=PREFIX/modulefiles or BASEPREFIX/$MODULE_VERSION/modulefiles if versioning installation mode enabled)
--with-loadedmodules=MODLIST
 Default modulefiles to load at Modules initialization time. Each modulefile in this list should be separated by :. Defined value is registered in the modulerc configuration file or in the initrc file if --with-initconf-in is set to etcdir. (default=no)
--with-quarantine-vars=<VARNAME[=VALUE] ...>
 Environment variables to put in quarantine when running the module command to ensure it a sane execution environment (each variable should be separated by space character). A value can eventually be set to a quarantine variable instead of emptying it. (default=no)
--with-tcl Directory containing the Tcl configuration script tclConfig.sh. Useful to compile Modules compatibility version or Modules Tcl extension library if this file cannot be automatically found in default locations.
--with-tclinclude
 Directory containing the Tcl header files. Useful to compile Modules compatibility version or Modules Tcl extension library if these headers cannot be automatically found in default locations.

MIGRATING

This document describes the major changes occurring between versions of Modules. It provides an overview of the new features and changed behaviors that will be encountered when upgrading.

Migrating from v4.3 to v4.4

This new version is backward-compatible with v4.3 and primarily fixes bugs and adds new features.

Warning

Modules configuration option handling has been reworked internally to provide a unified way for all options to get initialized, retrieved or set. Existing site-specific configuration script should be reviewed to make use of the new getConf, setConf, unsetConf and lappendConf procedures to manipulate configuration options.

New features

Version 4.4 introduces new functionalities that are described in this section.

Specify modules in a case insensitive manner

The ability to match module name in a case insensitive manner has been added. This feature can be enabled at different level with the following values set to the icase configuration option:

  • never: a case sensitive match is applied in any cases
  • search: a case insensitive match is applied to the avail, whatis and paths sub-commands
  • always: a case insensitive match is applied to search contexts and also to the other module sub-commands and modulefile Tcl commands for the module specification they receive as argument.

It can help for instance to load a module without knowing the case used to name its relative modulefile:

$ module config icase always
$ module load -v mysoftware
Loading MySoftware/1.0

Insensitive case match activation can be controlled at configure time with the --with-icase option, which could be passed any of the above activation levels. This option could be superseded with the MODULES_ICASE environment variable, which could be set through the config sub-command with the icase option. Command-line switch --icase supersedes in turns any other icase configurations. When this command-line switch is passed, icase mode equals always.

Extended default

The extended default mechanism has been introduced to help selecting a module when only the first numbers in its version are specified. Starting portion of the version, part separated from the rest of the version string by a . character, could be used to refer to a more precise version number.

This mechanism is activated through the new configuration option extended_default. It enables to refer to a module named foo/1.2.3 as foo/1.2 or foo/1:

$ module config extended_default 1
$ module load -v foo/1
Loading foo/1.2.3

When multiple versions match partial version specified and only one module should be selected, the default version (whether implicitly or explicitly defined) among matches is returned. The following example shows that foo/1.1.1, the foo module default version, is selected when it matches query. Elsewhere the highest version (also called the latest version or the implicit default) among matching modules is returned:

$ module av foo
--------------- /path/to/modulefiles ---------------
foo/1.1.1(default)  foo/1.2.1  foo/1.10
foo/1.1.10          foo/1.2.3
$ module load -v foo/1.1
Loading foo/1.1.1
$ module purge
$ module load -v foo/1.2
Loading foo/1.2.3
$ module purge
$ module load -v foo/1
Loading foo/1.1.1

In case implicit_default option is disabled and no explicit default is found among matches, an error is returned:

$ module config implicit_default 0
$ module load -v foo/1.2
ERROR: No default version defined for 'foo/1.2'

When it is enabled, extended default applies everywhere a module could be specified, which means it could be used with any module sub-command or any modulefile Tcl command receiving a module specification as argument. It may help for instance to declare dependencies between modules:

$ module show bar/3
----------------------------------------------------------
/path/to/modulefiles/bar/3.4:

prereq              foo/1.2
----------------------------------------------------------
$ module load --auto bar/3
Loading bar/3.4
  Loading requirement: foo/1.2.3

Extended default activation can be controlled at configure time with the --enable-extended-default option. This option could be superseded with the MODULES_EXTENDED_DEFAULT environment variable, which could be set through the config sub-command with the extended_default option.

Advanced module version specifiers

The ability to specify finer constraints on module version has been added to Modules. It enables to filter the module selection to a given version list or range by specifying after the module name a version constraint prefixed by the @ character.

This new feature leverages the version specifier syntax of the Spack package manager as this syntax covers all the needs for a fine-grained selection of module versions. It copes very well with command-line typing, by avoiding characters having a special meaning on shells. Moreover the users of Spack that also are users of Modules may already be familiar with this syntax.

The mechanism introduced here is called advanced module version specifier and it can be activated through the new configuration option advanced_version_spec. Constraints can be expressed to refine the selection of module version to:

  • a single version with the @version syntax, for instance foo@1.2.3 syntax will select module foo/1.2.3
  • a list of versions with the @version1,version2,... syntax, for instance foo@1.2.3,1.10 will match modules foo/1.2.3 and foo/1.10
  • a range of versions with the @version1:, @:version2 and @version1:version2 syntaxes, for instance foo@1.2: will select all versions of module foo greater than or equal to 1.2, foo@:1.3 will select all versions less than or equal to 1.3 and foo@1.2:1.3 matches all versions between 1.2 and 1.3 including 1.2 and 1.3 versions

This new feature enables for instance to list available versions of module foo higher or equal to 1.2:

$ module config advanced_version_spec 1
$ module av foo
--------------- /path/to/modulefiles ---------------
foo/1.1.1(default)  foo/1.2.1  foo/1.10
foo/1.1.10          foo/1.2.3
$ module av foo@1.2:
--------------- /path/to/modulefiles ---------------
foo/1.2.1  foo/1.2.3  foo/1.10

Then choose to load for instance a version higher than or equal to 1.2 and less than or equal to 1.3. Default version is selected if it corresponds to a version included in the range, elsewhere the highest version (also called latest version or implicit default) is selected:

$ module load -v foo@1.2:1.3
Loading foo/1.2.3

In case implicit_default option is disabled and no explicit default is found among version specifier matches, an error is returned:

$ module config implicit_default 0
$ module load -v foo@1.2:1.3
ERROR: No default version defined for 'foo@1.2:1.3'

When advanced module version specifier is enabled, it applies everywhere a module could be specified, which means it could be used with any module sub-command or any modulefile Tcl command receiving a module specification as argument. It may help for instance to declare smoother dependencies between modules:

$ module show bar@:2
----------------------------------------------------------
/path/to/modulefiles/bar/2.3:

prereq          foo@1.1.10,1.2.1
----------------------------------------------------------
$ module load --auto bar@:2
Loading bar/2.3
  Loading requirement: foo/1.2.1

Advanced specification of single version or list of versions may benefit from the activation of the Extended default mechanism (range of versions natively handles abbreviated versions):

$ module config extended_default 1
$ module load -v foo@1.2
Loading foo/1.2.3
$ module unload -v foo @1.2,1.5
Unloading foo/1.2.3

Advanced module version specifier activation can be controlled at configure time with the --enable-advanced-version-spec option. This option could be superseded with the MODULES_ADVANCED_VERSION_SPEC environment variable, which could be set through the config sub-command with the advanced_version_spec option.

Further reading

To get a complete list of the changes between Modules v4.3 and v4.4, please read the Release notes document.

Migrating from v4.2 to v4.3

This new version is backward-compatible with v4.2 and primarily fixes bugs and adds new features.

New features

Version 4.3 introduces new functionalities that are described in this section.

Modulepath rc file

A .modulerc file found at the root of an enabled modulepath directory is now evaluated when modulepath is walked through to locate modulefiles. This modulepath rc file gives for instance the ability to define module alias whose name does not correspond to any module directory in this modulepath. Thus this kind of module alias would not be found unless if it is defined at the modulepath global scope.

Further I/O operations optimization

Additional work has been performed to save a significant number of filesystem I/O operations made to search and evaluate modulefiles.

When fully read, the content of a modulefile is now cached in memory to avoid new I/O operations in case this modulefile should be read one more time during the same module command evaluation.

Except for path, paths, list, avail and aliases module commands always fully read a modulefile whether its full content is needed or just its header to verify its validity. This way modulefiles are only read once on commands that first check modulefile validity then read again valid files to get their full content.

Last but not least, Modules Tcl extension library is introduced to extend the Tcl language in order to provide more optimized I/O commands to read a file or a directory content than native Tcl commands do. This library is built and enabled in modulecmd.tcl script with --enable-libtclenvmodules configure argument (it is enabled by default). As this library is written in C, it must be compiled and --with-tcl or --with-tclinclude configure arguments may be used to indicate where to find Tcl development files.

Modules Tcl extension library greatly reduces the number of filesystem I/O operations by removing unneeded ioctl, fcntl and lstat system calls done (by Tcl open command) to read each modulefile. Directory content read is also improved by fetching hidden and regular files in one pass. Moreover .modulerc and .version read access is tested only if these files are found in the directory.

Colored output

The ability to graphically enhance some part of the produced output has been added to improve readability. Among others, error, warning and info message prefixes can be colored as well as modulepath, module alias and symbolic version.

Color mode can be set to never, auto or always. When color mode is set to auto, output is colored only if the standard error output channel is attached to a terminal.

Default color mode could be controlled at configure time with the --enable-color and the --disable-color option, which respectively correspond to the auto and never color mode. This default mode could be superseded with the CLICOLOR, CLICOLOR_FORCE and MODULES_COLOR environment variables and the --color command-line switch.

Color to apply to each element can be controlled with the MODULES_COLORS environment variable or the --with-dark-background-colors and --with-light-background-colors configure options. These variable and options take as value a colon-separated list in the same fashion LS_COLORS does. In this list, output item that should be highlighted is designated by a key which is associated to a Select Graphic Rendition (SGR) code.

The MODULES_TERM_BACKGROUND environment variable and the --with-terminal-background configure option help Modules to determine if the color set for dark background or the color set for light background should be used to color output in case no specific color set is defined with the MODULES_COLORS variable.

Output items able to be colorized and their relative key are: highlighted element (hi), debug information (db), tag separator (se); Error (er), warning (wa), module error (me) and info (in) message prefixes; Modulepath (mp), directory (di), module alias (al), module symbolic version (sy), module default version (de) and modulefile command (cm).

For instance the default color set for a terminal with dark background is defined to:

hi=1:db=2:se=2:er=91:wa=93:me=95:in=94:mp=1;94:di=94:al=96:sy=95:de=4:cm=92

When colored output is enabled and a specific graphical rendition is defined for module default version, the default symbol is omitted and instead the defined graphical rendition is applied to the relative modulefile. When colored output is enabled and a specific graphical rendition is defined for module alias, the @ symbol is omitted.

CLICOLOR and CLICOLOR_FORCE environment variables are also honored to define color mode. The never mode is set if CLICOLOR equals to 0. If CLICOLOR is set to another value, it corresponds to the auto mode. The always mode is set if CLICOLOR_FORCE is set to a value different than 0. Color mode set with these two variables is superseded by mode set with MODULES_COLOR environment variable.

Configure modulecmd with config sub-command

The config sub-command has been added to module to help getting or setting the modulecmd.tcl options. With no additional command-line argument, this sub-command reports the current value of all existing options with a mention to indicate if this value has been overridden from a command-line switch or from an environment variable.

See the description of this sub-command in the module man page for a complete reference on existing configuration options.

Most of the options can be altered by passing the option name and a value to the sub-command. Setting an option by this mean overrides its default value, set at installation time in modulecmd.tcl script, by defining the environment variable which supersedes this default.:

$ module config auto_handling 1
$ module config auto_handling
Modules Release 4.3.0 (2019-07-26)

- Config. name ---------.- Value (set by if default overridden) ---------------
auto_handling             1 (env-var)

Setting options with module config could be done in the Modules initialization RC file to change default value of options when module command is initialized.

When command-line switch --reset and an option name is passed to the config sub-command, it restores default value for configuration option by unsetting related environment variable.

With command-line switch --dump-state, the config sub-command reports, in addition to currently set options, the current state of modulecmd.tcl script and Modules-related environment variables. Providing the output of the module config --dump-state command when submitting an issue to the Modules project will help to analyze the situation.

Control module command verbosity

The ability to control message verbosity has been added so module command can be configured whether it should display more or less information. Available verbosity levels from the least to the most verbose are:

  • silent: turn off error, warning and informational messages but does not affect module command output result.
  • concise: enable error and warning messages but disable informational messages.
  • normal: turn on informational messages, like a report of the additional module evaluations triggered by loading or unloading modules, aborted evaluation issues or a report of each module evaluation occurring during a restore or source sub-commands.
  • verbose: add additional informational messages, like a systematic report of the loading or unloading module evaluations.
  • debug: print debugging messages about module command execution.

Default verbosity level can be controlled at configure time with the --with-verbosity option, which could be passed any of the above level names. This default verbosity level could be superseded with the MODULES_VERBOSITY environment variable, which could be set through the config sub-command with the verbosity option. Command-line switches --silent, --verbose and --debug supersede in turns any other verbosity configuration to respectively set module command silent, verbose or in debug mode.

Other new sub-commands, command-line switches and environment variables
  • The avail sub-command gets two new command-line switches: --indepth and --no-indepth. These options control whether search results should recursively include or not modulefiles from directories matching search query. Shell completion scripts have been updated to complete available modulefiles in the no in depth mode.
  • The MODULES_AVAIL_INDEPTH environment variable defines if the avail sub-command should include or exclude by default the modulefiles from directories matching search query. Its value is superseded by the use of the --indepth and --no-indepth command-line switches.
  • The clear sub-command, which was available on Modules version 3.2, has been reintroduced. This sub-command resets the Modules runtime information but does not apply further changes to the environment at all. This sub-command now leverages the --force command-line switch to skip its confirmation dialog.
  • The MODULES_SITECONFIG environment variable defines an additional siteconfig script which is loaded if it exists after the siteconfig script configured at build time in modulecmd.tcl. This ability is enabled by default and could be disabled with configure option --with-locked-configs=extra_siteconfig.
  • The MODULES_UNLOAD_MATCH_ORDER environment variable sets whether the firstly or the lastly loaded module should be selected for unload when multiple loaded modules match unload request. Configure option --with-unload-match-order defines this setting which can be superseded by the environment variable. By default, lastly loaded module is selected and it is recommended to keep this behavior when used modulefiles express dependencies between each other.
  • The MODULES_IMPLICIT_DEFAULT environment variable sets whether an implicit default version should be defined for modules with no default version explicitly defined. When enabled, which is the default behavior, a module version is automatically selected (latest one) when the generic name of the module is passed. When implicit default is disabled and no default version is explicitly defined for a module, the name of this module to evaluate should be fully qualified elsewhere an error is returned. Configure option --enable-implicit-default defines this setting which can be superseded by the environment variable. This superseding mechanism can be disabled with configure option --with-locked-configs=implicit_default.
  • The MODULES_SEARCH_MATCH environment variable defines the matching style to perform when searching for available modules. With starts_with value, modules whose name begins by search query string are returned. When search match style is set to contains, modules returned are those whose fully qualified name contains search query string. Configure option --with-search-match defines this setting which can be superseded by the environment variable, which in turns can be superseded by the --starts-with and --contains command-line switches of avail module sub-command.
  • The MODULES_SET_SHELL_STARTUP environment variable controls whether or not shell startup file should be set to ensure module command is defined once shell has been initialized. When enabled, the ENV and BASH_ENV environment variables are set, when module function is defined, to the Modules bourne shell initialization script. Configure options --enable-set-shell-startup and --disable-set-shell-startup define this setting which can be superseded by the environment variable.
  • When initializing the module command in a shell session, initialization configuration files stored in the defined configuration directory are taken into account if present instead of the configuration files stored in the initialization script directory. When they are stored in the configuration directory, these configuration files are named initrc and modulespath instead of respectively modulerc and .modulespath. The location of the installation of those files can be controlled with configure option --with-initconf-in, which accepts etcdir and initdir values.
  • The MODULES_WA_277 environment variable helps to define an alternative module alias on Tcsh shell when set to 1. It workarounds an issue on Tcsh history mechanism occurring with default module command alias: erroneous history entries are recorded each time the module command is called. However the alternative definition of the module alias weakens shell evaluation of the code produced by modulefiles. Characters with special meaning for Tcsh shell (like { and }) may not be used anymore in shell alias definition elsewhere the evaluation of the code produced by modulefiles will return a syntax error.
Further reading

To get a complete list of the changes between Modules v4.2 and v4.3, please read the Release notes document.

Migrating from v4.1 to v4.2

This new version is backward-compatible with v4.1 and primarily fixes bugs and adds new features.

New features

Version 4.2 introduces new functionalities that are described in this section.

Modulefile conflict constraints consistency

With the conflict modulefile command, a given modulefile can list the other modulefiles it conflicts with. To load this modulefile, the modulefiles it conflicts with cannot be loaded.

This constraint was until now satisfied when loading the modulefile declaring the conflict but it vanished as soon as this modulefile was loaded. In the following example a modulefile declares a conflict with b:

$ module load b a
WARNING: a cannot be loaded due to a conflict.
HINT: Might try "module unload b" first.
$ module list
Currently Loaded Modulefiles:
 1) b
$ module purge
$ module load a b
$ module list
Currently Loaded Modulefiles:
 1) a   2) b

Consistency of the declared conflict is now ensured to satisfy this constraint even after the load of the modulefile declaring it. This is achieved by keeping track of the conflict constraints of the loaded modulefiles in an environment variable called MODULES_LMCONFLICT:

$ module load a b
ERROR: WARNING: b cannot be loaded due to a conflict.
HINT: Might try "module unload a" first.
$ module list
Currently Loaded Modulefiles:
 1) a

An environment variable is used to keep track of this conflict information to proceed the same way than used to keep track of the loaded modulefiles with the LOADEDMODULES environment variable.

In case a conflict constraint toward a modulefile is set by an already loaded modulefile, loading the conflicting modulefile will lead to a load evaluation attempt in order for this modulefile to get the chance to solve the constraint violation. If at the end of the load evaluation, the conflict has not been solved, modulefile load will be discarded.

Warning

On versions 4.2.0 and 4.2.1, a conflict constraint set by an already loaded modulefile forbade the load of the conflicting modulefile. This has been changed starting version 4.2.2 to better cope with behaviors of previous Modules version: an evaluation attempt of the conflicting modulefile is made to give it the opportunity to solve this conflict by using module unload modulefile command.

Modulefile prereq constraints consistency

With the prereq modulefile command, a given modulefile can list the other modulefiles it pre-requires. To load this modulefile, the modulefiles it pre-requires must be loaded prior its own load.

This constraint was until now satisfied when loading the modulefile declaring the prereq but, as for the declared conflict, it vanished as soon as this modulefile was loaded. In the following example c modulefile declares a prereq on a:

$ module load c
WARNING: c cannot be loaded due to missing prereq.
HINT: the following module must be loaded first: a
$ module list
No Modulefiles Currently Loaded.
$ module load a c
$ module list
Currently Loaded Modulefiles:
 1) a   2) c
$ module unload a
$ module list
Currently Loaded Modulefiles:
 1) c

Consistency of the declared prereq is now ensured to satisfy this constraint even after the load of the modulefile declaring it. This is achieved, like for the conflict consistency, by keeping track of the prereq constraints of the loaded modulefiles in an environment variable called MODULES_LMPREREQ:

$ module load a c
$ module list
Currently Loaded Modulefiles:
 1) a   2) c
$ module unload a
ERROR: WARNING: a cannot be unloaded due to a prereq.
HINT: Might try "module unload c" first.
$ module list
Currently Loaded Modulefiles:
 1) a   2) c
By-passing module defined constraints

The ability to by-pass a conflict or a prereq constraint defined by modulefiles is introduced with the --force command line switch (-f for short notation) for the load, unload and switch sub-commands.

With this new command line switch, a given modulefile is loaded even if it conflicts with other loaded modulefiles or even if the modulefiles it pre-requires are not loaded. Some example reusing the same modulefiles a, b and c than above:

$ module load b
$ module load --force a
WARNING: a conflicts with b
$ module list
Currently Loaded Modulefiles:
 1) b   2) a
$ module purge
$ module load --force c
WARNING: c requires a loaded
$ module list
Currently Loaded Modulefiles:
 1) c

--force also enables to unload a modulefile required by another loaded modulefiles:

$ module load a c
$ module list
Currently Loaded Modulefiles:
 1) a   2) c
$ module unload --force a
WARNING: a is required by c
$ module list
Currently Loaded Modulefiles:
 1) c

In a situation where some of the loaded modulefiles have unsatisfied constraints corresponding to the prereq and conflict they declare, the save and reload sub-commands do not perform and return an error.

Automated module handling mode

An automatic management of the dependencies between modulefiles has been added and it is called automated module handling mode. This new mode consists in additional actions triggered when loading or unloading a modulefile to satisfy the constraints it declares.

When loading a modulefile, following actions are triggered:

  • Requirement Load (ReqLo): load of the modulefiles declared as a prereq of the loading modulefile.
  • Dependent Reload (DepRe): reload of the modulefiles declaring a prereq onto loaded modulefile or declaring a prereq onto a modulefile part of this reloading batch.

When unloading a modulefile, following actions are triggered:

  • Dependent Unload (DepUn): unload of the modulefiles declaring a non-optional prereq onto unloaded modulefile or declaring a non-optional prereq onto a modulefile part of this unloading batch. A prereq modulefile is considered optional if the prereq definition order is made of multiple modulefiles and at least one alternative modulefile is loaded.
  • Useless Requirement Unload (UReqUn): unload of the prereq modulefiles that have been automatically loaded for either the unloaded modulefile, an unloaded dependent modulefile or a modulefile part of this useless requirement unloading batch. Modulefiles are added to this unloading batch only if they are not required by any other loaded modulefiles. MODULES_LMNOTUASKED environment variable helps to keep track of these automatically loaded modulefiles and to distinguish them from modulefiles asked by user.
  • Dependent Reload (DepRe): reload of the modulefiles declaring a conflict or an optional prereq onto either the unloaded modulefile, an unloaded dependent or an unloaded useless requirement or declaring a prereq onto a modulefile part of this reloading batch.

In case a loaded modulefile has some of its declared constraints unsatisfied (pre-required modulefile not loaded or conflicting modulefile loaded for instance), this loaded modulefile is excluded from the automatic reload actions described above.

For the specific case of the switch sub-command, where a modulefile is unloaded to then load another modulefile. Dependent modulefiles to Unload are merged into the Dependent modulefiles to Reload that are reloaded after the load of the switched-to modulefile.

This automated module handling mode integrates concepts (like the Dependent Reload mechanism) of the Flavours extension, which was designed for Modules compatibility version. As a whole, automated module handling mode can be seen as a generalization and as an expansion of the Flavours concepts.

This new feature can be controlled at build time with the --enable-auto-handling configure option. This default configuration can be superseded at run-time with the MODULES_AUTO_HANDLING environment variable or the command line switches --auto and --no-auto.

By default, automated module handling mode is disabled and will stay so until the next major release version (5.0) where it will be enabled by default. This new feature is currently considered experimental and the set of triggered actions will be refined over the next feature releases.

Consistency of module load/unload commands in modulefile

With the module load modulefile command, a given modulefile can automatically load a modulefile it pre-requires. Similarly with the module unload modulefile command, a given modulefile can automatically unload a modulefile it conflicts with.

Both commands imply additional actions on the loaded environment (loading or unloading extra modulefiles) that should cope with the constraints defined by the loaded environment.

Additionally module load and module unload modulefile commands express themselves constraints on loaded environment that should stay satisfied to ensure consistency.

To ensure the consistency of module load modulefile command once the modulefile defining it has been loaded, this command is assimilated to a prereq command. Thus the defined constraint is recorded in the MODULES_LMPREREQ environment variable. Same approach is used for module unload modulefile command which is assimilated to a conflict command. Thus the defined constraint is recorded in the MODULES_LMCONFLICT environment variable.

To ensure the consistency of the loaded environment, the additional actions of the module load and module unload modulefile commands have been adapted in particular situations:

  • When unloading modulefile, module load command will unload the modulefile it targets only if no other loaded modulefile requires it and if this target has not been explicitly loaded by user.
  • When unloading modulefile, module unload command does nothing as the relative conflict registered at load time ensure environment consistency and will forbid conflicting modulefile load.

Please note that loading and unloading results may differ than from previous Modules version now that consistency is checked:

  • Modulefile targeted by a module load modulefile command may not be able to load due to a registered conflict in the currently loaded environment. Which in turn will break the load of the modulefile declaring the module load command.
  • Modulefile targeted by a module unload modulefile command may not be able to unload due to a registered prereq in the loaded environment. Which in turn will break the load of the modulefile declaring the module unload command.
  • If automated module handling mode is enabled, module load modulefile command is interpreted when unloading modulefile as part of the Useless Requirement Unload (UReqUn) mechanism not through modulefile evaluation. As a consequence, an error occurring when unloading the modulefile targeted by the module load command does not break the unload of the modulefile declaring this command. Moreover unload of the module load targets is done in the reverse loaded order, not in the module load command definition order.
Modulefile alias and symbolic modulefile name consistency

With the module-alias and module-version modulefile commands, alternative names can be given to a modulefile. When these names are used to load for instance a modulefile, they are resolved to the modulefile they target which is then processed for the load action.

Until now, the alias and symbolic version names were correctly resolved for the load and unload actions and also for the querying sub-commands (like avail or whatis). However this alternative name information vanishes once the modulefile it resolves to is loaded. As a consequence there was no consistency over these alternative designations. In the following example f modulefile declares a conflict on e alias which resolves to d modulefile:

$ module load e
$ module list
Currently Loaded Modulefiles:
 1) d
$ module info-loaded e
$ module load f
$ module list
Currently Loaded Modulefiles:
 1) d   2) f

Consistency of the alternative names set on a modulefile with module-alias and module-version commands is now ensured to enable modulefile commands prereq, conflict, is-loaded and module-info loaded using these alternative designations as argument. This consistency is achieved, like for the conflict and prereq consistencies, by keeping track of the alternative names of the loaded modulefiles in an environment variable called MODULES_LMALTNAME:

$ module load e
$ module list
Currently Loaded Modulefiles:
 1) d
$ module info-loaded e
d
$ module load f
WARNING: f cannot be loaded due to a conflict.
HINT: Might try "module unload e" first.
$ module list
Currently Loaded Modulefiles:
 1) d
Environment variable change through modulefile evaluation context

All environment variable edition commands (setenv, unsetenv, append-path, prepend-path and remove-path) have been updated to:

  • Reflect environment variable value change on the environment of the current modulefile Tcl interpreter. So using $env(VAR) will return the currently defined value for environment variable VAR, not the one found prior modulefile evaluation.
  • Clear environment variable content instead of unsetting it on the environment of the current modulefile Tcl interpreter to avoid raising error about accessing an undefined element in $env(). Code is still produced to purely unset environment variable in shell environment.

Exception is made for the whatis evaluation mode: environment variables targeted by variable edition commands are not set to the defined value in the evaluation context during this whatis evaluation. These variables are only initialized to an empty value if undefined. This exception is made to save performances on this global evaluation mode.

Improved module message report

Module sub-commands like load, unload or switch, may perform multiple load or unload modulefile evaluations in a row. Also these kind of evaluation modes may sometimes trigger additional load or unload evaluations, when for instance a modulefile contains a module load command.

To improve the readability of the module messages produced relatively to a load or an unload evaluation, these messages are now stacked under a Loading or an Unloading message block that gathers all the messages produced for a given modulefile evaluation:

$ module load --no-auto foo
Loading foo/1.2
  ERROR: foo/1.2 cannot be loaded due to missing prereq.
    HINT: the following module must be loaded first: bar/4.5

In addition, foreground load, unload, switch and restore actions (ie. asked on the command-line) now report a summary of the additional load and unload evaluations that were eventually triggered in the process:

$ module load --auto foo
Loading foo/1.2
  Loading requirement: bar/4.5
New modulefile commands

2 new modulefile Tcl commands have been introduced:

  • set-function: define a shell function on sh-kind and fish shells.
  • unset-function: unset a shell function on sh-kind and fish shells.
Further reading

To get a complete list of the changes between Modules v4.1 and v4.2, please read the Release notes document.

Migrating from v4.0 to v4.1

This new version is backward-compatible with v4.0 and primarily fixes bugs and adds new features.

New features

Version 4.1 introduces a bunch of new functionalities. These major new features are described in this section.

Virtual modules

A virtual module stands for a module name associated to a modulefile. The modulefile is the script interpreted when loading or unloading the virtual module which appears or can be found with its virtual name.

The module-virtual modulefile command is introduced to give the ability to define these virtual modules. This new command takes a module name as first argument and a modulefile location as second argument:

module-virtual app/1.2.3 /path/to/virtualmod/app

With this feature it is now possible to dynamically define modulefiles depending on the context.

Extend module command with site-specific Tcl code

module command can now be extended with site-specific Tcl code. modulecmd.tcl now looks at a siteconfig.tcl file in an etcdir defined at configure time (by default $prefix/etc). If it finds this Tcl script file, it is sourced within modulecmd.tcl at the beginning of the main procedure code.

siteconfig.tcl enables to supersede any global variable or procedure definitions made in modulecmd.tcl with site-specific code. A module sub-command can for instance be redefined to make it fit local needs without having to touch the main modulecmd.tcl.

Quarantine mechanism to protect module execution

To protect the module command run-time environment from side effect coming from the current environment definition a quarantine mechanism is introduced. This mechanism, sets within module function definition and shell initialization script, modifies the modulecmd.tcl run-time environment to sanitize it.

The mechanism is piloted by environment variables. First of all MODULES_RUN_QUARANTINE, a space-separated list of environment variable names. Every variable found in MODULES_RUN_QUARANTINE will be set in quarantine during the modulecmd.tcl run-time. Their value will be set empty or set to the value of the corresponding MODULES_RUNENV_<VAR> environment variable if defined. Once modulecmd.tcl is started it restores quarantine variables to their original values.

MODULES_RUN_QUARANTINE and MODULES_RUNENV_<VAR> environment variables can be defined at build time by using the following configure option:

--with-quarantine-vars='VARNAME[=VALUE] ...'

Quarantine mechanism is available for all supported shells except csh and tcsh.

Pager support

The informational messages Modules sends on the stderr channel may sometimes be quite long. This is especially the case for the avail sub-command when hundreds of modulefiles are handled. To improve the readability of those messages, stderr output can now be piped into a paging command.

This new feature can be controlled at build time with the --with-pager and --with-pager-opts configure options. Default pager command is set to less and its relative options are by default -eFKRX. Default configuration can be supersedes at run-time with MODULES_PAGER environment variables or command-line switches (--no-pager, --paginate).

Warning

On version 4.1.0, the PAGER environment variable was taken in consideration to supersede pager configuration at run-time. Since version 4.1.1, PAGER environment variable is ignored to avoid side effects coming from the system general pager configuration.

Module function to return value in scripting languages

On Tcl, Perl, Python, Ruby, CMake and R scripting shells, module function was not returning value and until now an occurred error led to raising a fatal exception.

To make module function more friendly to use on these scripting shells it now returns a value. False in case of error, true if everything goes well.

As a consequence, returned value of a module sub-command can be checked. For instance in Python:

if module('load', 'foo'):
  # success
else:
  # failure
New modulefile commands

4 new modulefile Tcl commands have been introduced:

  • is-saved: returns true or false whether a collection, corresponding to currently set collection target, exists or not.
  • is-used: returns true or false whether a given directory is currently enabled in MODULEPATH.
  • is-avail: returns true or false whether a given modulefile exists in currently enabled module paths.
  • module-info loaded: returns the exact name of the modulefile currently loaded corresponding to the name argument.

Multiple collections, paths or modulefiles can be passed respectively to is-saved, is-used and is-avail in which case true is returned if at least one argument matches condition (acts as a OR boolean operation). No argument may be passed to is-loaded, is-saved and is-used commands to return if anything is respectively loaded, saved or used.

If no loaded modulefile matches the module-info loaded query, an empty string is returned.

New module sub-commands

Modulefile-specific commands are sometimes wished to be used outside of a modulefile context. Especially for the commands managing path variables or commands querying current environment context. So the following modulefile-specific commands have been made reachable as module sub-commands with same arguments and properties as if called from within a modulefile:

  • append-path
  • prepend-path
  • remove-path
  • is-loaded
  • info-loaded

The is-loaded sub-command returns a boolean value. Small Python example:

if module('is-loaded', 'app'):
  print 'app is loaded'
else:
  print 'app not loaded'

info-loaded returns a string value and is the sub-command counterpart of the module-info loaded modulefile command:

$ module load app/0.8
$ module info-loaded app
app/0.8
Further reading

To get a complete list of the changes between Modules v4.0 and v4.1, please read the Release notes document.

Migrating from v3.2 to v4.0

Major evolution occurs with this v4.0 release as the traditional module command implemented in C is replaced by the native Tcl version. This full Tcl rewrite of the Modules package was started in 2002 and has now reached maturity to take over the binary version. This flavor change enables to refine and push forward the module concept.

This document provides an outlook of what is changing when migrating from v3.2 to v4.0 by first describing the introduced new features. Both v3.2 and v4.0 are quite similar and transition to the new major version should be smooth. Slights differences may be noticed in a few use-cases. So the second part of the document will help to learn about them by listing the features that have been discontinued in this new major release or the features where a behavior change can be noticed.

New features

On its overall this major release brings a lot more robustness to the module command with now more than 4000 non-regression tests crafted to ensure correct operations over the time. This version 4.0 also comes with fair amount of improved functionalities. The major new features are described in this section.

Additional shells supported

Modules v4 introduces support for fish, lisp, tcl and R code output.

Non-zero exit code in case of error

All module sub-commands will now return a non-zero exit code in case of error whereas Modules v3.2 always returned zero exit code even if issue occurred.

Output redirect

Traditionally the module command output text that should be seen by the user on stderr since shell commands are output to stdout to change shell's environment. Now on sh, bash, ksh, zsh and fish shells, output text is redirected to stdout after shell command evaluation if shell is in interactive mode.

Filtering avail output

Results obtained from the avail sub-command can now be filtered to only get the default version of each module name with use of the --default or -d command line switch. Default version is either the explicitly set default version or the highest numerically sorted modulefile or module alias if no default version set.

It is also possible to filter results to only get the highest numerically sorted version of each module name with use of the --latest or -L command line switch.

Extended support for module alias and symbolic version

Module aliases are now included in the result of the avail, whatis and apropos sub-commands. They are displayed in the module path section where they are defined or in a global/user modulerc section for aliases set in user's or global modulerc file. A @ symbol is added in parenthesis next to their name to distinguish them from modulefiles.

Search may be performed with an alias or a symbolic version-name passed as argument on avail, whatis and apropos sub-commands.

Modules v4 resolves module alias or symbolic version passed to unload command to then remove the loaded modulefile pointed by the mentioned alias or symbolic version.

A symbolic version sets on a module alias is now propagated toward the resolution path to also apply to the relative modulefile if it still correspond to the same module name.

Hiding modulefiles

Visibility of modulefiles can be adapted by use of file mode bits or file ownership. If a modulefile should only be used by a given subset of persons, its mode an ownership can be tailored to provide read rights to this group of people only. In this situation, module only reports the modulefile, during an avail command for instance, if this modulefile can be read by the current user.

These hidden modulefiles are simply ignored when walking through the modulepath content. Access issues (permission denied) occur only when trying to access directly a hidden modulefile or when accessing a symbol or an alias targeting a hidden modulefile.

Improved modulefiles location

When looking for an implicit default in a modulefile directory, aliases are now taken into account in addition to modulefiles and directories to determine the highest numerically sorted element.

Modules v4 resolves module alias or symbolic version when it points to a modulefile located in another modulepath.

Access issues (permission denied) are now distinguished from find issues (cannot locate) when trying to access directly a directory or a modulefile as done on load, display or whatis commands. In addition, on this kind of access not readable .modulerc or .version files are ignored rather producing a missing magic cookie error.

Module collection

Modules v4 introduces support for module collections. Collections describe a sequence of module use then module load commands that are interpreted by Modules to set the user environment as described by this sequence. When a collection is activated, with the restore sub-command, modulepaths and loaded modules are unused or unloaded if they are not part or if they are not ordered the same way as in the collection.

Collections are generated by the save sub-command that dumps the current user environment state in terms of modulepaths and loaded modules. By default collections are saved under the $HOME/.module directory. Collections can be listed with savelist sub-command, displayed with saveshow and removed with saverm.

Collections may be valid for a given target if they are suffixed. In this case these collections can only be restored if their suffix correspond to the current value of the MODULES_COLLECTION_TARGET environment variable. Saving collection registers the target footprint by suffixing the collection filename with .$MODULES_COLLECTION_TARGET.

Path variable element counter

Modules 4 provides path element counting feature which increases a reference counter each time a given path entry is added to a given path-like environment variable. As consequence a path entry element is removed from a path-like variable only if the related element counter is equal to 1. If this counter is greater than 1, path element is kept in variable and reference counter is decreased by 1.

This feature allows shared usage of particular path elements. For instance, modulefiles can append /usr/local/bin to PATH, which is not unloaded until all the modulefiles that loaded it unload too.

Optimized I/O operations

Substantial work has been done to reduce the number of I/O operations done during global modulefile analysis commands like avail or whatis. stat, open, read and close I/O operations have been cut down to the minimum required when walking through the modulepath directories to check if files are modulefiles or to resolve module aliases.

Interpretation of modulefiles and modulerc are handled by the minimum required Tcl interpreters. Which means a configured Tcl interpreter is reused as much as possible between each modulefile interpretation or between each modulerc interpretation.

Sourcing modulefiles

Modules 4 introduces the possibility to source a modulefile rather loading it. When it is sourced, a modulefile is interpreted into the shell environment but then it is not marked loaded in shell environment which differ from load sub-command.

This functionality is used in shell initialization scripts once module function is defined. There the etc/modulerc modulefile is sourced to setup the initial state of the environment, composed of module use and module load commands.

Removed features and substantial behavior changes

Following sections provide list of Modules v3.2 features that are discontinued on Modules v4 or features with a substantial behavior change that should be taken in consideration when migrating to v4.

Package initialization

MODULESBEGINENV environment snapshot functionality is not supported anymore on Modules v4. Modules collection mechanism should be used instead to save and restore sets of enabled modulepaths and loaded modulefiles.

Command line switches

Some command line switches are not supported anymore on v4.0. When still using them, a warning message is displayed and the command is ran with these unsupported switches ignored. Following command line switches are concerned:

  • --force, -f
  • --human
  • --verbose, -v
  • --silent, -s
  • --create, -c
  • --icase, -i
  • --userlvl lvl, -u lvl
Module sub-commands

During an help sub-command, Modules v4 does not redirect output made on stdout in ModulesHelp Tcl procedure to stderr. Moreover when running help, version 4 interprets all the content of the modulefile, then call the ModulesHelp procedure if it exists, whereas Modules 3.2 only interprets the ModulesHelp procedure and not the rest of the modulefile content.

When load is asked on an already loaded modulefiles, Modules v4 ignores this new load order whereas v3.2 refreshed shell alias definitions found in this modulefile.

When switching on version 4 an old modulefile by a new one, no error is raised if old modulefile is not currently loaded. In this situation v3.2 threw an error and abort switch action. Additionally on switch sub-command, new modulefile does not keep the position held by old modulefile in loaded modules list on Modules v4 as it was the case on v3.2. Same goes for path-like environment variables: replaced path component is appended to the end or prepended to the beginning of the relative path-like variable, not appended or prepended relatively to the position hold by the swapped path component.

During a switch command, version 4 interprets the swapped-out modulefile in unload mode, so the sub-modulefiles loaded, with module load order in the swapped-out modulefile are also unloaded during the switch.

Modules 4 provides path element counting feature which increases a reference counter each time a given path entry is added to a given environment variable. This feature also applies to the MODULEPATH environment variable. As consequence a modulepath entry element is removed from the modulepath enabled list only if the related element counter is equal to 1. When unusing a modulepath if its reference counter is greater than 1, modulepath is kept enabled and reference counter is decreased by 1.

On Modules 3.2 paths composing the MODULEPATH environment variable may contain reference to environment variable. These variable references are resolved dynamically when MODULEPATH is looked at during module sub-command action. This feature has been discontinued on Modules v4.

Following Modules sub-commands are not supported anymore on v4.0:

  • clear
  • update
Modules specific Tcl commands

Modules v4 provides path element counting feature which increases a reference counter each time a given path entry is added to a given environment variable. As a consequence a path entry element is not always removed from a path-like variable when calling to remove-path or calling to append-path or append-path at unloading time. The path element is removed only if its related element counter is equal to 1. If this counter is greater than 1, path element is kept in variable and reference counter is decreased by 1.

On Modules v4, module-info mode returns during an unload sub-command the unload value instead of remove on Modules v3.2. However if mode is tested against remove value, true will be returned. During a switch sub-command on Modules v4, unload then load is returned instead of switch1 then switch2 then switch3 on Modules v3.2. However if mode is tested against switch value, true will be returned.

When using set-alias, Modules v3.2 defines a shell function when variables are in use in alias value on Bourne shell derivatives, Modules 4 always defines a shell alias never a shell function.

Some Modules specific Tcl commands are not supported anymore on v4.0. When still using them, a warning message is displayed and these unsupported Tcl commands are ignored. Following Modules specific Tcl commands are concerned:

  • module-info flags
  • module-info trace
  • module-info tracepat
  • module-info user
  • module-log
  • module-trace
  • module-user
  • module-verbosity
Further reading

To get a complete list of the differences between Modules v3.2 and v4, please read the Differences between versions 3.2 and 4 document.

A significant number of issues reported for v3.2 have been closed on v4. List of these closed issues can be found at:

https://github.com/cea-hpc/modules/milestone/1?closed=1

module

SYNOPSIS

module [switches] [sub-command [sub-command-args]]

DESCRIPTION

module is a user interface to the Modules package. The Modules package provides for the dynamic modification of the user's environment via modulefiles.

Each modulefile contains the information needed to configure the shell for an application. Once the Modules package is initialized, the environment can be modified on a per-module basis using the module command which interprets modulefiles. Typically modulefiles instruct the module command to alter or set shell environment variables such as PATH, MANPATH, etc. Modulefiles may be shared by many users on a system and users may have their own set to supplement or replace the shared modulefiles.

The modulefiles are added to and removed from the current environment by the user. The environment changes contained in a modulefile can be summarized through the module command as well. If no arguments are given, a summary of the module usage and sub-commands are shown.

The action for the module command to take is described by the sub-command and its associated arguments.

Package Initialization

The Modules package and the module command are initialized when a shell-specific initialization script is sourced into the shell. The script creates the module command as either an alias or function and creates Modules environment variables.

The module alias or function executes the modulecmd.tcl program located in /usr/share/Modules/libexec and has the shell evaluate the command's output. The first argument to modulecmd.tcl specifies the type of shell.

The initialization scripts are kept in /usr/share/Modules/init/<shell> where <shell> is the name of the sourcing shell. For example, a C Shell user sources the /usr/share/Modules/init/csh script. The sh, csh, tcsh, bash, ksh, zsh and fish shells are supported by modulecmd.tcl. In addition, python, perl, ruby, tcl, cmake, r and lisp "shells" are supported which writes the environment changes to stdout as python, perl, ruby, tcl, lisp, r or cmake code.

Initialization may also be performed by calling the autoinit sub-command of the modulecmd.tcl program. Evaluation into the shell of the result of this command defines the module alias or function.

Examples of initialization

C Shell initialization (and derivatives):

source /usr/share/Modules/init/csh
module load modulefile modulefile ...

Bourne Shell (sh) (and derivatives):

. /usr/share/Modules/init/sh
module load modulefile modulefile ...

Perl:

require "/usr/share/Modules/init/perl.pm";
&module('load', 'modulefile', 'modulefile', '...');

Python:

import os
exec(open('/usr/share/Modules/init/python.py').read())
module('load', 'modulefile', 'modulefile', '...')

Bourne Shell (sh) (and derivatives) with autoinit sub-command:

eval "`/usr/share/Modules/libexec/modulecmd.tcl sh autoinit`"
Modulecmd startup

Upon invocation modulecmd.tcl sources a site-specific configuration script if it exists. The location for this script is /usr/share/Modules/etc/siteconfig.tcl. An additional siteconfig script may be specified with the $MODULES_SITECONFIG environment variable, if allowed by modulecmd.tcl configuration, and will be loaded if it exists after /usr/share/Modules/etc/siteconfig.tcl. Siteconfig is a Tcl script that enables to supersede any global variable or procedure definition of modulecmd.tcl.

Afterward, modulecmd.tcl sources rc files which contain global, user and modulefile specific setups. These files are interpreted as modulefiles. See modulefile for detailed information.

Upon invocation of modulecmd.tcl module run-command files are sourced in the following order:

  1. Global RC file as specified by $MODULERCFILE or /usr/share/Modules/etc/rc. If $MODULERCFILE points to a directory, the modulerc file in this directory is used as global RC file.
  2. User specific module RC file $HOME/.modulerc
  3. All .modulerc and .version files found during modulefile seeking.
Command line switches

The module command accepts command line switches as its first parameter. These may be used to control output format of all information displayed and the module behavior in case of locating and interpreting modulefiles.

All switches may be entered either in short or long notation. The following switches are accepted:

--help, -h

Give some helpful usage information, and terminates the command.

--version, -V

Lists the current version of the module command. The command then terminates without further processing.

--debug, -D

Debug mode. Causes module to print debugging messages about its progress.

--verbose, -v

Enable verbose messages during module command execution.

--silent, -s

Turn off error, warning and informational messages. module command output result is not affected by silent mode.

--paginate

Pipe all message output into less (or if set, $MODULES_PAGER) if error output stream is a terminal. See also MODULES_PAGER section.

--no-pager

Do not pipe message output into a pager.

--color[=WHEN]

Colorize the output. WHEN defaults to always or can be never or auto. See also MODULES_COLOR section.

--auto

On load, unload and switch sub-commands, enable automated module handling mode. See also MODULES_AUTO_HANDLING section.

--no-auto

On load, unload and switch sub-commands, disable automated module handling mode. See also MODULES_AUTO_HANDLING section.

--force, -f

On load, unload and switch sub-commands, by-pass any unsatisfied modulefile constraint corresponding to the declared prereq and conflict. Which means for instance that a modulefile will be loaded even if it comes in conflict with another loaded modulefile or that a modulefile will be unloaded even if it is required as a prereq by another modulefile.

On clear sub-command, skip the confirmation dialog and proceed.

--terse, -t

Display avail, list and savelist output in short format.

--long, -l

Display avail, list and savelist output in long format.

--default, -d

On avail sub-command, display only the default version of each module name. Default version is the explicitly set default version or also the implicit default version if config option implicit_default is enabled (see Locating Modulefiles section in the modulefile man page for further details on implicit default version).

--latest, -L

On avail sub-command, display only the highest numerically sorted version of each module name (see Locating Modulefiles section in the modulefile man page).

--starts-with, -S

On avail sub-command, return modules whose name starts with search query string.

--contains, -C

On avail sub-command, return modules whose fully qualified name contains search query string.

--indepth

On avail sub-command, include in search results the matching modulefiles and directories and recursively the modulefiles and directories contained in these matching directories.

--no-indepth

On avail sub-command, limit search results to the matching modulefiles and directories found at the depth level expressed by the search query. Thus modulefiles contained in directories part of the result are excluded.

--icase, -i

Match module specification arguments in a case insensitive manner.
Module Sub-Commands

help [modulefile...]

Print the usage of each sub-command. If an argument is given, print the Module-specific help information for the modulefile.

The parameter modulefile may also be a symbolic modulefile name or a modulefile alias. It may also leverage a specific syntax to finely select module version (see Advanced module version specifiers section below).

add modulefile...

See load.

load [--auto|--no-auto] [-f] modulefile...

Load modulefile into the shell environment.

The parameter modulefile may also be a symbolic modulefile name or a modulefile alias. It may also leverage a specific syntax to finely select module version (see Advanced module version specifiers section below).

rm modulefile...

See unload.

unload [--auto|--no-auto] [-f] modulefile...

Remove modulefile from the shell environment.

The parameter modulefile may also be a symbolic modulefile name or a modulefile alias. It may also leverage a specific syntax to finely select module version (see Advanced module version specifiers section below).

swap [modulefile1] modulefile2

See switch.

switch [--auto|--no-auto] [-f] [modulefile1] modulefile2

Switch loaded modulefile1 with modulefile2. If modulefile1 is not specified, then it is assumed to be the currently loaded module with the same root name as modulefile2.

The parameter modulefile may also be a symbolic modulefile name or a modulefile alias. It may also leverage a specific syntax to finely select module version (see Advanced module version specifiers section below).

show modulefile...

See display.

display modulefile...

Display information about one or more modulefiles. The display sub-command will list the full path of the modulefile and the environment changes the modulefile will make if loaded. (Note: It will not display any environment changes found within conditional statements.)

The parameter modulefile may also be a symbolic modulefile name or a modulefile alias. It may also leverage a specific syntax to finely select module version (see Advanced module version specifiers section below).

list [-t|-l]

List loaded modules.

avail [-d|-L] [-t|-l] [-S|-C] [--indepth|--no-indepth] [path...]

List all available modulefiles in the current MODULEPATH. All directories in the MODULEPATH are recursively searched for files containing the modulefile magic cookie. If an argument is given, then each directory in the MODULEPATH is searched for modulefiles whose pathname, symbolic version-name or alias match the argument. Argument may contain wildcard characters. Multiple versions of an application can be supported by creating a subdirectory for the application containing modulefiles for each version.

Symbolic version-names and aliases found in the search are displayed in the result of this sub-command. Symbolic version-names are displayed next to the modulefile they are assigned to within parenthesis. Aliases are listed in the MODULEPATH section where they have been defined. To distinguish aliases from modulefiles a @ symbol is added within parenthesis next to their name. Aliases defined through a global or user specific module RC file are listed under the global/user modulerc section.

When colored output is enabled and a specific graphical rendition is defined for module default version, the default symbol is omitted and instead the defined graphical rendition is applied to the relative modulefile. When colored output is enabled and a specific graphical rendition is defined for module alias, the @ symbol is omitted. The defined graphical rendition applies to the module alias name. See MODULES_COLOR and MODULES_COLORS sections for details on colored output.

The parameter path may also refer to a symbolic modulefile name or a modulefile alias. It may also leverage a specific syntax to finely select module version (see Advanced module version specifiers section below).

aliases

List all available symbolic version-names and aliases in the current MODULEPATH. All directories in the MODULEPATH are recursively searched in the same manner than for the avail sub-command. Only the symbolic version-names and aliases found in the search are displayed.

use [-a|--append] directory...

Prepend one or more directories to the MODULEPATH environment variable. The --append flag will append the directory to MODULEPATH.

Reference counter environment variable MODULEPATH_modshare is also set to increase the number of times directory has been added to MODULEPATH.

unuse directory...

Remove one or more directories from the MODULEPATH environment variable if reference counter of these directories is equal to 1 or unknown.

Reference counter of directory in MODULEPATH denotes the number of times directory has been enabled. When attempting to remove directory from MODULEPATH, reference counter variable MODULEPATH_modshare is checked and directory is removed only if its relative counter is equal to 1 or not defined. Elsewhere directory is kept and reference counter is decreased by 1.

refresh

See reload.

reload

Unload then load all loaded modulefiles.

No unload then load is performed and an error is returned if the loaded modulefiles have unsatisfied constraint corresponding to the prereq and conflict they declare.

purge

Unload all loaded modulefiles.

clear [-f]

Force the Modules package to believe that no modules are currently loaded. A confirmation is requested if command-line switch -f (or --force) is not passed. Typed confirmation should equal to yes or y in order to proceed.

source scriptfile...

Execute scriptfile into the shell environment. scriptfile must be written with modulefile syntax and specified with a fully qualified path. Once executed scriptfile is not marked loaded in shell environment which differ from load sub-command.

whatis [modulefile...]

Display the information set up by the module-whatis commands inside the specified modulefiles. These specified modulefiles may be expressed using wildcard characters. If no modulefile is specified, all module-whatis lines will be shown.

The parameter modulefile may also be a symbolic modulefile name or a modulefile alias. It may also leverage a specific syntax to finely select module version (see Advanced module version specifiers section below).

apropos string

See search.

keyword string

See search.

search string

Seeks through the module-whatis informations of all modulefiles for the specified string. All module-whatis informations matching the string in a case insensitive manner will be displayed. string may contain wildcard characters.

test modulefile...

Execute and display results of the Module-specific tests for the modulefile.

The parameter modulefile may also be a symbolic modulefile name or a modulefile alias. It may also leverage a specific syntax to finely select module version (see Advanced module version specifiers section below).

save [collection]

Record the currently set MODULEPATH directory list and the currently loaded modulefiles in a collection file under the user's collection directory $HOME/.module. If collection name is not specified, then it is assumed to be the default collection. If collection is a fully qualified path, it is saved at this location rather than under the user's collection directory.

If MODULES_COLLECTION_TARGET is set, a suffix equivalent to the value of this variable will be appended to the collection file name.

By default, if loaded modulefile corresponds to the explicitly defined default module version, the bare module name is recorded. If config option implicit_default is enabled, the bare module name is also recorded for the implicit default module version. If MODULES_COLLECTION_PIN_VERSION is set to 1, module version is always recorded even if it is the default version.

No collection is recorded and an error is returned if the loaded modulefiles have unsatisfied constraint corresponding to the prereq and conflict they declare.

restore [collection]

Restore the environment state as defined in collection. If collection name is not specified, then it is assumed to be the default collection. If collection is a fully qualified path, it is restored from this location rather than from a file under the user's collection directory. If MODULES_COLLECTION_TARGET is set, a suffix equivalent to the value of this variable is appended to the collection file name to restore.

When restoring a collection, the currently set MODULEPATH directory list and the currently loaded modulefiles are unused and unloaded then used and loaded to exactly match the MODULEPATH and loaded modulefiles lists saved in this collection file. The order of the paths and modulefiles set in collection is preserved when restoring. It means that currently loaded modules are unloaded to get the same LOADEDMODULES root than collection and currently used module paths are unused to get the same MODULEPATH root. Then missing module paths are used and missing modulefiles are loaded.

If a module, without a default version explicitly defined, is recorded in a collection by its bare name: loading this module when restoring the collection will fail if config option implicit_default is disabled.

saverm [collection]

Delete the collection file under the user's collection directory. If collection name is not specified, then it is assumed to be the default collection. If MODULES_COLLECTION_TARGET is set, a suffix equivalent to the value of this variable will be appended to the collection file name.

saveshow [collection]

Display the content of collection. If collection name is not specified, then it is assumed to be the default collection. If collection is a fully qualified path, this location is displayed rather than a collection file under the user's collection directory. If MODULES_COLLECTION_TARGET is set, a suffix equivalent to the value of this variable will be appended to the collection file name.

savelist [-t|-l]

List collections that are currently saved under the user's collection directory. If MODULES_COLLECTION_TARGET is set, only collections matching the target suffix will be displayed.

initadd modulefile...

Add modulefile to the shell's initialization file in the user's home directory. The startup files checked (in order) are:

C Shell

.modules, .cshrc, .csh_variables and .login

TENEX C Shell

.modules, .tcshrc, .cshrc, .csh_variables and .login

Bourne and Korn Shells

.modules, .profile

GNU Bourne Again Shell

.modules, .bash_profile, .bash_login, .profile and .bashrc

Z Shell

.modules, .zshrc, .zshenv and .zlogin

Friendly Interactive Shell

.modules, .config/fish/config.fish

If a module load line is found in any of these files, the modulefiles are appended to any existing list of modulefiles. The module load line must be located in at least one of the files listed above for any of the init sub-commands to work properly. If the module load line is found in multiple shell initialization files, all of the lines are changed.

initprepend modulefile...

Does the same as initadd but prepends the given modules to the beginning of the list.

initrm modulefile...

Remove modulefile from the shell's initialization files.

initswitch modulefile1 modulefile2

Switch modulefile1 with modulefile2 in the shell's initialization files.

initlist

List all of the modulefiles loaded from the shell's initialization file.

initclear

Clear all of the modulefiles from the shell's initialization files.

path modulefile

Print path to modulefile.

The parameter modulefile may also be a symbolic modulefile name or a modulefile alias. It may also leverage a specific syntax to finely select module version (see Advanced module version specifiers section below).

paths modulefile

Print path of available modulefiles matching argument.

The parameter modulefile may also be a symbolic modulefile name or a modulefile alias. It may also leverage a specific syntax to finely select module version (see Advanced module version specifiers section below).

append-path [-d C|--delim C|--delim=C] [--duplicates] variable value...

Append value to environment variable. The variable is a colon, or delimiter, separated list. See append-path in the modulefile man page for further explanation.

prepend-path [-d C|--delim C|--delim=C] [--duplicates] variable value...

Prepend value to environment variable. The variable is a colon, or delimiter, separated list. See prepend-path in the modulefile man page for further explanation.

remove-path [-d C|--delim C|--delim=C] [--index] variable value...

Remove value from the colon, or delimiter, separated list in environment variable. See remove-path in the modulefile man page for further explanation.

is-loaded [modulefile...]

Returns a true value if any of the listed modulefiles has been loaded or if any modulefile is loaded in case no argument is provided. Returns a false value elsewhere. See is-loaded in the modulefile man page for further explanation.

The parameter modulefile may also be a symbolic modulefile name or a modulefile alias. It may also leverage a specific syntax to finely select module version (see Advanced module version specifiers section below).

is-saved [collection...]

Returns a true value if any of the listed collections exists or if any collection exists in case no argument is provided. Returns a false value elsewhere. See is-saved in the modulefile man page for further explanation.

is-used [directory...]

Returns a true value if any of the listed directories has been enabled in MODULEPATH or if any directory is enabled in case no argument is provided. Returns a false value elsewhere. See is-used in the modulefile man page for further explanation.

is-avail modulefile...

Returns a true value if any of the listed modulefiles exists in enabled MODULEPATH. Returns a false value elsewhere. See is-avail in the modulefile man page for further explanation.

The parameter modulefile may also be a symbolic modulefile name or a modulefile alias. It may also leverage a specific syntax to finely select module version (see Advanced module version specifiers section below).

info-loaded modulefile

Returns the names of currently loaded modules matching passed modulefile. Returns an empty string if passed modulefile does not match any loaded modules. See module-info loaded in the modulefile man page for further explanation.

config [--dump-state|name [value]|--reset name]

Gets or sets modulecmd.tcl options. Reports the currently set value of passed option name or all existing options if no name passed. If a name and a value are provided, the value of option name is set to value. If command-line switch --reset is passed in addition to a name, overridden overridden value for option name is cleared.

When a reported option value differs from default value a mention is added to indicate whether the overridden value is coming from a command-line switch (cmd-line) or from an environment variable (env-var). When a reported option value is locked and cannot be altered a (locked) mention is added.

If no value is currently set for an option name, the mention <undef> is reported.

When command-line switch --dump-state is passed, current modulecmd.tcl state and Modules-related environment variables are reported in addition to currently set modulecmd.tcl options.

Existing option names are:

  • advanced_version_spec: advanced module version specification to finely select modulefiles (defines environment variable MODULES_ADVANCED_VERSION_SPEC when set
  • auto_handling: automated module handling mode (defines MODULES_AUTO_HANDLING)
  • avail_indepth: avail sub-command in depth search mode (defines MODULES_AVAIL_INDEPTH)
  • avail_report_dir_sym: display symbolic versions targeting directories on avail sub-command
  • avail_report_mfile_sym: display symbolic versions targeting modulefiles on avail sub-command
  • collection_pin_version: register exact modulefile version in collection (defines MODULES_COLLECTION_PIN_VERSION)
  • collection_target: collection target which is valid for current system (defines MODULES_COLLECTION_TARGET)
  • color: colored output mode (defines MODULES_COLOR)
  • colors: chosen colors to highlight output items (defines MODULES_COLORS)
  • contact: modulefile contact address (defines MODULECONTACT)
  • extended_default: allow partial module version specification (defines MODULES_EXTENDED_DEFAULT)
  • extra_siteconfig: additional site-specific configuration script location (defines MODULES_SITECONFIG)
  • home: location of Modules package master directory (defines MODULESHOME)
  • icase: enable case insensitive match (defines MODULES_ICASE)
  • ignored_dirs: directories ignored when looking for modulefiles
  • implicit_default: set an implicit default version for modules (defines MODULES_IMPLICIT_DEFAULT)
  • locked_configs: configuration options that cannot be superseded
  • pager: text viewer to paginate message output (defines MODULES_PAGER)
  • rcfile: global run-command file location (defines MODULERCFILE)
  • run_quarantine: environment variables to indirectly pass to modulecmd.tcl (defines MODULES_RUN_QUARANTINE)
  • silent_shell_debug: disablement of shell debugging property for the module command (defines MODULES_SILENT_SHELL_DEBUG)
  • search_match: module search match style (defines MODULES_SEARCH_MATCH)
  • set_shell_startup: ensure module command definition by setting shell startup file (defines MODULES_SET_SHELL_STARTUP)
  • siteconfig: primary site-specific configuration script location
  • tcl_ext_lib: Modules Tcl extension library location
  • term_background: terminal background color kind (defines MODULES_TERM_BACKGROUND)
  • unload_match_order: unload firstly loaded or lastly loaded module matching request (defines MODULES_UNLOAD_MATCH_ORDER)
  • verbosity: module command verbosity level (defines MODULES_VERBOSITY)
  • wa_277: workaround for Tcsh history issue (defines MODULES_WA_277)

The options avail_report_dir_sym, avail_report_mfile_sym, ignored_dirs, locked_configs, siteconfig and tcl_ext_lib cannot be altered. Moreover all options referred in locked_configs value are locked thus they cannot be altered.

Modulefiles

modulefiles are written in the Tool Command Language (Tcl) and are interpreted by modulecmd.tcl. modulefiles can use conditional statements. Thus the effect a modulefile will have on the environment may change depending upon the current state of the environment.

Environment variables are unset when unloading a modulefile. Thus, it is possible to load a modulefile and then unload it without having the environment variables return to their prior state.

Advanced module version specifiers

When the advanced module version specifiers mechanism is enabled (see MODULES_ADVANCED_VERSION_SPEC), the specification of modulefile passed on Modules sub-commands changes. After the module name a version constraint prefixed by the @ character may be added. It could be directly appended to the module name or separated from it with a space character.

Constraints can be expressed to refine the selection of module version to:

  • a single version with the @version syntax, for instance foo@1.2.3 syntax will select module foo/1.2.3
  • a list of versions with the @version1,version2,... syntax, for instance foo@1.2.3,1.10 will match modules foo/1.2.3 and foo/1.10
  • a range of versions with the @version1:, @:version2 and @version1:version2 syntaxes, for instance foo@1.2: will select all versions of module foo greater than or equal to 1.2, foo@:1.3 will select all versions less than or equal to 1.3 and foo@1.2:1.3 matches all versions between 1.2 and 1.3 including 1.2 and 1.3 versions

Advanced specification of single version or list of versions may benefit from the activation of the extended default mechanism (see MODULES_EXTENDED_DEFAULT) to use an abbreviated notation like @1 to refer to more precise version numbers like 1.2.3. Range of versions on its side natively handles abbreviated versions.

In order to be specified in a range of versions or compared to a range of versions, the version major element should corresponds to a number. For instance 10a, 1.2.3, 1.foo are versions valid for range comparison whereas default or foo.2 versions are invalid for range comparison.

Collections

Collections describe a sequence of module use then module load commands that are interpreted by modulecmd.tcl to set the user environment as described by this sequence. When a collection is activated, with the restore sub-command, module paths and loaded modules are unused or unloaded if they are not part or if they are not ordered the same way as in the collection.

Collections are generated by the save sub-command that dumps the current user environment state in terms of module paths and loaded modules. By default collections are saved under the $HOME/.module directory.

Collections may be valid for a given target if they are suffixed. In this case these collections can only be restored if their suffix correspond to the current value of the MODULES_COLLECTION_TARGET environment variable (see the dedicated section of this topic below).

EXIT STATUS

The module command exits with 0 if its execution succeed. Elsewhere 1 is returned.

ENVIRONMENT

LOADEDMODULES

A colon separated list of all loaded modulefiles.

MODULECONTACT

Email address to contact in case any issue occurs during the interpretation of modulefiles.

MODULEPATH

The path that the module command searches when looking for modulefiles. Typically, it is set to the master modulefiles directory, /usr/share/Modules/modulefiles, by the initialization script. MODULEPATH can be set using module use or by the module initialization script to search group or personal modulefile directories before or after the master modulefile directory.

Path elements registered in the MODULEPATH environment variable may contain reference to environment variables which are converted to their corresponding value by module command each time it looks at the MODULEPATH value. If an environment variable referred in a path element is not defined, its reference is converted to an empty string.

MODULERCFILE

The location of a global run-command file containing modulefile specific setup. See Modulecmd startup section for detailed information.

MODULESHOME

The location of the master Modules package file directory containing module command initialization scripts, the executable program modulecmd.tcl, and a directory containing a collection of master modulefiles.

MODULES_ADVANCED_VERSION_SPEC

If set to 1, enable advanced module version specifiers (see Advanced module version specifiers section). If set to 0, disable advanced module version specifiers.

Advanced module version specifiers enablement is defined in the following order of preference: MODULES_ADVANCED_VERSION_SPEC environment variable then the default set in modulecmd.tcl script configuration. Which means MODULES_ADVANCED_VERSION_SPEC overrides default configuration.

MODULES_AUTO_HANDLING

If set to 1, enable automated module handling mode. If set to 0 disable automated module handling mode. Other values are ignored.

Automated module handling mode consists in additional actions triggered when loading or unloading a modulefile to satisfy the constraints it declares. When loading a modulefile, following actions are triggered:

  • Requirement Load: load of the modulefiles declared as a prereq of the loading modulefile.
  • Dependent Reload: reload of the modulefiles declaring a prereq onto loaded modulefile or declaring a prereq onto a modulefile part of this reloading batch.

When unloading a modulefile, following actions are triggered:

  • Dependent Unload: unload of the modulefiles declaring a non-optional prereq onto unloaded modulefile or declaring a non-optional prereq onto a modulefile part of this unloading batch. A prereq modulefile is considered optional if the prereq definition order is made of multiple modulefiles and at least one alternative modulefile is loaded.
  • Useless Requirement Unload: unload of the prereq modulefiles that have been automatically loaded for either the unloaded modulefile, an unloaded dependent modulefile or a modulefile part of this useless requirement unloading batch. Modulefiles are added to this unloading batch only if they are not required by any other loaded modulefiles.
  • Dependent Reload: reload of the modulefiles declaring a conflict or an optional prereq onto either the unloaded modulefile, an unloaded dependent or an unloaded useless requirement or declaring a prereq onto a modulefile part of this reloading batch.

In case a loaded modulefile has some of its declared constraints unsatisfied (pre-required modulefile not loaded or conflicting modulefile loaded for instance), this loaded modulefile is excluded from the automatic reload actions described above.

For the specific case of the switch sub-command, where a modulefile is unloaded to then load another modulefile. Dependent modulefiles to Unload are merged into the Dependent modulefiles to Reload that are reloaded after the load of the switched-to modulefile.

Automated module handling mode enablement is defined in the following order of preference: --auto/--no-auto command line switches, then MODULES_AUTO_HANDLING environment variable, then the default set in modulecmd.tcl script configuration. Which means MODULES_AUTO_HANDLING overrides default configuration and --auto/--no-auto command line switches override every other ways to enable or disable this mode.

MODULES_AVAIL_INDEPTH

If set to 1, enable in depth search results for avail sub-command. If set to 0 disable avail sub-command in depth mode. Other values are ignored.

When in depth mode is enabled, modulefiles and directories contained in directories matching search query are also included in search results. When disabled these modulefiles and directories contained in matching directories are excluded.

avail sub-command in depth mode enablement is defined in the following order of preference: --indepth/--no-indepth command line switches, then MODULES_AVAIL_INDEPTH environment variable, then the default set in modulecmd.tcl script configuration. Which means MODULES_AVAIL_INDEPTH overrides default configuration and --indepth/--no-indepth command line switches override every other ways to enable or disable this mode.

MODULES_CMD

The location of the active module command script.

MODULES_COLLECTION_PIN_VERSION

If set to 1, register exact version number of modulefiles when saving a collection. Elsewhere modulefile version number is omitted if it corresponds to the explicitly set default version and also to the implicit default when config option implicit_default is enabled.

MODULES_COLLECTION_TARGET

The collection target that determines what collections are valid thus reachable on the current system.

Collection directory may sometimes be shared on multiple machines which may use different modules setup. For instance modules users may access with the same HOME directory multiple systems using different OS versions. When it happens a collection made on machine 1 may be erroneous on machine 2.

When a target is set, only the collections made for that target are available to the restore, savelist, saveshow and saverm sub-commands. Saving collection registers the target footprint by suffixing the collection filename with .$MODULES_COLLECTION_TARGET. Collection target is not involved when collection is specified as file path on the saveshow, restore and save sub-commands.

For example, the MODULES_COLLECTION_TARGET variable may be set with results from commands like lsb_release, hostname, dnsdomainname, etc.

MODULES_COLOR

Defines if output should be colored or not. Accepted values are never, auto and always.

When color mode is set to auto, output is colored only if the standard error output channel is attached to a terminal.

Colored output enablement is defined in the following order of preference: --color command line switch, then MODULES_COLOR environment variable, then CLICOLOR and CLICOLOR_FORCE environment variables, then the default set in modulecmd.tcl script configuration. Which means MODULES_COLOR overrides default configuration and the CLICOLOR/CLICOLOR_FORCE variables. --color command line switch overrides every other ways to enable or disable this mode.

CLICOLOR and CLICOLOR_FORCE environment variables are also honored to define color mode. The never mode is set if CLICOLOR equals to 0. If CLICOLOR is set to another value, it corresponds to the auto mode. The always mode is set if CLICOLOR_FORCE is set to a value different than 0. Color mode set with these two variables is superseded by mode set with MODULES_COLOR environment variable.

MODULES_COLORS

Specifies the colors and other attributes used to highlight various parts of the output. Its value is a colon-separated list of output items associated to a Select Graphic Rendition (SGR) code. It follows the same syntax than LS_COLORS.

Output items are designated by keys. Items able to be colorized are: highlighted element (hi), debug information (db), tag separator (se); Error (er), warning (wa), module error (me) and info (in) message prefixes; Modulepath (mp), directory (di), module alias (al), module symbolic version (sy), module default version (de) and modulefile command (cm).

See the Select Graphic Rendition (SGR) section in the documentation of the text terminal that is used for permitted values and their meaning as character attributes. These substring values are integers in decimal representation and can be concatenated with semicolons. Modules takes care of assembling the result into a complete SGR sequence (33[...m). Common values to concatenate include 1 for bold, 4 for underline, 30 to 37 for foreground colors and 90 to 97 for 16-color mode foreground colors. See also https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters for a complete SGR code reference.

No graphical rendition will be applied to an output item that could normaly be colored but which is not defined in the color set. Thus if MODULES_COLORS is defined empty, no output will be colored at all.

The color set is defined for Modules in the following order of preference: MODULES_COLORS environment variable, then the default set in modulecmd.tcl script configuration. Which means MODULES_COLORS overrides default configuration.

MODULES_EXTENDED_DEFAULT

If set to 1, a specified module version is matched against starting portion of existing module versions, where portion is a substring separated from the rest of the version string by a . character. For example specified modules mod/1 and mod/1.2 will match existing modulefile mod/1.2.3.

In case multiple modulefiles match specified module version and a single module has to be selected, explicitly set default version is returned if it is part of matching modulefiles. Elsewhere implicit default among matching modulefiles is returned if defined (see MODULES_IMPLICIT_DEFAULT section)

This environment variable supersedes the value of the configuration option extended_default set in modulecmd.tcl script.

MODULES_ICASE

When module specification are passed as argument to module sub-commands or modulefile Tcl commands, defines the case sensitiveness to apply to match them. When MODULES_ICASE is set to never, a case sensitive match is applied in any cases. When set to search, a case insensitive match is applied to the avail, whatis and paths sub-commands. When set to always, a case insensitive match is also applied to the other module sub-commands and modulefile Tcl commands for the module specification they receive as argument.

Case sensitiveness behavior is defined in the following order of preference: --icase command line switch, which corresponds to the always mode, then MODULES_ICASE environment variable, then the default set in modulecmd.tcl script configuration. Which means MODULES_ICASE overrides default configuration and --icase command line switch overrides every other ways to set case sensitiveness behavior.

MODULES_IMPLICIT_DEFAULT

Defines (if set to 1) or not (if set to 0) an implicit default version for modules without a default version explicitly defined (see Locating Modulefiles section in the modulefile man page).

Without either an explicit or implicit default version defined a module must be fully qualified (version should be specified in addition to its name) to get:

  • targeted by module load, switch, display, help, test and path sub-commands.
  • restored from a collection, unless already loaded in collection-specified order.
  • automatically loaded by automated module handling mechanisms (see MODULES_AUTO_HANDLING section) when declared as module requirement, with prereq or module load modulefile commands.

An error is returned in the above situations if either no explicit or implicit default version is defined.

This environment variable supersedes the value of the configuration option implicit_default set in modulecmd.tcl script. This environment variable is ignored if implicit_default has been declared locked in locked_configs configuration option.

MODULES_LMALTNAME

A colon separated list of the alternative names set through module-version and module-alias statements corresponding to all loaded modulefiles. Each element in this list starts by the name of the loaded modulefile followed by all alternative names resolving to it. The loaded modulefile and its alternative names are separated by the ampersand character.

This environment variable is intended for module command internal use to get knowledge of the alternative names matching loaded modulefiles in order to keep environment consistent when conflicts or pre-requirements are set over these alternative designations. It also helps to find a match after modulefiles being loaded when unload, is-loaded or info-loaded actions are run over these names.

MODULES_LMCONFLICT

A colon separated list of the conflict statements defined by all loaded modulefiles. Each element in this list starts by the name of the loaded modulefile declaring the conflict followed by the name of all modulefiles it declares a conflict with. These loaded modulefiles and conflicting modulefile names are separated by the ampersand character.

This environment variable is intended for module command internal use to get knowledge of the conflicts declared by the loaded modulefiles in order to keep environment consistent when a conflicting module is asked for load afterward.

MODULES_LMNOTUASKED

A colon separated list of all loaded modulefiles that were not explicitly asked for load from the command-line.

This environment variable is intended for module command internal use to distinguish the modulefiles that have been loaded automatically from modulefiles that have been asked by users.

MODULES_LMPREREQ

A colon separated list of the prereq statements defined by all loaded modulefiles. Each element in this list starts by the name of the loaded modulefile declaring the pre-requirement followed by the name of all modulefiles it declares a prereq with. These loaded modulefiles and pre-required modulefile names are separated by the ampersand character. When a prereq statement is composed of multiple modulefiles, these modulefile names are separated by the pipe character.

This environment variable is intended for module command internal use to get knowledge of the pre-requirement declared by the loaded modulefiles in order to keep environment consistent when a pre-required module is asked for unload afterward.

MODULES_PAGER

Text viewer for use to paginate message output if error output stream is attached to a terminal. The value of this variable is composed of a pager command name or path eventually followed by command-line options.

Paging command and options are defined for Modules in the following order of preference: MODULES_PAGER environment variable, then the default set in modulecmd.tcl script configuration. Which means MODULES_PAGER overrides default configuration.

If MODULES_PAGER variable is set to an empty string or to the value cat, pager will not be launched.

MODULES_RUNENV_<VAR>

Value to set to environment variable <VAR> for modulecmd.tcl run-time execution if <VAR> is referred in MODULES_RUN_QUARANTINE.

MODULES_RUN_QUARANTINE

A space separated list of environment variable names that should be passed indirectly to modulecmd.tcl to protect its run-time environment from side-effect coming from their current definition.

Each variable found in MODULES_RUN_QUARANTINE will have its value emptied or set to the value of the corresponding MODULES_RUNENV_<VAR> variable when defining modulecmd.tcl run-time environment.

Original values of these environment variables set in quarantine are passed to modulecmd.tcl via <VAR>_modquar variables.

MODULES_SEARCH_MATCH

When searching for modules with avail sub-command, defines the way query string should match against available module names. With starts_with value, returned modules are those whose name begins by search query string. When set to contains, any modules whose fully qualified name contains search query string are returned.

Module search match style is defined in the following order of preference: --starts-with and --contains command line switches, then MODULES_SEARCH_MATCH environment variable, then the default set in modulecmd.tcl script configuration. Which means MODULES_SEARCH_MATCH overrides default configuration and --starts-with/--contains command line switches override every other ways to set search match style.

MODULES_SET_SHELL_STARTUP

If set to 1, defines when module command initializes the shell startup file to ensure that the module command is still defined in sub-shells. Setting shell startup file means defining the ENV and BASH_ENV environment variable to the Modules bourne shell initialization script. If set to 0, shell startup file is not defined.

MODULES_SILENT_SHELL_DEBUG

If set to 1, disable any xtrace or verbose debugging property set on current shell session for the duration of either the module command or the module shell initialization script. Only applies to Bourne Shell (sh) and its derivatives.

MODULES_SITECONFIG

Location of a site-specific configuration script to source into modulecmd.tcl. See also Modulecmd startup section.

This environment variable is ignored if extra_siteconfig has been declared locked in locked_configs configuration option.

MODULES_TERM_BACKGROUND

Inform Modules of the terminal background color to determine if the color set for dark background or the color set for light background should be used to color output in case no specific color set is defined with the MODULES_COLORS variable. Accepted values are dark and light.

MODULES_UNLOAD_MATCH_ORDER

When a module unload request matches multiple loaded modules, unload firstly loaded module or lastly loaded module. Accepted values are returnfirst and returnlast.

MODULES_USE_COMPAT_VERSION

If set to 1 prior to Modules package initialization, enable Modules compatibility version (3.2 release branch) rather main version at initialization scripts running time. Modules package compatibility version should be installed along with main version for this environment variable to have any effect.

MODULES_VERBOSITY

Defines the verbosity level of the module command. Available verbosity levels from the least to the most verbose are:

  • silent: turn off error, warning and informational messages but does not affect module command output result.
  • concise: enable error and warning messages but disable informational messages.
  • normal: turn on informational messages, like a report of the additional module evaluations triggered by loading or unloading modules, aborted evaluation issues or a report of each module evaluation occurring during a restore or source sub-commands.
  • verbose: add additional informational messages, like a systematic report of the loading or unloading module evaluations.
  • debug: print debugging messages about module command execution.

Module command verbosity is defined in the following order of preference: --silent, --verbose and --debug command line switches, then MODULES_VERBOSITY environment variable, then the default set in modulecmd.tcl script configuration. Which means MODULES_VERBOSITY overrides default configuration and --silent/--verbose/--debug command line switches overrides every other ways to set verbosity level.

MODULES_WA_277

If set to 1 prior to Modules package initialization, enables workaround for Tcsh history issue (see https://github.com/cea-hpc/modules/issues/277). This issue leads to erroneous history entries under Tcsh shell. When workaround is enabled, an alternative module alias is defined which fixes the history mechanism issue. However the alternative definition of the module alias weakens shell evaluation of the code produced by modulefiles. Characters with special meaning for Tcsh shell (like { and }) may not be used anymore in shell alias definition elsewhere the evaluation of the code produced by modulefiles will return a syntax error.

_LMFILES_

A colon separated list of the full pathname for all loaded modulefiles.

<VAR>_modquar

Value of environment variable <VAR> passed to modulecmd.tcl in order to restore <VAR> to this value once started.

<VAR>_modshare

Reference counter variable for path-like variable <VAR>. A colon separated list containing pairs of elements. A pair is formed by a path element followed its usage counter which represents the number of times this path has been enabled in variable <VAR>. A colon separates the two parts of the pair.

FILES

/usr/share/Modules

The MODULESHOME directory.

/usr/share/Modules/etc/siteconfig.tcl

The site-specific configuration script of modulecmd.tcl. An additional configuration script could be defined using the MODULES_SITECONFIG environment variable.

/usr/share/Modules/etc/rc

The system-wide modules rc file. The location of this file can be changed using the MODULERCFILE environment variable as described above.

$HOME/.modulerc

The user specific modules rc file.

$HOME/.module

The user specific collection directory.

/usr/share/Modules/modulefiles

The directory for system-wide modulefiles. The location of the directory can be changed using the MODULEPATH environment variable as described above.

/usr/share/Modules/libexec/modulecmd.tcl

The modulefile interpreter that gets executed upon each invocation of module.

/usr/share/Modules/init/<shell>

The Modules package initialization file sourced into the user's environment.

SEE ALSO

modulefile

modulefile

DESCRIPTION

modulefiles are written in the Tool Command Language, Tcl(n) and are interpreted by the modulecmd.tcl program via the module user interface. modulefiles can be loaded, unloaded, or switched on-the-fly while the user is working; and can be used to implement site policies regarding the access and use of applications.

A modulefile begins with the magic cookie, '#%Module'. A version number may be placed after this string. The version number is useful as the modulefile format may change thus it reflects the minimum version of modulecmd.tcl required to interpret the modulefile. If a version number doesn't exist, then modulecmd.tcl will assume the modulefile is compatible. Files without the magic cookie or with a version number greater than the current version of modulecmd.tcl will not be interpreted.

Each modulefile contains the changes to a user's environment needed to access an application. Tcl is a simple programming language which permits modulefiles to be arbitrarily complex, depending upon the application's and the modulefile writer's needs. If support for extended tcl (tclX) has been configured for your installation of the Modules package, you may use all the extended commands provided by tclX, too.

A typical modulefile is a simple bit of code that set or add entries to the PATH, MANPATH, or other environment variables. A Modulefile is evaluated against current modulecmd.tcl's mode which leads to specific evaluation results. For instance if the modulefile sets a value to an environment variable, this variable is set when modulefile is loaded and unset when modulefile is unloaded.

Tcl has conditional statements that are evaluated when the modulefile is interpreted. This is very effective for managing path or environment changes due to different OS releases or architectures. The user environment information is encapsulated into a single modulefile kept in a central location. The same modulefile is used by every user on any machine. So, from the user's perspective, starting an application is exactly the same irrespective of the machine or platform they are on.

modulefiles also hide the notion of different types of shells. From the user's perspective, changing the environment for one shell looks exactly the same as changing the environment for another shell. This is useful for new or novice users and eliminates the need for statements such as "if you're using the C Shell do this ..., otherwise if you're using the Bourne shell do this ...". Announcing and accessing new software is uniform and independent of the user's shell. From the modulefile writer's perspective, this means one set of information will take care of every type of shell.

Modules Specific Tcl Commands

The Modules Package uses commands which are extensions to the "standard" Tool Command Language Tcl(n) package. Unless otherwise specified, the Module commands return the empty string. Some commands behave differently when a modulefile is loaded or unloaded. The command descriptions assume the modulefile is being loaded.

break

This is not a Modules-specific command, it's actually part of Tcl, which has been overloaded similar to the continue and exit commands to have the effect of causing the module not to be listed as loaded and not affect other modules being loaded concurrently. All non-environment commands within the module will be performed up to this point and processing will continue on to the next module on the command line. The break command will only have this effect if not used within a Tcl loop though.

An example: Suppose that a full selection of modulefiles are needed for various different architectures, but some of the modulefiles are not needed and the user should be alerted. Having the unnecessary modulefile be a link to the following notavail modulefile will perform the task as required.

#%Module1.0
## notavail modulefile
##
proc ModulesHelp { } {
    puts stderr "This module does nothing but alert the user"
    puts stderr "that the [module-info name] module is not available"
}

module-whatis "Notifies user that module is not available."
set curMod [module-info name]
if { [ module-info mode load ] } {
    puts stderr "Note: '$curMod' is not available for [uname sysname]."
}
break

chdir directory

Set the current working directory to directory.

continue

This is not a modules specific command but another overloaded Tcl command and is similar to the break or exit commands except the module will be listed as loaded as well as performing any environment or Tcl commands up to this point and then continuing on to the next module on the command line. The continue command will only have this effect if not used within a Tcl loop though.

exit [N]

This is not a modules specific command but another overloaded Tcl command and is similar to the break or continue commands. However, this command will cause the immediate cessation of this module and any additional ones on the command line. This module and the subsequent modules will not be listed as loaded. No environment commands will be performed in the current module.

setenv variable value

Set environment variable to value. The setenv command will also change the process' environment. A reference using Tcl's env associative array will reference changes made with the setenv command. Changes made using Tcl's env associative array will NOT change the user's environment variable like the setenv command. An environment change made this way will only affect the module parsing process. The setenv command is also useful for changing the environment prior to the exec or system command. When a modulefile is unloaded, setenv becomes unsetenv. If the environment variable had been defined it will be overwritten while loading the modulefile. A subsequent unload will unset the environment variable - the previous value cannot be restored! (Unless you handle it explicitly ... see below.)

unsetenv variable [value]

Unsets environment variable. However, if there is an optional value, then when unloading a module, it will set variable to value. The unsetenv command changes the process' environment like setenv.

getenv variable [value]

Returns value of environment variable. If variable is not defined value is returned if set _UNDEFINED_ is returned elsewhere. getenv command should be preferred over Tcl global variable env to query environment variables.

append-path [-d C|--delim C|--delim=C] [--duplicates] variable value...

See prepend-path.

prepend-path [-d C|--delim C|--delim=C] [--duplicates] variable value...

Append or prepend value to environment variable. The variable is a colon, or delimiter, separated list such as PATH=directory:directory:directory. The default delimiter is a colon ':', but an arbitrary one can be given by the --delim option. For example a space can be used instead (which will need to be handled in the Tcl specially by enclosing it in " " or { }). A space, however, can not be specified by the --delim=C form.

A reference counter environment variable is also set to increase the number of times value has been added to environment variable. This reference counter environment variable is named by suffixing variable by _modshare.

When value is already defined in environement variable, it is not added again except if --duplicates option is set.

If the variable is not set, it is created. When a modulefile is unloaded, append-path and prepend-path become remove-path.

If value corresponds to the concatenation of multiple elements separated by colon, or delimiter, character, each element is treated separately.

remove-path [-d C|--delim C|--delim=C] [--index] variable value...

Remove value from the colon, or delimiter, separated list in variable. See prepend-path or append-path for further explanation of using an arbitrary delimiter. Every string between colons, or delimiters, in variable is compared to value. If the two match, value is removed from variable if its reference counter is equal to 1 or unknown.

When --index option is set, value refers to an index in variable list. The string element pointed by this index is set for removal.

Reference counter of value in variable denotes the number of times value has been added to variable. This information is stored in environment variable_modshare. When attempting to remove value from variable, relative reference counter is checked and value is removed only if counter is equal to 1 or not defined. Elsewhere value is kept in variable and reference counter is decreased by 1.

If value corresponds to the concatenation of multiple elements separated by colon, or delimiter, character, each element is treated separately.

prereq modulefile...

See conflict.

conflict modulefile...

prereq and conflict control whether or not the modulefile will be loaded. The prereq command lists modulefiles which must have been previously loaded before the current modulefile will be loaded. Similarly, the conflict command lists modulefiles which conflict with the current modulefile. If a list contains more than one modulefile, then each member of the list acts as a Boolean OR operation. Multiple prereq and conflict commands may be used to create a Boolean AND operation. If one of the requirements have not been satisfied, an error is reported and the current modulefile makes no changes to the user's environment.

If an argument for prereq is a directory and any modulefile from the directory has been loaded, then the prerequisite is met. For example, specifying X11 as a prereq means that any version of X11, X11/R4 or X11/R5, must be loaded before proceeding.

If an argument for conflict is a directory and any other modulefile from that directory has been loaded, then a conflict will occur. For example, specifying X11 as a conflict will stop X11/R4 and X11/R5 from being loaded at the same time.

The parameter modulefile may also be a symbolic modulefile name or a modulefile alias. It may also leverage a specific syntax to finely select module version (see Advanced module version specifiers section below).

is-loaded [modulefile...]

The is-loaded command returns a true value if any of the listed modulefiles has been loaded or if any modulefile is loaded in case no argument is provided. If a list contains more than one modulefile, then each member acts as a boolean OR operation. If an argument for is-loaded is a directory and any modulefile from the directory has been loaded is-loaded would return a true value.

The parameter modulefile may also be a symbolic modulefile name or a modulefile alias. It may also leverage a specific syntax to finely select module version (see Advanced module version specifiers section below).

is-saved [collection...]

The is-saved command returns a true value if any of the listed collections exists or if any collection exists in case no argument is provided. If a list contains more than one collection, then each member acts as a boolean OR operation.

If MODULES_COLLECTION_TARGET is set, a suffix equivalent to the value of this variable is appended to the passed collection name. In case no collection argument is provided, a true value will only be returned if a collection matching currently set target exists.

is-used [directory...]

The is-used command returns a true value if any of the listed directories has been enabled in MODULEPATH or if any directory is enabled in case no argument is provided. If a list contains more than one directory, then each member acts as a boolean OR operation.

is-avail modulefile...

The is-avail command returns a true value if any of the listed modulefiles exists in enabled MODULEPATH. If a list contains more than one modulefile, then each member acts as a boolean OR operation. If an argument for is-avail is a directory and a modulefile exists in the directory is-avail would return a true value.

The parameter modulefile may also be a symbolic modulefile name or a modulefile alias. It may also leverage a specific syntax to finely select module version (see Advanced module version specifiers section below).

module [sub-command] [sub-command-args]

Contains the same sub-commands as described in the module man page in the Module Sub-Commands section. This command permits a modulefile to load or unload other modulefiles. No checks are made to ensure that the modulefile does not try to load itself. Often it is useful to have a single modulefile that performs a number of module load commands. For example, if every user on the system requires a basic set of applications loaded, then a core modulefile would contain the necessary module load commands.

Command line switches --auto, --no-auto and --force are ignored when passed to a module command set in a modulefile.

module-info option [info-args]

Provide information about the modulecmd.tcl program's state. Some of the information is specific to the internals of modulecmd.tcl. option is the type of information to be provided, and info-args are any arguments needed.

module-info type

Returns either "C" or "Tcl" to indicate which module command is being executed, either the "C" version or the Tcl-only version, to allow the modulefile writer to handle any differences between the two.

module-info mode [modetype]

Returns the current modulecmd.tcl's mode as a string if no modetype is given.

Returns 1 if modulecmd.tcl's mode is modetype. modetype can be: load, unload, remove, switch, display, help, test or whatis.

module-info command [commandname]

Returns the currently running modulecmd.tcl's command as a string if no commandname is given.

Returns 1 if modulecmd.tcl's command is commandname. commandname can be: load, unload, reload, source, switch, display, avail, aliases, list, whatis, search, purge, restore, help or test.

module-info name

Return the name of the modulefile. This is not the full pathname for modulefile. See the Modules Variables section for information on the full pathname.

module-info specified

Return the name of the modulefile specified on the command line.

module-info shell [shellname]

Return the current shell under which modulecmd.tcl was invoked if no shellname is given. The current shell is the first parameter of modulecmd.tcl, which is normally hidden by the module alias.

If a shellname is given, returns 1 if modulecmd.tcl's current shell is shellname, returns 0 elsewhere. shellname can be: sh, bash, ksh, zsh, csh, tcsh, fish, tcl, perl, python, ruby, lisp, cmake, r.

module-info shelltype [shelltypename]

Return the family of the shell under which modulefile was invoked if no shelltypename is given. As of module-info shell this depends on the first parameter of modulecmd.tcl. The output reflects a shell type determining the shell syntax of the commands produced by modulecmd.tcl.

If a shelltypename is given, returns 1 if modulecmd.tcl's current shell type is shelltypename, returns 0 elsewhere. shelltypename can be: sh, csh, fish, tcl, perl, python, ruby, lisp, cmake, r.

module-info alias name

Returns the full modulefile name to which the modulefile alias name is assigned

module-info version modulefile

Returns the physical module name and version of the passed symbolic version modulefile. The parameter modulefile might either be a full qualified modulefile with name and version, another symbolic modulefile name or a modulefile alias.

module-info symbols modulefile

Returns a list of all symbolic versions assigned to the passed modulefile. The parameter modulefile might either be a full qualified modulefile with name and version, another symbolic modulefile name or a modulefile alias.

module-info loaded modulefile

Returns the names of currently loaded modules matching passed modulefile. The parameter modulefile might either be a fully qualified modulefile with name and version or just a directory which in case all loaded modulefiles from the directory will be returned. The parameter modulefile may also be a symbolic modulefile name or a modulefile alias.

module-version modulefile version-name...

Assigns the symbolic version-name to the modulefile. This command should be placed in one of the modulecmd.tcl rc files in order to provide shorthand invocations of frequently used modulefile names.

The special version-name default specifies the default version to be used for module commands, if no specific version is given. This replaces the definitions made in the .version file in former modulecmd.tcl releases.

The parameter modulefile may be either

  • a fully or partially qualified modulefile with name / version. If name is '.' then the current directory name is assumed to be the module name. (Use this for deep modulefile directories.)
  • a symbolic modulefile name
  • another modulefile alias

module-alias name modulefile

Assigns the modulefile to the alias name. This command should be placed in one of the modulecmd.tcl rc files in order to provide shorthand invocations of frequently used modulefile names.

The parameter modulefile may be either

  • a fully qualified modulefile with name and version
  • a symbolic modulefile name
  • another modulefile alias

module-virtual name modulefile

Assigns the modulefile to the virtual module name. This command should be placed in rc files in order to define virtual modules.

A virtual module stands for a module name associated to a modulefile. The modulefile is the script interpreted when loading or unloading the virtual module which appears or can be found with its virtual name.

The parameter modulefile corresponds to the relative or absolute file location of a modulefile.

module-whatis string

Defines a string which is displayed in case of the invocation of the module whatis command. There may be more than one module-whatis line in a modulefile. This command takes no actions in case of load, display, etc. invocations of modulecmd.tcl.

The string parameter has to be enclosed in double-quotes if there's more than one word specified. Words are defined to be separated by whitespace characters (space, tab, cr).

set-alias alias-name alias-string

Sets an alias or function with the name alias-name in the user's environment to the string alias-string. For some shells, aliases are not possible and the command has no effect. When a modulefile is unloaded, set-alias becomes unset-alias.

unset-alias alias-name

Unsets an alias with the name alias-name in the user's environment.

set-function function-name function-string

Creates a function with the name function-name in the user's environment with the function body function-string. For some shells, functions are not possible and the command has no effect. When a modulefile is unloaded, set-function becomes unset-function.

unset-function function-name

Removes a function with the name function-name from the user's environment.

system string

Run string command through shell. On Unix, command is passed to the /bin/sh shell whereas on Windows it is passed to cmd.exe. modulecmd.tcl redirects stdout to stderr since stdout would be parsed by the evaluating shell. The exit status of the executed command is returned.

uname field

Provide lookup of system information. Most field information are retrieved from the tcl_platform array (see tclvars(n) man page). Uname will return the string "unknown" if information is unavailable for the field.

uname will invoke uname(1) command in order to get the operating system version and domainname(1) to figure out the name of the domain.

field values are:

  • sysname: the operating system name
  • nodename: the hostname
  • domain: the name of the domain
  • release: the operating system release
  • version: the operating system version
  • machine: a standard name that identifies the system's hardware

x-resource [resource-string|filename]

Merge resources into the X11 resource database. The resources are used to control look and behavior of X11 applications. The command will attempt to read resources from filename. If the argument isn't a valid file name, then string will be interpreted as a resource. Either filename or resource-string is then passed down to be xrdb(1) command.

modulefiles that use this command, should in most cases contain one or more x-resource lines, each defining one X11 resource. The DISPLAY environment variable should be properly set and the X11 server should be accessible. If x-resource can't manipulate the X11 resource database, the modulefile will exit with an error message.

Examples:

x-resource /u2/staff/leif/.xres/Ileaf

The content of the Ileaf file is merged into the X11 resource database.

x-resource [glob ~/.xres/ileaf]

The Tcl glob function is used to have the modulefile read different resource files for different users.

x-resource {Ileaf.popup.saveUnder: True}

Merge the Ileaf resource into the X11 resource database.

Modules Variables

The ModulesCurrentModulefile variable contains the full pathname of the modulefile being interpreted.

Locating Modulefiles

Every directory in MODULEPATH is searched to find the modulefile. A directory in MODULEPATH can have an arbitrary number of sub-directories. If the user names a modulefile to be loaded which is actually a directory, the directory is opened and a search begins for an actual modulefile. First, modulecmd.tcl looks for a file with the name .modulerc in the directory. If this file exists, its contents will be evaluated as if it was a modulefile to be loaded. You may place module-version, module-alias and module-virtual commands inside this file.

Additionally, before seeking for .modulerc files in the module directory, the global modulerc file and the .modulerc file found at the root of the modulepath directory are sourced, too. If a named version default now exists for the modulefile to be loaded, the assigned modulefile now will be sourced. Otherwise the file .version is looked up in the module directory.

If the .version file exists, it is opened and interpreted as Tcl code and takes precedence over a .modulerc file in the same directory. If the Tcl variable ModulesVersion is set by the .version file, modulecmd.tcl will use the name as if it specifies a modulefile in this directory. This will become the default modulefile in this case. ModulesVersion cannot refer to a modulefile located in a different directory.

If ModulesVersion is a directory, the search begins anew down that directory. If the name does not match any files located in the current directory, the search continues through the remaining directories in MODULEPATH.

Every .version and .modulerc file found is Tcl interpreted. The difference is that .version only applies to the current directory, and the .modulerc applies to the current directory and all subdirectories. Changes made in these files will affect the subsequently interpreted modulefile.

If no default version may be figured out, an implicit default is selected when this behavior is enabled (see MODULES_IMPLICIT_DEFAULT in module). If disabled, module names should be fully qualified when no explicit default is defined for them, elsewhere no default version is found and an error is returned. If enabled, then the highest numerically sorted modulefile, virtual module or module alias under the directory will be used. The dictionary comparison method of the lsort(n) Tcl command is used to achieve this sort. If highest numerically sorted element is an alias, search continues on its modulefile target.

For example, it is possible for a user to have a directory named X11 which simply contains a .version file specifying which version of X11 is to be loaded. Such a file would look like:

#%Module1.0
##
##  The desired version of X11
##
set ModulesVersion "R4"

The equivalent .modulerc would look like:

#%Module1.0
##
##  The desired version of X11
##
module-version "./R4" default

If the extended default mechanism is enabled (see MODULES_EXTENDED_DEFAULT in module) the module version specified is matched against starting portion of existing module versions, where portion is a substring separated from the rest of version string by a . character.

If user names a modulefile that cannot be found in the first modulepath directory, modulefile will be searched in next modulepath directory and so on until a matching modulefile is found. If search goes through a module alias or a symbolic version, this alias or symbol is resolved by first looking at the modulefiles in the modulepath where this alias or symbol is defined. If not found, resolution looks at the other modulepaths in their definition order.

When locating modulefiles, if a .modulerc, a .version, a directory or a modulefile cannot be read during the search it is simply ignored with no error message produced. Visibility of modulefiles can thus be adapted to the rights the user has been granted. Exception is made when trying to directly access a directory or a modulefile. In this case, the access issue is returned as an error message.

A modulefile whose name or element in its name starts with a '.' dot is considered hidden. Hidden modulefile is not displayed or taken into account except if it is explicitly named. By inheritance, a symbolic version-name assigned to a hidden modulefile is displayed or taken into account only if explicitly named. Module alias targeting a hidden modulefile appears like any other module alias.

Advanced module version specifiers

When the advanced module version specifiers mechanism is enabled (see MODULES_ADVANCED_VERSION_SPEC in module), the specification of modulefile passed on Modules specific Tcl commands changes. After the module name a version constraint prefixed by the @ character may be added. It could be directly appended to the module name or separated from it with a space character.

Constraints can be expressed to refine the selection of module version to:

  • a single version with the @version syntax, for instance foo@1.2.3 syntax will select module foo/1.2.3
  • a list of versions with the @version1,version2,... syntax, for instance foo@1.2.3,1.10 will match modules foo/1.2.3 and foo/1.10
  • a range of versions with the @version1:, @:version2 and @version1:version2 syntaxes, for instance foo@1.2: will select all versions of module foo greater than or equal to 1.2, foo@:1.3 will select all versions less than or equal to 1.3 and foo@1.2:1.3 matches all versions between 1.2 and 1.3 including 1.2 and 1.3 versions

Advanced specification of single version or list of versions may benefit from the activation of the extended default mechanism (see MODULES_EXTENDED_DEFAULT in module) to use an abbreviated notation like @1 to refer to more precise version numbers like 1.2.3. Range of versions on its side natively handles abbreviated versions.

In order to be specified in a range of versions or compared to a range of versions, the version major element should corresponds to a number. For instance 10a, 1.2.3, 1.foo are versions valid for range comparison whereas default or foo.2 versions are invalid for range comparison.

Modulefile Specific Help

Users can request help about a specific modulefile through the module command. The modulefile can print helpful information or start help oriented programs by defining a ModulesHelp subroutine. The subroutine will be called when the module help modulefile command is used.

Modulefile Specific Test

Users can request test of a specific modulefile through the module command. The modulefile can perform some sanity checks on its definition or on its underlying programs by defining a ModulesTest subroutine. The subroutine will be called when the module test modulefile command is used. The subroutine should return 1 in case of success. If no or any other value is returned, test is considered failed.

Modulefile Display

The module display modulefile command will detail all changes that will be made to the environment. After displaying all of the environment changes modulecmd.tcl will call the ModulesDisplay subroutine. The ModulesDisplay subroutine is a good place to put additional descriptive information about the modulefile.

ENVIRONMENT

MODULEPATH

Path of directories containing modulefiles.

SEE ALSO

module, Tcl(n), TclX(n), xrdb(1), exec(n), uname(1), domainname(1), tclvars(n), lsort(n)

NOTES

Tcl was developed by John Ousterhout at the University of California at Berkeley.

TclX was developed by Karl Lehenbauer and Mark Diekhans.

Differences between versions 3.2 and 4

This document lists functionality differences between Modules version 3.2 and Modules version 4. Modules version 3.2 is also referred in this document as compatibility version whereas Modules version 4 is also referred as new main version. Modules version 4 is based on what was previously called Modules-Tcl. The goal of this document is to reference the features of the compatibility version that are missing or behave differently on the new main version and the features that can only be found on this new version.

First part the of the document covers the features that are missing or that behave differently on Modules 4 than on compatibility version. The second part of the document covers the features that are specific to the Modules 4 version thus missing on compatibility version. Comparison takes as a basis version 3.2.10 of compatibility version against Modules version 4.0. Any change made past these versions will explicitly mention the release number starting from the difference appears or disappears.

Regarding missing features, this document only lists their name or the command line argument related to them. Please refer to the module and the modulefile man pages of the compatibility or main version to learn the details about these features.

Features missing or with different behavior than compatibility version

This section describes the features of the compatibility version that are not supported or that behave differently on Modules 4.

Package Initialization

MODULESBEGINENV environment snapshot functionality is not supported on version 4. Modules collection mechanism should be preferred to save and restore sets of enabled modulepaths and loaded modulefiles. Modules 4 also introduces a system configuration file init/modulerc, located in Modules installation directory. Starting version 4.3, this file could also be etc/initrc. This modulerc/initrc file is sourced by Modules shell initialization scripts and helps to setup the initial environment right after initializing the module command.

Command line switches

--human

--create, -c

--userlvl lvl, -u lvl

These command line switches are not supported on Modules 4. When these options are passed on the command-line, it produces an Unsupported option warning and command is ran with the unsupported switches ignored.

--ter

--lon

--sil

--verb

These intermediate-form command line switches are not supported on Modules 4. Short or long switch name should be used instead.

-h

This command line switch is short version of --help switch on Modules 4 whereas it is short version of --human switch on compatibility version.

--force, -f

This command line switch was not supported starting Modules version 4.0 but reintroduced starting version 4.2 with a different meaning: instead of enabling an active dependency resolution mechanism --force command line switch now enables to by-pass dependency consistency when loading or unloading a modulefile.

--verbose, -v

--silent, -s

These command line switches were not supported starting Modules version 4.0 but reintroduced starting version 4.3. However, reintroduced --silent switch does not redirect stderr channel to /dev/null if stderr is found not to be a tty.

--icase, -i

This command line switch was not supported starting Modules version 4.0 but reintroduced starting version 4.4. When --icase switch is now set it applies to search query string and module specificiation on all sub-commands and modulefile Tcl commands.
Module Sub-Commands

On compatibility version, paths composing the MODULEPATH environment variable may contain reference to environment variable. These variable references are resolved dynamically when MODULEPATH is looked at during module sub-command action like avail. This feature was missing on Modules 4.0 but it has been re-introduced on Modules 4.1.

update

This module sub-commands is not supported on Modules 4.

clear

This command line switch was not supported starting Modules version 4.0 but reintroduced starting version 4.3. It now takes into account the --force command-line switch to skip confirmation dialog.

refresh

On compatibility version, only the shell aliases defined by the currently loaded modulefiles are set again on a refresh command. Whereas on new main version this command is an alias on the reload command that unload then load all the currently loaded modulefiles.

help

Compatibility version redirects output made on stdout in ModulesHelp Tcl procedure to stderr.

During an help sub-command, only the ModulesHelp Tcl procedure of a modulefile is interpreted on compatibility version. Version 4 interprets all the content of the modulefile, then call the ModulesHelp procedure if it exists.

On version 4, ModulesHelp subroutine is not ran if an error occurred during the interpretation of the modulefile main body.

display

On version 4, ModulesDisplay subroutine is not ran if an error occurred during the interpretation of the modulefile main body.

avail

On compatibility version, the same Tcl interpreter is used for the interpretation of all .modulerc or .version files during an avail command but the state of this interpreter is not reset between each interpretation. So some variable and procedure definitions may spread from one interpretation to another on this compatibility version. Modules 4 reuses the same interpreter for all .modulerc or .version interpretation but it is cleaned between each interpretation to protect from definition spread.

In case of --terse or --long mode, all enabled modulepaths will be displayed whether they hold result to display or not. Modules 4 outputs only the modulepaths where matching results are found. Modulepaths with no result to report are discarded from output.

apropos

On Modules 4, string passed as argument is always searched in a case insensitive manner.

load

On Modules 4, the value of an environment variable is set even if the new value is the same as the current value of this variable in environment.

When an already loaded modulefiles is asked for load again, compatibility version will refresh the shell alias definition this modulefile hold if any, whereas Modules 4 will ignore the new load order.

In case of modulefile loading another modulefile, if sub-modulefile load fails calling modulefile will still be loaded on compatibility version whereas Modules 4 will also abort calling modulefile load.

Starting with version 4.1, content sent to the stdout channel during a modulefile interpretation is spooled to effectively transmit this content to stdout after rendering the environment changes made by this modulefile.

unload

On Modules 4, the value of an environment variable is set even if the new value is the same as the current value of this variable in environment.

Compatibility version enables to load a modulefile by passing on the command-line the name of a module alias or symbolic version pointing to this modulefile. However this module alias or symbolic version name cannot be used to unload the modulefile once loaded. Modules 4 enables to pass a module alias or symbolic version name to unload a loaded modulefile referred by this name.

On versions 4.0 and 4.1, unloading an unexistent modulefile generates an Unable to locate modulefile error. Starting with version 4.2, unloading a module only looks at loaded module list and does not trigger a modulefile search. So starting version 4.2 the same behavior than Modules compatibility version is obtained.

Starting with version 4.1, content sent to the stdout channel during a modulefile interpretation is spooled to effectively transmit this content to stdout after rendering the environment changes made by this modulefile.

When the specified module to unload matches multiple loaded modules, Modules 4 unloads lastly loaded module whereas compatibility version unloads firstly loaded module. A configuration option unload_match_order has been introduced in version 4.3 and it enables to restore the behavior of compatibility version when it is set to returnfirst.

switch

When switching on version 4 an old modulefile by a new one, no error is raised if old modulefile is not currently loaded. In this situation compatibility version throws an error and abort switch action.

When switching on Modules 4 an old modulefile by a new one, this new modulefile does not keep the position that the old modulefile had in the LOADEDMODULES list as done on compatibility version but it is appended to the end of the list. Same goes for PATH-like environment variables: replaced PATH component is appended to the end or prepended to the beginning of the relative PATH-like variable, not appended or prepended relatively to the position hold by the swapped PATH component.

When a modulefile loads another modulefile with a module load order, this sub-module is not unloaded when the top modulefile is swapped-out during a switch command on compatibility version. Version 4 interprets the swapped-out modulefile in unload mode, so the module load order is interpreted as module unload order and sub-module is unloaded.

use

When the modulepath to enable is passed as a relative path, compatibility version will set it using passed relative name whereas Modules 4 will determine the corresponding absolute path and will register it rather passed relative name.

unuse

Modules 4 provides path element counting feature which increases a reference counter each time a given path entry is added to a given environment variable. This feature also applies to the MODULEPATH environment variable. As consequence a modulepath entry element is removed from the modulepath enabled list only if the related element counter is equal to 1. When unusing a modulepath if its reference counter is greater than 1, modulepath is kept enabled and reference counter is decreased by 1.

whatis

On Modules 4, environment variable edition commands (setenv, unsetenv, append-path, prepend-path and remove-path) do no set variable to the defined value on the modulefile evaluation context during a whatis evaluation. Instead environment variables are initialized with an empty value if undefined, to avoid raising error when attempting access to an undefined element during the modulefile evaluation.

initadd

initprepend

initswitch

On version 4 no message is displayed to give details on how list of modulefiles to load has been altered in initialization file.

initrm

No message is displayed on Modules 4 to inform of the modulefiles that have been removed from the loading list in initialization file.

Empty module load line is left on version 4 when last modulefile from a line is asked to be removed. On compatibility version module load null line is set in this case.

initclear

Empty module load lines are left on version 4 whereas module load null lines are set on compatibility version.
Modules Specific Tcl Commands

append-path

prepend-path

Modules 4 produces an error when adding a bare colon character : as a path element to a path-like variable, as this colon cannot be distinguished from the colon used for path separator.

Modules 4 supports adding or removing empty path element to a path-like variable, whereas compatibility version looses track of this path element when the path-like variable is modified afterward. Empty path element enables to set a leading colon character :, which has a specific meaning on some regular environment variable like MANPATH or LD_LIBRARY_PATH.

When adding a path element to the MANPATH environment variable, Modules 4 is treating this variable like any other whereas a special treatment was applied on compatibility version: a default MANPATH value, set at configure time, was appended in case MANPATH variable was unset.

remove-path

Modules 4 provides path element counting feature which increases a reference counter each time a given path entry is added to a given environment variable. As consequence a path entry element is removed from a path-like variable only if the related element counter is equal to 1. If this counter is greater than 1, path element is kept in variable and reference counter is decreased by 1.

When unloading a modulefile, remove-path command is not applied to environment variable on Modules 4, whereas on compatibility version it is processed the exact same way than when loading modulefile.

exit

On Modules 4 code passed to the exit Modules specific Tcl command will not be thrown to be the module return value.

module-alias

module-version

In case the specified aliased module or the symbolic version introduces a resolution loop with already defined aliases or symbolic versions, this new alias or symbolic version is not registered and an error message is raised. On compatibility version, alias or symbolic version introducing loop are registered as the modulefile resolution is not computed at registration time.

module-info

module-info flags

module-info trace

module-info tracepat

module-info user

These module-info options are related to compatibility version-specific features so they are available on Modules 4 but with a dummy implementation that always returns false or an empty value.

module-info mode

During an unload sub-command, unload is returned instead of remove. However if mode is tested against remove value, true will be returned.

During a switch sub-command, unload then load is returned instead of switch1 then switch2 then switch3. However if mode is tested against switch value, true will be returned.

module-info name

If the module name passed to the command-line has been specified as a full path name, the module-info name used in modulefile returns this file base name on compatibility version whereas it returns on Modules 4+ the full path name as it is identified by this name once loaded.

module-info version

Declared aliases or symbolic versions are not registered anymore if they introduce a resolution loop. As a result module-info version does not return an *undef* string value as it does not face resolution loop situation anymore.

module-info symbols

Declared aliases or symbolic versions are not registered anymore if they introduce a resolution loop. As a consequence symbolic versions introducing loop situation are not part anymore of the module-info symbols returned result as they are not registered.

A symbolic version sets on a module alias will be propagated toward the resolution path to also apply to the relative modulefile if it still correspond to the same module name.

module-log

module-trace

module-user

module-verbosity

These Modules specific Tcl commands are related to compatibility version-specific features so they are available on Modules 4 but with a dummy implementation that always displays a warning message saying the command is not implemented.

module-whatis

When multiple words are passed as argument to module-whatis but they are not enclosed in double-quotes or curly braces they will be displayed as a single line on Modules 4 whereas compatibility version displays them as one line per word.

set-alias

Whereas compatibility version sets a shell function when variables are in use in alias value on Bourne shell derivatives, Modules 4 always defines a shell alias never a shell function.
Locating Modulefiles

On version 4, when a module alias is set and overrides name of an existing directory, this alias is taken into account to locate the default version of this module name and the modulefiles locating in the directory are ignored.

When looking for an implicit default in a modulefile directory, aliases are taken into account in addition to modulefiles and directories to determine the highest numerically sorted element.

Modules 4 will resolve module alias or symbolic version passed to unload command to then remove the loaded modulefile pointed by the mentioned alias or symbolic version.

Modules 4 resolves module alias or symbolic version pointing to a modulefile located in another modulepath.

When locating modulefiles on Modules 4, if a .modulerc, a .version, a directory or a modulefile cannot be read during the search it is simply ignored with no error message produced. Visibility of modulefiles can thus be adapted to the rights the user has been granted. Exception is made when trying to directly access a directory or a modulefile. In this case, the access issue is returned as an error message. Access issue is also returned when a direct access is made to a module alias or a symbolic version targeting an unreadable modulefile.

Features specific to the new main version

This section describes the features of Modules version 4 that are not supported on the compatibility version. Please refer to the above section for features supported by both versions but behaving differently.

Package Initialization

Compatibility version does not support fish, lisp, tcl and R as code output.

On version 4 and for sh, bash, ksh, zsh and fish shells, text output, like listing from the avail command, is redirected from stderr to stdout after shell command evaluation if shell is in interactive mode. Starting version 4.1, this content redirection occurs if shell session is attached to a terminal.

Modulecmd startup

Starting with version 4.1, modulecmd.tcl sources upon invocation a site-specific configuration script named siteconfig.tcl. This Tcl script enables to supersede any global variable or procedure definition of modulecmd.tcl.

Command line switches

--debug, -D

--default, -d

--latest, -L

These command line switches are not supported on compatibility version.

--paginate

--no-pager

These command line switches appeared on version 4.1 and are not supported on compatibility version.

--auto

--no-auto

These command line switches appeared on version 4.2 and are not supported on compatibility version.

--indepth

--no-indepth

--color

--starts-with, -S

--contains, -C

These command line switches appeared on version 4.3 and are not supported on compatibility version.
Module Sub-Commands

All module sub-commands will return a non-zero exit code in case of error whereas on compatibility version issues that occurred do not lead to an exit of the module command with a non-zero code.

Starting with version 4.1, module function for all scripting languages, like Perl or Python, always returns a value. In case of error, a false boolean value is returned instead of raising a fatal exception. For module sub-commands returning a text value, the module function will actually return this value. In all other cases a true boolean value is returned.

reload

source

search

save

restore

saverm

saveshow

savelist

path

paths

autoinit

aliases

test

These module sub-commands are not supported on compatibility version.

append-path

prepend-path

remove-path

is-loaded

is-saved

is-used

is-avail

info-loaded

These module sub-commands appeared on version 4.1 and are not supported on compatibility version.

config

This module sub-command appeared on version 4.3 and is not supported on compatibility version.

avail

whatis

apropos

Non-critical errors are not displayed on these sub-commands. Only valid results are returned.

Module aliases are included in the result of these sub-commands. They are displayed in the module path section where they are defined or in a global/user modulerc section for aliases set in user's or global modulerc file. A @ symbol is added in parenthesis next to their name to distinguish them from modulefiles.

Search may be performed with an alias or a symbolic version-name passed as argument.

Arguments to these avail, whatis and apropos commands may use wildcard characters to express glob patterns.

Collections

Modules collections are not supported on compatibility version.

Environment

MODULES_COLLECTION_TARGET

MODULES_USE_COMPAT_VERSION

<VAR>_modshare

These environment variables are not supported on compatibility version.

MODULES_CMD

MODULES_COLLECTION_PIN_VERSION

MODULES_PAGER

MODULES_RUNENV_<VAR>

MODULES_RUN_QUARANTINE

MODULES_SILENT_SHELL_DEBUG

<VAR>_modquar

These environment variables appeared on version 4.1 and are not supported on compatibility version.

MODULES_AUTO_HANDLING

MODULES_LMALTNAME

MODULES_LMCONFLICT

MODULES_LMNOTUASKED

MODULES_LMPREREQ

These environment variables appeared on version 4.2 and are not supported on compatibility version.

MODULES_AVAIL_INDEPTH

MODULES_COLOR

MODULES_COLORS

MODULES_IMPLICIT_DEFAULT

MODULES_SEARCH_MATCH

MODULES_SET_SHELL_STARTUP

MODULES_SITECONFIG

MODULES_TERM_BACKGROUND

MODULES_UNLOAD_MATCH_ORDER

MODULES_VERBOSITY

MODULES_WA_277

These environment variables appeared on version 4.3 and are not supported on compatibility version.

MODULES_ADVANCED_VERSION_SPEC

MODULES_EXTENDED_DEFAULT

MODULES_ICASE

These environment variables appeared on version 4.4 and are not supported on compatibility version.
Modules Specific Tcl Commands

conflict

prereq

Starting with version 4.2, these Modules-specific Tcl commands support being called with a symbolic modulefile or a modulefile alias passed as argument.

module

In case of module load command specifying multiple modulefiles, when mode is set to unload these modulefiles will be unloaded in the reverse order to ensure correct handling of prerequisites.

module-info

module-info command

This module-info option is not supported on compatibility version.

module-info loaded

This module-info option appeared on version 4.1 and is not supported on compatibility version.

append-path

Starting with version 4.1, append-path handles being called with multiple value arguments and option --duplicates is added.

prepend-path

Starting with version 4.1, prepend-path handles being called with multiple value arguments and option --duplicates is added.

remove-path

Starting with version 4.1, remove-path handles being called with multiple value arguments and option --index is added.

is-loaded

Starting with version 4.1, is-loaded supports being called with no argument passed. In this case, it returns true if any modulefile is currently loaded, false elsewhere.

Starting with version 4.2, is-loaded supports being called with a symbolic modulefile or a modulefile alias passed as argument.

This Modules-specific Tcl command was not enabled for modulerc evaluation starting Modules version 4.0 but it has been reintroduced starting version 4.2.1.

is-saved

is-used

is-avail

module-virtual

These Modules-specific Tcl commands appeared on version 4.1 and are not supported on compatibility version.

set-function

unset-function

These Modules-specific Tcl commands appeared on version 4.2 and are not supported on compatibility version.

Frequently Asked Questions on Environment Modules

Module command

How does the module command work?

The command module is an alias for something like:

sh:

module ()
{
   eval `/some/path/modulecmd sh $*`
}

csh:

eval `/some/path/modulecmd csh !*`

Where the modulecmd outputs valid shell commands to stdout which manipulates the shell's environment. Any text that is meant to be seen by the user must be sent to stderr. For example:

puts stderr "\n\tSome Text to Show\n"
I put the module command in a script and I run the script... it doesn't change my environment?

A child process (script) can not change the parent process environment. A module load in a script only affects the environment for the script itself. The only way you can have a script change the current environment is to source the script which reads it into the current process.

sh:

. somescript

csh:

source somescript
How do I capture the module command output?

This ties in with the very first question. Since the module command is essentially an eval, the visible output to the screen must necessarily be sent to stderr. It becomes a matter on how to capture output from stderr for the various shells. The following examples just show how to spool the output from the avail command to a file. This also works for the various other module commands like list, display, etc. There are also various tricks for piping stderr to another program.

sh:

module avail 2> spoolfile

csh: (overwrite existing file)

module avail >&! spoolfile
How to use the module command from Makefile?

To make use of the module command from a Makefile, the shell initialization script should first be sourced within Makefile rule to define the module function in that context. Environment variable MODULESHOME may help to locate the shell initialization script in a generic way, like done in the following example:

module_list:
   source $$MODULESHOME/init/bash; module list

Modulefiles

I want the modulefile to source some rc script that came with some application

If you want to do this... you can, but that's not what modules is all about. It is possible to have the modulefile output some text to stdout to source some script when loading. However, you lose the advantage of this tool, because you won't be able to unload this environment. If you're tempted to do this... don't.

However, you can craft a modulefile by capturing the environment variables created or changed by the rc script. This is the goal of the createmodule.py and the createmodule.sh utilities provided in the modules distribution:

/usr/share/Modules/bin/createmodule.py somescript

You can also check out https://sourceforge.net/projects/env2/, which can translate the shell file into a modulefile and possibly reduce the amount of work needed to convert and maintain.

How do I specify the default modulefile for some modulefile directory?

Modules usually uses the the highest lexicographically sorted modulefile under the directory, unless there is a .version file in that directory which has a format like the following where "native" is a modulefile (or a sub-directory) in that directory. It's also possible to set the default with a .modulerc file with a module-version command.

#%Module1.0#####################################################################
##
## version file for Perl
##
set ModulesVersion "native"
I don't want a default modulefile for the directory?

Follow the same prescription as setting a default, but give some bogus value, say no_default. The module command will return an error message when no specific version is given.

Build Issues

The configure script complains about Tclx
...
checking for TclX configuration (tclxConfig.sh)... not found
checking for TclX version... using 8.4
checking TCLX_VERSION... 8.4
checking TCLX_LIB_SPEC... TCLX_LIB_SPEC not found, need to use --with-tclx-lib
checking TCLX_INCLUDE_SPEC... TCLX_INCLUDE_SPEC not found, need to use --with-tclx-inc
...

TclX is an optional library that can speed up some operations. You don't need TclX for modules to compile and work, so you can add the --without-tclx option when configuring and it should proceed to completion. In fact, it should have succeeded anyways and just not attempt to use TclX.

Otherwise, you can load the TclX library package for your OS and the configure script should find it. If not then if you know where the tclxConfig.sh file or the library and include files are placed then use the following options:

--with-tclx=<dir>       directory containing TclX configuration
                        (tclxConfig.sh) [[searches]]
--with-tclx-ver=X.Y     TclX version to use [[search]]
--with-tclx-lib=<dir>   directory containing tclx libraries (libtclxX.Y)
                        [[none]]
--with-tclx-inc=<dir>   directory containing tclx include files
                        (tclExtend.h,...) [[none]]

Meta Information

Why does modules use Tcl?

The first versions of the Modules package used shell scripts to do its magic. The original authors then chose to implement the same in C to speed things up and to add features. At the time the only easily embeddable interpreter was Tcl which provided a standard language and the glue. Now that other interpreters are available they could be embedded, but haven't so far. There is also a pure Tcl version available.

How can I help?

We can use help at various levels. The best way to contribute is to send in a patch file (see the FAQ on how to generate a patch file) with whatever fixes. The patch will be reviewed and tested. If you are a regular contributer then you'll likely be invited to become a developer and to have direct source access, and the fame, power, and prestige that all entails.

How do I download the source repository?

Anonymously clone the git repository, view the list of branches, and set to a specific branch:

git clone git://git.code.sf.net/p/modules/git modules-myversion
cd modules-myversion
git branch -a
git checkout modules-3-X-Y
git status
How do I generate a patch file?
If you're starting from a tarball

Unpack the tarball and it should place the sources into a directory named modules-3.X.Y , then rename the directory to modules-3.X.Y-myversion or something like that. Make whatever changes you want, and be sure to test the changes and if you can add tests to identify the bug and the fix... that will endear yourself to the developers.

Once you have the changes in your version, then unpack the original sources from the tarball in a directory side-by-side to the directory with your version, and at that parent level run the following diff command:

diff -u -r -P -N modules-3.X.Y modules-3.X.Y-myversion  > my.patch
If you're starting from the git cloned repository:

From within the git repositories.

git diff > my.patch

Release notes

This file describes changes in recent versions of Modules. It primarily documents those changes that are of interest to users and admins.

Modules 4.4.1 (2020-01-03)

  • Fix error and warning messages relative to dependency management to enclose dependency specification in single quotes to clearly distinguish specification from each other.
  • Skip output of module loading message if module is already loaded.
  • Doc: add demonstration material played at SC19 to promote the new features of Modules.
  • Contrib: add playdemo script to play recorded demonstration cast.
  • Doc: add a web anchor to each modulefile Tcl command, module sub-command and module environment variable documentation.
  • Install: update RPM spec file to enable build on el8.
  • Doc: fix RST syntax for bullet lists in design docs. (fix issue #306)
  • In case module avail query does not match a directory but only its contained elements (for instance module av mod/7 matches mod/7.1 and mod/7.2 but not mod/), fix query processing to correctly return latest or default element in case --latest or --default flags are set.
  • In case a module avail query performed in a no-indepth mode with --latest or --default flags either enabled or disabled, fix query processing to return directory elements if they are part of result.
  • When a module avail query performed in no-indepth mode targets a virtual module, fix result to filter-out the directory holding the virtual module from result.
  • Fix module avail --default queries when modulefile default version does not match query: select latest version from modulefiles matching query unless implicit_default configuration is disabled in which case no default version is returned.
  • Improve highlighting of module avail and whatis search result by coloring module names matching search query expressed with the advanced version specifiers. name@1,3 or name@1:3 queries now highlight name/1 and name/3 strings found in search result.
  • Contrib: add the mlprof script which wraps modulecmd.tcl to collect profiling information on its execution.
  • Contrib: adapt mb script to profile modulecmd.tcl run tests rather bench them when profile argument is passed to the script.
  • Improve overall performances of module names and versions comparison by introducing optimized procedures and caching in memory module search results.

Modules 4.4.0 (2019-11-17)

  • Doc: add Return file basename on module-info name for full path modulefile recipe to cookbook. (fix issue #297)
  • Rework internal handling of configuration options to gather all option definitions in a global array and use the same initialization and retrieval procedure, named getConf, for all these options.
  • Add the setConf, unsetConf and lappendConf procedures to provide unified ways to set the value of configuration option. These procedures should be used in site configuration files to override configuration option value instead of directly setting corresponding option variable as it was done in previous Modules releases.
  • Add the ability to match module specification in a case insensitive manner. Default case sensitiveness behavior is set at ./configure time with the --with-icase option. It could be superseded with the MODULES_ICASE environment variable, that could be set with config module sub-command through the icase option. Command-line switch --icase (-i) enables to supersede defined case sensitiveness configuration. (fix issue #212 with contribution from Eric Deveaud)
  • Introduce the extended default mechanism, to help selecting a module when only the first numbers in its version are specified. Starting portion of the version, part separated from the rest of the version string by a . character, will get matched to the appropriate complete version name. In case multiple versions match partial version specified and only one module should be returned, default version (implicit or explicit) among matches is returned. In case implicit_default option is disabled and no explicit default is found among matches, an error is returned. This mechanism is enabled through a new configuration option named extended_default (which defines MODULES_EXTENDED_DEFAULT environment variable when set). It may be enabled by default in modulecmd.tcl script with option --enable-extended-default passed to the ./configure script.
  • Introduce the advanced module version specifiers mechanism to specify finer constraints on module version. This new feature enables to filter the module selection to a given version list or range by specifying after the module name a version constraint prefixed by the @ character. It leverages the version specifier syntax of the Spack package manager. A single version can be specified with the @version syntax, a list of versions with @version1,version2,..., a greater than or equal to range with @version1: syntax, a less than or equal to range with @:version2 and an in between or equal to range with @version1:version2 syntax. In case implicit_default option is disabled and no explicit default is found among version specifier matches, an error is returned. This mechanism is enabled through a new configuration option named advanced_version_spec (which defines MODULES_ADVANCED_VERSION_SPEC environment variable when set). It may be enabled by default in modulecmd.tcl script with option --enable-advanced-version-spec passed to the ./configure script.
  • Conflict defined with a generic module name or an advanced version specifier may match multiple loaded modules (generally in case multiple loaded modules share same root name). Loaded environment analysis has been fixed to bind conflict to all loaded modules matching it. As a result the Dependent Reload mechanism is not triggered when one loaded module matching conflict is removed if another loaded module still match the conflict.
  • Doc: add Module selection contexts, Insensitive case, Extended default and Advanced module version specifiers design notes.
  • Make MODULESHOME environment variable controllable through the config sub-command with home configuration option. A --with-moduleshome argument is also added to the ./configure script to set specific default value for this option at installation time. (fix issue #292)

Modules 4.3.1 (2019-09-21)

  • Contrib: add mb script to bench Modules versions.
  • Correct modulecmd.tcl script startup to correctly report error in case Tcl extension library fails to load. (fix issue #284)
  • Install: fix typo on CFLAGS definition in lib/Makefile. (fix issue #287 with contribution from Felix Neumärker)
  • Remove useless code in Modules Tcl extension library
  • Make URLs in README correctly rendered in HTML. (contribution from Per Persson)
  • Doc: clarify modulefile evaluation modes in modulefile.4 man page. (fix issue #289)
  • When looking at the closest match among loaded modules when switching module with just a single module argument specified, load the information on the currently set environment to get the alternative names of loaded modules prior to look at closest module match. (fix issue #290)
  • Doc: describe the way to determine the site-specific configuration script location in cookbook recipes implying the installation of such a file. (fix issue #266)
  • Doc: add Log module command recipe to cookbook. (fix issue #283)
  • Doc: add Expose procedures and variables to modulefiles recipe to cookbook.
  • Doc: add Make defined modulepaths persist over sudo recipe to cookbook.
  • Doc: add Ensure user fully qualify the modules they use recipe to cookbook.
  • Introduce the wa_277 configuration option to workaround an issue with Tcsh history mechanism. Default module alias definition for Tcsh hits an issue with shell history mechanism: erroneous history entries are recorded each time the module command is called. When wa_277 option is enabled (which sets the MODULES_WA_277 environment variable to 1), an alternative module alias is defined which fixes the history mechanism issue. However the alternative definition of the module alias weakens shell evaluation of the code produced by modulefiles. Characters with special meaning for Tcsh shell (like { and }) may not be used anymore in shell alias definition elsewhere the evaluation of the code produced by modulefiles will return a syntax error. (fix issue #277)
  • Doc: add Tips for Code Reuse in Modulefiles recipe to cookbook. (contribution from Tom Payerle)
  • Fix the whatis and paths sub-command results for module symbolic versions targeting a directory when implicit_default configuration option is disabled. No error is returned and same result is now obtained whether the symbolic name or its target is used as argument for those two sub-commands. (fix issue #294)
  • Fix the whatis and paths sub-command results for module aliases targeting a directory when implicit_default configuration option is disabled. No error is returned and same result is now obtained whether the alias name or its target is used as argument for those two sub-commands. (fix issue #295)
  • Rework all the ternary operator expressions in modulecmd.tcl that may result in a nan value (whatever the case used to write this string) as the expr Tcl command raises an error when it returns such a value, which breaks Modules as soon as a modulefile, an alias or a symbolic version is named nan. (fix issue #296)

Modules 4.3.0 (2019-07-26)

  • Introduce Vim addon files to highlight the modulefile syntax. Installation of these files, which is enabled by default, is controlled by the --enable-vim-addons and --vimdatadir configure options. (contribution from Felix Neumärker)
  • If modulefile is fully read, cache the content read and the file header computed to avoid another file read if the same modulefile need to be read multiple times.
  • Except for path, paths, list, avail and aliases module commands always fully read a modulefile whether its full content is needed or just its header to verify its validity. Proceed this way to only read file once on commands that first just check modulefile validity then read again valid files to get their full content.
  • Introduce Modules Tcl extension library (written in C) to extend Tcl language in order to provide more optimized I/O commands to read a file or a directory content than native Tcl commands do.
  • Install: add --libdir, --enable-libtclenvmodules, --with-tcl and --with-tclinclude options to configure script to control libtclenvmodules build and installation.
  • When an error is caught during modulecmd.tcl first initialization steps, ensure the error report facility is initialized to render error message.
  • When looking for modulefiles in enabled modulepaths, take .modulerc file found at the root of a modulepath directory into account. Which means these rc files are now evaluated like global rc files and can be used to define module aliases targeting modulefiles stored in the underlying file tree.
  • Correctly get available default (-d) and latest (-L) version whether search pattern is passed with an ending forward slash character or not or if it contains a * wildcard character.
  • Append a forward slash character to any directory result of an avail command to better distinguish these directories from regular files.
  • Introduce the ability to control whether avail command search results should recursively include or not modulefiles from directories matching search query by use of the --indepth and --no-indepth command-line switches or the environment variable MODULES_AVAIL_INDEPTH. Default behavior is set at the ./configure time with the --enable-avail-indepth and --disable-avail-indepth switches. (fix issue #150)
  • Update bash, fish and zsh completion scripts to propose available modulefiles in the no in depth mode.
  • Add the ability to graphically enhance some part of the produced output to improve readability by the use of the --color command-line switch or the MODULES_COLOR environment variable. Both accept the following values: never, auto and always. When color mode is set to auto, output is colored if stderr is attached to a terminal. Default color mode could be controlled at configure time with the --enable-color and the --disable-color option, which respectively correspond to the auto and never color mode.
  • Control the color to apply to each element with the MODULES_COLORS environment variable or the --with-dark-background-colors and --with-light-background-colors configure options. These variable and options take as value a colon-separated list in the same fashion LS_COLORS does. In this list, each element that should be highlighted is associated to a Select Graphic Rendition (SGR) code.
  • Inform Modules of the terminal background color with the MODULES_TERM_BACKGROUND environment variable or the --with-terminal-background configure option, which helps to determine if either the dark or light background colors should be used to color output in case no specific color set is defined with the MODULES_COLORS.
  • Color prefix tag of debug, error, warning, module error and info messages.
  • Highlight the modulefile or collection name when reporting messages for a an action made over this modulefile or collection.
  • Color the modulepaths reported on a use command.
  • Highlight title of separator lines or column name of table header.
  • Color modulepaths, directories, aliases and symbols reported by the avail, aliases, list, whatis and search commands.
  • When color mode is enabled and module aliases are colored, do not associate them a @ tag as the color already distinguish them from regular modulefile.
  • When color mode is enabled and a Select Graphic Rendition (SGR) code is set for the default modulefile symbol, apply this SGR code to the modulefile name instead of associating it the default symbol tag.
  • Highlight matched module search query string among avail, whatis and search command results.
  • Highlight the modulefile and collection full path name on display, help, test and saveshow command reports.
  • Color modulefile Tcl commands set in a modulefile on a display command report.
  • Color module commands set in a collection on a saveshow command report.
  • Re-introduce clear sub-command. (fix issue #203)
  • Leverage --force command-line switch on clear sub-command to skip confirmation dialog. (fix issue #268)
  • Init: improve readability of variable definition operations by writing one definition operation per line rather having multiple commands on a single line like VAR=val; export VAR. (fix issue #225)
  • Add the ability to define a site-specific configuration file with an environment variable: MODULES_SITECONFIG. When set, the script file pointed by the variable is sourced (if readable) after the site-specific configuration file initially defined in modulecmd.tcl. (contribution from Ben Bowers, fix issue #234)
  • Doc: add description in the module.1 man page of MODULERCFILE in the environment section and siteconfig.tcl in the files section.
  • Install: provide at installation time a bare site-specific configuration script in designated etcdir if no pre-existing siteconfig.tcl file is found at designated location.
  • Introduce the config sub-command to get and set modulecmd.tcl options and to report its current state.
  • Contrib: update createmodule.py script to support execution from the cmd shell. (contribution from Jacques Raphanel, fix issue #270)
  • Add the ability to configure when unloading a module and multiple loaded modules match request if firstly loaded module should be chosen or lastly loaded module. Configure option --with-unload-match-order defines this setting which can be superseded with the MODULES_UNLOAD_MATCH_ORDER environment variable. This variable can be set with the option unload_match_order on the config sub-command. By default, lastly loaded module is selected. It is recommended to keep this behavior when the modulefiles used express dependencies between each other.
  • Add the ability to configure whether an implicit default version should be defined for modules with no default version explicitly defined. When enabled, which stays the default behavior, a module version is automatically selected (latest one) when the generic name of the module is passed. When implicit default selection is disabled, the name of modules to evaluate should be fully qualified elsewhere an error is returned. This option is set at ./configure time with the --enable-implicit-default and --disable-implicit-default options. It could be superseded with the MODULES_IMPLICIT_DEFAULT environment variable, that could be set with config module sub-command through the implicit_default option.
  • Install: add to the configure script the --with-locked-configs option to ignore environment variable superseding of Modules configurations defined in modulecmd.tcl script. Lockable configuration option are extra_siteconfig and implicit_default. Currently locked options are reported through the locked_configs option on the config sub-command.
  • Introduce the ability to control the module search match. Search query string should match module name start or any part of module fully qualified name. Default search match behavior is set at ./configure time with the --with-search-match option. It could be superseded with the MODULES_SEARCH_MATCH environment variable, that could be set with config module sub-command through the search_match option. Command-line switches --starts-with (-S) and --contains (-C) for avail module sub-command enable to supersede defined search match configuration.
  • Introduce the ability not to set the shell startup file that ensure module command is defined once shell has been initialized. Setting shell startup file currently means defining ENV and BASH_ENV environment variables to the Modules bourne shell initialization script. ./configure options --enable-set-shell-startup and --disable-set-shell-startup define if shell startup should be set or not by default. It could be superseded with the MODULES_SET_SHELL_STARTUP environment variable, that could be set with config module sub-command through the set_shell_startup option.
  • Cookbook: add the test-modulefiles recipe. (fix issue #182 with contribution from Colin Marquardt)
  • Fix location of global RC file to @etcdir@/rc instead of @prefix@/etc/rc to cope with @etcdir@ specific setup (@etcdir@ defaults to @prefix@/etc).
  • Take into account Modules initialization configurations found in etc directory if they exist rather in init directory. If initrc configuration file is found in etcdir then it is preferred over modulerc file in initdir. Following the same trend, modulespath configuration file is found in etcdir then it is preferred over .modulespath file in initdir.
  • Introduce the ability to install the Modules initialization configuration files in the etcdir rather than in the initdir. A new configure option is introduced for this task: --with-initconf-in. Accepted values for this option are: etcdir or initdir (default).
  • Add the --enable-modulespath configure option, which is an alias for the --enable-dotmodulespath option as .modulespath configuration file is named modulespath when installed in etcdic.
  • Install: update RPM spec file to disable set_shell_startup option by default, set /etc/environment-modules as configuration directory and store Modules initialization configuration files in it.
  • Report an error when a module load or unload evaluation aborts due to the use of the break or exit modulefile commands. This error notification clarifies that module evaluation failed. (fix issue #267)
  • Remove the message block display output for the reload, purge and restore sub-commands to preserve this output style for modulefile evaluation modes (load, unload and switch) and thus clarify understanding.
  • When unloading a module that contains a module load or module switch modulefile command, inhibit the unload performed of the useless requirement when auto_handling mode is disabled if currently performing a purge, reload or restore sub-command. As the unload sequence is determined and managed from these top commands.
  • Add ability to control module command message verbosity with configuration option. Introduced verbosity levels from the least to the most verbose are silent, concise, normal, verbose and debug. This option could be set at ./configure time with --with-verbosity option. It could be superseded with the MODULES_VERBOSITY environment variable, that could be set with config module sub-command through the verbosity option. Silent, verbose and debug verbosity modes can be set at the command-line level respectively with --silent/-s, --verbose/-v and --debug/-D command-line switches. (fix issue #204)
  • When verbosity level is normal or higher, reports every module loads or unloads performed to restore a collection or source a scriptfile, even if there is no specific message to output for these module evaluations. Clarifies what module evaluations have been triggered by these sub-commands.
  • Also honor the CLICOLOR and CLICOLOR_FORCE environment variables to define color mode. (fix issue #279)

Modules 4.2.5 (2019-07-08)

  • Correctly escape ? character in shell alias. (fix issue #275)
  • When resolving the enabled list of modulepaths, ensure resolved path entries are unique. (fix issue #274)
  • Right trim '#' characters from the fetched modulefile magic cookie string to ensure a correct compatibility version comparison. Useful when modulefile first line is equal to #%Module4.2##############.
  • Fix argument parsing for the append-path, prepend-path and remove-path modulefile commands to consider every arguments found after the variable name as variable values and not command option even if argument starts with - character. (fix issue #278)
  • Fix automatic loading of modulefiles when multiple module names are set on a single module load modulefile command. When auto_handling mode was disabled, the load of not loaded modules was not achieved as soon as some modules on this list were already loaded. (fix issue #281)

Modules 4.2.4 (2019-04-26)

  • Better track each module evaluation and the context associated to it in order to report a more accurate information on the additional modules loaded or unloaded when proceeding the main evaluation request. (fix issue #244, #245, #246, #247 and #248)
  • Doc: preserve quotes and dashes when making HTML docs. (fix issue #250 with contribution from Riccardo Coccioli)
  • Fix hanging list sub-command when terminal width is equal to the single column text width to be printed. (contribution from Jesper Dahlberg)
  • During an additional evaluation triggered by an automated module handling mechanism, ensure warning and error messages are reported under the message block of the main evaluation. (fix issue #252)
  • During the unload of a module when the automated module handling mode is disabled, report a warning message for each unload of a useless requirement that fails as done when the automated module handling mode is enabled. (fix issue #253)
  • When multiple modules are listed on a prereq command, drop the output of those modules that fails to load (by the Requirement Load automated mechanism) to only keep the output of the module whose load succeed. (fix issue #254)
  • Fix switch sub-command when the switched-off module cannot be unloaded when other loaded modules depend on it. Whole switch process is failed and no load of the switched-on module is attempted. (fix issue #251)
  • When switching modules, report failure of switched-off module unload or switched-on module load under the message block of the switch action. A failed switched-off module unload is reported as an error, as it aborts the switch evaluation, whereas a failed switched-on module load is reported as a warning. (fix issue #255)
  • When a module requirement is seen missing but the load of this module was attempted, report a more specific error or warning message to let user understand that the load of the requirement was attempted but failed. (fix issue #257)
  • When loading a module, report any missing requirement on the message reporting block corresponding to this module load. This warning or error message comes in addition to the eventual Requirement Load message reported under the message block of the main evaluation. (fix issue #258)
  • When unloading a module which has some dependent module still loaded, produce a more specific error or warning message if an evaluation of these dependent modules has been realized or if the unload of the required module is forced. (fix issue #259)
  • When a conflicting module is seen loaded but the unload of this module was attempted, report a Conflict Unload error or warning message toward the main evaluation message block. (fix issue #261)
  • When loading a module, report any loaded conflict on the message reporting block corresponding to this module load. This warning or error message comes in addition to the eventual Conflict Unload message reported under the message block of the main evaluation. (fix issue #261)
  • Correctly report loading state of conflicting module. (fix issue #262)
  • Adapt warning, error and info messages relative to the Dependent Reload mechanism to distinguish the unload phase from the load (reload) phase of this mechanism. In the automated module handling summary report, unloaded modules via this mechanism are reported in the Unloading dependent list and modules reloaded afterward are reported against the Reloading dependent list. (fix issue #263)
  • When the automated module handling mode is disabled, do not attempt to load a requirement expressed in a modulefile with a module load command, if this requirement is already loaded or loading.
  • Skip load or unload evaluation of a module whose respectively load or unload was already attempted but failed. If this second evaluation attempt occurs within the same main evaluation frame. (fix issue #264)
  • When reloading modules through the Dependent Reload automated mechanism, prevent modules to automatically load of other modules with the module load modulefile command, as it is done for the prereq command. (fix issue #265)
  • Raise an error when an invalid option is set on append-path, prepend-path or remove-path modulefile command. (fix issue #249)
  • Zsh initializes by default the MANPATH environment variable to an empty value when it starts. To preserve manpath system configuration even after addition to this variable by modulefiles, set MANPATH variable to : if found empty. (improve fix for issue #224)
  • Doc: provide a short installation guideline in README file. (fix issue #230)

Modules 4.2.3 (2019-03-23)

  • Add all the module dependency-related internal information to those saved prior a modulefile evaluation in order to correctly restore internal state in case modulefile evaluation fails.
  • Init: in shell initialization scripts, initialize MANPATH if not set with a value that preserves manpath system configuration even after addition of paths to this variable by modulefiles. (fix issue#224)
  • Enable to define an entire path entry to the MODULEPATH variable which corresponds to a variable reference only. (fix issue#223)
  • Cookbook: add the modulefiles-in-git recipe. (contribution from Scott Johnson)
  • When module switch commands are found in modulefiles, track switched-off modulefile as a conflict and switched-to modulefile as a requirement to apply same behaviors than for module load and module unload commands in modulefiles. If module switch has only one argument, do not define a conflict toward switched-off modulefile. CAUTION: it is not recommended to use `module switch` command in modulefiles. (fix issue#229)
  • When unloading a module, revert module switch commands found in modulefile: switched-on module is converted to a module unload, like for module load command. Nothing is done for switched-off module, like for module unload command. (fix issue#226)
  • For default element in a modulefile directory which is a module alias that points to a modulefile, when this modulefile is loaded, it receives as alternative names the eventual module aliases set on the distant directory holding the alias pointing to it. (fix issue#231)
  • When unloading a module that contains module load or module switch commands in its modulefile, select for unload the automatically loaded requirement module which has been loaded prior its dependent. (fix issue#232)
  • Doc: describe Emacs settings useful for adhering to coding conventions in CONTRIBUTING guide. (fix issue #233 with contribution from Ben Bowers)
  • When looking for a loaded or loading dependency requirement, select among the eventual multiple candidates the closest match to the dependent module.
  • During the unload of a module, if the unload of one of its dependent (by the Dependent Unload mechanism) fails, abort the whole unload process. Exception made if the force mode is enabled. In this case failing module stays loaded and the Dependent Unload mechanism continues with next module to unload.
  • During the unload of a module, if the unload of one of its useless requirements (by the Useless Requirement Unload mechanism) fails, keep the requirements of this failing module loaded. Such error is reported as a warning and it does not stop the whole unload process. (fix issue#240)
  • During the load or the unload of a module, if the unload of one of its dependent (by the Dependent Reload mechanism) fails, abort the whole unload or load process. Exception made if the force mode is enabled. In this case failing module stays loaded and Dependent Reload mechanism continues with next module to unload. This failing module is removed from the Dependent Reload list, so it will not take part of the load phrase of the mechanism. (fix issue#239)
  • During the load or the unload of a module, if the load of one of its dependent (by the Dependent Reload mechanism) fails, abort the whole unload or load process. Exception made if the force mode is enabled. In this case failing module stays loaded and Dependent Reload mechanism continues with next module to load. When the mechanism is applied during a switch command, force mode is enabled by default on the load phase. (fix issue#241)
  • When reloading all loaded modules with the reload sub-command, if one reloading module fails to unload or load, abort the whole reload process to preserve environment sanity. (fix issue#237)
  • During the unload of a module when the automated module handling mode is disabled and this module declares its requirements with the module load modulefile command. If the unload of one of its useless requirements (by the Useless Requirement Unload mechanism) fails, whole unload process is not aborted and continue with next module to unload. (fix issue#238)
  • Contrib: add mtreview utility script that analyzes test suite log file to compare actual and expected output of failed test. mt does not output the full test suite logs anymore but only the information produced by mtreview on failed tests.
  • Install: exclude Continuous Integration configurations from dist tarballs.

Modules 4.2.2 (2019-02-17)

  • Correct the Dependent Unload mechanism when it triggers the unload of 2 modules making together a requirement from another module. This module is now also added to the dependent modules to unload.
  • Doc: add a cookbook section in the documentation and port there the 3 pre-existing recipes: inhibit-report-info, top-priority-values and unload-firstly-loaded.
  • Doc: add a CONTRIBUTING guide.
  • Doc: fix a typo on the Python initialization example in module man page.
  • Doc: add a FAQ entry to describe the use of module from Makefile. (with contribution from Robert McLay)
  • Trim any white-space, newline or ; characters at the beginning or end of the function body passed to set-function modulefile command.
  • Init: add recognition of the --auto, --no-auto and --force command-line switches in fish shell completion script.
  • Init: add recognition of the --auto, --no-auto, --force, --paginate and --no-pager command-line switches in zsh shell completion script.
  • When the load of a modulefile is asked but a conflict is registered against this modulefile by an already loaded module, the load evaluation is now performed and the conflict is checked after this evaluation. If the conflict is still there, this evaluation (and the evaluation of its requirements) is rolled back. (fix issue#216)
  • Init: fix _module_not_yet_loaded alias in tcsh completion script to handle situation when noclobber variable is set. Also ensure actual rm command is called and not an alias. (fix issue#219)
  • Fix warning message when the load of a modulefile is forced over a reflexive conflict (message was reported twice).
  • When looking at the dependency of a loaded module, only consider requirement loaded before dependent module (holding a prior position in the loaded module list) as valid. Those loaded after dependent module are considered as an unmet dependency thus they are not taking part in the Dependent Unload, the Useless Requirement Unload and the Dependent Reload mechanisms.

Modules 4.2.1 (2018-11-11)

  • Cookbook: add the inhibit-report-info recipe.
  • Cookbook: port unload-firstly-loaded and top-priority-values recipes to v4.2.
  • Init: fix listing of loaded modules for fish and tcsh shell completions.
  • Init: fix saved collection listing when no collection found for bash, zsh, tcsh and fish shell completions.
  • Adapt system modulefile Tcl command to execute the command passed as argument through shell, like it is performed on compatibility version. (fix issue#205)
  • Correctly filter modulefile search memory cache entries when using a full search result to search later on a specific modulefile.
  • Prefix debug messages by information on the current modulefile or modulerc interpreter if any.
  • Init: fix listing of loaded modules on unload and switch sub-commands for bash shell completion.
  • Refrain module unload modulefile command from unloading a module required by another loading module.
  • Enable is-loaded modulefile Tcl command in modulerc interpretation context, like done on compatibility version. (fix issue#207)
  • Check a required module is not already loading before attempting to load it. Helps to handle cyclic dependencies.
  • Compute loaded modules requirement dependency relations without cycle and consider the module closing the cycle in a constraint violation state to avoid reloading loops on the Dependent Reload mechanism.
  • Safely unset dependency reference when computing dependency relations as some dependencies expressed may target same module.
  • Ensure a loaded module matching multiple entries of a same or prereq will just be considered as one module matching this requirement.
  • Init: quote prompt in csh and tcsh script with :q rather double quotes to accommodate prompts with embedded newlines. (fix issue#209 with contribution from Satya Mishra)
  • Init: skip shell environment alteration if autoinit command fails. (fix issue#208)
  • Reword path-like variable element counter reference handling to simply ignore the counter values not coherent with the content of related path-like variable. (fix issue#206)

Modules 4.2.0 (2018-10-18)

  • Add chdir and puts environment settings to the per-modulefile evaluation saved context. So previous values of these settings are restored in case of evaluation failure.
  • Fix save and restore of x-resource environment settings on the per-modulefile evaluation context.
  • Use the correct warning procedure to report the full reference counter inconsistency message (so this message is fully inhibited during global whatis evaluations).
  • Make append-path, prepend-path, remove-path and unsetenv commands alter env Tcl global array during display, help, test or whatis evaluation modes. Thus an invalid argument passed to these commands will now raise error on these modes. (see Environment variable change through modulefile evaluation context section in MIGRATING document)
  • On whatis mode, append-path, prepend-path, remove-path, setenv and unsetenv commands initialize variables if undefined but do not set them to their accurate value for performance concern.
  • Clear value instead of unsetting it during an unload mode evaluation of setenv or *-path commands to avoid breaking later reference to the variable in modulefile.
  • Make getenv command returns value on help, test or whatis evaluation modes. (fix issue#188)
  • Add an argument to the getenv command to return the value of this argument if the queried variable is undefined.
  • Use a different modulefile interpreter for each evaluation mode.
  • Adapt the procedure called for each modulefile command depending on the evaluation mode to adapt behavior of these commands to the module command currently running.
  • Report calling name and arguments for modulefile commands on display mode. For the commands evaluated during this mode, trigger this report at the end of the evaluation.
  • Inhibit chdir, conflict, module, module-log, module-trace, module-user, module-verbosity, prereq, set-alias, system, unset-alias, x-resource commands on help, test and whatis evaluation modes.
  • Ignore chdir, module, module-trace, module-verbosity, module-user and module-log commands found during modulerc evaluation.
  • Correctly restore an empty string value on sub-interpreter global variables when sanitizing this interpreter between two modulefile/modulerc evaluations.
  • Cache in memory results of a modulefile search to reuse it in case of rerun instead of re-walking the filesystem.
  • Evaluate global rc files once module sub-command is known and registered, so it can be queried during their evaluation.
  • Rename _moduleraw shell function in _module_raw to use a common _module_ prefix for all module-related internal shell functions.
  • Install: add --enable-append-binpath and --enable-append-binpath configure options to append rather prepend the bin or man directory when adding them to the relative environment variable.
  • Doc: clarify documentation for module usage on scripting language like Perl or Python to mention that arguments to the module function should be passed as list and not as a single string.
  • When interpreting a setenv modulefile order during an unload evaluation, variable is still set to be unset in generated shell code but it is set to the value defined on the setenv order in the interpreter context instead of being cleared.
  • Register the conflicts defined by loaded modules in the environment (variable MODULES_LMCONFLICT) and ensure they keep satisfied. (see Modulefile conflict constraints consistency section in MIGRATING document)
  • Register the prereqs defined by loaded modules in the environment (variable MODULES_LMPREREQ) and ensure they keep satisfied. (see Modulefile prereq constraints consistency section in MIGRATING document)
  • Introduce the automated module handling mode, which consists in additional actions triggered when loading or unloading a modulefile to satisfy the dependency constraints it declares. Those actions are when loading a modulefile: the Requirement Load and the Dependent Reload. When unloading a modulefile, Dependent Unload, Useless Requirement Unload and Dependent Reload actions are triggered. (see Automated module handling mode section in MIGRATING document)
  • Track the loaded modules that have been automatically loaded (with environment variable MODULES_LMNOTUASKED) to distinguish them from modules that have been explicitly asked by user. This information helps to determine what module becomes a useless requirement once all its dependent modules are unloaded.
  • Track in saved collections the loaded modules that have been automatically loaded by add of a --notuasked argument to module load collection lines. So this information is restored in loaded environment when collection is restored. This --notuasked argument is ignored outside of a collection restore context.
  • Consider modules loaded from a module source file as explicitly asked by user.
  • Install: add --enable-auto-handling configure option to enable or disable the automatic modulefile handling mechanism.
  • Process list of loaded modules or modules to load one by one during the restore, purge and reload sub-commands whatever the auto handling mode is.
  • Add the ability to control whether the auto_handling mode should be enabled or disabled with an environment variable called MODULES_AUTO_HANDLING or from the command-line with --auto and --no-auto switches. These command-line switches are ignored when called from modulefile.
  • Init: add pager-related command-line options in shell completion scripts.
  • Doc: describe MODULES_LMCONFLICT, MODULES_LMPREREQ and MODULES_LMNOTUASKED in module.1 man page.
  • Add -f and --force command-line switches to by-pass dependency consistency during load, unload or switch sub-commands. (see By-passing module defined constraints section in MIGRATING document)
  • Disallow collection save or loaded modules reload if some loaded modules have some of their dependency constraints unsatisfied.
  • The Dependent Reload action of a load, unload and switch sub-commands excludes modules that have unsatisfied constraints and includes modules whose constraints are satisfied again (when sub-command process solves a conflict for instance).
  • Doc: describe --force, --auto and --no-auto command-line switches and MODULES_AUTO_HANDLING variable in module.1 man page.
  • Ignore directories .SYNC (DesignSync) and .sos (SOS) when walking through modulepath directory content. (contribution from Colin Marquardt)
  • Install: look for make rather gmake on MSYS2.
  • Fix exec() usage in Python module function definition to retrieve the correct return status on Python3.
  • Cookbook: add the top-priority-values and unload-firstly-loaded recipes.
  • Install: add gcc to the build requirements in RPM specfile.
  • Silent any prereq violation warning message when processing Dependent Reload mechanism or purge sub-command.
  • Doc: mention createmodule.sh and createmodule.py scripts in FAQ. (fix issue#189)
  • Register all alternative names of loaded modules in environment with MODULES_LMALTNAME variable. These names correspond to the symbolic versions and aliases resolving to the loaded modules. Helps to consistenly solve conflict or prereq constraints set over these alternative names. (fix issue#143 / see Consistency of module load/unload commands in modulefile section in MIGRATING document)
  • Doc: describe MODULES_LMALTNAME in module.1 man page.
  • Install: add --with-bin-search-path configure option to get in control of the path list used to search the tools required to build and configure Modules. (fix issue#164)
  • Install: add --enable-silent-shell-debug-support configure option to add the ability to control whether or not code to support silent shell debug should be added to the module function and sh-kind initialization scripts. (fix issue#166)
  • Install: add --enable-quarantine-support configure option to add the ability to control whether or not code to support quarantine mechanism should be added to the module function and initialization scripts. (fix issue#167)
  • Check version set in modulefile magic cookie. If modulefile sets a version number greater than modulecmd.tcl script version, this modulefile is not evaluated like when no magic cookie is set at all. (fix issue#171 / see Express Modules compatibility of modulefile with versioned magic cookie section in MIGRATING document)
  • Fix uninitialized variable in procedure producing list of element output. (fix issue#195)
  • Ensure the consistency of module load modulefile command once the modulefile defining it has been loaded by assimilating this command to a prereq command. Thus the defined constraint is recorded in the MODULES_LMPREREQ environment variable. Same approach is used for module unload modulefile command which is assimilated to a conflict command. Thus the defined constraint is recorded in the MODULES_LMCONFLICT environment variable. (see Modulefile alias and symbolic modulefile name consistency section in MIGRATING document)
  • Only look at loaded modules when unloading so unloading an nonexistent modulefile does not produce an error anymore. (fix issue#199)
  • Report error raised from modulefile evaluation as ERROR rather WARNING, like when a conflict constraint is hit. Moreover this kind of evaluation error is now silenced on global evaluation like when proceding avail or search sub-commands.
  • Record messages to report them by block on when processing a load or an unload modulefile evaluation to improve readability on these evaluating modes that may cascade additional actions. (see Improved module message report section in MIGRATING document)
  • Foreground load, unload, switch and restore actions (ie. asked on the command-line) now report a summary of the additional load and unload evaluations that were eventually triggered in the process.
  • Support del and remove aliases for unload sub-command like on compatibility version. (fix issue#200 with contribution from Wenzler)
  • Correctly transmit the arguments along with the command to execute on system modulefile command. (fix issue#201)
  • Contrib: add mt utility script which helps to run just specific part of the test suite.
  • Introduce set-function and unset-function modulefile commands to define shell function on sh-kind and fish shells. (fix issue#193 with contribution from Ben Bowers)

Modules 4.1.4 (2018-08-20)

  • Doc: fix typo on getenv command description in modulefile(4) man page and clarify this command should be preferred over ::env variable to query environment variable value in modulefile.
  • Init: fix bash and zsh completion scripts to enable Extended Regular Expression (ERE) on sed command with -E argument (rather -r) for compatibility with OS X's and BSDs' sed. (fix issue#178)
  • Handle default version sets on an hidden modulefile (were not found previously). (fix issue#177)
  • Init: fix ksh initialization script for ksh88 compatibility. (fix issue#159)
  • Install: use sed command rather grep and cut in configure and Makefile scripts. (fix issue#175 with contribution from Michael Sternberg)
  • Fix typo, tab indentation and pipe opening mode on createmodule.py utility script. (contribution from Jan Synacek)
  • Check ModulesVersion value set from .version rc file to ensure this value refers to a version name in current directory. Report error if a nested value is detected and ignore this value. (fix issue#176)

Modules 4.1.3 (2018-06-18)

  • Make setenv command alter env Tcl global array during help, test or whatis evaluation modes. (fix issue#160)
  • Doc: describe MANPATH variable special treatment on compatibility version in diff_v3_v4 document.
  • Initialize and export _moduleraw SH shell function if stderr is attached to a terminal. Was previously checking stdout. (fix issue#169)
  • For csh shells, quote code generated by modulecmd.tcl to pass it to the eval shell command.
  • Escape special characters when producing code to define shell aliases (fix issue#165)
  • Correct modulefile lookup when a modulefile directory is overwritten by a module alias definition but it contains an empty sub-directory. (fix issue#170)
  • Doc: describe getenv command in modulefile(4) man page.
  • Improve SH shell detection in profile.sh initialization script to use shell variable on bash or zsh to determine current shell name. (fix issue#173)

Modules 4.1.2 (2018-03-31)

  • Add an example global rc file in contrib/etc directory that ensures MODULEPATH is always defined.
  • Check HOME environment variable is defined on savelist and is-saved commands or raise error if not.
  • Fix saving of deep module default version in collection when version pinning is disabled: if foo/bar/version is default version for foo, collection will retain just foo (was retaining foo/bar).
  • Enable to save and restore collections containing full path modulefiles eventually with no modulepath defined.
  • Run puts command not related to stderr or stdout channels in calling modulefile context to correctly get access to the targeted file channel. (fix issue#157)
  • Quote autoinit result for eval interpretation on SH-kind shells to avoid parameter expansion to randomly occur on generated code depending on file or directory names of current working directory. (fix RH bug#1549664)
  • Ignore empty elements found in MODULEPATH, LOADEDMODULES or _LMFILES_ to ensure all elements in these variables are non-empty strings.
  • Raise error if loaded environment is in an inconsistent state when calling commands requiring correlation of information from the LOADEDMODULES and the _LMFILES_ environment variables. Error raised on load, unload, switch, reload, purge, list, save and restore commands. May affect info-loaded or is-loaded commands if module passed as argument to these command is specified as a full path modulefile.
  • Fix list command to process loaded modules information before performing any content output.
  • Install: adapt configure script and Makefiles to support installation on Cygwin system.
  • Detect terminal width on Windows cmd terminal with mode command.
  • Improve Windows cmd shell support: error code returned, echoing text, shell alias creation and removal, working directory change.
  • Raise error when an empty module name is passed to module sub-commands like load, display or unload.
  • Raise error when an empty collection name is passed to module sub-commands like save, saveshow or restore.
  • Raise error when an empty path is passed to module unuse sub-command, like already done on use sub-command.
  • Clear argument list if an empty module command name is passed.
  • Fix module function definition for all shells in autoinit command to correctly handle empty-string parameters or parameters containing white-spaces, quotes, escape characters.
  • Fix module function definition for Python to accept being called with no argument.
  • Fix parameter expansion on module function for all SH-kind shells when quarantine mode is activated.
  • Escape \ character when producing R shell code.

Modules 4.1.1 (2018-02-17)

  • Make separator lines, used on display command result for instance, fit small screen width.
  • Install: give ability to build and install Modules from git repository without documentation if sphinx-build cannot be found.
  • Install: adapt configure script and Makefiles to support installation on FreeBSD, Solaris and OS X systems. (fix issue#147)
  • Rework code generated by autoinit for sh-kind shells to avoid use of local variables as those are defined differently through the sh variants. (also fix issue#147)
  • Init: use a default value on undefined variables in sh-kind scripts to avoid unbound variables in bash -eu mode. (fix issue#151)
  • Correctly detect terminal column number on Solaris.
  • Init: fix csh init script to get compatibility with pure csh shell
  • Sanitize content of MODULEPATH before using it at run-time, to make potential relative paths absolute, remove trailing slashes, etc. (fix issue#152)
  • Check loaded modulefiles still exists before displaying statistics on them during a list action.
  • Use a specific reference counter variable name (MODULES_MODSHARE_<VAR> instead of <VAR>_modshare) for DYLD-specific variables. (fix issue#153)
  • No error raise when updating a DYLD or LD path-like variable on OS X when System Integrity Protection (SIP) is enabled. In this situation, these variables are not exported in subshell context, so they appear undefined.
  • Init: protect arguments passed to the _moduleraw sh function from interfering content of current working directory. (fix issue#154)
  • Install: move hostname RPM requirement to the compat sub-package.
  • Start pager process only if some text has to be printed. (partially fix issue#146)
  • Ignore PAGER environment variable to configure Modules pager to avoid side effects coming from a general pager configuration not compatible with Modules pager handling. (fix issue#146)
  • Do not blank anymore default Modules pager options if default pager is less when the LESS environment variable is defined. (fix issue#146)

Warning

With this bugfix release, changes have been made on the pager setup to avoid side effects coming from the system general pager configuration. As a result PAGER environment variable is now ignored and MODULES_PAGER should be used instead to adapt Modules pager configuration at run-time.

Modules 4.1.0 (2018-01-15)

  • Extend stderr output redirection on sh-kind shells to all terminal-attached shell session, not only interactive shell session.
  • Extend shell code produced by the autoinit command to perform the same environment initialization as done in init shell scripts (default value set for module-specific environment variables, parse or source of configuration files).
  • Make init shell scripts rely on autoinit command to define the module command and setup its default environment.
  • Fix error rendering code for Tcl shell by producing a call to the error procedure.
  • Introduce pager support to handle informational messages, using less command with -eFKRX options by default. Environment variable MODULES_PAGER or PAGER may be used to supersede default pager command and options. --paginate and --no-pager switches enable or disable pager from the command line.
  • Install: add --with-pager and --with-pager-opts configure options to define default pager command and its relative command-line options.
  • Introduce quarantine mechanism to protect module execution against side effect coming from the current environment definition. Variables whose name has been put in MODULES_RUN_QUARANTINE will be emptied or set to the value hold by MODULES_RUNENV_<VAR> in the modulecmd.tcl run-time environment. Quarantine variable original value is then restored within modulecmd.tcl execution context once it has started.
  • Install: add --with-quarantine-vars configure option to define at build time the MODULES_RUN_QUARANTINE and MODULES_RUNENV_<VAR> environment variables set in initialization scripts.
  • Add MODULES_SILENT_SHELL_DEBUG environment variable to disable on sh shell and derivatives any xtrace or verbose debugging property for the duration of either the module command or the module shell initialization script. (fix issue#121)
  • Change error code produced by modulecmd.tcl for the Tcl, Perl, Python, Ruby, CMake and R scripting languages to return a 'false' boolean value in case of error rather raising a fatal exception.
  • Adapt module function definition for Tcl, Perl, Python, Ruby, CMake and R scripting languages to always return a value, result of the modulecmd.tcl run. When modulecmd.tcl run does not produce a specific status, a 'true' boolean value is returned. On CMake, resulting value is returned though a module_result global variable.
  • Spool content sent to the stdout channel with puts command during a modulefile interpretation, to effectively transmit this content to stdout after rendering the environment changes made by this modulefile. (fix issue#113)
  • Introduce append-path, prepend-path, remove-path and is-loaded module sub-commands, based on existing modulefile-specific Tcl commands. (fix issue#116)
  • Introduce is-saved, is-used and is-avail modulefile Tcl commands and module sub-commands to test availability of collection, modulepath or modulefile.
  • Raise error when a call to path or paths module sub-commands is attempted during a modulefile interpretation. Both commands now return text rather print text on scripting languages. An empty string is returned in no match case instead of a false boolean value.
  • Introduce module-info loaded modulefile command and its module sub-command counterpart info-loaded. This new command returns name of the modules currently loaded corresponding to the name passed as argument. (fix issue#3)
  • Fix is-loaded command to correctly handle multiple module names passed as argument (fix issue#138)
  • Support no argument on is-loaded, is-saved and is-used commands to return if anything is respectively loaded, saved or used.
  • Interpret module source command set in modulefile in unload mode when the modulefile itself is interpreted in this mode.
  • Consider a modulefile passed with name starting by ./ or ../ a full path name modulefile, like those starting by /. These kind of names are converted to absolute path names, for instance to register them in loaded modulefile list during a load command.
  • Correlate modulefile passed as full path name (starting by either ./, ../ or /) to already loaded modulefile registered with regular module name (file name without its modulepath prefix) to prevent for instance from loading twice same modulefile. Correlate in the same way regular module name to already loaded full path name modulefile.
  • Introduce MODULES_COLLECTION_PIN_VERSION environment variable to record modulefile version number when saving collections even if version corresponds to the default one. (fix issue#89)
  • Fix location of etc/rc global RC file to @prefix@/etc/rc instead of $MODULESHOME/etc/rc not to depend on MODULESHOME environment variable value.
  • Strengthen argument check for append-path, prepend-path and remove-path modulefile Tcl commands and module sub-commands. Raise error if argument list is not correct.
  • Fix support for the --delim=C argument form on append-path, prepend-path and remove-path commands.
  • Fix path reference counter handling in case path element is an empty string. Distinguish an empty path element from a variable set empty to clear it.
  • Pass multiple path elements separated by delimiter character as one string on append-path, prepend-path and remove-path commands.
  • Accept multiple path element arguments on append-path, prepend-path and remove-path commands.
  • Introduce the --duplicates argument option to append-path and prepend-path commands to add a path element already registered in variable.
  • Introduce the --index argument option to remove-path command to delete a path entry by passing its position index in variable.
  • Provide the ability to setup a site-specific configuration sourced at the start of modulecmd.tcl main procedure. This configuration is a Tcl script named siteconfig.tcl which enables to supersede any Tcl definition made in modulecmd.tcl. Location of this file is controlled at configure time with the --etcdir option.
  • Add the ability to handle paths containing reference to environment variable in MODULEPATH. When these kind of paths are used by module command, the variable references are converted to their corresponding value or to an empty string if they are not defined.
  • Enclose value set to environment variable on Tcl within curly braces rather double quotes to protect special characters in it from interpretation.
  • Correctly parse .modulespath initialization file to handle lines without any # character or to handle files with no content to extract.
  • Re-introduce the --enable-versioning configure option, which appends Modules version to installation prefix and deploy a versions modulepath shared between all versioning enabled Modules installation. A modulefile corresponding to Modules version is added to the shared modulepath and enables to switch from one Modules version to another.
  • Fix removal of CMake generated temporary script file by stripping newline character from script file name.
  • Add MODULES_CMD environment variable to expose path to the currently active module command script. This variable is set at initialization time.
  • Introduce modulecmd wrapper script, installed in binary directory, which executes the active module command.
  • Fix modulefile Tcl interpreter reset when handling list variables. (fix issue#145)
  • Introduce 'module-virtual' modulefile Tcl command to associate a virtual module name to a modulefile. This module can be located with its virtual name and the associated modulefile is the script interpreted when loading, unloading, etc.
  • Resolution of relative paths occurring during a modulefile interpretation to target a modulefile or a modulepath now takes the directory of the currently interpreted modulefile as the current working directory to solve the relative paths.

Modules 4.0.0 (2017-10-16)

Starting with this release, modules-tcl has become Modules. The following changes describe the differences with last modules-tcl release (1.923). To learn about the changes between this release and last Modules 3.2 release, please see the MIGRATING document.

  • Relax constraint on command-line argument position so options and switches can be passed either before or after command name.
  • Report unsupported option warning rather stop on error when compatibility-version specific command-line switches are passed ( --force, --human, --verbose, --silent, --create, --icase, --userlvl).
  • Keep empty module load line in shell configuration files after running the initrm or initclear commands.
  • Always return the value of tcl_platform(osVersion) for uname release
  • Optimize code output, for Perl to only return 1; once for a no-operation situation and for Python to not import os when there is only an error to render.
  • Use value of system command uname -n for uname nodename.
  • Add support for CMake shell
  • Ignore / character used as suffix in modulefile name passed on command line.
  • Rename Perl initialization script in perl.pm and Python in python.py.
  • Add support for Ruby shell (with contribution from Tammo Tjarks)
  • Add support for R shell (with contribution from Roy Storey)
  • When a default is set for a given module name, target modulefile can be referred on as modulename/default in addition to just modulename.
  • Locate symbolic versions on avail command even these symbols are set over a module alias or another symbolic version. In this situation the symbol spread along the resolution path until reaching a modulefile.
  • Define a more standard shebang on modulecmd.tcl script.
  • Determine modulefile corresponding to given module name using the loaded context only on unload situation.
  • Enable to unload mod/dir/subdir/vers when unload of mod or mod/dir asked. Was previously working only if deep module to unload was also the default version for these root names.
  • Make -l/-t switches mutually exclusive. Last switch mentioned on the command-line is honored.
  • Output parsable modulepath header when -l/-t switches are enabled.
  • When searching for a module in a given modulepath directory, if a module alias or a symbolic version matches searched module but the target of this alias or symbol is not found in current modulepath directory, search for this target restarting search from the first modulepath in list to ensure modulepath priority.
  • Solve aliases or symbolic versions looking for all modulepaths on search and paths commands. Was previously solved if their target was found in same modulepath directory.
  • Add support for hidden dot modulefiles. A hidden modulefile does not appear in case of wild search, it is only returned when search is about its exact name.
  • No table header print in --long mode on an avail command if no result are returned.
  • Add blank line between displayed list of elements, for instance between modulepath content on avail command.
  • Improve readability of error messages encountered during modulefile execution by putting Tcl error message first after the Module ERROR prefix.
  • Do not exit immediately when an internal error occurs in currently interpreted modulefile. Consider this interpretation as failed and continue to proceed the other modulefile arguments.
  • When multiple modulefiles are passed on display, help and test commands only output one separator line between 2 interpreted modulefiles.
  • Fix environment settings stack handling issue when restoring stack after a failed attempt to load a modulefile in a modulefile.
  • Failed attempt to load or unload a modulefile within a modulefile now leads to this upper modulefile load or unload failure. Previously upper modulefile were loaded respectively unloaded even if its dependent sub-modulefile failed to load or unload.
  • During a switch command, if the unloading part fails the loading part will not be tried. Unloading part fails if module to unload does not exist or its unload interpretation raise error.
  • Init: use module source rather shell command source to load modulerc system configuration in sh-kind, csh-kind and fish shell init scripts.
  • Install: transform configuration options to bind to an existing compatibility Modules version into option (--enable-compat-version) to build and install this compatibility version along with main version.
  • Init: adapt initialization scripts to handle both main and compatibility version. By default a shell script enables main version and if the environment variable MODULES_USE_COMPAT_VERSION is set to 1, the compatibility version is enabled instead of main version.
  • Install: import from compatibility version and install add.modules and mkroot utility scripts (scripts developed by R.K. Owen).
  • Install: update RPM spec file to handle compatibility version as a compat sub-package.
  • Add completion script for Fish shell (contribution from BEFH).
  • Doc: extend content of diff_v3_v4 to details all noticeable changes between v3.2 and v4.0.
  • Doc: introduce MIGRATING guide to learn the major changes when moving from v3.2 to v4.0.
  • Fix list command when full pathname modulefile is loaded (fix bug#132)
  • Install: handle version number though git tags in scripts, documentation and RPM spec file.
  • Doc: migrate documents from POD format to reStructuredText to benefit from Sphinx documentation framework and Read The Docs publishing capabilities.

Above changes describe the differences with modules-tcl release 1.923. To learn about the changes between Modules 4.0 and last Modules 3.2 release, please see the MIGRATING document.

modules-tcl-1.923 (2017-07-20)

  • Fix aliases command when a global or user RC file is set.
  • Find and solve global or user RC aliases and symbolic versions on search, whatis and paths commands.
  • Do not look at currently loaded modules to resolve the target of a module alias.
  • Rework default and latest versions search on avail command. Correct display when at a given level a sub-directory element is last element in directory among modulefiles. Previously sub-directory was printed but last file among modulefiles was also printed (2 latest versions at the same level). A directory tagged "default" does not appear anymore in default listing result as its content (the default version found in that directory) will be displayed.
  • When an alias is set and overrides name of an existing directory, take this alias into account for default and latest choice and ignore directory content.
  • Bad default set will lead to no result displayed for the corresponding module in case of default avail display.
  • Correct inclusion of aliases in output result when these aliases are not part of the exact same module path than module path of the search.
  • Rewrite existing shell initialization file with initadd, initprepend, initswitch, initrm and initclear commands rather than writing a new file then copying this new file to replace the existing initialization file. In addition only re-writes shell initialization file if its content need to be altered.
  • Raise an error on initadd, initprepend, initswitch, initrm and initclear commands when no module load line are found in shell initialization file.
  • Normalize error messages for the various collection-related commands when collection cannot be accessed.
  • Cleanup existing reference counters of a path list variable when this variable is altered by a setenv or an unsetenv command.
  • Init: do not pollute tab-completion with moduleraw command. (Bert Wesarg)
  • Make use of the same Tcl interp for each modulefile interpretation and use another one for each modulerc (but the same for each modulerc). By doing so we proceed like on C-version where same interpreter is used across modulefile or modulerc interpretation. Huge performance improvement is achieved with this change on commands making intensive use of interp like avail. Interpreter state is reset from one interpretation to another: the initial variable and procedure state is restored before each new interpretation to avoid spread of definitions from one interpretation to another. Also in case of nested interpretation each interpretation level has its own interpreter so a module loaded by another does not influence the interpretation of the module loading it.
  • Improve performance of aliases and symbolic versions resolution by computing these resolution at definition time. As a consequence resolution loop are not registered anymore and produce an error message when spotted not at display time.
  • Reduce number of access system call by trying access to modulefile when reading the content of a modulefile directory rather testing access before trying it.
  • No error raise on empty argument list for load. To cope with initadd behavior that requires at least an empty module load line in startup files. (fix SF bug#88)
  • Fix initadd to handle load line without trailing space. Was previously expecting load directive to be written "module load " to get a match. With fix, module load line will also be matched.
  • Like C-version catch raised error when break or continue are called from outside of a loop to handle them as when they are called from modulefile main body. (fix SF bug#87)
  • Return error on module use command when an empty path string is provided rather ignoring it.
  • Workaround min and max functions and lreverse procedure for correct operations under Tcl version 8.4.
  • Install: add --with-tclsh configure option to give the ability to choose the Tcl interpreter shell to setup in initialization scripts.
  • Handle error raised from the ModulesDisplay, ModulesHelp and ModulesTest procedures in the same way than for the evaluation of the modulefile content. An error occurring during the evaluation of the modulefile content will lead to no evaluation of the display, help and test command specific functions.
  • Remove debug module command
  • Doc: describe path, paths and autoinit module command.
  • Correct use of xrdb tool when not installed in default path.
  • Fix init* module commands to behave more like C-version and document remaining differences in diff_with_c-version.
  • Init: make sh init script closer to POSIX specification to support sh flavors different than Bash or Zsh like Dash.
  • Fix column-mode display for very short width terminal.
  • Install: introduce an install non-regression testsuite which is triggered by the make testinstall command and checks modules-tcl installation is operational.
  • Init: fix modulerc load test on fish init script.
  • Init: fix interactive shell test on sh init script.
  • Install: add --enable-example-modulefiles configure option that install by default some modulefiles provided as example in the system modulefiles directory.
  • Install: when uninstalling, do not remove modulefiles directory if it is not empty.
  • Add completion script for Zsh shell.
  • Add module test command to trigger when called execution of a ModulesTest procedure in target modulefile following same kind of mechanism than module help.

modules-tcl-1.832 (2017-04-29)

  • Fix getenv sub-command to correctly return environment variable value.
  • Clarify in man-pages display of module alias and symbolic version-name on avail command and management of file access issue when locating modulefiles.
  • Distinguish access issue (permission denied) from find issue (cannot locate) when trying to access directly a directory or a modulefile as done on load, display or whatis commands. In addition on this kind of access, not readable .modulerc files are ignored rather producing a missing magic cookie error.
  • When mode is set to unload, module load commands in modulefile are interpreted as module unload commands. To guaranty correct behavior regarding requirements, the module list passed to the load command is reversed to unload the modulefiles in the reverse order than they have been loaded.
  • Correct display command to only report module commands set in modulefile and not those set in the various .modulerc on the path toward this modulefile.
  • Fix bash and tcsh completion scripts to eliminate symbolic version names from avail command result.
  • Improve avail command when a symbolic version-name is passed as argument to return the modulefile target of this symbolic version-name.
  • When looking for an implicit default in a directory, now a module alias is taken into account so it can be returned as the last element in it (highest numerically sorted version).
  • Fix list command to correctly display the default tag along loaded modules when set via a .version file.
  • Fix long output of list command to display the symbolic version-names associated to each loaded module if any.
  • Improve avail command to return alias module when an alias name is passed as argument.
  • On a --default listing, a modulefile does not appear anymore if a directory is set default at the same level. On a --latest listing, a directory does not appear anymore if set default but not the latest.
  • Read modulerc and validate its header in a single open/read/close sequence instead of two in order to reduce to number of IO operations during an avail command.
  • Drastically reduce grid size computation time which removes overhead when displaying module avail results in column-mode.
  • Translate module name to currently interpreted module name when name correspond to the last part this interpreted module only in case of symbolic version-name or alias resolution.
  • Avoid resetting regular path (/usr/bin) or manpath (/usr/share/man) when switching from Tcl to C version in switchml utility.
  • Raise error on x-resource if DISPLAY environment variable is not set.
  • Fix lisp init script which was broken for environment change actions.

modules-tcl-1.775 (2017-03-07)

  • Improve README with examples, requirements, links, etc. Also update INSTALL documentation with details on the new configure/make/make install process.
  • Add display of a release date next to the version number when calling for --help or --version.
  • Update diff_with_c-version document to describe the features of the Tcl-version that are not supported on the C-version. Also state that the diff takes C version 3.2.10 against Tcl version 1.729 as a basis.
  • Introduce switchml tool, a shell function (or alias for csh or tcsh shells) that swap currently enabled Modules version (C or Tcl) by the other version (C or Tcl). Configure option --with-cver-initdir must be defined to enable switchml in initialization script.
  • Define a PATH and MANPATH in shell initialization scripts that point to the defined modules-tcl installation directories.
  • Give ability to generate distribution tarball from the git repository with Makefile dist target.
  • Introduce an installation process for this software following the configure/make/make install fashion. Configure step enables to choose installation paths and init scripts features to activate. Make step mainly translates init scripts with the configuration set. Make install creates target directories and copy files into them.
  • Fix MODULESHOME setup in autoinit command to define it as an absolute path and set it to the upper directory when modulecmd.tcl is located in a bin or a libexec directory.
  • Correct alias and version resolution on avail command which was erroneous in case of a modulefile holding symbols (like default) and targeted by aliases. Avail output was showing the aliases holding the symbols instead of the modulefile.

modules-tcl-1.729 (2017-02-01)

  • Add documentation in module(1) man page on the modulefile collection concept and the relative save, restore, saverm, saveshow and savelist commands.
  • Add document to list the differences of the functionalities that can be found on the C-version of the Modules package compared to the Tcl-version.
  • Improve modulecmd.tcl shebang to only search tclsh once if found in PATH.
  • Add module-info mode check against remove and switch values.
  • Introduce module-info command Modules-specific Tcl command to distinguish complex load or unload commands that cannot be determined with module-info mode alone. For instance a modulefile can now be aware that a switch, a restore or a purge command is currently being run.
  • Enable usage of module-info Modules-specific Tcl command from a modulerc file.
  • Fix module-info specified Modules-specific Tcl command.
  • No exit raise on modulefile or modulerc error during avail, aliases, whatis and search commands to avoid harming results from these global commands if error exists in a few modulefiles.
  • Exit with error code when a critical error is encountered when interpreting a modulefile or a modulerc.
  • Inhibit non-critical error report raised from modulefiles during avail, aliases, whatis and search commands to avoid error flood when parsing all modulefiles or modulercs.
  • Handle multiple lines of module-whatis Modules-specific Tcl commands defined for the same modulefile.
  • Handle multiple arguments passed to the module-whatis Modules-specific Tcl commands. They are joined to get a single line of text.
  • Return error on whatis command if searched modulefile is not found.

modules-tcl-1.704 (2017-01-20)

  • Set path variable counter to 1 for paths without a known reference count (was previously set to 999999999).
  • Introduce envml utility which acts as an application launcher where module commands are instantiated to setup environment before launching the given application.
  • Always register paths provided to be part of MODULEPATH environment variable as absolute paths to get independent from the current working directory.
  • Inhibit next modulefiles interpretation with exit Modules-specific Tcl command only if current mode is load.
  • Add argument to module-info shell and module-info shelltype to test current shell or shelltype value.
  • Fix use of default version-name to not consider it as a module symbol if a modulefile is named default.
  • Fix path variable counters when : character is used in elements of a path-like variable.
  • Update module(1) and modulefile(4) man pages to clear content specific to the C version of Modules and add content specific to or adapt content that behave differently on this Tcl version.
  • Fix TCLSH variable issue in Python init script.

modules-tcl-1.677 (2017-01-04)

  • Make switch command handle a single argument. The modulefile to switch to is the one passed on the command-line and the modulefile to unload is assumed to be the currently loaded module with the same root name as this modulefile specified on the command-line.
  • Make switch command idempotent by always ending up with old unloaded and new loaded, whatever the starting situation is.
  • Fix exit Modules-specific Tcl command.
  • Add refresh command as alias on reload command.
  • Add dummy module-log, module-trace, module-user and module-verbosity Modules-specific Tcl commands to enable support for modulefiles using them.
  • Fix system Modules-specific Tcl command to behave like described on the man page.
  • Fix module list when module loaded with full path
  • Disable g_force property by default to avoid loading a modulefile already loaded. It also avoids path element reference counting to get increased when the same module is asked twice for load.
  • Clarify module-info mode option and set help mode on module help command.
  • Clarify module-info flags and user options.
  • Handle empty or separator path on add-path ad unload-path commands.
  • Delete environment variable targeted by an unsetenv command on unload mode if no value has been provided along. On display mode, print environment variable value if any has been passed to unsetenv command.
  • When setting Tcl variable, enclose value within double quotes.
  • Fix perl quoting style for variable set, escape single quotes rather double quotes.
  • Call unuse command instead of use command on a module unload.
  • Fix continue Modules-specific Tcl command.
  • Add chdir Modules-specific Tcl command.
  • Fix break Modules-specific Tcl command.

modules-tcl-1.655 (2016-11-23)

  • No display of modulepath header if no module found in it.
  • Remove call to module aliases on module avail command, as aliases are now directly included in the avail results.
  • Include module aliases in the displayed result of an avail command. Also display aliases defined in a global or user modulerc file.
  • Exit with error code if error occurred on display or help commands.
  • Fix module-info symbols resolution.
  • Better handling of .modulerc and .version files when searching for a modulefile.
  • Fix module-info version resolution.
  • Fix module-info alias resolution.
  • Register alias and version by the short module name and improve their resolution to avoid loop.
  • Source $MODULERCFILE/modulerc when $MODULERCFILE is dir.
  • Make it so you can do module avail un, wildcard * character implied.

modules-tcl-1.632 (2016-09-06)

  • Raise error if command does not receive the excepted number of arguments.
  • Improve column-mode display to get a denser output on avail command.
  • Standardize the output of Warning, Error, InternalBug and ErrorAndExit messages.
  • Add short option -d for --delim on prepend-path.
  • Introduce collection target concept to distinguish between machines, environments or domains that are incompatible with each other.
  • Introduce saveshow command, to display content of saved collections.
  • Improve save and restore commands to handle collection specified as absolute or relative file path.
  • Introduce saverm command, to delete saved collections.
  • Enable to restore collection with multiple modulefiles specified on the same line.
  • Fix restore command when there is no module to load in collection.
  • Fix restore command when collection fully rewind module paths.
  • Fix restore command to preserve module path order set in collection.
  • Raise error if try to save an empty environment in a collection.

modules-tcl-1.602 (2016-08-13)

  • Add support for Fish shell.
  • Import recent tests added to C-version on 10-use and 50-cmds testsuites.
  • Add short option -d for --delim on append-path and remove-path.
  • Fix load and implement unload x-resource.
  • Fix Python code that was broken or not Python3-compliant. Fixed code is used to define the module command, to render error and to process x-resource.
  • Always dictionary-sort (also called numerical-sort) list of modulefiles or list of collections.
  • Fix bash completion script to be compliant with bash posix mode.

modules-tcl-1.578 (2014-12-24)

  • First release to be described in this NEWS file but it does not mean this is the first version of modules-tcl as this Modules flavor is born in 2002.
  • At this stage, modules-tcl handles a majority of the module commands and modulefile Tcl commands available on C version.

Cookbook

Modules can be used in many ways. The following collection of recipes provides various installation examples that shed lights on how to take advantage of existing Modules features and how to extend the module command to achieve specific needs.

Ensure user fully qualify the modules they use

When managing a vast software catalog accessible by multiple users, it is often desired that these users understand exactly what are the software they enable in their environment. This is especially important when new software versions are introduced in the catalog.

On a regular Modules installation, if multiple versions of a given module are available, latest version is selected when user load this software module by specifying its generic name (module load software). So when a new version is installed for software, users automatically end up with this new version enabled in their environment.

Depending on software, a precise version control may be required to avoid issues. In this case the implicit default version selection done by Modules is not desired. This recipe describe the way to handle this kind of situation.

Implementation

Starting version 4.3 of Modules, a new option called implicit_default is introduced. When enabled (which means configuration option is set to 1) if a module is specified by its generic name an implicit default is automatically defined (latest version) if no explicit default is defined. When implicit_default configuration option is disabled (when set to 0), no implicit default is computed and an error is returned to user in case module has been specified by its generic name but no default version has been set.

So to ensure user fully qualify the modules they use, this implicit_default configuration option should be disabled. It could be achieved by setting the option in the initrc file installed in the configuration directory (or in the modulerc file installed in the initialization script directory if this location is preferred).

initrc
#%Module

module config implicit_default 0

It may be desired to lock this option, to ensure users do not alter it afterward. The lock_configs configuration option fills this need. By setting this option and the implicit_default in a site-specific configuration script, users will not be able to change the implicit_default behavior you configure.

siteconfig.tcl
# disable implicit_default option
setConf implicit_default 0

# forbid `implicit_default` config option superseding
lappendConf locked_configs implicit_default

Compatible with Modules v4.3+

Installation

Create site-specific configuration directory if it does not exist yet:

$ mkdir /usr/share/Modules/etc

Then copy there the initialization RC file of this recipe:

$ cp example/ensure-user-qualify-modules/initrc /usr/share/Modules/etc/

Or if you want to enforce the implicit_default disablement setup for users, copy there the site-specific configuration script of this recipe:

$ cp example/ensure-user-qualify-modules/siteconfig.tcl /usr/share/Modules/etc/

If you currently use Modules version 4.3, copy the configuration script specific to this version:

$ cp example/ensure-user-qualify-modules/siteconfig.tcl-4.3 /usr/share/Modules/etc/siteconfig.tcl

Note

Defined location for the site-specific configuration script may vary from one installation to another. To determine the expected location for this file on your setup, check the value of the siteconfig option:

$ module config siteconfig

Once file is installed, you could verify option value is correct:

$ module config implicit_default
Modules Release 4.3.0 (2019-07-26)

- Config. name ---------.- Value (set by if default overridden) ---------------
implicit_default          0 (locked)
Usage example

Enable the modulepath where the example modulefiles are located:

$ module use example/ensure-user-qualify-modules/modulefiles

Attempt to load a module, which does not defined a default version, by its generic name:

$ module load -v softa
ERROR: No default version defined for 'softa'

Load succeed if module is fully qualified:

$ module load -v softa/1
Loading softa/1

For modules which define explicitly a default version, they can still be loaded by their generic name:

$ module load -v softb
Loading softb/1

Expose procedures and variables to modulefiles

Same piece of code may be relevant for multiple modulefiles in your setup. Sharing code (procedures and variables) is preferred to redefining it in each modulefile. The following recipe describes an efficient way to define Tcl procedures and variables that will be then available from the modulefile evaluation context.

Implementation

To expose site-specific procedures and variables across all modulefiles during their evaluation a site-specific configuration script is proposed.

This script exposes registered procedures to the Tcl interpreters that evaluate either modulerc or modulefile scripts.

By using the env global array, which holds environment variables, variables could also be exposed to those Tcl interpreters. Variables exposed this way, will be found set within modulefile or modulerc evaluation context but will not be exported to the environment changes the modulecmd.tcl script produces.

siteconfig.tcl
# append site-specific procedures referenced in the g_siteProcsToExposeToItrp
# variable defined below to the list of procedures exposed in the modulefile
# and modulerc evaluation interpreters
proc addSiteProcsToItrpAliasList {itrpaliasvname keyname args} {
   # ensure this proc is only called once at itrpaliasvname initialization
   trace remove variable $itrpaliasvname write addSiteProcsToItrpAliasList
   upvar #0 $itrpaliasvname itrpaliasv
   # register each site-specific procedure
   foreach procname $::g_siteProcsToExposeToItrp {
      if {$keyname ne {}} {
         set itrpaliasv($procname) $procname
      } else {
         lappend itrpaliasv $procname $procname
      }
   }
}
trace add variable ::g_modfileBaseAliases write addSiteProcsToItrpAliasList
trace add variable ::g_modrcAliases write addSiteProcsToItrpAliasList


# Define here site-specific procedures that should be exposed to modulefile
# and modulerc interpreter contexts
# *Beware* not to override an existing procedure of modulecmd.tcl script
proc mysiteproc {} {
   return sitevalue
}

# list all site-specific procedures to expose to modulefile and modulerc
# interpreter contexts
set g_siteProcsToExposeToItrp [list mysiteproc]

# Define here site-specific variables that should be exposed to modulefile
# and modulerc interpreter contexts. Use environment variable env array to
# transmit these variables
# *Beware* not to override an existing environment variable
set env(mysitevar) sitevarvalue

Compatible with Modules v4.2+

Installation

Create site-specific configuration directory if it does not exist yet:

$ mkdir /usr/share/Modules/etc

Then copy there the site-specific configuration script of this recipe:

$ cp example/expose-procs-vars-to-modulefiles/siteconfig.tcl /usr/share/Modules/etc/

Note

Defined location for the site-specific configuration script may vary from one installation to another. To determine the expected location for this file on your setup, check the value of the siteconfig option on Modules version 4.3 or above:

$ module config siteconfig

On older version of Modules, check the modulecmd.tcl script:

$ grep '^set g_siteconfig ' $MODULES_CMD

The configuration script proposed should then be adapted to your needs:

  • define your own procedures
  • register them into the g_siteProcsToExposeToItrp list variable to expose them to the modulefile and modulerc evaluation contexts
  • define your own variables using the env array variable
Usage example

Enable the modulepath where the example modulefiles are located:

$ module use example/expose-procs-vars-to-modulefiles/modulefiles

Display one of the example modulefiles that makes use of the site-specific procedure and variable defined in the siteconfig.tcl script:

$ module show foo
-------------------------------------------------------------------
.../modulefiles/foo/1:

setenv          FOO1 sitevalue
setenv          FOO2 sitevarvalue
-------------------------------------------------------------------

Load one example modulefile and check that the environment variable it defines, which rely on the site-specific procedure and variable, are well set:

$ module load bar
$ echo $BAR1
sitevalue
$ echo $BAR2
sitevarvalue

Inhibit output of informative messages

Since Modules v4.2, additional module load or unload triggered by the load or the unload of a modulefile are reported to the user to help understand what happened automatically. These informative messages may not be desired sometimes and here is a proposed way to inhibit them.

Implementation

Starting version v4.3, a verbosity configuration option is introduced to increase or decrease the variety of the messages produced by the module command. To inhibit the output of the info-level messages, the concise verbosity level should be selected:

$ module config verbosity concise

For v4.2 versions, a site-specific configuration script is proposed to inhibit the output of the info-level messages.

siteconfig.tcl
set g_inhibit_inforeport 1 ;# Non-critical info reporting disabled if == 1

# override 'reportInfo' procedure to inhibit messages if g_inhibit_inforeport
# is set to 1
proc reportInfo {message {title INFO}} {
   if {!$::g_inhibit_inforeport} {
      # use reportError for conveniance but there is no error here
      reportError $message 0 $title 0
   }
}

Compatible with Modules v4.2

Installation (only for version older than v4.3)

Create site-specific configuration directory if it does not exist yet:

$ mkdir /usr/share/Modules/etc

Then copy there the site-specific configuration script of this recipe:

$ cp example/inhibit-report-info/siteconfig.tcl /usr/share/Modules/etc/

Note

Defined location for the site-specific configuration script may vary from one installation to another. To determine the expected location for this file on your setup, check the modulecmd.tcl script:

$ grep '^set g_siteconfig ' $MODULES_CMD
Usage example

With a bare bar modulefile:

bar
#%Module

And a foo modulefile that pre-requires bar:

foo
#%Module
prereq bar

Enable the modulepath where the example modulefiles are located:

$ module use example/inhibit-report-info/modulefiles

Load foo with auto handling mode enabled. The info-level message inhibition should let foo load quiet:

$ module load --auto foo
$

Log module command

It is sometimes desired to better understand the module usage on the system we manage. Especially to determine what are the modulefiles most used and what are those never used that could be removed. This recipe describes a way to track the module usage by logging each request made.

Implementation

Logging module commands is implemented by the use of a site-specific configuration that supersedes the definition of the module command to execute the logger command, in order to send a message to the system log, prior processing the module command itself. The log message sent describes the module command called and who called it.

siteconfig.tcl
# override 'module' procedure to log each call made by user
rename ::module ::__module
proc module {command args} {
   if {[getEvalModuleStackDepth] == 0} {
      exec logger -t module "[get-env USER]: $command [join $args]"
   }
   return [eval __module "{$command}" $args]
}

Compatible with Modules v4.2+

Installation

Create site-specific configuration directory if it does not exist yet:

$ mkdir /usr/share/Modules/etc

Then copy there the site-specific configuration script of this recipe:

$ cp example/log-module-commands/siteconfig.tcl /usr/share/Modules/etc/

Note

Defined location for the site-specific configuration script may vary from one installation to another. To determine the expected location for this file on your setup, check the value of the siteconfig option on Modules version 4.3 or above:

$ module config siteconfig

On older version of Modules, check the modulecmd.tcl script:

$ grep '^set g_siteconfig ' $MODULES_CMD
Usage example

Loading a bare modulefile:

$ module load example

A log entry can then be retrieved from system log files:

$ journalctl -q -t module -n 1
Sep 12 20:24:01 hostname module[9925]: username: load example

Return file basename on module-info name for full path modulefile

When module name is specified as a full pathname, the module-info name command used in modulefile was returning the file basename on Modules compatibility version. Starting version 4 of Modules, the full pathname is returned when module is specified this way as once loaded this module is identified by its full pathname. This recipe describes a way to get back the behavior of Modules compatibility version for the module-info name modulefile command.

Implementation

Return file basename on module-info name for modules specified as full path modulefile is implemented by the use of a site-specific configuration that supersedes the definition of the module-info name command to return modulefile basename instead of full pathname.

siteconfig.tcl
# override 'module-info' procedure to return file basename for 'name' action
# when modulefile is specified as a full path file
rename ::module-info ::__module-info
proc module-info {what {more {}}} {
   if {$what eq {name}} {
      set name [currentModuleName]
      if {[isModuleFullPath $name]} {
         return [file tail $name]
      } else {
         return $name
      }
   } else {
      return [__module-info $what $more]
   }
}

Compatible with Modules v4.2+

Installation

Create site-specific configuration directory if it does not exist yet:

$ mkdir /usr/share/Modules/etc

Then copy there the site-specific configuration script of this recipe:

$ cp example/module-info-name-return-basename/siteconfig.tcl /usr/share/Modules/etc/

Note

Defined location for the site-specific configuration script may vary from one installation to another. To determine the expected location for this file on your setup, check the value of the siteconfig option on Modules version 4.3 or above:

$ module config siteconfig

On older version of Modules, check the modulecmd.tcl script:

$ grep '^set g_siteconfig ' $MODULES_CMD
Usage example

With an info/name modulefile that sets an environment variable with the result of the module-info name modulefile command:

info/name
#%Module
setenv MODNAME [module-info name]

Load info/name by its full pathname then check value of the environment variable set:

$ module load ./example/module-info-name-return-basename/modulefiles/info/name
$ echo $MODNAME
name

Version control your Modulefiles using Git

The Modules concept is a great way to manage versions of tools on a common server, but managing the Modulefiles themselves is error-prone when not controlled using a SCM like Git.

Goals
  • To be able to create, edit, and test Modulefiles without the risk of breaking other users.
  • To be able to track changes to the system-wide Modulefiles using Git.
  • To enable testing of new tool versions (with their associated Modulefiles) before making the new version generally available (since the new Modulefile will not be public until pushed).
Assumptions

Details are tweakable via TCL variables

  • You have Environment Modules version 4.1 or later installed on your system, and Git version 2.4 or later.

  • You have a Unix user named modules that exists only for managing the Modulefiles, and controlling updates to them.

  • The path /home/modules/modulefiles is in your modulerc file:

    module use --append /home/modules/modulefiles
    
  • Other Unix users (not named modules) use the modules from /home/modules/modulefiles.

Principles of Operation

First we create a git repo for the Modulefiles.

Then we install a Modulefile named localmodules that, when loaded, switches MODULEPATH to a locally-created git clone of the Modulefiles. When unloaded, it switches MODULEPATH back to the default.

After this, any time a user wants to edit the Modulefiles, he works in his local git repo. After editing, testing, and commiting to the local git repo, git push updates the master repo, which (assuming the user knows the password for user modules) automatically updates /home/modules/modulefiles.

Implementation
localmodules
#%Module4.1
##
## When loaded, use a local git repo for our Modulefiles,
## instead of the system-wide location that is typically used.
##
## This is useful for editing and testing Modulefiles.
##
## Tune to your system:
## $specialuser, $localmoddir, $globalmodfetch, $globalmodpush
##
## Author: Scott Johnson <scottjohnsoninsf@gmail.com>
##
## Originally developed at:
## github.com/scottj97/environment-modules-in-git


eval set [array get env HOME]

# Special Unix username that owns the master Modulefiles repo
set specialuser modules

# Where each user's local copy should go:
set localmoddir $HOME/modulefiles

# Where `git fetch` can find the master repo.
# This must be a filesystem path, since it will also be used by Modules:
set globalmodfetch /home/modules/modulefiles

# Where `git push` should write to the master repo:
set globalmodpush ssh://modules@localhost/home/modules/modulefiles



proc ModulesHelp {} {
   global localmoddir
   puts stderr "localmodules: switch to local Git repo for Modulefiles\n"
   puts stderr {This is useful for editing and testing Modulefiles.}
   puts stderr {Usage:}
   puts stderr {   $ module load localmodules}
   puts stderr "Then edit and test modulefiles in $localmoddir"
   puts stderr {When complete, git commit and push, then}
   puts stderr {   $ module unload localmodules}
}

module-whatis   {switch MODULEPATH to local git repo}

# Runs `system` and dies if error code is nonzero
proc safeSystem cmd {
   set retcode [system $cmd]
   if {[expr {$retcode != 0}]} {
      error "`$cmd` returned non-zero exit code: $retcode"
   }
}

# Make sure $localmoddir is what we expect, so we don't clobber
# anybody's work if they happen to have something unexpected here
proc ensureProperLocalmoddir {} {
   global localmoddir
   global globalmodfetch
   global globalmodpush

   # Make sure it's a directory
   if {![file isdirectory $localmoddir]} {
      error "a file named $localmoddir already exists, and\
         I don't want to clobber it"
   }

   # Make sure it has the expected .git remote setup
   if {![file isdirectory [file join $localmoddir .git]]} {
      error "expected git repo inside $localmoddir, found none"
   }
   safeSystem "if \[ `git -C $localmoddir remote get-url origin` !=\
      \"$globalmodfetch\" ]; then exit 1; fi"
   safeSystem "if \[ `git -C $localmoddir remote get-url --push origin` !=\
      \"$globalmodpush\" ]; then exit 1; fi"
}

# No $localmoddir exists, so run `git clone` to create
proc createLocalmoddir {} {
   global localmoddir
   global globalmodfetch
   global globalmodpush

   safeSystem "git clone $globalmodfetch $localmoddir"
   safeSystem "git -C $localmoddir remote set-url --push origin $globalmodpush"
}

proc checkRepoStatus {} {
   global localmoddir
   safeSystem "git -C $localmoddir remote update"
   safeSystem "git -C $localmoddir status"
}

# Special modules user not allowed to load or unload this.
# Why? Because it would defeat the purpose of tracking changes, if the
# changes were committed by this anonymous special user.
eval set [array get env USER]
if {$USER == $specialuser} {
   error "special user $specialuser should not load this module"
}

# create directory if necessary
if [module-info mode load] {
   if {![file exists $localmoddir]} {
      createLocalmoddir
   }
   ensureProperLocalmoddir
}

## These two work for load, but not for unload
## (the $globalmodfetch doesn't get put back in):
##   remove-path MODULEPATH $globalmodfetch
##   append-path MODULEPATH $localmoddir

## These two work for load, but not for unload
## (the $globalmodfetch doesn't get put back in):
##   module unuse $globalmodfetch
##   module use --append $localmoddir

## This method assumes that $MODULES_REPO is part
## of MODULEPATH, e.g. in your modulerc:
##   setenv MODULES_REPO /home/modules/modulefiles
##   module use /\$MODULES_REPO


if [module-info mode load] {
   setenv MODULES_REPO $localmoddir
}
if [module-info mode unload] {
   # unsetenv gets converted to setenv since we're unloading
   unsetenv MODULES_REPO $globalmodfetch
}

if [module-info mode load] {
   puts stderr "\nSwitched to local modulefiles in $localmoddir"
   puts stderr {When editing and testing complete, git commit and push, then:}
   puts stderr "   $ module unload localmodules\n"
   checkRepoStatus
}
Installation

First convert the existing Modulefiles into a git repo at /home/modules/modulefiles, as user modules:

cd /home/modules/modulefiles
git init
git add .
git commit -m 'Initial checkin of existing Modulefiles'
# Enable updates when receiving pushes:
git config --local receive.denyCurrentBranch updateInstead

Edit your global $MODULESHOME/init/modulerc file to use the new env var MODULES_REPO instead of hard-coding the path (requires Modules 4.1). Your modulerc should have:

setenv MODULES_REPO /home/modules/modulefiles
module use /\$MODULES_REPO

(The extra slash required before $MODULES_REPO is a bug to be fixed in 4.2.3.)

Copy the localmodules file from the Modules source tree to your repo:

cd /home/modules/modulefiles
curl --output localmodules https://raw.githubusercontent.com/cea-hpc/modules/master/doc/example/modulefiles-in-git/modulefiles/localmodules

Edit paths in the top of localmodules, if your installation differs from the assumptions, then:

git add localmodules
git commit -m 'Add localmodules from github.com/cea-hpc/modules'
Usage example

As a regular user (i.e. anyone but user modules):

module load localmodules
cd $HOME/modulefiles

Edit, test, then:

git commit -am 'Make some edits'
git push
module unload localmodules

After a successful push and unload, it is safe to delete your local $HOME/modulefiles directory if you wish.

Make defined modulepaths persist over sudo

When running a command as another user with sudo, current user environment is most of the time flushed for security concerns. As a result, if one would like to use the modulecmd.tcl script in such context, an error is returned as modulecmd.tcl does not find modulepath defined (MODULEPATH variable is not set). Following recipe describes how to ensure the default modulepaths are set every time the modulecmd.tcl script is run.

Implementation

Every time the modulecmd.tcl script is run, it evaluates during its start-up phase a global RC file following the same kind of evaluation than for modulefiles.

To ensure modulepaths are always defined, a check could be added in this global RC file to verify at least one modulepath is set (thanks to the is-used Tcl modulefile command). If no modulepath is found set, the .modulespath configuration file, which contains the default modulepaths, can be parsed to enable on the fly the default modulepaths (with module use Tcl modulefile command).

Global RC file
#%Module

# ensure MODULEPATH is always defined, use content of .modulespath config file
# to initialize it if not defined
if {![is-used] && [file readable /usr/share/Modules/init/.modulespath]} {
    set fid [open /usr/share/Modules/init/.modulespath r]
    set fdata [split [read $fid] \n]
    close $fid
    foreach fline $fdata {
        if {[regexp {^\s*(.*?)\s*(#.*|)$} $fline match patharg] == 1\
            && $patharg ne {}} {
            eval module use --append [split $patharg :]
        }
    }
}

Compatible with Modules v4.1+

Installation

Copy the global RC file of this recipe in the configuration directory:

$ cp example/modulepaths-persist-over-sudo/rc /usr/share/Modules/etc/

The location of the .modulespath file defined in the proposed RC script should be adapted to reflect the location where this file is installed on your setup.

Usage example

Without the proposed RC file installed, MODULEPATH environment variable is lost through the sudo call:

$ sudo $MODULES_CMD bash avail >/dev/null
ERROR: No module path defined

Once RC file is installed, flushed MODULEPATH is restored on the fly based on .modulespath configuration file:

$ sudo $MODULES_CMD bash use >/dev/null
Search path for module files (in search order):
  /usr/share/Modules/modulefiles
  /etc/modulefiles
  /usr/share/modulefiles

Thus available modulefiles are found again:

$ sudo $MODULES_CMD bash avail >/dev/null
--------------- /usr/share/Modules/modulefiles ---------------
dot  module-git  module-info  modules  null  use.own

Testing Modulefiles

The following is an example for a ModulesTest proc of a Modulefile and its output. It checks whether the TESTDIR is a directory, checks that it can enter it, and whether a file TESTFILE can successfully be created there.

This code gets executed when you use the test command.

Code
test_dir_and_file
#%Module1.0 # -*- mode: tcl; -*-

proc ModulesTest { } {
    set retcode 1  ;# default: 1 meaning PASS

    puts stderr "Running ModulesTest for directory existence..."
    if { [file isdirectory $::env(TESTDIR)] } {
        puts stderr "Is a directory: $::env(TESTDIR)"
    } else {
        puts stderr "ERROR: Is not a directory: $::env(TESTDIR)"
        set retcode 0
    }
    puts stderr "Running ModulesTest for directory existence...done"

    puts stderr "Running ModulesTest for directory permissions..."
    set cmd { cd $::env(TESTDIR) }
    if { [catch $cmd errmsg] } {
        puts stderr "ERROR: Was not able to enter directory $::env(TESTDIR): ${errmsg}"
        set retcode 0
    } else {
        puts stderr "Was able to enter directory $::env(TESTDIR)"
    }
    puts stderr "Running ModulesTest for directory permissions...done"

    puts stderr "Running ModulesTest for file creation..."
    set cmd { open $::env(TESTFILE) w }
    if { [catch $cmd errmsg] } {
        puts stderr "ERROR: Was not able to create file $::env(TESTFILE): ${errmsg}"
        set retcode 0
    } else {
        puts stderr "Was able to create file $::env(TESTFILE)"
    }
    puts stderr "Running ModulesTest for file creation...done"

    return ${retcode}
}

setenv TESTDIR  /tmp/$::env(USER)/testdir
setenv TESTFILE $::env(TESTDIR)/testfile
Usage example

Enable the modulepath where the example modulefiles are located:

$ module use example/test-modulefiles/modulefiles

Run the test both with the test directory not existing and existing:

$ module test test_dir_and_file
-------------------------------------------------------------------
Module Specific Test for .../modulefiles/test_dir_and_file:

Running ModulesTest for directory existence...
ERROR: Is not a directory: /tmp/testuser/testdir
Running ModulesTest for directory existence...done
Running ModulesTest for directory permissions...
ERROR: Was not able to enter directory /tmp/testuser/testdir: couldn't change working directory to "/tmp/testuser/testdir": no such file or directory
Running ModulesTest for directory permissions...done
Running ModulesTest for file creation...
ERROR: Was not able to create file /tmp/testuser/testdir/testfile: couldn't open "/tmp/testuser/testdir/testfile": no such file or directory
Running ModulesTest for file creation...done
Test result: FAIL
-------------------------------------------------------------------
$ mkdir /tmp/$USER/testdir
$ module test test_dir_and_file
-------------------------------------------------------------------
Module Specific Test for .../modulefiles/test_dir_and_file:

Running ModulesTest for directory existence...
Is a directory: /tmp/testuser/testdir
Running ModulesTest for directory existence...done
Running ModulesTest for directory permissions...
Was able to enter directory /tmp/testuser/testdir
Running ModulesTest for directory permissions...done
Running ModulesTest for file creation...
Was able to create file /tmp/testuser/testdir/testfile
Running ModulesTest for file creation...done
Test result: PASS
-------------------------------------------------------------------

Tips for Code Reuse in Modulefiles

Although Modules allow one to manage many packages and versions of packages on a system, managing the modulefiles themselves can become error prone, especially since the differences between modulefiles for different versions of the same package are often rather small. This can lead to issues with the consistency of the module definitions.

E.g., let us say you have a package foo, version 1.0 with a corresponding modulefile. A bit later, foo version 2.0 comes out, and you add a modulefile for that, likely copying the 1.0 version and editing a few lines. Then a bug is discovered in the version 1.0 modulefile, e.g. an environment variable that would be useful in some cases was omitted, or a typo in the help function. The version 1.0 modulefile is fixed, but did you remember to fix the 2.0 modulefile which, since it was created by copying the version 1.0 modulefile, likely has the same error?

This page includes some tips to reduce the amount of redundant code in your modulefiles (i.e. increase the amount of code reuse) so that they are easier to manage and more consistent.

A Simple Example

We return to our "foo" example. A fairly traditional set up would have a "foo" directory somewhere under your MODULEPATH with modulefiles 1.0 and 2.0 underneath it. Each of 1.0 and 2.0 will likely be largely the same, having basically the same help text, whatis, and variables set, with only some changes to some text and paths to reflect the version difference. Example code for this and other cases discussed in this document can be found in the "doc/example/tips-for-code-reuse" subdirectory of this package. The modulefiles for this simple example start in the "foo" subdirectory. For example, the version 1.0 modulefile might look something like

#%Module1.0
##
## foo

proc ModulesHelp { } {
   puts stderr "
FooA: A simple example of modulefile code reuse
Version 1.0

blah, blah, blah
"
}
module-whatis "foo version 1.0"

conflict foo
prepend-path PATH /software/foo/1.0/bin
prepend-path MANPATH /software/foo/1.0/share/man
prepend-path LD_LIBRARY_PATH /software/foo/1.0/lib

Although the above is simple enough, there is still much redundancy between the version 1.0 and 2.0 files, and we do not bother showing the file for 2.0 because it is so similar (only 5 chars change between the 1.0 and 2.0 versions, basically all the "1.0" strings become "2.0"). The command "module avail foo" shows versions 1.0 and 2.0, and loading either will set the environmental variables PATH, MANPATH, and LD_LIBRARY_PATH appropriately, conflict with itself (so only one version of foo can be loaded at a time), and define the help and whatis texts.

To refactor this to increase code reuse, we copy one of the original modulefiles to "common", and change all the references to the version number to a "$version" variable. To avoid confusion with the previous version, we change the package name from "foo" to "fooA", and the new versions can be found in the "fooA" subdirectory of "doc/example/tips-for-code-reuse". After adding some comments, etc, the common module becomes

#Common modulefile for fooA
#Expects the following variables to have been set
#   version: the version of fooA


proc ModulesHelp { } {
   global version
   puts stderr "
FooA: A simple example of modulefile code reuse
Version $version

This is a simple example of code reuse in modulefiles.
We have a couple versions of fooA, and the only differences
in what the modulefiles for the different fooA versions do
is that some paths include the version number.

"
}
module-whatis "fooA version $version"
    
conflict fooA
set rootdir /software/fooA/$version
prepend-path PATH $rootdir/bin
prepend-path MANPATH $rootdir/share/man
prepend-path LD_LIBRARY_PATH $rootdir/lib

We then create a pair of small stub files to replace "1.0" and "2.0". These simply just set the version variable appropriately, and then "source" the "common" file. For "1.0", the file would look like

#%Module1.0
set version 1.0

set moduledir [file dirname $ModulesCurrentModulefile]
source $moduledir/common

A similar file would be created for "2.0", just changing the version number in the "set version" line. The "set moduledir" line sets the Tcl variable moduledir to contain the name of the directory in which the final modulefile (i.e. "1.0") is located, so we can find the "common" file.

The common file then handles all the work of defining the PATH, MANPATH, and LD_LIBRARY_PATH environmental variables, using the value of the Tcl variable "version" passed to it by the stub file. It also handles defining the help procedure and the whatis text, and the conflict with itself.

Note that the "common" file does NOT start with the Modules magic "#%Module1.0"; this will keep "common" from showing up in "module avail fooA". The "1.0" and "2.0" files do need to start with the magic "#%Module1.0" tag so the module command will "see" them. Because of this, the "module avail fooA" command will just show the 1.0 and 2.0 versions as expected.

The files for this example are in the "doc/example/tips-for-code-reuse/fooA" directory.

A Simple Example, revisited

The "fooA" case above is fairly common, and we can actually improve upon what we did above. To avoid confusion, we will repeat using the package name "fooB", and the files for this example will be in the "doc/example/tips-for-code-reuse/fooB" directory.

Using introspection in the modulefiles, we can get the version number of fooB from the name of the modulefile. So we add code to the top of "common" to default the version variable from the modulename.

We then copy the "1.0" stub modulefile to ".generic", and remove the line which sets the version. Because is starts with a leading ".", the generic modulefile will not be displayed in "module avail" and such. Since this generic modulefile is now version independent, we can replace "1.0" and "2.0" with symlinks to the .generic file.

The new common file looks like

#Common modulefile for fooB
#Expects the following variables to have been set
#   version: the version of fooB, defaults to last component of module tag

if [info exists version]==0 {
   set version [file tail [module-info version [module-info name] ] ]
}

proc ModulesHelp { } {
   global version
   puts stderr "
FooB: A simple example of modulefile code reuse, revisited
Version $version

This our second visit to simple example of code reuse in modulefiles.
Because the all of the differences between the different fooB versions
modulefiles is contained in the version number, we replace the stub
modulefiles for the two versions with symlinks to a generic version
file, and infer the version from the tag given to the module command.

The generic modulefile, .generic, does not appear in 'module avail' 
commands because of the leading period (.).  Indeed, this generic modulefile
does is not even 'bar' specific, and typically we actually put the file
in an utilities directory outside the MODULEPATH and symlink to it from
multiple packages.

"
}
module-whatis "fooB version $version"
    
conflict fooB
set rootdir /software/fooB/$version
prepend-path PATH $rootdir/bin
prepend-path MANPATH $rootdir/share/man
prepend-path LD_LIBRARY_PATH $rootdir/lib

The .generic stub file looks like

#%Module######################
##
## generic modulefile, 
##
## This just sources the file common in the same directory
##
## Usage:
## Just symlink this file to .generic in the directory with common, and
## then make symlink to .generic for all versions of the app

set moduledir [file dirname $ModulesCurrentModulefile]
source $moduledir/common

Again, the common file handles setting the environmental variables PATH, MANPATH, and LD_LIBRARY_PATH, using the Tcl variable version which was defaulted from modulename. This works even in the case where the user does not specify the full module path, and the modulecmd defaults the version (e.g. if the user types "module load fooB" without specifying the version of fooB.) The common file also handles defining the help procedure and whatis text. When the command "module avail fooB" is issued, the common file does not get listed (because it does not start with the magic "#%Module1.0" tag), nor does the .generic file get listed (because it starts with a period (".")), but the two 1.0 and 2.0 symlinks do get listed, just as one wants.

This replaces a file for each version of fooB with one common file doing all the work, one generic file, and a bunch of symlinks. And the .generic file is not even specific to fooB. Indeed, at our site, we put the generic modulefile in an "utilities" directory outside of the MODULEPATH, and just symlink it to ".generic" in each application directory, and then symlink the versions to this symlinked ".generic". So we end up with one "common" file for each application, one shared generic modulefile, and a bunch of symlinks.

A More Complicated Example

Although the simple cases like the "foo" example above are not uncommon, many packages are more complicated. We now consider the fictitious "bar" package (example modulefiles in "example/tips-for-code-reuse/bar" directory). This is admittedly a contrived example, but it displays some of the ways in which we can modify the above simple cases to handle the more complicated needs of some packages. Our "bar" package has the follow characteristics:

  • We have two versions of "bar" built, "1.0" and "2.0"
  • For each bar version, we have builds for three different threading models: nothreads, pthreads, and openmp.
  • We expect users to use commands specifying both the bar version and the threading model, e.g. "module load fooB/1.0/pthreads" or "module load fooB/2.0/openmp"
  • The path to the installation directories include both the version number of "bar" and the threading model
  • The package requires the environmental variable BAR_LICENSE_FILE to be set appropriately
  • All builds of bar version 1.0 use one license file which is different than that used by bar version2.0
  • Bar 2.0 nothreads and openmp builds use the same license file, with a completely different name than that used by bar version 1.0.
  • The bar 2.0 pthreads build uses its very own license file with a very different filename than those used by bar version 1.0 or the other threading models of version 2.0.
  • The "nothreads" builds have a prerequisite on "fooB", with bar 1.0 wanting fooB version 1.1, and bar 2.0 wanting fooB version 3.2

Even with the above exceptions, there are still more similarities than differences between the various modulefile definitions. Like in the "fooA" case, we will have a "common" script that does almost all the work, and stub files for each of the variants, but in this case the stub files are expected to define some more variables. Our "common" file, which can be found in the "example/tips-for-code-reuse/bar" directory, looks like name "fooB", and the files for this example will be in the

#Common modulefile for bar
#Expects the following variables to have been set
#   version: the version of bar, 
#      defaults to last component of module tag
#   threadingmodel: one of 'nothreads', 'openmp' or 'pthreads'
#   licensefile: or will default based on version

if [info exists version]==0 {
   set version [file tail [module-info version [module-info name] ] ]
}

#Default to nothreads
if [info exists threadingmodel]==0 {
   set threadingmodel nothreads
}

#Default licensefile based on version
if [info exists licensefile]==0  {
   if [string equal $version 1.0] {
      set licensefile /somepath/to/version1/licenseFile.lic
   } else {
      set licensefile /a/completely/different/licenseFile.lic
   }
}

proc ModulesHelp { } {
   global version threadingmodel licensefile

   set threadstr $threadingmodel
   if [ string equal $threadingmodel nothreads ] {
      set threadstr {no threading support}
   }
   puts stderr "
Bar: Not so simple modulefile example
Version $version
Threading Model: $threadstr

This is a more complicated example of code reuse in modulefiles.
We have multiple versions of bar on the system, and each version
comes with multiple variants for different threading support modules.
Plus we assume that the env var BAR_LICENSE_FILE needs to be set
differently depending on the bar version.

Using license file: $licensefile

"
}
module-whatis "bar version $version with threading $threadingmodel"
    
conflict bar
set rootdir /software/bar/$version/$threadingmodel
prepend-path PATH $rootdir/bin
prepend-path MANPATH $rootdir/share/man
prepend-path LD_LIBRARY_PATH $rootdir/lib
setenv BAR_LICENSE_FILE $licensefile

Here we have extended the parameters which are allowed to be passed in from the build specific "stub" files; in addition to the version of "bar", the stub files are expected to have set the variables "threadingmodel" and optionally "licensefile". If "licensefile" was not set, the common script will default it based on the version of "bar". The rest of the "common" file is similar to the "fooA" case, except that we use both "version" and "threadingmodel" in setting the paths, and now define BAR_LICENSE_FILE based on "licensefile". Again, almost all the work is done in the common file, including setting the relevant environmental variables, defining the help procedure and whatis text, and preventing multiple versions of bar being loaded at the same time.

We now create stubfiles for each of the three threading models underneath directories for each bar version. These can all be found under the "example/tips-for-code-reuse/bar" directory. The one for bar 1.0 and openmp looks like

#%Module1.0
set version 1.0
set threadingmodel openmp

set moduledir [file dirname $ModulesCurrentModulefile]
source $moduledir/../common

The pthreads version is almost identical, just setting threadingmodel to "pthreads" instead of "openmp". The "openmp" build for bar version 2.0 is also very similar, differing only in value "version" is set to. In all three cases, these stubfiles are basically the same as those used in the "fooA" example; we set a couple of Tcl variables (version and threadingmodel), and then source the common file which does all the work. The licensefile variable is left unset so the common file will default it correctly based on the bar version.

The stub file for the pthreads build for bar version 2.0 is as below:

#%Module1.0
set version 2.0
set threadingmodel pthreads

set licensefile /special/license/file/for/bar/2.0/with/pthreads/license.lic

set moduledir [file dirname $ModulesCurrentModulefile]
source $moduledir/../common

This version is similar to the previous three, with the addition of explicitly setting the "licensefile" variable. This value will be used in the common file to set BAR_LICENSE_FILE, rather than the default which would have been set in the common file had no value been provided.

Finally, the two "nothreads" build also have a slightly different stub file than the other builds. The one for bar version 2.0 is shown below:

#%Module1.0
set version 2.0
set threadingmodel nothreads

prereq fooB/3.2

set moduledir [file dirname $ModulesCurrentModulefile]
source $moduledir/../common

Here we add a "prereq fooB/3.2" to require that the correct version of fooB was loaded. The bar version 1.0 stubfile is almost the same, just changing the setting of the version variable from 2.0 to 1.0, and changing the version of fooB needed as a prerequisite.

So instead of having six somewhat lengthy modulefiles (~40 lines each), one for each combination of bar version and threading model, we put almost all the work into a single, slightly longer (55 lines) common file, with six small (8 lines or less) stub files which mostly just set variables to define the behavior of the common file.

When customization is needed for a specific build, we showed two ways of accommodating such. First, for simple, more-or-less "one-off" cases, you can add some code to the appropriate "stubfiles" to handle the added complexity, like was done with the "prereq fooB" for the "nothreads" builds in the examples.

Alternatively, one can add some additional logic to the common script to accommodate the complexity, like was done with the license file differences between builds. This is the recommended way to handle complexity which is likely to recur in multiple places. Generally, this is done by:

  • adding a parameter to be passed from the stub file to the common file and setting appropriately in the stub files (e.g. licensefile in bar/2.0/pthreads)
  • adding logic to the common file to default it appropriately (e.g. licensefile for the other builds)

The above was only a simple example of what could be done, but it shows how modulefiles can leverage the fact that the modulefiles are evaluated in a full programming language to increase the amount of code re-use, which should reduce errors, improve consistency, and in general make things more manageable over the long run.

The tips given above should work with both 3.x and 4.x versions of the Tcl based environmental packages. They have been explicitly tested on versions 3.2.10 and 4.3.0.

Top priority environment variable values

Multiple modulefiles may alter the same environment variable. It may be wanted that among those modulefiles one should have the priority over the others and the value it sets should persist even if another modulefile loaded after attempts to alter the variable.

When using the setenv modulefile command, a top priority value should persist over later setenv tries. On append-path modulefile command, this top priority value should stay last position and for prepend-path modulefile command, value should stay first position.

Implementation

Top priority values are implemented by the use of a site-specific configuration that supersedes the definition of the setenv, append-path and prepend-path commands to introduce a --top argument. This argument enables a value set with this flag on to hold top priority and thus cannot be altered unless by another top priority value.

For append-path command, --top ensure value will stay at last position in path-like variable. Same goes for prepend-path where --top ensure first position in path-like variable.

siteconfig.tcl
# override 'setenv' procedure to add a '--top' optional argument
rename ::setenv ::__setenv
proc setenv {args} {
   set topPriority 0
   set errArgMsg "wrong # args: should be \"setenv ?--top? var val\""
   switch -- [llength $args] {
      {3} {
         if {[lindex $args 0] eq "--top"} {
            set topPriority 1
         } else {
            error $errArgMsg
         }
         set var [lindex $args 1]
         set val [lindex $args 2]
      }
      {2} {
         set var [lindex $args 0]
         set val [lindex $args 1]
      }
      default {
         error $errArgMsg
      }
   }

   if {$topPriority} {
      # define an helper variable to know a top-priority value has been set
      if {[currentMode] ne "display"} {
         __setenv MODULES_PRIORITY_$var $val
      }
      __setenv $var $val
   # set non-priority value only if no top priority value already set
   } elseif {![info exists ::env(MODULES_PRIORITY_$var)]} {
      __setenv $var $val
   }
}

# override 'setenv-un' procedure to interpret the '--top' optional argument
# when setenv is evaluated on an unload mode
rename ::setenv-un ::__setenv-un
proc setenv-un {args} {
   set topPriority 0
   set errArgMsg "wrong # args: should be \"setenv-un ?--top? var val\""
   switch -- [llength $args] {
      {3} {
         if {[lindex $args 0] eq "--top"} {
            set topPriority 1
         } else {
            error $errArgMsg
         }
         set var [lindex $args 1]
         set val [lindex $args 2]
      }
      {2} {
         set var [lindex $args 0]
         set val [lindex $args 1]
      }
      default {
         error $errArgMsg
      }
   }

   if {$topPriority} {
      # define an helper variable to know a top-priority value has been set
      if {[currentMode] ne "display"} {
         __setenv-un MODULES_PRIORITY_$var $val
      }
      __setenv-un $var $val
   # set non-priority value only if no top priority value already set
   } elseif {![info exists ::env(MODULES_PRIORITY_$var)]} {
      __setenv-un $var $val
   }
}

# override 'add-path' procedure to add a '--top' optional argument, which
# will benefit to the 'append-path' and 'prepend-path' modulefile commands
rename ::add-path ::__add-path
proc add-path {pos args} {
   set keep_top_priority 0
   set arglist [lsearch -all -inline -not -exact $args "--top"]
   lassign [eval parsePathCommandArgs "add-path" $arglist] separator\
      allow_dup idx_val var path_list

   # top priority asked
   if {[llength $arglist] != [llength $args]} {
      # record this top priority value in an helper variable
      __setenv MODULES_PRIORITY_${pos}_$var $path_list
   } elseif {[info exists ::env(MODULES_PRIORITY_${pos}_$var)]} {
      set keep_top_priority 1
   }

   # ensure top-priority value keeps first or last position by unloading it
   # priority new value addition, then restoring it
   if {$keep_top_priority} {
      eval __unload-path $var $::env(MODULES_PRIORITY_${pos}_$var)
   }

   eval __add-path $pos $arglist

   if {$keep_top_priority} {
      eval __add-path $pos $var $::env(MODULES_PRIORITY_${pos}_$var)
   }
}

rename ::unload-path ::__unload-path
proc unload-path {args} {
   set arglist [lsearch -all -inline -not -exact $args "--top"]
   lassign [eval parsePathCommandArgs "unload-path" $arglist] separator\
      allow_dup idx_val var path_list

   if {[llength $arglist] != [llength $args]} {
      # wipe priority helper variable when unloading top priority value
      switch -- [lindex [info level -1] 0] {
         {append-path}  { set pos "append" }
         {prepend-path} { set pos "prepend" }
      }
      if {[info exists pos]} {
         __setenv MODULES_PRIORITY_${pos}_$var $path_list
      }
   }

   eval __unload-path $arglist
}

Compatible with Modules v4.2

Installation

Create site-specific configuration directory if it does not exist yet:

$ mkdir /usr/share/Modules/etc

Then copy there the site-specific configuration script of this recipe:

$ cp example/top-priority-values/siteconfig.tcl /usr/share/Modules/etc/

Note

Defined location for the site-specific configuration script may vary from one installation to another. To determine the expected location for this file on your setup, check the value of the siteconfig option on Modules version 4.3 or above:

$ module config siteconfig

On older version of Modules, check the modulecmd.tcl script:

$ grep '^set g_siteconfig ' $MODULES_CMD
Usage example

With a bar/1 modulefile that sets environment variables in a regular way:

bar/1
#%Module
# define a regular value for variable
setenv TESTVAR value

# prepend a regular value to a path-like variable
prepend-path TESTPATH prevalue

# append a regular value to a path-like variable
append-path TESTPATH postvalue

And a foo/1 modulefile that sets the same variables than bar/1 but with the --top priority flag:

foo/1
#%Module
# define a value for variable holding top priority (not overwritten by non-top priority value)
setenv --top TESTVAR topvalue

# prepend a value to a path-like variable, value that stays first position
prepend-path --top TESTPATH topprevalue

# append a value to a path-like variable, value that stays last position
append-path --top TESTPATH toppostvalue

Enable the modulepath where the example modulefiles are located:

$ module use example/top-priority-values/modulefiles

Load foo/1 then bar/1 modulefiles and check value of the environment variable set:

$ module load foo/1 bar/1
$ echo $TESTVAR
topvalue
$ echo $TESTPATH
topprevalue:prevalue:postvalue:toppostvalue

Unload firstly loaded module matching name

Since Modules v4, unloading a given module name unloads lastly loaded module matching this given name. On Modules v3 the module selected for the unload was the firstly loaded not the lastly loaded. This recipe gives a way to restore the behavior of the v3 version.

Implementation

Starting version v4.3, an unload_match_order configuration option is introduced to control whether firstly loaded module or lastly loaded module should be selected for the unload. To select firstly loaded module:

$ module config unload_match_order returnfirst

For older v4 versions, a site-specific configuration script is proposed to select firstly loaded module matching name rather lastly loaded.

siteconfig.tcl
# override 'getLoadedMatchingName' procedure to set behavior argument to the
# 'returnfirst' value by default
rename ::getLoadedMatchingName ::__getLoadedMatchingName
proc getLoadedMatchingName {name {behavior returnfirst} {loading 0}} {
   return [__getLoadedMatchingName $name $behavior $loading]
}

Compatible with Modules v4.2

Installation (only for version older than v4.3)

Create site-specific configuration directory if it does not exist yet:

$ mkdir /usr/share/Modules/etc

Then copy there the site-specific configuration script of this recipe:

$ cp example/unload-firstly-loaded/siteconfig.tcl /usr/share/Modules/etc/

Note

Defined location for the site-specific configuration script may vary from one installation to another. To determine the expected location for this file on your setup, check the modulecmd.tcl script:

$ grep '^set g_siteconfig ' $MODULES_CMD
Usage example

With a bare foo/1 modulefile:

foo/1
#%Module

And a bare foo/2 modulefile:

foo/2
#%Module

Enable the modulepath where the example modulefiles are located:

$ module use example/unload-firstly-loaded/modulefiles

Load both foo modulefiles then attempt to unload foo name:

$ module load foo/1 foo/2
$ module list
Currently Loaded Modulefiles:
 1) foo/1   2) foo/2
$ module unload foo
$ module list
Currently Loaded Modulefiles:
 1) foo/2

Contributing

Thank you for considering contributing to Modules!

Support questions

Please use the modules-interest mailing list for questions. Do not use the issue tracker for this.

Asking for new features

Please submit your new feature wishes first to the modules-interest mailing list. Discussion will help to clarify your needs and sometimes the wanted feature may already be available.

Reporting issues

  • Describe what you expected to happen.
  • If possible, include a minimal, complete, and verifiable example to help us identify the issue.
  • Describe what actually happened. Run the module command in --debug mode and include all the debug output obtained in your report.
  • Provide the current configuration and state of your Modules installation by running the module config --dump-state command.
  • Provide the name and content of the modulefiles you try to manipulate.

Submitting patches

  • Whether your patch is supposed to solve a bug or add a new feature, please include tests. In case of a bug, explain clearly under which circumstances it happens and make sure the test fails without your patch.
  • If you are not yet familiar with the git command and GitHub, please read the don't be afraid to commit tutorial.
Start coding
Running the tests

Run the basic test suite with:

make test

This only runs the tests for the current environment. Travis-CI and AppVeyor will run the full suite when you submit your pull request.

Running test coverage

Generating a report of lines that do not have test coverage can indicate where to start contributing or what your tests should cover for the code changes you submit.

Run make test COVERAGE=y which will automatically setup the Nagelfar Tcl code coverage tool in your modules development directory. Then the full testsuite will be run in coverage mode and a modulecmd-test.tcl_m annotated script will be produced:

make test COVERAGE=y
# then open modulecmd-test.tcl_m and look for ';# Not covered' lines
Building the docs

Build the docs in the doc directory using Sphinx:

cd doc
make html

Open _build/html/index.html in your browser to view the docs.

Read more about Sphinx.

Coding conventions
  • Maximum line length is 78 characters

  • Use 3 spaces to indent code (do not use tab character)

  • Adopt Tcl minimal escaping style

  • Procedure names: lowerCameCase

  • Variable names: nocaseatall

  • Curly brace and square bracket placement:

    if {![info exists ::g_already_report]} {
       set ::g_already_report 1
    }
    
Emacs settings for coding conventions

This is an example emacs configuration that adheres to the first two coding conventions. You may wish to add this to your .emacs or .emacs.d/ to modify your tcl-mode:

(add-hook 'tcl-mode-hook
   (lambda ()
     (setq indent-tabs-mode nil)
     (setq tcl-indent-level 3)
     (setq tcl-continued-indent-level 3)
     (font-lock-add-keywords nil '(("^[^\n]\\{79\\}\\(.*\\)$" 1
                                    font-lock-warning-face prepend)))))

Submitting installation recipes

  • If you want to share your installation tips and tricks, efficient ways you have to write or organize your modulefiles or some extension you made to the module command please add a recipe to the cookbook section of the documentation.
  • Create a directory under doc/example and put there the extension code or example modulefiles your recipe is about.
  • Describe this recipe through a reStructuredText document in doc/source/cookbook. It is suggested to have an Implementation, an Installation and an Usage example sections in that document to get as much as possible the same document layout across recipes.
  • Submit a patch with all the above content.

Design notes

Developer notes on feature specifications and code design.

Advanced module version specifiers

Configuration
  • Introduce advanced_version_spec option name

    • off by default in v4 as previously soft@1 could be a module name

    • on by default in v5

    • in case extended_default is disabled

      • means short-hand notation cannot be used

        • for soft/1.1 query soft@1 returns nothing
    • in case implicit_default is disabled

      • means a default should be found over version range or list in selection context
Specification
  • Following Spack spec

  • same grammar used whatever the context

    • command-line or as argument to modulefile command (like command)
  • versions are specified whether

    • as specific words (separated by " ")
    • or as suffix to module name
  • change command specifications which were previously accepting list of modules

    • like module1 module2/vers module3

    • now these modules could express versions appended to their name with @

      • like module1@1.8 module2@vers module3
    • or these versions could be defined as words next to module name

      • like module1@1.8 module2 @vers module3
    • as a consequence, it denies use of @ in module names

    • such change requires an option to be enabled to avoid breaking compat

  • single version could be specified with soft@vers

    • which matches soft/vers modulefile
  • version could be specified as range

    • soft@:vers or soft@vers: or soft@vers1:vers2

    • Tcl-dictionarily determine what is between specified range

    • extended_default is always considered on when matching range

      • as 2.10 is included in @1:3 whatever the configuration
    • to be specified in a range or compared to a range, version major element should match an hexadecimal number

      • which also means be only composed by [0-9af] characters
      • for instance 10a, 1.2.3, 1.foo, 10.2.good are versions valid for range comparison
      • but 10g, default, foo.2, .1.3.4 are versions invalid for range comparison
    • a version range using in its definition version invalid for range comparison raises error

      • for instance @bar:foo
    • existing module versions invalid for range comparison are ignored

      • which means versions 10g, default, .1.13.4 or new are excluded from result for a @1.10: range query
    • when range is defined as @major:major.minor, version matching major version but above major.minor are excluded

      • for instance @1:1.10 will matches 1.0 and 1.8 but not 1.12
  • version could be specified as list

    • soft@vers,vers,vers

    • version specified could be text, like if symbolic version names are used

    • should benefit from extended default specification

      • to just express version with their major release number for instance
    • an empty string among list is considered as a specification error

      • for instance soft@vers,vers, or soft@vers,,vers
    • version specifier cannot mix list and range in the same expression (error raised elsewhere)

      • like soft@1.2,1.4:1.6,1.8
  • when using extended default syntax

    • version selection is performed same way for @vers than for /vers
    • described in extended default design
  • when icase is enabled for selection context and multiple directories match module name

    • for instance query is ICase@1.1,1.2,1.4 and following modules exist: ICASE/1.1, icase/1.2, iCaSe/1.3 and iCaSe/1.4
    • as no ICase directory exists, and a version in highest directory icase matches query (1.2), icase/1.2 is returned
    • if query is iCaSe@1.1,1.2,1.4, iCaSe/1.4 will be selected as iCaSe directory matches query module name
    • if query is ICase@1.1,1.4 or icase@1.1,1.4, as no version match in highest directory iCaSe/1.4 will be selected
  • in case of deep modulefiles

    • specified version is matched at the level directly under specified module name

      • not below levels

      • for instance soft@vers, will match soft/vers, not soft/deep/vers

      • to specify version for deep modules:"soft/deep@vers

      • to ease version comparison deep version cannot be specified after the @ character like soft@deep/vers

        • such specification will raise an error
  • advanced version specifier cannot be used with full path modulefile

    • when a full path modulefile is specified any advanced version set afterward is treated literally
    • for instance /path/to/modulefiles/mymod@1.2 will lead to the access of file mymod@1.2 in directory /path/to/modulefiles
  • in case version is specified multiple times

    • lastly mentioned (read from left to right) value is retained (it overwrite previous values)

    • like module@1.8 @2.0 or module@1.8@2.0

    • beware of version specified over a fully qualified modulefile like in soft/1.8@1.10" or "soft/1.8 @1.10

      • it resolves to soft/1.8/1.10 as advanced version specified is treated as an additional directory level
  • in case modulefile is named module@vers in filesystem

    • it is not found when option advanced_version_spec is enabled
    • as it is translated to module/vers
  • when special characters like ? or * are used in version name or value

    • they are evaluated as Tcl glob pattern on return all matching modules context

    • they are treated literally on single module selection and compatibility check context, no wildcard meaning is applied

    • like currently done when specifying module version on command-line

      • which leads to errors as no corresponding module is found:

        $ module load loc_dv6/*
        ERROR: Unable to locate a modulefile for 'loc_dv6/*'
        
  • if version range or list does not contain a defined default

    • in a selection context

      • highest version is returned if implicit_default is enabled

      • error returned if implicit_default is disabled

        • even if version range or list specifies non-existent modules and only one existent module
    • in a compatibility expression context

      • range or list is matched against loaded environment whether the implicit_default state
      • when no match found and evaluation are triggered, selection context applies
  • when version is specified over an alias

    • should proceed like for real modulefile

    • when alias equal to a bare module with no version

      • foo is alias on bar modulefile, bar is a file (not a dir with version modulefiles)
      • query alias@:2 should behave like query alias/2
    • when alias equal to a module/version modulefile

      • foo is alias on bar/3 modulefile
      • query alias@:2 should behave like query alias/2
  • Contexts where it could be used

Note

Advanced version specifier does not apply for the moment to the Module identification to select one module context. Adding support for this context will require a significant rework on module alias and symbolic version registering and resolving code.

  • impact of advanced version specifier implementation over code

    • question especially over auto_handling code like conflict and prereq handling

    • it should not impact triggers and actions

    • but consist in an overall change of procedures comparing queries against loaded environment

      • procedures like doesModuleConflict
    • also adapting getModules to restrict version possibilities to what has been specified

      • for instance with query soft@1,2 should only return versions matching
  • prereq/conflict persistency

    • LMPREREQ and LMCONFLICT content should reflect specified version constraint

    • it could be expressed in these variables somewhat like it is specified to the

      • prereq/conflict modulefile commands

      • for instance MODULES_LMPREREQ=soft/1.10&bar@1.8,1.10&foo@<2|foo@3<4

      • delimiters characters are :, & and |

        • so use of characters * , *@, , is not an issue
        • but for : which express version ranges it should be substituted to <
  • prereq/conflict specification

    • could consolidate different version set for same module on the same prereq/conflict list

      • to indicate a preferred order (if available)
      • like prereq foo@1.8 foo@1.10
      • or prereq foo @1.8 foo@1.10
    • also to trigger alternative requirement resolution in case first one failed

      • as each module version specification leads to one evaluation only

        • even if multiple modulefiles correspond to this specification

          • like prereq soft@1.8,1.9,1.10 will lead to soft/1.10 load
        • best candidate is chosen from matches

          • in case implicit_default is disabled an explicit default should be part of the list or range for the triggered evaluation to succeed
      • whereas prereq soft@1.8 soft@1.9 soft@1.10 will lead to a tentative load

        • of soft/1.8, then soft/1.9 if it failed then soft/1.8 if it also failed
    • one module version specification may match multiple loaded modules

      • like conflict soft@1.8,1.9,1.10 matches loaded modules soft/1.8 and soft/1.10
      • similar to situations where requirement or conflict is expressed over module generic name, like soft, and multiple versions of module are loaded
Corner cases
  • When icase is enabled on all contexts and multiple directories match same icase module name

    • for instance following modules exist: ICASE/1.1, icase/1.2, iCaSe/1.3 and iCaSe/1.4

    • a module avail -i icase will sort iCaSe/1.4 as the highest entry

    • however a module load -i icase@1.1,1.2,1.4 command will load icase/1.2

      • as icase directory matches query and version 1.2 is found in icase directory
    • but a module load -i icase@1.1,1.4 command will load iCaSe/1.4

      • as no version 1.1 nor 1.4 is found in icase directory

Extended default

Configuration
  • introduce extended_default option name

  • off by default in v4 as previously soft/1 was an error

  • on by default in v5, option could even disappear

  • set as a separate option than advanced_version_spec

    • as it affects also basic soft/vers version specification
    • seem easier to understand for user if concepts are distinguished
Specification
  • Take partial version identifier and returns matches

    • for soft/10.1.2.4 soft/10.1.2.3 soft/10.1.1
    • query soft/10 returns highest among 3
    • query soft/10.1 returns highest among 3
    • query soft/1 returns nothing
    • query soft/10.1.2 returns highest among soft/10.1.2.4 soft/10.1.2.3
  • In situation where soft/1.1(default) soft/1.2 soft/2.1 soft/2.2

    • query soft/1 returns soft/1.1
    • query soft/2 returns soft/2.2
  • Character considered as version number separator: .

    • list: . and -
    • - was also considered initially, but cannot determine in all case the highest version specified after this character (may find a hash name, strings like rc, alpha, beta, etc)
    • not possible with + as it is used by variant specification
  • Does not apply to the root part of module name

    • e.g. foo.2
  • If implicit_default is disabled

    • it makes extended_default inoperant if queried version does not include a defined default
    • even if only one modulefile matches query
    • with situation described above query soft/1 returns soft/1.1
    • but query soft/2 returns an error as no default is found among version 2 modulefiles
  • Contexts where it could be used

Insensitive case

Configuration
  • Introduce the icase option name

    • Which is made persistent through the MODULES_ICASE environment variable

    • Many people asked for separate options as applying an icase approach to a module loading context is not seen desired by everybody whereas it is in an module search context

    • Defined levels of enablement are:

      • never
      • search
      • always
    • icase option will be set by default to

      • never in v4 not to change existing behaviors
      • search in v5 as it seems to be a general improvement for everybody
    • A command-line switch --icase (short form -i) is added

      • Was there in Modules 3 (for search sub-command only)
      • When set, equals to an always icase mode
  • No immediate need for a --no-icase command-line switch

    • Combining configuration option and --icase command-line switch seems sufficient
Specification
  • When enabled, match query string in a case insensitive manner

    • query soFT returns soft, SOFT, soFT, SOft, sOft and so on
  • In case multiple files correspond to the same icase word

    • like soft, soFT, SoFt, SOFT filenames
    • query SOFT returns SOFT (exact match is returned among possibilities)
    • query SoFt returns SoFt (exact match is returned among possibilities)
    • query SOft returns soft (highest dictionarily-sorted match is returned among possibilities)
    • query soFt returns soft (highest dictionarily-sorted match is returned among possibilities)
  • When icase is enabled for search context it applies to

  • When icase is enabled for all context it applies to

    • search context like described above

    • module specification passed as argument in following contexts:

    • module alias and symbolic version resolution triggered by

      • module-info alias
      • module-info version
      • getPathToModule
      • isModuleEvaluated
    • the gathering of all module alias and symbolic version targeting a given module

      • this is processed by getAllModuleResolvedName procedure

      • which is called by

        • doesLoadingModuleMatchesName
        • cmdModuleLoad
  • Note that whatis specification passed as argument to the search sub-command is always matched in a case insensitive manner

Corner cases
  • When looking for the best match among loaded modules to select one module to unload, lastly loaded module, or firstly loaded module depending on unload_match_order configuration, will be returned

    • When insensitive case is enabled, last or first icase match will be returned even if an exact match is present among the loaded module list

    • This behavior has an impact in case multiple available modules correspond to the same insensitive case string

      • For instance iCaSe and IcAsE modules
  • When icase is enabled on all contexts and multiple directories match same icase module name

    • for instance following modules exist: ICASE/1.1, icase/1.2, iCaSe/1.3 and iCaSe/1.4

    • a module avail -i icase will sort iCaSe/1.4 as the highest entry

    • however a module load -i icase command will load icase/1.2

      • as icase directory matches query
    • and also module load -i ICase command will load icase/1.2

      • as no directory ICase exists, result is returned from highest directory: icase

Module selection contexts

Description of the different contexts where a module is expressed to get resolved to modulefiles.

Module identification to select one module
  • specification expresses exactly one module

  • must qualify version to select in case a module has multiple versions

  • expression may

    • be absolute like mod/version
    • be relative to the modulefile currently being evaluated like ./version or /version
    • refer to symbolic version or module alias
  • specification used to resolve argument passed to the following commands:

    • module-version
    • module-alias
    • module-virtual (cannot use symbolic version or module alias, should define an actual module)
    • module-info symbols
    • module-info version
    • module-info loaded
  • relies on getModuleNameVersion procedure to get absolute name

Module version specification to return all matching modules
  • specification expresses one or multiple modules

  • expression may

    • be absolute like mod/version
    • refer to implicit or explicitly defined default version like mod
    • refer to extended default version like mod/1 (to refer to mod/1.1.1)
    • refer to symbolic version or module alias
    • specify multiple versions as list (mod@1,2) or range (mod@:1 or mod@1:2)
  • all modules matching specification are retrieved with getModules

  • specification used to resolve argument passed to the following commands:

    • avail
    • paths
    • whatis
  • used to get all alias and symbolic version of loaded modules treated by:

    • list
  • used to get all existing aliases and symbolic version (no module specification) by:

    • aliases
  • used to get all existing modulefiles (no module specification) by:

    • search
Module version specification to select one module
  • specification expresses one or multiple modules

  • relies on the module version specification to return all matching modules

  • then among matching modules, one is selected with getPathToModule:

    • the one set has the default version (also called the explicit default version)
    • or the highest version in case no explicit default is found among results (also called the implicit default version)
    • nothing is returned in case no explicit default is found among matching modules and implicit default version mechanism is disabled
  • module selection may trigger another match retrieval

    • for instance in case selection leads to an alias that resolves to a bare module name
  • specification used to resolve argument passed to the following commands:

    • load
    • unload (with attempt to match against loaded modules to resolve argument)
    • switch
    • help
    • test
    • display
    • path
    • is-avail
  • used to resolve aliases or symbolic versions treated by following commands:

    • paths
    • search
Module version specification to check compatibility
  • specification expresses one or multiple modules

  • expression may

    • be absolute like mod/version
    • refer to implicit or explicitly defined default version like mod
    • refer to extended default version like mod/1 (to refer to mod/1.1.1)
    • refer to symbolic version or module alias
    • specify multiple versions as list (mod@1,2) or range (mod@:1 or mod@1:2)
  • version specification is matched against loaded or loading modules with variety of procedures:

    • getLoadedMatchingName
    • getLoadedWithClosestName
    • isModuleEvaluated
    • doesModuleMatchesName
    • doesLoadingModuleMatchesName
  • specification used to resolve argument passed to the following commands:

    • is-loaded
    • info-loaded
    • prereq
    • conflict
  • for prereq command when version specification does not have a match among loaded or loading modules

    • version specification is used to select one module per module specification
    • for instance prereq mod@:1.8 mod@1.10 triggers load tentative of default version among mod@:1.8 then if this tentative fails load of mod@1.10 is attempted
    • another example with prereq mod mod@1.10, which triggers load tentative of mod/default then if it fails load of mod@1.10 is attempted

License

Modules is distributed under the GNU General Public License version 2 (GPL v2).