Skip to content

Commit 4ac2f6d

Browse files
committed
support use of glob patterns for paths to files with external modules metadata
1 parent 825e22f commit 4ac2f6d

File tree

2 files changed

+46
-11
lines changed

2 files changed

+46
-11
lines changed

easybuild/tools/options.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1471,14 +1471,25 @@ def parse_external_modules_metadata(cfgs):
14711471
"""
14721472
Parse metadata for external modules.
14731473
1474-
:param cfgs: list of config files providing metadata for external modules
1474+
:param cfgs: list of (glob patterns for) paths to config files providing metadata for external modules
14751475
:return: parsed metadata for external modules
14761476
"""
1477+
if cfgs is None:
1478+
cfgs = []
1479+
1480+
# expand glob patterns, and report error for faulty paths
1481+
paths = []
1482+
for cfg in cfgs:
1483+
res = glob.glob(cfg)
1484+
if res:
1485+
paths.extend(res)
1486+
else:
1487+
# if there are no matches, we report an error to avoid silently ignores faulty paths
1488+
raise EasyBuildError("Specified path for file with external modules metadata does not exist: %s", cfg)
1489+
cfgs = paths
14771490

14781491
# use external modules metadata configuration files that are available by default, unless others are specified
14791492
if not cfgs:
1480-
cfgs = []
1481-
14821493
# we expect to find *external_modules_metadata.cfg files in etc/ on same level as easybuild/framework
14831494
topdirs = [os.path.dirname(os.path.dirname(os.path.dirname(__file__)))]
14841495

@@ -1502,14 +1513,11 @@ def parse_external_modules_metadata(cfgs):
15021513

15031514
parsed_metadata = ConfigObj()
15041515
for cfg in cfgs:
1505-
if os.path.isfile(cfg):
1506-
_log.debug("Parsing %s with external modules metadata", cfg)
1507-
try:
1508-
parsed_metadata.merge(ConfigObj(cfg))
1509-
except ConfigObjError as err:
1510-
raise EasyBuildError("Failed to parse %s with external modules metadata: %s", cfg, err)
1511-
else:
1512-
raise EasyBuildError("Specified path for file with external modules metadata does not exist: %s", cfg)
1516+
_log.debug("Parsing %s with external modules metadata", cfg)
1517+
try:
1518+
parsed_metadata.merge(ConfigObj(cfg))
1519+
except ConfigObjError as err:
1520+
raise EasyBuildError("Failed to parse %s with external modules metadata: %s", cfg, err)
15131521

15141522
# make sure name/version values are always lists, make sure they're equal length
15151523
for mod, entry in parsed_metadata.items():

test/framework/options.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3544,6 +3544,33 @@ def test_parse_external_modules_metadata(self):
35443544
err_msg = "Different length for lists of names/versions in metadata for external module"
35453545
self.assertErrorRegex(EasyBuildError, err_msg, parse_external_modules_metadata, [testcfg])
35463546

3547+
# if path to non-existing file is used, an error is reported
3548+
doesnotexist = os.path.join(self.test_prefix, 'doesnotexist')
3549+
error_pattern = "Specified path for file with external modules metadata does not exist"
3550+
self.assertErrorRegex(EasyBuildError, error_pattern, parse_external_modules_metadata, [doesnotexist])
3551+
3552+
# glob pattern can be used to specify file locations to parse_external_modules_metadata
3553+
cfg1 = os.path.join(self.test_prefix, 'cfg_one.ini')
3554+
write_file(cfg1, '\n'.join(['[one/1.0]', 'name = one', 'version = 1.0']))
3555+
cfg2 = os.path.join(self.test_prefix, 'cfg_two.ini')
3556+
write_file(cfg2, '\n'.join([
3557+
'[two/2.0]', 'name = two', 'version = 2.0',
3558+
'[two/2.1]', 'name = two', 'version = 2.1',
3559+
]))
3560+
cfg3 = os.path.join(self.test_prefix, 'cfg3.ini')
3561+
write_file(cfg3, '\n'.join(['[three/3.0]', 'name = three', 'version = 3.0']))
3562+
cfg4 = os.path.join(self.test_prefix, 'cfg_more.ini')
3563+
write_file(cfg4, '\n'.join(['[one/1.2.3]', 'name = one', 'version = 1.2.3', 'prefix = /one/1.2.3/']))
3564+
3565+
metadata = parse_external_modules_metadata([os.path.join(self.test_prefix, 'cfg*.ini')])
3566+
3567+
self.assertEqual(sorted(metadata.keys()), ['one/1.0', 'one/1.2.3', 'three/3.0', 'two/2.0', 'two/2.1'])
3568+
self.assertEqual(metadata['one/1.0'], {'name': ['one'], 'version': ['1.0']})
3569+
self.assertEqual(metadata['one/1.2.3'], {'name': ['one'], 'version': ['1.2.3'], 'prefix': '/one/1.2.3/'})
3570+
self.assertEqual(metadata['two/2.0'], {'name': ['two'], 'version': ['2.0']})
3571+
self.assertEqual(metadata['two/2.1'], {'name': ['two'], 'version': ['2.1']})
3572+
self.assertEqual(metadata['three/3.0'], {'name': ['three'], 'version': ['3.0']})
3573+
35473574
def test_zip_logs(self):
35483575
"""Test use of --zip-logs"""
35493576

0 commit comments

Comments
 (0)