Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/configure.rst
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ The valid attributes of a system are the following:
* ``modules_system``: The modules system that should be used for loading environment modules on this system (default :class:`None`).
Three types of modules systems are currently supported:

- ``tmod``: The classic Tcl implementation of the `environment modules <https://sourceforge.net/projects/modules/files/Modules/modules-3.2.10/>`__.
- ``tmod4``: The version 4 of the Tcl implementation of the `environment modules <http://modules.sourceforge.net/>`__.
- ``tmod``: The classic Tcl implementation of the `environment modules <https://sourceforge.net/projects/modules/files/Modules/modules-3.2.10/>`__ (versions older than 3.2 are not supported).
- ``tmod4``: The version 4 of the Tcl implementation of the `environment modules <http://modules.sourceforge.net/>`__ (versions older than 4.1 are not supported).
- ``lmod``: The Lua implementation of the `environment modules <https://lmod.readthedocs.io/en/latest/>`__.
* ``prefix``: Default regression prefix for this system (default ``.``).
* ``stagedir``: Default stage directory for this system (default :class:`None`).
Expand Down
50 changes: 40 additions & 10 deletions reframe/core/modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,8 @@ def is_module_loaded(self, name):
If module ``name`` refers to multiple real modules, this method will
return :class:`True` only if all the referees are loaded.
"""
return all(self._is_module_loaded(m) for m in self.resolve_module(name))
return all(self._is_module_loaded(m)
for m in self.resolve_module(name))

def _is_module_loaded(self, name):
return self._backend.is_module_loaded(Module(name))
Expand Down Expand Up @@ -375,34 +376,48 @@ def __str__(self):
class TModImpl(ModulesSystemImpl):
"""Module system for TMod (Tcl)."""

MIN_VERSION = (3, 2)

def __init__(self):
# Try to figure out if we are indeed using the TCL version
try:
completed = os_ext.run_command('modulecmd -V')
except OSError as e:
raise ConfigError(
'could not find a sane Tmod installation: %s' % e) from e
'could not find a sane TMod installation: %s' % e) from e

version_match = re.search(r'^VERSION=(\S+)', completed.stdout,
re.MULTILINE)
tcl_version_match = re.search(r'^TCL_VERSION=(\S+)', completed.stdout,
re.MULTILINE)

if version_match is None or tcl_version_match is None:
raise ConfigError('could not find a sane Tmod installation')
raise ConfigError('could not find a sane TMod installation')

self._version = version_match.group(1)
version = version_match.group(1)
try:
ver_major, ver_minor, *_ = [int(v) for v in version.split('.')]
except ValueError:
raise ConfigError(
'could not parse TMod version string: ' + version) from None

if (ver_major, ver_minor) < self.MIN_VERSION:
raise ConfigError(
'unsupported TMod version: %s (required >= %s)' %
(version, self.MIN_VERSION))

self._version = version
self._command = 'modulecmd python'
try:
# Try the Python bindings now
completed = os_ext.run_command(self._command)
except OSError as e:
raise ConfigError(
'could not get the Python bindings for Tmod: ' % e) from e
'could not get the Python bindings for TMod: ' % e) from e

if re.search(r'Unknown shell type', completed.stderr):
raise ConfigError(
'Python is not supported by this Tmod installation')
'Python is not supported by this TMod installation')

def name(self):
return 'tmod'
Expand Down Expand Up @@ -484,22 +499,37 @@ def emit_unload_instr(self, module):
class TMod4Impl(TModImpl):
"""Module system for TMod 4."""

MIN_VERSION = (4, 1)

def __init__(self):
self._command = 'modulecmd python'
try:
completed = os_ext.run_command(self._command + ' -V', check=True)
except OSError as e:
raise ConfigError(
'could not find a sane Tmod4 installation') from e
'could not find a sane TMod4 installation') from e
except SpawnedProcessError as e:
raise ConfigError(
'could not get the Python bindings for Tmod4') from e
'could not get the Python bindings for TMod4') from e

version_match = re.match('^Modules Release (\S+)\s+', completed.stderr)
version_match = re.match(r'^Modules Release (\S+)\s+',
completed.stderr)
if not version_match:
raise ConfigError('could not retrieve the TMod4 version')

self._version = version_match.group(1)
version = version_match.group(1)
try:
ver_major, ver_minor, *_ = [int(v) for v in version.split('.')]
except ValueError:
raise ConfigError(
'could not parse TMod4 version string: ' + version) from None

if (ver_major, ver_minor) < self.MIN_VERSION:
raise ConfigError(
'unsupported TMod4 version: %s (required >= %s)' %
(version, self.MIN_VERSION))

self._version = version

def name(self):
return 'tmod4'
Expand Down