Skip to content

Commit

Permalink
allow extensions to add text to the module file
Browse files Browse the repository at this point in the history
Introduce `make_extension_module_extra` which gets called during module
file creation for every extension similar to `make_module_extra`.
This ensures it will also be called for parallel extension or --module-only builds.

Fixes easybuilders#4647
  • Loading branch information
Flamefire committed Sep 23, 2024
1 parent 8db3bd8 commit 1759ad1
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 5 deletions.
18 changes: 14 additions & 4 deletions easybuild/framework/easyblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -1463,21 +1463,30 @@ def make_module_extra_extensions(self):
Sets optional variables for extensions.
"""
# add stuff specific to individual extensions
lines = [self.module_extra_extensions]
txt = self.module_extra_extensions

if not self.ext_instances:
self.prepare_for_extensions()
self.init_ext_instances()

for ext in self.ext_instances:
ext_txt = ext.make_extension_module_extra()
if ext_txt:
txt += ext_txt

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

return ''.join(lines)
return txt

def make_module_footer(self):
"""
Insert a footer section in the module file, primarily meant for contextual information
"""
footer = [self.module_generator.comment("Built with EasyBuild version %s" % VERBOSE_VERSION)]
footer = []

# add extra stuff for extensions (if any)
if self.cfg.get_ref('exts_list'):
Expand All @@ -1504,6 +1513,7 @@ def make_module_footer(self):
self.log.warning("Not including footer in Lua syntax in non-Lua module file: %s",
self.cfg['modluafooter'])

footer.append(self.module_generator.comment("Built with EasyBuild version %s" % VERBOSE_VERSION))
return ''.join(footer)

def make_module_extend_modpath(self):
Expand Down
4 changes: 4 additions & 0 deletions easybuild/framework/extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,10 @@ def toolchain(self):
"""
return self.master.toolchain

def make_extension_module_extra(self):
"""Similar to make_module_extra but only called for extensions"""
return ''

def sanity_check_step(self):
"""
Sanity check to run after installing extension
Expand Down
2 changes: 1 addition & 1 deletion easybuild/framework/extensioneasyblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,6 @@ def make_module_extra(self, extra=None):
"""Add custom entries to module."""

txt = EasyBlock.make_module_extra(self)
if extra is not None:
if extra:
txt += extra
return txt
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,15 @@ def postrun(self):

EB_toy.install_step(self.master, name=self.name)

def make_extension_module_extra(self):
"""Extra stuff for toy extensions"""
txt = super(Toy_Extension, self).make_extension_module_extra()
value = self.name
if self.version:
value += '-' + self.version
txt += self.module_generator.set_environment('TOY_EXT_VAR', value)
return txt

def sanity_check_step(self, *args, **kwargs):
"""Custom sanity check for toy extensions."""
self.log.info("Loaded modules: %s", self.modules_tool.list())
Expand Down
24 changes: 24 additions & 0 deletions test/framework/toy_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,8 @@ def test_toy_advanced(self):
# set by ToyExtension easyblock used to install extensions
'^setenv.*TOY_EXT_BAR.*bar',
'^setenv.*TOY_EXT_BARBAR.*barbar',
'^setenv.*TOY_EXT_VAR.*bar',
'^setenv.*TOY_EXT_VAR.*barbar',
]
for pattern in patterns:
self.assertTrue(re.search(pattern, toy_mod_txt, re.M), "Pattern '%s' found in: %s" % (pattern, toy_mod_txt))
Expand Down Expand Up @@ -1804,6 +1806,8 @@ def test_module_only_extensions(self):
# first try normal --module-only, should work fine
self.eb_main([test_ec, '--module-only'], do_build=True, raise_error=True)
self.assertExists(toy_mod)
# Extra stuff from extension(s) is included
self.assertRegex(read_file(toy_mod), 'TOY_EXT_VAR.*barbar-0.0')
remove_file(toy_mod)

# rename file required for barbar extension, so we can check whether sanity check catches it
Expand Down Expand Up @@ -1858,6 +1862,14 @@ def test_toy_exts_parallel(self):
stdout, stderr = self.run_test_toy_build_with_output(ec_file=test_ec, extra_args=args)
self.assertEqual(stderr, '')

# Extra stuff from extension(s) should be included
ext_var_patterns = [
'TOY_EXT_VAR.*ls-',
'TOY_EXT_VAR.*bar-0.0',
'TOY_EXT_VAR.*barbar-0.0',
'TOY_EXT_VAR.*toy-0.0',
]

# take into account that each of these lines may appear multiple times,
# in case no progress was made between checks
patterns = [
Expand All @@ -1872,6 +1884,10 @@ def test_toy_exts_parallel(self):
error_msg = "Expected pattern '%s' should be found in %s'" % (regex.pattern, stdout)
self.assertTrue(regex.search(stdout), error_msg)

module_contents = read_file(toy_mod)
for pattern in ext_var_patterns:
self.assertRegex(module_contents, pattern)

# also test skipping of extensions in parallel
args.append('--skip')
stdout, stderr = self.run_test_toy_build_with_output(ec_file=test_ec, extra_args=args)
Expand All @@ -1890,6 +1906,10 @@ def test_toy_exts_parallel(self):
error_msg = "Expected pattern '%s' should be found in %s'" % (regex.pattern, stdout)
self.assertTrue(regex.search(stdout), error_msg)

module_contents = read_file(toy_mod)
for pattern in ext_var_patterns:
self.assertRegex(module_contents, pattern)

# check behaviour when using Toy_Extension easyblock that doesn't implement required_deps method;
# framework should fall back to installing extensions sequentially
toy_ext_eb = os.path.join(topdir, 'sandbox', 'easybuild', 'easyblocks', 'generic', 'toy_extension.py')
Expand Down Expand Up @@ -1917,6 +1937,10 @@ def test_toy_exts_parallel(self):
error_msg = "Expected pattern '%s' should be found in %s'" % (regex.pattern, stdout)
self.assertTrue(regex.search(stdout), error_msg)

module_contents = read_file(toy_mod)
for pattern in ext_var_patterns:
self.assertRegex(module_contents, pattern)

def test_backup_modules(self):
"""Test use of backing up of modules with --module-only."""

Expand Down

0 comments on commit 1759ad1

Please sign in to comment.