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
19 changes: 14 additions & 5 deletions easybuild/framework/easyblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -1655,14 +1655,23 @@ def make_module_req(self):
)
self.module_load_environment.update(self.make_module_req_guess())

# Only inject path-like environment variables into module file
env_var_requirements = sorted([
(envar_name, envar_val) for envar_name, envar_val in self.module_load_environment.items()
# Expand and inject path-like environment variables into module file
env_var_requirements = {
envar_name: envar_val
for envar_name, envar_val in sorted(self.module_load_environment.items())
if envar_val.is_path
])
}
self.log.debug(f"Tentative module environment requirements before path expansion: {env_var_requirements}")
# TODO: handle non-path variables in make_module_extra
# in the meantime, just report if any is found
non_path_envars = set(self.module_load_environment) - set(env_var_requirements)
if non_path_envars:
self.log.warning(
f"Non-path variables found in module load environment: {non_path_envars}."
"This is not yet supported by this version of EasyBuild."
)

for env_var, search_paths in env_var_requirements:
for env_var, search_paths in env_var_requirements.items():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lexming Without the .items() this is horribly wrong, no? How did it pass CI in the previous PR...

Copy link
Contributor Author

@lexming lexming Jan 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

currently env_var_requirements is a list of tuples, this PR changes it to a dict

if self.dry_run:
self.dry_run_msg(f" ${env_var}:{', '.join(search_paths)}")
# Don't expand globs or do any filtering for dry run
Expand Down
1 change: 1 addition & 0 deletions easybuild/tools/modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ def __setattr__(self, name, value):
"""
if name != name.upper():
raise EasyBuildError(f"Names of ModuleLoadEnvironment attributes must be uppercase, got '{name}'")

try:
(contents, kwargs) = value
except ValueError:
Expand Down
24 changes: 23 additions & 1 deletion test/framework/easyblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,8 @@ def test_make_module_req(self):
full_path = os.path.join(eb.installdir, path, 'subpath')
os.makedirs(full_path)
write_file(os.path.join(full_path, 'any.file'), 'test')
txt = eb.make_module_req()
with eb.module_generator.start_module_creation():
txt = eb.make_module_req()
if get_module_syntax() == 'Tcl':
self.assertFalse(re.search(r"prepend-path\s+LD_LIBRARY_PATH\s+\$%s\n" % sub_lib_path,
txt, re.M))
Expand All @@ -603,6 +604,27 @@ def test_make_module_req(self):
txt, re.M))
self.assertFalse(re.search(r'prepend_path\("PATH", pathJoin\(root, "%s"\)\)\n' % sub_path_path, txt, re.M))

# Module load environement may contain non-path variables
# TODO: remove whenever this is properly supported, in the meantime check warning
eb.module_load_environment.NONPATH = ('non_path', {'var_type': "STRING"})
eb.module_load_environment.PATH = ['bin']
with self.mocked_stdout_stderr():
txt = eb.make_module_req()

self.assertEqual(list(eb.module_load_environment), ['PATH', 'LD_LIBRARY_PATH', 'NONPATH'])

if get_module_syntax() == 'Tcl':
self.assertTrue(re.match(r"^\nprepend-path\s+PATH\s+\$root/bin\n$", txt, re.M))
self.assertFalse(re.match(r"^\nprepend-path\s+NONPATH\s+\$root/non_path\n$", txt, re.M))
elif get_module_syntax() == 'Lua':
self.assertTrue(re.match(r'^\nprepend_path\("PATH", pathJoin\(root, "bin"\)\)\n$', txt, re.M))
self.assertFalse(re.match(r'^\nprepend_path\("NONPATH", pathJoin\(root, "non_path"\)\)\n$', txt, re.M))
else:
self.fail("Unknown module syntax: %s" % get_module_syntax())

logtxt = read_file(eb.logfile)
self.assertTrue(re.search(r"WARNING Non-path variables found in module load env.*NONPATH", logtxt, re.M))

# cleanup
eb.close_log()
os.remove(eb.logfile)
Expand Down
Loading