diff --git a/easybuild/framework/easyblock.py b/easybuild/framework/easyblock.py index df88ad9ffd..8b89cc255c 100644 --- a/easybuild/framework/easyblock.py +++ b/easybuild/framework/easyblock.py @@ -4208,6 +4208,15 @@ def sanity_check_load_module(self, extension=False, extra_modules=None): self.sanity_check_fail_msgs.append("loading fake module failed: %s" % err) self.log.warning("Sanity check: %s" % self.sanity_check_fail_msgs[-1]) + # This should happen after `self.load_module` or `load_fake_module` as this calls purge the + # current modules + sanitycheck_deps = self.cfg['sanitycheck_dependencies'] + if sanitycheck_deps: + self.log.info("Sanity check dependencies enabled, loading dependencies before sanity check...") + # load dependencies (if any) before running sanity check commands + mod_names = [d['short_mod_name'] for d in sanitycheck_deps] + self.modules_tool.load(mod_names, allow_reload=True) + return self.fake_mod_data def _sanity_check_step(self, custom_paths=None, custom_commands=None, extension=False, extra_modules=None): diff --git a/easybuild/framework/easyconfig/default.py b/easybuild/framework/easyconfig/default.py index 272e9b87bf..994ec03b7a 100644 --- a/easybuild/framework/easyconfig/default.py +++ b/easybuild/framework/easyconfig/default.py @@ -168,6 +168,7 @@ # DEPENDENCIES easyconfig parameters 'allow_system_deps': [[], "Allow listed system dependencies (format: (, ))", DEPENDENCIES], + 'sanitycheck_dependencies': [[], "List of dependencies required for the sanity checks", DEPENDENCIES], 'builddependencies': [[], "List of build dependencies", DEPENDENCIES], 'dependencies': [[], "List of dependencies", DEPENDENCIES], 'hiddendependencies': [[], "List of dependencies available as hidden modules", DEPENDENCIES], diff --git a/easybuild/framework/easyconfig/easyconfig.py b/easybuild/framework/easyconfig/easyconfig.py index dd022fc786..932b3680a8 100644 --- a/easybuild/framework/easyconfig/easyconfig.py +++ b/easybuild/framework/easyconfig/easyconfig.py @@ -816,6 +816,10 @@ def remove_false_versions(deps): builddeps = [self._parse_dependency(dep, build_only=True) for dep in builddeps] self['builddependencies'] = remove_false_versions(builddeps) + sanitycheck_deps = self['sanitycheck_dependencies'] + self['sanitycheck_dependencies'] = remove_false_versions( + self._parse_dependency(dep, sanity_only=True) for dep in sanitycheck_deps) + # keep track of parsed multi deps, they'll come in handy during sanity check & module steps... self.multi_deps = self.get_parsed_multi_deps() @@ -1611,7 +1615,7 @@ def get_parsed_multi_deps(self): return multi_deps # private method - def _parse_dependency(self, dep, hidden=False, build_only=False): + def _parse_dependency(self, dep, hidden=False, build_only=False, sanity_only=False): """ parses the dependency into a usable dict with a common format dep can be a dict, a tuple or a list. @@ -1625,6 +1629,7 @@ def _parse_dependency(self, dep, hidden=False, build_only=False): :param hidden: indicate whether corresponding module file should be installed hidden ('.'-prefixed) :param build_only: indicate whether this is a build-only dependency + :param sanity_only: indicate whether this is a sanity-only dependency """ # convert tuple to string otherwise python might complain about the formatting self.log.debug("Parsing %s as a dependency" % str(dep)) @@ -1646,6 +1651,8 @@ def _parse_dependency(self, dep, hidden=False, build_only=False): 'hidden': hidden, # boolean indicating whether this this a build-only dependency 'build_only': build_only, + # boolean indicating whether this is a sanity-only dependency + 'sanity_only': sanity_only, # boolean indicating whether this dependency should be resolved via an external module 'external_module': False, # metadata in case this is an external module; diff --git a/easybuild/framework/easyconfig/format/format.py b/easybuild/framework/easyconfig/format/format.py index e4971c888d..2edc858179 100644 --- a/easybuild/framework/easyconfig/format/format.py +++ b/easybuild/framework/easyconfig/format/format.py @@ -50,7 +50,7 @@ FORMAT_VERSION_REGEXP = re.compile(r'^#\s+%s\s*(?P\d+)\.(?P\d+)\s*$' % FORMAT_VERSION_KEYWORD, re.M) FORMAT_DEFAULT_VERSION = EasyVersion('1.0') -DEPENDENCY_PARAMETERS = ['builddependencies', 'dependencies', 'hiddendependencies'] +DEPENDENCY_PARAMETERS = ['builddependencies', 'dependencies', 'hiddendependencies', 'sanitycheck_dependencies'] # values for these keys will not be templated in dump() EXCLUDED_KEYS_REPLACE_TEMPLATES = ['description', 'easyblock', 'exts_default_options', 'exts_list',