Skip to content

Commit dda2fd4

Browse files
authored
Merge pull request easybuilders#4468 from boegel/from_commit
add support for `--from-commit` and `--include-easyblocks-from-commit`
2 parents a491c8e + 52648c0 commit dda2fd4

File tree

11 files changed

+646
-94
lines changed

11 files changed

+646
-94
lines changed

easybuild/framework/easyconfig/tools.py

Lines changed: 70 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,9 @@
6060
from easybuild.tools.filetools import find_easyconfigs, is_patch_file, locate_files
6161
from easybuild.tools.filetools import read_file, resolve_path, which, write_file
6262
from easybuild.tools.github import GITHUB_EASYCONFIGS_REPO
63-
from easybuild.tools.github import det_pr_labels, det_pr_title, download_repo, fetch_easyconfigs_from_pr, fetch_pr_data
64-
from easybuild.tools.github import fetch_files_from_pr
63+
from easybuild.tools.github import det_pr_labels, det_pr_title, download_repo, fetch_easyconfigs_from_commit
64+
from easybuild.tools.github import fetch_easyconfigs_from_pr, fetch_pr_data
65+
from easybuild.tools.github import fetch_files_from_commit, fetch_files_from_pr
6566
from easybuild.tools.multidiff import multidiff
6667
from easybuild.tools.py2vs3 import OrderedDict
6768
from easybuild.tools.toolchain.toolchain import is_system_toolchain
@@ -310,7 +311,7 @@ def get_paths_for(subdir=EASYCONFIGS_PKG_SUBDIR, robot_path=None):
310311
return paths
311312

312313

313-
def alt_easyconfig_paths(tmpdir, tweaked_ecs=False, from_prs=None, review_pr=None):
314+
def alt_easyconfig_paths(tmpdir, tweaked_ecs=False, from_prs=None, from_commit=None, review_pr=None):
314315
"""Obtain alternative paths for easyconfig files."""
315316

316317
# paths where tweaked easyconfigs will be placed, easyconfigs listed on the command line take priority and will be
@@ -321,18 +322,20 @@ def alt_easyconfig_paths(tmpdir, tweaked_ecs=False, from_prs=None, review_pr=Non
321322
tweaked_ecs_paths = (os.path.join(tmpdir, 'tweaked_easyconfigs'),
322323
os.path.join(tmpdir, 'tweaked_dep_easyconfigs'))
323324

324-
# paths where files touched in PRs will be downloaded to,
325-
# which are picked up via 'pr_paths' build option in fetch_files_from_pr
326-
pr_paths = []
325+
# paths where files touched in commit/PRs will be downloaded to,
326+
# which are picked up via 'extra_ec_paths' build option in fetch_files_from_pr
327+
extra_ec_paths = []
327328
if from_prs:
328-
pr_paths = from_prs[:]
329-
if review_pr and review_pr not in pr_paths:
330-
pr_paths.append(review_pr)
329+
extra_ec_paths = from_prs[:]
330+
if review_pr and review_pr not in extra_ec_paths:
331+
extra_ec_paths.append(review_pr)
332+
if extra_ec_paths:
333+
extra_ec_paths = [os.path.join(tmpdir, 'files_pr%s' % pr) for pr in extra_ec_paths]
331334

332-
if pr_paths:
333-
pr_paths = [os.path.join(tmpdir, 'files_pr%s' % pr) for pr in pr_paths]
335+
if from_commit:
336+
extra_ec_paths.append(os.path.join(tmpdir, 'files_commit_' + from_commit))
334337

335-
return tweaked_ecs_paths, pr_paths
338+
return tweaked_ecs_paths, extra_ec_paths
336339

337340

338341
def det_easyconfig_paths(orig_paths):
@@ -346,27 +349,31 @@ def det_easyconfig_paths(orig_paths):
346349
except ValueError:
347350
raise EasyBuildError("Argument to --from-pr must be a comma separated list of PR #s.")
348351

352+
from_commit = build_option('from_commit')
349353
robot_path = build_option('robot_path')
350354

351355
# list of specified easyconfig files
352356
ec_files = orig_paths[:]
353357

358+
commit_files, pr_files = [], []
354359
if from_prs:
355-
pr_files = []
356360
for pr in from_prs:
357-
# path to where easyconfig files should be downloaded is determined via 'pr_paths' build option,
358-
# which corresponds to the list of PR paths returned by alt_easyconfig_paths
361+
# path to where easyconfig files should be downloaded is determined
362+
# via 'extra_ec_paths' build options,
363+
# which corresponds to the list of commit/PR paths returned by alt_easyconfig_paths
359364
pr_files.extend(fetch_easyconfigs_from_pr(pr))
360-
361-
if ec_files:
362-
# replace paths for specified easyconfigs that are touched in PR
363-
for i, ec_file in enumerate(ec_files):
364-
for pr_file in pr_files:
365-
if ec_file == os.path.basename(pr_file):
366-
ec_files[i] = pr_file
367-
else:
368-
# if no easyconfigs are specified, use all the ones touched in the PR
369-
ec_files = [path for path in pr_files if path.endswith('.eb')]
365+
elif from_commit:
366+
commit_files = fetch_easyconfigs_from_commit(from_commit, files=ec_files)
367+
368+
if ec_files:
369+
# replace paths for specified easyconfigs that are touched in commit/PRs
370+
for i, ec_file in enumerate(ec_files):
371+
for file in commit_files + pr_files:
372+
if ec_file == os.path.basename(file):
373+
ec_files[i] = file
374+
else:
375+
# if no easyconfigs are specified, use all the ones touched in the commit/PRs
376+
ec_files = [path for path in commit_files + pr_files if path.endswith('.eb')]
370377

371378
filter_ecs = build_option('filter_ecs')
372379
if filter_ecs:
@@ -784,7 +791,7 @@ def avail_easyblocks():
784791
return easyblocks
785792

786793

787-
def det_copy_ec_specs(orig_paths, from_pr):
794+
def det_copy_ec_specs(orig_paths, from_pr=None, from_commit=None):
788795
"""Determine list of paths + target directory for --copy-ec."""
789796

790797
if from_pr is not None and not isinstance(from_pr, list):
@@ -848,4 +855,41 @@ def det_copy_ec_specs(orig_paths, from_pr):
848855
elif pr_matches:
849856
raise EasyBuildError("Found multiple paths for %s in PR: %s", filename, pr_matches)
850857

858+
# consider --from-commit (only if --from-pr was not used)
859+
elif from_commit:
860+
tmpdir = os.path.join(tempfile.gettempdir(), 'fetch_files_from_commit_%s' % from_commit)
861+
commit_paths = fetch_files_from_commit(from_commit, path=tmpdir)
862+
863+
# assume that files need to be copied to current working directory for now
864+
target_path = os.getcwd()
865+
866+
if orig_paths:
867+
last_path = orig_paths[-1]
868+
869+
# check files touched by commit and see if the target directory for --copy-ec
870+
# corresponds to the name of one of these files;
871+
# if so we should copy the specified file(s) to the current working directory,
872+
# since interpreting the last argument as target location is very unlikely to be correct in this case
873+
commit_filenames = [os.path.basename(p) for p in commit_paths]
874+
if last_path in commit_filenames:
875+
paths = orig_paths[:]
876+
else:
877+
target_path = last_path
878+
# exclude last argument that is used as target location
879+
paths = orig_paths[:-1]
880+
881+
# if list of files to copy is empty at this point,
882+
# we simply copy *all* files touched by the PR
883+
if not paths:
884+
paths = commit_paths
885+
886+
# replace path for files touched by commit (no need to worry about others)
887+
for idx, path in enumerate(paths):
888+
filename = os.path.basename(path)
889+
commit_matches = [x for x in commit_paths if os.path.basename(x) == filename]
890+
if len(commit_matches) == 1:
891+
paths[idx] = commit_matches[0]
892+
elif commit_matches:
893+
raise EasyBuildError("Found multiple paths for %s in commit: %s", filename, commit_matches)
894+
851895
return paths, target_path

easybuild/main.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ def process_eb_args(eb_args, eb_go, cfg_settings, modtool, testing, init_session
329329

330330
if options.copy_ec:
331331
# figure out list of files to copy + target location (taking into account --from-pr)
332-
eb_args, target_path = det_copy_ec_specs(eb_args, from_pr_list)
332+
eb_args, target_path = det_copy_ec_specs(eb_args, from_pr=from_pr_list, from_commit=options.from_commit)
333333

334334
categorized_paths = categorize_files_by_type(eb_args)
335335

@@ -765,8 +765,14 @@ def prepare_main(args=None, logfile=None, testing=None):
765765

766766

767767
if __name__ == "__main__":
768-
init_session_state, eb_go, cfg_settings = prepare_main()
768+
# take into account that EasyBuildError may be raised when parsing the EasyBuild configuration
769+
try:
770+
init_session_state, eb_go, cfg_settings = prepare_main()
771+
except EasyBuildError as err:
772+
print_error(err.msg)
773+
769774
hooks = load_hooks(eb_go.options.hooks)
775+
770776
try:
771777
main(prepared_cfg_data=(init_session_state, eb_go, cfg_settings))
772778
except EasyBuildError as err:

easybuild/tools/config.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ def mk_full_default_path(name, prefix=DEFAULT_PREFIX):
220220
'filter_env_vars',
221221
'filter_rpath_sanity_libs',
222222
'force_download',
223+
'from_commit',
223224
'git_working_dirs_path',
224225
'github_user',
225226
'github_org',
@@ -229,6 +230,7 @@ def mk_full_default_path(name, prefix=DEFAULT_PREFIX):
229230
'http_header_fields_urlpat',
230231
'hooks',
231232
'ignore_dirs',
233+
'include_easyblocks_from_commit',
232234
'insecure_download',
233235
'job_backend_config',
234236
'job_cores',
@@ -403,7 +405,7 @@ def mk_full_default_path(name, prefix=DEFAULT_PREFIX):
403405
'build_specs',
404406
'command_line',
405407
'external_modules_metadata',
406-
'pr_paths',
408+
'extra_ec_paths',
407409
'robot_path',
408410
'valid_module_classes',
409411
'valid_stops',

0 commit comments

Comments
 (0)