Skip to content

Commit bb0a777

Browse files
committed
add 'shell_vars' option to modextravars to control resolution of shell variables
1 parent ad20bd0 commit bb0a777

File tree

2 files changed

+44
-14
lines changed

2 files changed

+44
-14
lines changed

easybuild/tools/module_generator.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ class ModuleGenerator:
137137
REGEX_SHELL_VAR = re.compile(rf'\$({REGEX_SHELL_VAR_PATTERN})')
138138
REGEX_QUOTE_SHELL_VAR = re.compile(rf'[\"\']\$({REGEX_SHELL_VAR_PATTERN})[\"\']')
139139

140+
# default options for modextravars
141+
DEFAULT_MODEXTRAVARS_PUSHENV = False
142+
DEFAULT_MODEXTRAVARS_SHELL_VARS = True
143+
140144
def __init__(self, application, fake=False):
141145
"""ModuleGenerator constructor."""
142146
self.app = application
@@ -430,24 +434,25 @@ def unpack_setenv_value(self, env_var_name, env_var_val):
430434
"""
431435
Unpack value that specifies how to define an environment variable with specified name.
432436
"""
433-
use_pushenv = False
437+
use_pushenv = self.DEFAULT_MODEXTRAVARS_PUSHENV
438+
shell_vars = self.DEFAULT_MODEXTRAVARS_SHELL_VARS
434439

435440
# value may be specified as a string, or as a dict for special cases
436441
if isinstance(env_var_val, str):
437442
value = env_var_val
438-
439443
elif isinstance(env_var_val, dict):
440-
use_pushenv = env_var_val.get('pushenv', False)
444+
use_pushenv = env_var_val.get('pushenv', self.DEFAULT_MODEXTRAVARS_PUSHENV)
445+
shell_vars = env_var_val.get('shell_vars', self.DEFAULT_MODEXTRAVARS_SHELL_VARS)
441446
try:
442447
value = env_var_val['value']
443-
except KeyError:
448+
except KeyError as err:
444449
raise EasyBuildError("Required key 'value' is missing in dict that specifies how to set $%s: %s",
445-
env_var_name, env_var_val)
450+
env_var_name, env_var_val) from err
446451
else:
447452
raise EasyBuildError("Incorrect value type for setting $%s environment variable (%s): %s",
448453
env_var_name, type(env_var_val), env_var_val)
449454

450-
return value, use_pushenv
455+
return value, use_pushenv, shell_vars
451456

452457
# From this point on just not implemented methods
453458

@@ -1060,12 +1065,13 @@ def set_environment(self, key, value, relpath=False):
10601065
self.log.info("Not including statement to define environment variable $%s, as specified", key)
10611066
return ''
10621067

1063-
set_value, use_pushenv = self.unpack_setenv_value(key, value)
1068+
set_value, use_pushenv, shell_vars = self.unpack_setenv_value(key, value)
10641069

10651070
if relpath:
10661071
set_value = os.path.join('$root', set_value) if set_value else '$root'
10671072

1068-
set_value = self.REGEX_SHELL_VAR.sub(r'$::env(\1)', set_value)
1073+
if shell_vars:
1074+
set_value = self.REGEX_SHELL_VAR.sub(r'$::env(\1)', set_value)
10691075

10701076
# quotes are needed, to ensure smooth working of EBDEVEL* modulefiles
10711077
set_value = quote_str(set_value, tcl=True)
@@ -1161,6 +1167,7 @@ class ModuleGeneratorLua(ModuleGenerator):
11611167

11621168
START_STR = '[==['
11631169
END_STR = ']==]'
1170+
CONCAT_STR = ' .. '
11641171

11651172
def __init__(self, *args, **kwargs):
11661173
"""ModuleGeneratorLua constructor."""
@@ -1529,18 +1536,19 @@ def set_environment(self, key, value, relpath=False):
15291536
self.log.info("Not including statement to define environment variable $%s, as specified", key)
15301537
return ''
15311538

1532-
set_value, use_pushenv = self.unpack_setenv_value(key, value)
1539+
set_value, use_pushenv, shell_vars = self.unpack_setenv_value(key, value)
15331540

15341541
if relpath:
15351542
set_value = self._path_join_cmd(set_value)
1536-
set_value = self.REGEX_QUOTE_SHELL_VAR.sub(r'os.getenv("\1")', set_value)
1543+
if shell_vars:
1544+
set_value = self.REGEX_QUOTE_SHELL_VAR.sub(r'os.getenv("\1")', set_value)
15371545
else:
1538-
lua_concat = ' .. '
1539-
set_value = self.REGEX_SHELL_VAR.sub(rf'{lua_concat}os.getenv("\1"){lua_concat}', set_value)
1540-
set_value = lua_concat.join([
1546+
if shell_vars:
1547+
set_value = self.REGEX_SHELL_VAR.sub(rf'{self.CONCAT_STR}os.getenv("\1"){self.CONCAT_STR}', set_value)
1548+
set_value = self.CONCAT_STR.join([
15411549
# quote any substrings that are not lua commands
15421550
quote_str(x) if not x.startswith('os.') else x
1543-
for x in set_value.strip(lua_concat).split(lua_concat)
1551+
for x in set_value.strip(self.CONCAT_STR).split(self.CONCAT_STR)
15441552
])
15451553

15461554
env_setter = 'pushenv' if use_pushenv else 'setenv'

test/framework/module_generator.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -983,6 +983,28 @@ def test_env(self):
983983
("/abspath/with/$VAR", True, 'setenv\tkey\t\t"/abspath/with/$::env(VAR)"\n', 'setenv("key", pathJoin("/", "abspath", "with", os.getenv("VAR")))\n'), # noqa
984984
("/abspath/$VAR/dir", False, 'setenv\tkey\t\t"/abspath/$::env(VAR)/dir"\n', 'setenv("key", "/abspath/" .. os.getenv("VAR") .. "/dir")\n'), # noqa
985985
("/abspath/$VAR/dir", True, 'setenv\tkey\t\t"/abspath/$::env(VAR)/dir"\n', 'setenv("key", pathJoin("/", "abspath", os.getenv("VAR"), "dir"))\n'), # noqa
986+
# modextravars defined with dicts
987+
({'value': 'value'}, False, 'setenv\tkey\t\t"value"\n', 'setenv("key", "value")\n'), # noqa
988+
({'value': 'value',
989+
'pushenv': True}, False, 'pushenv\tkey\t\t"value"\n', 'pushenv("key", "value")\n'), # noqa
990+
({'value': 'value',
991+
'pushenv': False}, False, 'setenv\tkey\t\t"value"\n', 'setenv("key", "value")\n'), # noqa
992+
({'value': "$VAR",
993+
'shell_vars': True}, False, 'setenv\tkey\t\t"$::env(VAR)"\n', 'setenv("key", os.getenv("VAR"))\n'), # noqa
994+
({'value': "$VAR",
995+
'shell_vars': True}, True, 'setenv\tkey\t\t"$root/$::env(VAR)"\n', 'setenv("key", pathJoin(root, os.getenv("VAR")))\n'), # noqa
996+
({'value': "$VAR",
997+
'shell_vars': False}, False, 'setenv\tkey\t\t"$VAR"\n', 'setenv("key", "$VAR")\n'), # noqa
998+
({'value': "$VAR",
999+
'shell_vars': False}, True, 'setenv\tkey\t\t"$root/$VAR"\n', 'setenv("key", pathJoin(root, "$VAR"))\n'), # noqa
1000+
({'value': "path/$VAR/dir",
1001+
'shell_vars': True}, False, 'setenv\tkey\t\t"path/$::env(VAR)/dir"\n', 'setenv("key", "path/" .. os.getenv("VAR") .. "/dir")\n'), # noqa
1002+
({'value': "path/$VAR/dir",
1003+
'shell_vars': True}, True, 'setenv\tkey\t\t"$root/path/$::env(VAR)/dir"\n', 'setenv("key", pathJoin(root, "path", os.getenv("VAR"), "dir"))\n'), # noqa
1004+
({'value': "path/$VAR/dir",
1005+
'shell_vars': False}, False, 'setenv\tkey\t\t"path/$VAR/dir"\n', 'setenv("key", "path/$VAR/dir")\n'), # noqa
1006+
({'value': "path/$VAR/dir",
1007+
'shell_vars': False}, True, 'setenv\tkey\t\t"$root/path/$VAR/dir"\n', 'setenv("key", pathJoin(root, "path", "$VAR", "dir"))\n'), # noqa
9861008
)
9871009
# test set_environment
9881010
for test_value, test_relpath, ref_tcl, ref_lua in collection:

0 commit comments

Comments
 (0)