Skip to content

Commit bd78cd2

Browse files
authored
Merge pull request #3379 from boegel/module_version
skip lines that start with 'module-version' when determining whether a module exists in ModulesTool.exist
2 parents 7fd37c0 + 4b8137a commit bd78cd2

File tree

2 files changed

+65
-6
lines changed

2 files changed

+65
-6
lines changed

easybuild/tools/modules.py

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,7 @@ def mod_exists_via_show(mod_name):
547547
548548
:param mod_name: module name
549549
"""
550+
self.log.debug("Checking whether %s exists based on output of 'module show'", mod_name)
550551
stderr = self.show(mod_name)
551552
res = False
552553
# Parse the output:
@@ -555,13 +556,38 @@ def mod_exists_via_show(mod_name):
555556
# - Check first non-whitespace line for something that looks like an absolute path terminated by a colon
556557
mod_exists_regex = r'\s*/.+:\s*'
557558
for line in stderr.split('\n'):
559+
560+
self.log.debug("Checking line '%s' to determine whether %s exists...", line, mod_name)
561+
562+
# skip whitespace lines
558563
if OUTPUT_MATCHES['whitespace'].search(line):
564+
self.log.debug("Treating line '%s' as whitespace, so skipping it", line)
559565
continue
566+
567+
# if any errors occured, conclude that module doesn't exist
560568
if OUTPUT_MATCHES['error'].search(line):
569+
self.log.debug("Line '%s' looks like an error, so concluding that %s doesn't exist",
570+
line, mod_name)
561571
break
562-
if re.match(mod_exists_regex, line):
563-
res = True
572+
573+
# skip warning lines, which may be produced by modules tool but should not be used
574+
# to determine whether a module file exists
575+
if line.startswith('WARNING: '):
576+
self.log.debug("Skipping warning line '%s'", line)
577+
continue
578+
579+
# skip lines that start with 'module-' (like 'module-version'),
580+
# see https://github.com/easybuilders/easybuild-framework/issues/3376
581+
if line.startswith('module-'):
582+
self.log.debug("Skipping line '%s' since it starts with 'module-'", line)
583+
continue
584+
585+
# if line matches pattern that indicates an existing module file, the module file exists
586+
res = bool(re.match(mod_exists_regex, line))
587+
self.log.debug("Result for existence check of %s based on 'module show' output line '%s': %s",
588+
mod_name, line, res)
564589
break
590+
565591
return res
566592

567593
if skip_avail:
@@ -577,14 +603,19 @@ def mod_exists_via_show(mod_name):
577603

578604
mods_exist = []
579605
for (mod_name, visible) in mod_names:
606+
self.log.info("Checking whether %s exists...", mod_name)
580607
if visible:
581608
mod_exists = mod_name in avail_mod_names
582609
# module name may be partial, so also check via 'module show' as fallback
583-
if not mod_exists and maybe_partial:
610+
if mod_exists:
611+
self.log.info("Module %s exists (found in list of available modules)", mod_name)
612+
elif maybe_partial:
613+
self.log.info("Module %s not found in list of available modules, checking via 'module show'...",
614+
mod_name)
584615
mod_exists = mod_exists_via_show(mod_name)
585616
else:
586617
# hidden modules are not visible in 'avail', need to use 'show' instead
587-
self.log.debug("checking whether hidden module %s exists via 'show'..." % mod_name)
618+
self.log.info("Checking whether hidden module %s exists via 'show'..." % mod_name)
588619
mod_exists = mod_exists_via_show(mod_name)
589620

590621
# if no module file was found, check whether specified module name can be a 'wrapper' module...
@@ -593,14 +624,14 @@ def mod_exists_via_show(mod_name):
593624
# Lmod will report module wrappers as non-existent when full module name is used,
594625
# see https://github.com/TACC/Lmod/issues/446
595626
if not mod_exists:
596-
self.log.debug("Module %s not found via module avail/show, checking whether it is a wrapper", mod_name)
627+
self.log.info("Module %s not found via module avail/show, checking whether it is a wrapper", mod_name)
597628
wrapped_mod = self.module_wrapper_exists(mod_name)
598629
if wrapped_mod is not None:
599630
# module wrapper only really exists if the wrapped module file is also available
600631
mod_exists = wrapped_mod in avail_mod_names or mod_exists_via_show(wrapped_mod)
601632
self.log.debug("Result for existence check of wrapped module %s: %s", wrapped_mod, mod_exists)
602633

603-
self.log.debug("Result for existence check of %s module: %s", mod_name, mod_exists)
634+
self.log.info("Result for existence check of %s module: %s", mod_name, mod_exists)
604635

605636
mods_exist.append(mod_exists)
606637

test/framework/modules.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,34 @@ def test_exist(self):
310310
if self.modtool.__class__ != EnvironmentModulesC:
311311
self.assertEqual(self.modtool.exist(['Java/Alias', 'Java/NonExist']), [True, False])
312312

313+
# set 'module avail' cache entries to empty lists,
314+
# to enforce fallback to 'module show'
315+
import easybuild.tools.modules
316+
for key in easybuild.tools.modules.MODULE_AVAIL_CACHE:
317+
easybuild.tools.modules.MODULE_AVAIL_CACHE[key] = []
318+
319+
# clear 'module show' cache, to keep control below
320+
easybuild.tools.modules.MODULE_SHOW_CACHE.clear()
321+
self.assertEqual(self.modtool.exist(['Java/1.8', 'Java/1.8.0_181']), [True, True])
322+
323+
# mimic more verbose stderr output produced by old Tmod version,
324+
# including a warning produced when multiple .modulerc files are being picked up
325+
# see https://github.com/easybuilders/easybuild-framework/issues/3376
326+
ml_show_java18_stderr = '\n'.join([
327+
"module-version Java/1.8.0_181 1.8",
328+
"WARNING: Duplicate version symbol '1.8' found",
329+
"module-version Java/1.8.0_181 1.8",
330+
"-------------------------------------------------------------------",
331+
"/modulefiles/lang/Java/1.8.0_181:",
332+
"-------------------------------------------------------------------",
333+
])
334+
335+
# overwrite 'module show' cache entries with output that includes extra lines
336+
for key in easybuild.tools.modules.MODULE_SHOW_CACHE:
337+
easybuild.tools.modules.MODULE_SHOW_CACHE[key] = ml_show_java18_stderr
338+
339+
self.assertEqual(self.modtool.exist(['Java/1.8', 'Java/1.8.0_181']), [True, True])
340+
313341
reset_module_caches()
314342

315343
# what if we're in an HMNS setting...

0 commit comments

Comments
 (0)