Skip to content

Commit a48c6bb

Browse files
committed
Refactor make_extension_string
The current usage was confusing as it isn't clear what should be overridden and what should be used. See #4340 - Make `make_extension_string` a free function to just provide a common format - Promote `make_extension_list` to a public method and document it - Error when overriding the old methods - Update the module generator and remove the confusingly named member methods
1 parent b5c1dd9 commit a48c6bb

File tree

2 files changed

+29
-40
lines changed

2 files changed

+29
-40
lines changed

easybuild/framework/easyblock.py

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,18 @@
120120
_log = fancylogger.getLogger('easyblock')
121121

122122

123+
def make_extension_string(app, name_version_sep='-', ext_sep=', ', sort=True):
124+
"""
125+
Generate a string with a list of extensions of the given EasyBlock instance.
126+
127+
The name and version are separated by name_version_sep and each extension is separated by ext_sep
128+
"""
129+
exts_list = (name_version_sep.join(ext) for ext in app.make_extension_list())
130+
if sort:
131+
exts_list = sorted(exts_list, key=str.lower)
132+
return ext_sep.join(exts_list)
133+
134+
123135
class EasyBlock(object):
124136
"""Generic support for building and installing software, base class for actual easyblocks."""
125137

@@ -1519,9 +1531,9 @@ def make_module_extra_extensions(self):
15191531

15201532
# set environment variable that specifies list of extensions
15211533
# We need only name and version, so don't resolve templates
1522-
exts_list = self.make_extension_string(ext_sep=',', sort=False)
1523-
env_var_name = convert_name(self.name, upper=True)
1524-
lines.append(self.module_generator.set_environment('EBEXTSLIST%s' % env_var_name, exts_list))
1534+
exts_list = make_extension_string(self, ext_sep=',', sort=False)
1535+
env_var_name = 'EBEXTSLIST' + convert_name(self.name, upper=True)
1536+
lines.append(self.module_generator.set_environment(env_var_name, exts_list))
15251537

15261538
return ''.join(lines)
15271539

@@ -1800,14 +1812,19 @@ def load_dependency_modules(self):
18001812
# EXTENSIONS UTILITY FUNCTIONS
18011813
#
18021814

1803-
def _make_extension_list(self):
1815+
def make_extension_list(self):
18041816
"""
18051817
Return a list of extension names and their versions included in this installation
18061818
1807-
Each entry should be a (name, version) tuple or just (name, ) if no version exists
1819+
Each entry should be a (name, version) tuple or just (name, ) if no version exists.
1820+
Custom EasyBlocks may override this to add extensions that cannot be found automatically.
18081821
"""
18091822
# Each extension in exts_list is either a string or a list/tuple with name, version as first entries
18101823
# As name can be a templated value we must resolve templates
1824+
if hasattr(self, '_make_extension_list'):
1825+
self.log.nosupport("self._make_extension_list is replaced by self.make_extension_list", '5.0')
1826+
if hasattr(self, 'make_extension_string'):
1827+
self.log.nosupport("self.make_extension_string was removed in favor of the free function", '5.0')
18111828
exts_list = []
18121829
for ext in self.cfg.get_ref('exts_list'):
18131830
if isinstance(ext, str):
@@ -1817,17 +1834,6 @@ def _make_extension_list(self):
18171834
resolve_template(ext[1], self.cfg.template_values)))
18181835
return exts_list
18191836

1820-
def make_extension_string(self, name_version_sep='-', ext_sep=', ', sort=True):
1821-
"""
1822-
Generate a string with a list of extensions.
1823-
1824-
The name and version are separated by name_version_sep and each extension is separated by ext_sep
1825-
"""
1826-
exts_list = (name_version_sep.join(ext) for ext in self._make_extension_list())
1827-
if sort:
1828-
exts_list = sorted(exts_list, key=str.lower)
1829-
return ext_sep.join(exts_list)
1830-
18311837
def prepare_for_extensions(self):
18321838
"""Ran before installing extensions (eg to set templates)"""
18331839

easybuild/tools/module_generator.py

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
from textwrap import wrap
4646

4747
from easybuild.base import fancylogger
48+
from easybuild.framework.easyblock import make_extension_string
4849
from easybuild.tools.build_log import EasyBuildError, print_warning
4950
from easybuild.tools.config import build_option, get_module_syntax, install_path
5051
from easybuild.tools.filetools import convert_name, mkdir, read_file, remove_file, resolve_path, symlink, write_file
@@ -610,21 +611,6 @@ def use(self, paths, prefix=None, guarded=False, user_modpath=None):
610611
"""
611612
raise NotImplementedError
612613

613-
def _generate_extension_list(self):
614-
"""
615-
Generate a string with a list of extensions.
616-
617-
The name and version are separated by name_version_sep and each extension is separated by ext_sep
618-
"""
619-
return self.app.make_extension_string()
620-
621-
def _generate_extensions_list(self):
622-
"""
623-
Generate a list of all extensions in name/version format
624-
"""
625-
exts_str = self.app.make_extension_string(name_version_sep='/', ext_sep=',')
626-
return exts_str.split(',') if exts_str else []
627-
628614
def _generate_help_text(self):
629615
"""
630616
Generate syntax-independent help text used for `module help`.
@@ -671,7 +657,7 @@ def _generate_help_text(self):
671657
lines.extend(self._generate_section("Compatible modules", compatible_modules_txt))
672658

673659
# Extensions (if any)
674-
extensions = self._generate_extension_list()
660+
extensions = make_extension_string(self.app)
675661
lines.extend(self._generate_section("Included extensions", '\n'.join(wrap(extensions, 78))))
676662

677663
return '\n'.join(lines)
@@ -686,10 +672,10 @@ def _generate_multi_deps_list(self):
686672
mod_list = []
687673
txt = ''
688674
vlist = self.app.cfg['multi_deps'].get(key)
689-
for idx in range(len(vlist)):
675+
for idx, version in enumerate(vlist):
690676
for deplist in self.app.cfg.multi_deps:
691677
for dep in deplist:
692-
if dep['name'] == key and dep['version'] == vlist[idx]:
678+
if dep['name'] == key and dep['version'] == version:
693679
modname = dep['short_mod_name']
694680
# indicate which version is loaded by default (unless that's disabled)
695681
if idx == 0 and self.app.cfg['multi_deps_load_default']:
@@ -728,7 +714,7 @@ def _generate_whatis_lines(self):
728714
if multi_deps:
729715
whatis.append("Compatible modules: %s" % ', '.join(multi_deps))
730716

731-
extensions = self._generate_extension_list()
717+
extensions = make_extension_string(self.app)
732718
if extensions:
733719
whatis.append("Extensions: %s" % extensions)
734720

@@ -1284,12 +1270,9 @@ def get_description(self, conflict=True):
12841270
elif conflict:
12851271
# conflict on 'name' part of module name (excluding version part at the end)
12861272
lines.extend(['', 'conflict("%s")' % os.path.dirname(self.app.short_mod_name)])
1287-
1288-
if build_option('module_extensions'):
1289-
extensions_list = self._generate_extensions_list()
1290-
1273+
extensions_list = self.app.make_extension_list()
12911274
if extensions_list:
1292-
extensions_stmt = 'extensions("%s")' % ','.join([str(x) for x in extensions_list])
1275+
extensions_stmt = 'extensions("%s")' % ','.join(['/'.join(x) for x in extensions_list])
12931276
# put this behind a Lmod version check as 'extensions' is only (well) supported since Lmod 8.2.8,
12941277
# see https://lmod.readthedocs.io/en/latest/330_extensions.html#module-extensions and
12951278
# https://github.com/TACC/Lmod/issues/428

0 commit comments

Comments
 (0)