Skip to content

Commit

Permalink
Merge pull request #4196 from lexming/ext-startdir
Browse files Browse the repository at this point in the history
enforce absolute paths as start dir of extensions
  • Loading branch information
ocaisa authored Jan 31, 2023
2 parents 2d769e5 + 183d036 commit 2d906da
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 10 deletions.
29 changes: 19 additions & 10 deletions easybuild/framework/extensioneasyblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -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, ..."""
Expand Down
44 changes: 44 additions & 0 deletions test/framework/easyblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down

0 comments on commit 2d906da

Please sign in to comment.