Skip to content

Commit 39c9d36

Browse files
committed
Add make_extension_string and _make_extension_list to EasyBlock
This allows custom EasyBlocks to override thise and e.g. add more extensions which should be mentioned in the module. This also unifies the handling of getting and converting those into a string which fixes a bug with e.g. R ECs where extensions may only be a plain string.
1 parent 6f598eb commit 39c9d36

File tree

8 files changed

+41
-31
lines changed

8 files changed

+41
-31
lines changed

easybuild/framework/easyblock.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1429,7 +1429,7 @@ def make_module_extra_extensions(self):
14291429

14301430
# set environment variable that specifies list of extensions
14311431
# We need only name and version, so don't resolve templates
1432-
exts_list = ','.join(['-'.join(ext[:2]) for ext in self.cfg.get_ref('exts_list')])
1432+
exts_list = self.make_extension_string(ext_sep=',', sort=False)
14331433
env_var_name = convert_name(self.name, upper=True)
14341434
lines.append(self.module_generator.set_environment('EBEXTSLIST%s' % env_var_name, exts_list))
14351435

@@ -1710,6 +1710,27 @@ def load_dependency_modules(self):
17101710
# EXTENSIONS UTILITY FUNCTIONS
17111711
#
17121712

1713+
def _make_extension_list(self):
1714+
"""
1715+
Return a list of extension names and their versions included in this installation
1716+
1717+
Each entry should be a (name, version) tuple or just (name, ) if no version exists
1718+
"""
1719+
# We need only name and version, so don't resolve templates
1720+
# Each extension in exts_list is either a string or a list/tuple with name, version as first entries
1721+
return [(ext, ) if isinstance(ext, string_type) else ext[:2] for ext in self.cfg.get_ref('exts_list')]
1722+
1723+
def make_extension_string(self, name_version_sep='-', ext_sep=', ', sort=True):
1724+
"""
1725+
Generate a string with a list of extensions.
1726+
1727+
The name and version are separated by name_version_sep and each extension is separated by ext_sep
1728+
"""
1729+
exts_list = (name_version_sep.join(ext) for ext in self._make_extension_list())
1730+
if sort:
1731+
exts_list = sorted(exts_list, key=str.lower)
1732+
return ext_sep.join(exts_list)
1733+
17131734
def prepare_for_extensions(self):
17141735
"""
17151736
Also do this before (eg to set the template)

easybuild/tools/module_generator.py

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -606,28 +606,17 @@ def use(self, paths, prefix=None, guarded=False, user_modpath=None):
606606

607607
def _generate_extension_list(self):
608608
"""
609-
Generate a string with a comma-separated list of extensions.
610-
"""
611-
# We need only name and version, so don't resolve templates
612-
exts_list = self.app.cfg.get_ref('exts_list')
613-
extensions = ', '.join(sorted(['-'.join(ext[:2]) for ext in exts_list], key=str.lower))
609+
Generate a string with a list of extensions.
614610
615-
return extensions
611+
The name and version are separated by name_version_sep and each extension is separated by ext_sep
612+
"""
613+
return self.app.make_extension_string()
616614

617615
def _generate_extensions_list(self):
618616
"""
619617
Generate a list of all extensions in name/version format
620618
"""
621-
exts_list = self.app.cfg['exts_list']
622-
# the format is extension_name/extension_version
623-
exts_ver_list = []
624-
for ext in exts_list:
625-
if isinstance(ext, tuple):
626-
exts_ver_list.append('%s/%s' % (ext[0], ext[1]))
627-
elif isinstance(ext, string_type):
628-
exts_ver_list.append(ext)
629-
630-
return sorted(exts_ver_list, key=str.lower)
619+
return self.app.make_extension_string(name_version_sep='/', ext_sep=',').split(',')
631620

632621
def _generate_help_text(self):
633622
"""

test/framework/easyblock.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,7 +1033,7 @@ def test_init_extensions(self):
10331033
toy_ec_txt = read_file(toy_ec_file)
10341034

10351035
test_ec = os.path.join(self.test_prefix, 'test.eb')
1036-
test_ec_txt = toy_ec_txt.replace("('barbar', '0.0', {", "('barbar', '0.0', {'easyblock': 'DummyExtension',")
1036+
test_ec_txt = toy_ec_txt.replace("('barbar', '1.2', {", "('barbar', '1.2', {'easyblock': 'DummyExtension',")
10371037
write_file(test_ec, test_ec_txt)
10381038
ec = process_easyconfig(test_ec)[0]
10391039
eb = get_easyblock_instance(ec)
@@ -1837,7 +1837,7 @@ def test_collect_exts_file_info(self):
18371837
self.assertTrue(isinstance(exts_file_info, list))
18381838
self.assertEqual(len(exts_file_info), 4)
18391839

1840-
self.assertEqual(exts_file_info[0], {'name': 'ls'})
1840+
self.assertEqual(exts_file_info[0], {'name': 'ulimit'})
18411841

18421842
self.assertEqual(exts_file_info[1]['name'], 'bar')
18431843
self.assertEqual(exts_file_info[1]['src'], os.path.join(toy_ext_sources, 'bar-0.0.tar.gz'))
@@ -1849,7 +1849,7 @@ def test_collect_exts_file_info(self):
18491849
self.assertEqual(exts_file_info[1]['patches'][1]['path'], os.path.join(toy_ext_sources, bar_patch2))
18501850

18511851
self.assertEqual(exts_file_info[2]['name'], 'barbar')
1852-
self.assertEqual(exts_file_info[2]['src'], os.path.join(toy_ext_sources, 'barbar-0.0.tar.gz'))
1852+
self.assertEqual(exts_file_info[2]['src'], os.path.join(toy_ext_sources, 'barbar-1.2.tar.gz'))
18531853
self.assertNotIn('patches', exts_file_info[2])
18541854

18551855
self.assertEqual(exts_file_info[3]['name'], 'toy')
@@ -1862,7 +1862,7 @@ def test_collect_exts_file_info(self):
18621862
self.assertTrue(isinstance(exts_file_info, list))
18631863
self.assertEqual(len(exts_file_info), 4)
18641864

1865-
self.assertEqual(exts_file_info[0], {'name': 'ls'})
1865+
self.assertEqual(exts_file_info[0], {'name': 'ulimit'})
18661866

18671867
self.assertEqual(exts_file_info[1]['name'], 'bar')
18681868
self.assertNotIn('src', exts_file_info[1])

test/framework/easyconfigs/test_ecs/t/toy/toy-0.0-gompi-2018a-test.eb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ exts_default_options = {
2727
}
2828

2929
exts_list = [
30-
'ls', # extension that is part of "standard library"
30+
'ulimit', # extension that is part of "standard library"
3131
('bar', '0.0', {
3232
'buildopts': " && gcc bar.c -o anotherbar",
33-
'checksums': ['f3676716b610545a4e8035087f5be0a0248adee0abb3930d3edb76d498ae91e7'], # checksum for
33+
'checksums': ['f3676716b610545a4e8035087f5be0a0248adee0abb3930d3edb76d498ae91e7'], # checksum for
3434
# custom extension filter to verify use of stdin value being passed to filter command
3535
'exts_filter': ("cat | grep '^bar$'", '%(name)s'),
3636
'patches': [
@@ -43,7 +43,7 @@ exts_list = [
4343
# cfr. https://github.com/easybuilders/easybuild-framework/pull/3034
4444
'keepsymlinks': True,
4545
}),
46-
('barbar', '0.0', {
46+
('barbar', '1.2', {
4747
'start_dir': 'src',
4848
}),
4949
(name, version, {

test/framework/module_generator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,7 @@ def test_module_extensions(self):
749749

750750
patterns = [
751751
r'^if convertToCanonical\(LmodVersion\(\)\) >= convertToCanonical\("8\.2\.8"\) then\n' +
752-
r'\s*extensions\("bar/0.0,barbar/0.0,ls,toy/0.0"\)\nend$',
752+
r'\s*extensions\("bar/0.0,barbar/1.2,toy/0.0,ulimit"\)\nend$',
753753
]
754754

755755
for pattern in patterns:

test/framework/options.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5688,7 +5688,7 @@ def test_inject_checksums(self):
56885688
r"^== \* bar-0\.0\.tar\.gz: %s$" % bar_tar_gz_sha256,
56895689
r"^== \* %s: %s$" % (bar_patch, bar_patch_sha256),
56905690
r"^== \* %s: %s$" % (bar_patch_bis, bar_patch_bis_sha256),
5691-
r"^== \* barbar-0\.0\.tar\.gz: d5bd9908cdefbe2d29c6f8d5b45b2aaed9fd904b5e6397418bb5094fbdb3d838$",
5691+
r"^== \* barbar-1\.2\.tar\.gz: d5bd9908cdefbe2d29c6f8d5b45b2aaed9fd904b5e6397418bb5094fbdb3d838$",
56925692
]
56935693
for pattern in patterns:
56945694
regex = re.compile(pattern, re.M)
@@ -5744,7 +5744,7 @@ def test_inject_checksums(self):
57445744
self.assertEqual(ec['checksums'], [{'toy-0.0.tar.gz': toy_source_sha256},
57455745
{'toy-0.0_fix-silly-typo-in-printf-statement.patch': toy_patch_sha256}])
57465746
self.assertEqual(ec['exts_default_options'], {'source_urls': ['http://example.com/%(name)s']})
5747-
self.assertEqual(ec['exts_list'][0], 'ls')
5747+
self.assertEqual(ec['exts_list'][0], 'ulimit')
57485748
self.assertEqual(ec['exts_list'][1], ('bar', '0.0', {
57495749
'buildopts': " && gcc bar.c -o anotherbar",
57505750
'checksums': [
@@ -5758,7 +5758,7 @@ def test_inject_checksums(self):
57585758
'unknowneasyconfigparameterthatshouldbeignored': 'foo',
57595759
'keepsymlinks': True,
57605760
}))
5761-
self.assertEqual(ec['exts_list'][2], ('barbar', '0.0', {
5761+
self.assertEqual(ec['exts_list'][2], ('barbar', '1.2', {
57625762
'checksums': ['d5bd9908cdefbe2d29c6f8d5b45b2aaed9fd904b5e6397418bb5094fbdb3d838'],
57635763
'start_dir': 'src',
57645764
}))
556 Bytes
Binary file not shown.

test/framework/toy_build.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,7 +1088,7 @@ def test_toy_advanced(self):
10881088
toy_mod_txt = read_file(toy_module)
10891089

10901090
patterns = [
1091-
'^setenv.*EBEXTSLISTTOY.*bar-0.0,barbar-0.0',
1091+
'^setenv.*EBEXTSLISTTOY.*ulimit,bar-0.0,barbar-1.2',
10921092
# set by ToyExtension easyblock used to install extensions
10931093
'^setenv.*TOY_EXT_BAR.*bar',
10941094
'^setenv.*TOY_EXT_BARBAR.*barbar',
@@ -2198,7 +2198,7 @@ def test_reproducibility_ext_easyblocks(self):
21982198
ec1 = os.path.join(self.test_prefix, 'toy1.eb')
21992199
ec1_txt = '\n'.join([
22002200
toy_ec_txt,
2201-
"exts_list = [('barbar', '0.0', {'start_dir': 'src'})]",
2201+
"exts_list = [('barbar', '1.2', {'start_dir': 'src'})]",
22022202
"",
22032203
])
22042204
write_file(ec1, ec1_txt)
@@ -2968,7 +2968,7 @@ def test_toy_multi_deps(self):
29682968
test_ec = os.path.join(self.test_prefix, 'test.eb')
29692969

29702970
# also inject (minimal) list of extensions to test iterative installation of extensions
2971-
test_ec_txt += "\nexts_list = [('barbar', '0.0', {'start_dir': 'src'})]"
2971+
test_ec_txt += "\nexts_list = [('barbar', '1.2', {'start_dir': 'src'})]"
29722972

29732973
test_ec_txt += "\nmulti_deps = {'GCC': ['4.6.3', '7.3.0-2.30']}"
29742974
write_file(test_ec, test_ec_txt)

0 commit comments

Comments
 (0)