@@ -1323,13 +1323,82 @@ class EnvironmentModules(EnvironmentModulesTcl):
13231323 MAX_VERSION = None
13241324 VERSION_REGEXP = r'^Modules\s+Release\s+(?P<version>\d\S*)\s'
13251325
1326+ def __init__ (self , * args , ** kwargs ):
1327+ """Constructor, set Environment Modules-specific class variable values."""
1328+ # ensure in-depth modulepath search (MODULES_AVAIL_INDEPTH has been introduced in v4.3)
1329+ setvar ('MODULES_AVAIL_INDEPTH' , '1' , verbose = False )
1330+ # match against module name start (MODULES_SEARCH_MATCH has been introduced in v4.3)
1331+ setvar ('MODULES_SEARCH_MATCH' , 'starts_with' , verbose = False )
1332+ # ensure no debug message (MODULES_VERBOSITY has been introduced in v4.3)
1333+ setvar ('MODULES_VERBOSITY' , 'normal' , verbose = False )
1334+ # make module search case sensitive (search is case insensitive by default since v5.0)
1335+ setvar ('MODULES_ICASE' , 'never' , verbose = False )
1336+ # disable extended default (introduced in v4.4 and enabled by default in v5.0)
1337+ setvar ('MODULES_EXTENDED_DEFAULT' , '0' , verbose = False )
1338+ # hard disable output redirection, output messages are expected on stderr
1339+ setvar ('MODULES_REDIRECT_OUTPUT' , '0' , verbose = False )
1340+ # make sure modulefile cache is ignored (cache mechanism supported since v5.3)
1341+ setvar ('MODULES_IGNORE_CACHE' , '1' , verbose = False )
1342+ # ensure only module names are returned on avail (MODULES_AVAIL_TERSE_OUTPUT added in v4.7)
1343+ setvar ('MODULES_AVAIL_TERSE_OUTPUT' , '' , verbose = False )
1344+ # ensure only module names are returned on list (MODULES_LIST_TERSE_OUTPUT added in v4.7)
1345+ setvar ('MODULES_LIST_TERSE_OUTPUT' , '' , verbose = False )
1346+
1347+ super (EnvironmentModules , self ).__init__ (* args , ** kwargs )
1348+
1349+ def check_module_function (self , allow_mismatch = False , regex = None ):
1350+ """Check whether selected module tool matches 'module' function definition."""
1351+ # Modules 5.1.0+: module command is called from _module_raw shell function
1352+ # Modules 4.2.0..5.0.1: module command is called from _module_raw shell function if it has
1353+ # been initialized in an interactive shell session (i.e., a session attached to a tty)
1354+ if self .testing :
1355+ if '_module_raw' in os .environ :
1356+ out , ec = os .environ ['_module_raw' ], 0
1357+ else :
1358+ out , ec = None , 1
1359+ else :
1360+ cmd = "type _module_raw"
1361+ out , ec = run_cmd (cmd , simple = False , log_ok = False , log_all = False , force_in_dry_run = True , trace = False )
1362+
1363+ if regex is None :
1364+ regex = r".*%s" % os .path .basename (self .cmd )
1365+ mod_cmd_re = re .compile (regex , re .M )
1366+
1367+ if ec == 0 and mod_cmd_re .search (out ):
1368+ self .log .debug ("Found pattern '%s' in defined '_module_raw' function." % mod_cmd_re .pattern )
1369+ else :
1370+ self .log .debug ("Pattern '%s' not found in '_module_raw' function, falling back to 'module' function" ,
1371+ mod_cmd_re .pattern )
1372+ super (EnvironmentModules , self ).check_module_function (allow_mismatch , regex )
1373+
13261374 def check_module_output (self , cmd , stdout , stderr ):
13271375 """Check output of 'module' command, see if if is potentially invalid."""
13281376 if "_mlstatus = False" in stdout :
13291377 raise EasyBuildError ("Failed module command detected: %s (stdout: %s, stderr: %s)" , cmd , stdout , stderr )
13301378 else :
13311379 self .log .debug ("No errors detected when running module command '%s'" , cmd )
13321380
1381+ def get_setenv_value_from_modulefile (self , mod_name , var_name ):
1382+ """
1383+ Get value for specific 'setenv' statement from module file for the specified module.
1384+
1385+ :param mod_name: module name
1386+ :param var_name: name of the variable being set for which value should be returned
1387+ """
1388+ # Tcl-based module tools produce "module show" output with setenv statements like:
1389+ # "setenv GCC_PATH /opt/gcc/8.3.0"
1390+ # "setenv VAR {some text}
1391+ # - line starts with 'setenv'
1392+ # - whitespace (spaces & tabs) around variable name
1393+ # - curly braces around value if it contain spaces
1394+ value = super (EnvironmentModules , self ).get_setenv_value_from_modulefile (mod_name = mod_name ,
1395+ var_name = var_name )
1396+
1397+ if value :
1398+ value = value .strip ('{}' )
1399+
1400+ return value
1401+
13331402
13341403class Lmod (ModulesTool ):
13351404 """Interface to Lmod."""
@@ -1340,7 +1409,6 @@ class Lmod(ModulesTool):
13401409 DEPR_VERSION = '7.0.0'
13411410 REQ_VERSION_DEPENDS_ON = '7.6.1'
13421411 VERSION_REGEXP = r"^Modules\s+based\s+on\s+Lua:\s+Version\s+(?P<version>\d\S*)\s"
1343- USER_CACHE_DIR = os .path .join (os .path .expanduser ('~' ), '.lmod.d' , '.cache' )
13441412
13451413 SHOW_HIDDEN_OPTION = '--show-hidden'
13461414
@@ -1356,7 +1424,14 @@ def __init__(self, *args, **kwargs):
13561424 setvar ('LMOD_EXTENDED_DEFAULT' , 'no' , verbose = False )
13571425
13581426 super (Lmod , self ).__init__ (* args , ** kwargs )
1359- self .supports_depends_on = StrictVersion (self .version ) >= StrictVersion (self .REQ_VERSION_DEPENDS_ON )
1427+ version = StrictVersion (self .version )
1428+
1429+ self .supports_depends_on = version >= self .REQ_VERSION_DEPENDS_ON
1430+ # See https://lmod.readthedocs.io/en/latest/125_personal_spider_cache.html
1431+ if version >= '8.7.12' :
1432+ self .USER_CACHE_DIR = os .path .join (os .path .expanduser ('~' ), '.cache' , 'lmod' )
1433+ else :
1434+ self .USER_CACHE_DIR = os .path .join (os .path .expanduser ('~' ), '.lmod.d' , '.cache' )
13601435
13611436 def check_module_function (self , * args , ** kwargs ):
13621437 """Check whether selected module tool matches 'module' function definition."""
@@ -1433,7 +1508,8 @@ def update(self):
14331508 # don't actually update local cache when testing, just return the cache contents
14341509 return stdout
14351510 else :
1436- cache_fp = os .path .join (self .USER_CACHE_DIR , 'moduleT.lua' )
1511+ suffix = build_option ('module_cache_suffix' ) or ''
1512+ cache_fp = os .path .join (self .USER_CACHE_DIR , 'moduleT%s.lua' % suffix )
14371513 self .log .debug ("Updating Lmod spider cache %s with output from '%s'" , cache_fp , cmd )
14381514 cache_dir = os .path .dirname (cache_fp )
14391515 if not os .path .exists (cache_dir ):
0 commit comments