From a508adbe5edf3f77e378bff4c37e5dba044cc6d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Fri, 5 Apr 2024 00:49:31 +0200 Subject: [PATCH 1/6] Make module-extensions true by default --- easybuild/tools/config.py | 2 +- easybuild/tools/options.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/easybuild/tools/config.py b/easybuild/tools/config.py index 9791eb3dcc..b7d31f2883 100644 --- a/easybuild/tools/config.py +++ b/easybuild/tools/config.py @@ -292,7 +292,6 @@ def mk_full_default_path(name, prefix=DEFAULT_PREFIX): 'install_latest_eb_release', 'logtostdout', 'minimal_toolchains', - 'module_extensions', 'module_only', 'package', 'parallel_extensions_install', @@ -328,6 +327,7 @@ def mk_full_default_path(name, prefix=DEFAULT_PREFIX): 'lib64_fallback_sanity_check', 'lib64_lib_symlink', 'map_toolchains', + 'module_extensions', 'modules_tool_version_check', 'mpi_tests', 'pre_create_installdir', diff --git a/easybuild/tools/options.py b/easybuild/tools/options.py index 54e9b81982..a7c30a4d30 100644 --- a/easybuild/tools/options.py +++ b/easybuild/tools/options.py @@ -581,7 +581,7 @@ def config_options(self): "(implies recursive unloading of modules).", None, 'store_true', False), 'module-extensions': ("Include 'extensions' statement in generated module file (Lua syntax only)", - None, 'store_true', False), + None, 'store_true', True), 'module-naming-scheme': ("Module naming scheme to use", None, 'store', DEFAULT_MNS), 'module-syntax': ("Syntax to be used for module files", 'choice', 'store', DEFAULT_MODULE_SYNTAX, sorted(avail_module_generators().keys())), From 3170d9fe5e70715a58e425b5d16cacec4bd2600e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Sat, 6 Apr 2024 04:06:39 +0200 Subject: [PATCH 2/6] Simplify and fix module description generators Old method needlessly involved template resolutions, duplicating the template resolving code, but only partially and would break if anything but the 4 most common templates were used. --- easybuild/tools/module_generator.py | 53 ++++++++--------------------- 1 file changed, 15 insertions(+), 38 deletions(-) diff --git a/easybuild/tools/module_generator.py b/easybuild/tools/module_generator.py index c537003de5..f4565b0950 100644 --- a/easybuild/tools/module_generator.py +++ b/easybuild/tools/module_generator.py @@ -816,20 +816,19 @@ def get_description(self, conflict=True): """ Generate a description. """ - txt = '\n'.join([ + lines = [ "proc ModulesHelp { } {", " puts stderr {%s" % re.sub(r'([{}\[\]])', r'\\\1', self._generate_help_text()), " }", '}', '', - ]) - - lines = [ - '%(whatis_lines)s', - '', - "set root %(installdir)s", ] + lines.extend([ + "module-whatis {%s}" % re.sub(r'([{}\[\]])', r'\\\1', line) + for line in self._generate_whatis_lines() + ]) + if self.app.cfg['moduleloadnoconflict']: cond_unload = self.conditional_statement(self.is_loaded('%(name)s'), "module unload %(name)s") lines.extend([ @@ -845,18 +844,9 @@ def get_description(self, conflict=True): # - 'conflict Compiler/GCC/4.8.2/OpenMPI' for 'Compiler/GCC/4.8.2/OpenMPI/1.6.4' lines.extend(['', "conflict %s" % os.path.dirname(self.app.short_mod_name)]) - whatis_lines = [ - "module-whatis {%s}" % re.sub(r'([{}\[\]])', r'\\\1', line) - for line in self._generate_whatis_lines() - ] - txt += '\n'.join([''] + lines + ['']) % { - 'name': self.app.name, - 'version': self.app.version, - 'whatis_lines': '\n'.join(whatis_lines), - 'installdir': self.app.installdir, - } + lines.extend(['', "set root %(installdir)s"]) - return txt + return '\n'.join([''] + lines + ['']) def getenv_cmd(self, envvar, default=None): """ @@ -1261,18 +1251,17 @@ def get_description(self, conflict=True): """ Generate a description. """ - txt = '\n'.join([ + lines = [ 'help(%s%s' % (self.START_STR, self.check_str(self._generate_help_text())), '%s)' % self.END_STR, '', - ]) - - lines = [ - "%(whatis_lines)s", - '', - 'local root = "%(installdir)s"', ] + for line in self._generate_whatis_lines(): + lines.append("whatis(%s%s%s)" % (self.START_STR, self.check_str(line), self.END_STR)) + + lines.extend(['', 'local root = "%(installdir)s"']) + if self.app.cfg['moduleloadnoconflict']: self.log.info("Nothing to do to ensure no conflicts can occur on load when using Lua modules files/Lmod") @@ -1280,10 +1269,6 @@ def get_description(self, conflict=True): # conflict on 'name' part of module name (excluding version part at the end) lines.extend(['', 'conflict("%s")' % os.path.dirname(self.app.short_mod_name)]) - whatis_lines = [] - for line in self._generate_whatis_lines(): - whatis_lines.append("whatis(%s%s%s)" % (self.START_STR, self.check_str(line), self.END_STR)) - if build_option('module_extensions'): extensions_list = self._generate_extensions_list() @@ -1294,15 +1279,7 @@ def get_description(self, conflict=True): # https://github.com/TACC/Lmod/issues/428 lines.extend(['', self.conditional_statement(self.check_version("8", "2", "8"), extensions_stmt)]) - txt += '\n'.join([''] + lines + ['']) % { - 'name': self.app.name, - 'version': self.app.version, - 'whatis_lines': '\n'.join(whatis_lines), - 'installdir': self.app.installdir, - 'homepage': self.app.cfg['homepage'], - } - - return txt + return '\n'.join([''] + lines + ['']) def getenv_cmd(self, envvar, default=None): """ From 22862e1cd66d29a129ae3b2c61f72f751db6128e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Mon, 8 Apr 2024 10:54:50 +0000 Subject: [PATCH 3/6] Use installdir directly instead of introducing a template variable --- easybuild/tools/module_generator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easybuild/tools/module_generator.py b/easybuild/tools/module_generator.py index f4565b0950..8b829c75b7 100644 --- a/easybuild/tools/module_generator.py +++ b/easybuild/tools/module_generator.py @@ -844,7 +844,7 @@ def get_description(self, conflict=True): # - 'conflict Compiler/GCC/4.8.2/OpenMPI' for 'Compiler/GCC/4.8.2/OpenMPI/1.6.4' lines.extend(['', "conflict %s" % os.path.dirname(self.app.short_mod_name)]) - lines.extend(['', "set root %(installdir)s"]) + lines.extend(['', "set root " + self.app.installdir]) return '\n'.join([''] + lines + ['']) @@ -1260,7 +1260,7 @@ def get_description(self, conflict=True): for line in self._generate_whatis_lines(): lines.append("whatis(%s%s%s)" % (self.START_STR, self.check_str(line), self.END_STR)) - lines.extend(['', 'local root = "%(installdir)s"']) + lines.extend(['', 'local root = "%s"' % self.app.installdir]) if self.app.cfg['moduleloadnoconflict']: self.log.info("Nothing to do to ensure no conflicts can occur on load when using Lua modules files/Lmod") From a0fa9e52ef90a73eacbd7b57dce3de19a2b1313b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Wed, 28 Aug 2024 01:57:29 +0200 Subject: [PATCH 4/6] Resolve template also for extension version string --- easybuild/framework/easyblock.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/easybuild/framework/easyblock.py b/easybuild/framework/easyblock.py index 72fa56cab8..437724cda4 100644 --- a/easybuild/framework/easyblock.py +++ b/easybuild/framework/easyblock.py @@ -1748,7 +1748,8 @@ def _make_extension_list(self): if isinstance(ext, str): exts_list.append((resolve_template(ext, self.cfg.template_values), )) else: - exts_list.append((resolve_template(ext[0], self.cfg.template_values), ext[1])) + exts_list.append((resolve_template(ext[0], self.cfg.template_values), + resolve_template(ext[1], self.cfg.template_values))) return exts_list def make_extension_string(self, name_version_sep='-', ext_sep=', ', sort=True): From 57cc313ac67682ea3411fedfc602107ba52b05d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Wed, 28 Aug 2024 18:39:51 +0200 Subject: [PATCH 5/6] Fix accidental module whitespace/order changes --- easybuild/tools/module_generator.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/easybuild/tools/module_generator.py b/easybuild/tools/module_generator.py index 8b829c75b7..895cbc5cd1 100644 --- a/easybuild/tools/module_generator.py +++ b/easybuild/tools/module_generator.py @@ -829,6 +829,8 @@ def get_description(self, conflict=True): for line in self._generate_whatis_lines() ]) + lines.extend(['', "set root " + self.app.installdir]) + if self.app.cfg['moduleloadnoconflict']: cond_unload = self.conditional_statement(self.is_loaded('%(name)s'), "module unload %(name)s") lines.extend([ @@ -844,9 +846,7 @@ def get_description(self, conflict=True): # - 'conflict Compiler/GCC/4.8.2/OpenMPI' for 'Compiler/GCC/4.8.2/OpenMPI/1.6.4' lines.extend(['', "conflict %s" % os.path.dirname(self.app.short_mod_name)]) - lines.extend(['', "set root " + self.app.installdir]) - - return '\n'.join([''] + lines + ['']) + return '\n'.join(lines + ['']) def getenv_cmd(self, envvar, default=None): """ @@ -1279,7 +1279,7 @@ def get_description(self, conflict=True): # https://github.com/TACC/Lmod/issues/428 lines.extend(['', self.conditional_statement(self.check_version("8", "2", "8"), extensions_stmt)]) - return '\n'.join([''] + lines + ['']) + return '\n'.join(lines + ['']) def getenv_cmd(self, envvar, default=None): """ From ac9ddeaa06c6634268d7327b8e280348221b2eb1 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Wed, 28 Aug 2024 20:21:57 +0200 Subject: [PATCH 6/6] enhance test_exts_list to verify that template values used in extension name/version are resolved as expected --- test/framework/easyconfig.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/framework/easyconfig.py b/test/framework/easyconfig.py index 7dc088bff3..3db9386310 100644 --- a/test/framework/easyconfig.py +++ b/test/framework/easyconfig.py @@ -522,7 +522,8 @@ def test_exts_list(self): with self.mocked_stdout_stderr(): modfile = os.path.join(eb.make_module_step(), 'PI', '3.14' + eb.module_generator.MODULE_FILE_EXTENSION) modtxt = read_file(modfile) - regex = re.compile('EBEXTSLISTPI.*ext1-1.0,ext2-2.0') + # verify that templates used for extensions are resolved as they should + regex = re.compile('EBEXTSLISTPI.*"ext1-1.0,ext2-2.0,ext-PI-3.14,ext-pi-3.0') self.assertTrue(regex.search(modtxt), "Pattern '%s' found in: %s" % (regex.pattern, modtxt)) def test_extensions_templates(self):