diff --git a/easybuild/framework/extensioneasyblock.py b/easybuild/framework/extensioneasyblock.py index c9aa1eeacb..db75ad0c77 100644 --- a/easybuild/framework/extensioneasyblock.py +++ b/easybuild/framework/extensioneasyblock.py @@ -100,18 +100,27 @@ def __init__(self, *args, **kwargs): self.ext_dir = None # dir where extension source was unpacked def _set_start_dir(self): - """Set value for self.start_dir + """Set absolute path of self.start_dir similarly to EasyBlock.guess_start_dir - Uses existing value of self.start_dir if it is already set and exists - otherwise self.ext_dir (path to extracted source) if that is set and exists, similar to guess_start_dir + Uses existing value of self.start_dir if it is already set, an absolute path and exists + otherwise use self.ext_dir (path to extracted source) as base dir if that is set and exists. """ - possible_dirs = (self.start_dir, self.ext_dir) - for possible_dir in possible_dirs: - if possible_dir and os.path.isdir(possible_dir): - self.cfg['start_dir'] = possible_dir - self.log.debug("Using start_dir: %s", self.start_dir) - return - self.log.debug("Unable to determine start_dir as none of these paths is set and exists: %s", possible_dirs) + ext_start_dir = '' + + if self.start_dir: + ext_start_dir = self.start_dir + + if not os.path.isabs(ext_start_dir) and self.ext_dir: + # start dir is either empty or a _relative_ path provided by user through self.start_dir + # generate absolute path from ext_dir + ext_start_dir = os.path.join(self.ext_dir, ext_start_dir) + + if os.path.isdir(ext_start_dir): + self.cfg['start_dir'] = ext_start_dir + self.log.debug("Using extension start dir: %s", ext_start_dir) + else: + # non-existing start dir means wrong input from user + self.log.debug("Provided start dir for extension does not exist: %s", ext_start_dir) def run(self, unpack_src=False): """Common operations for extensions: unpacking sources, patching, ...""" diff --git a/test/framework/easyblock.py b/test/framework/easyblock.py index a8cd59375e..9bda723b41 100644 --- a/test/framework/easyblock.py +++ b/test/framework/easyblock.py @@ -2164,6 +2164,50 @@ def check_start_dir(expected_start_dir): err_pattern = "Specified start dir .*/toy-0.0/thisstartdirisnotthere does not exist" self.assertErrorRegex(EasyBuildError, err_pattern, check_start_dir, 'whatever') + def test_extension_set_start_dir(self): + """Test start dir with extensions.""" + test_easyconfigs = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'easyconfigs', 'test_ecs') + ec = process_easyconfig(os.path.join(test_easyconfigs, 't', 'toy', 'toy-0.0.eb'))[0] + + cwd = os.getcwd() + self.assertTrue(os.path.exists(cwd)) + + def check_ext_start_dir(expected_start_dir): + """Check start dir.""" + # make sure we're in an existing directory at the start + change_dir(cwd) + eb = EasyBlock(ec['ec']) + eb.extensions_step(fetch=True, install=False) + # extract sources of the extension + ext = eb.ext_instances[-1] + ext.run(unpack_src=True) + abs_expected_start_dir = os.path.join(eb.builddir, expected_start_dir) + self.assertTrue(os.path.samefile(ext.cfg['start_dir'], abs_expected_start_dir)) + self.assertTrue(os.path.samefile(os.getcwd(), abs_expected_start_dir)) + + ec['ec']['exts_defaultclass'] = 'DummyExtension' + + # default (no start_dir specified): use unpacked dir as start dir + ec['ec']['exts_list'] = [ + ('barbar', '0.0', {}), + ] + check_ext_start_dir('barbar/barbar-0.0') + + # use start dir defined in extension + ec['ec']['exts_list'] = [ + ('barbar', '0.0', { + 'start_dir': 'src'}), + ] + check_ext_start_dir('barbar/barbar-0.0/src') + + # clean error when specified start dir does not exist + ec['ec']['exts_list'] = [ + ('barbar', '0.0', { + 'start_dir': 'nonexistingdir'}), + ] + err_pattern = "Failed to change from .*barbar/barbar-0.0 to nonexistingdir.*" + self.assertErrorRegex(EasyBuildError, err_pattern, check_ext_start_dir, 'whatever') + def test_prepare_step(self): """Test prepare step (setting up build environment).""" test_easyconfigs = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'easyconfigs', 'test_ecs')