|
53 | 53 | from easybuild.tools.build_log import EasyBuildError, print_msg, print_warning |
54 | 54 | from easybuild.tools.config import build_option |
55 | 55 | from easybuild.tools.environment import restore_env |
56 | | -from easybuild.tools.filetools import find_easyconfigs, is_patch_file, read_file, resolve_path, which, write_file |
57 | | -from easybuild.tools.github import fetch_easyconfigs_from_pr, download_repo |
| 56 | +from easybuild.tools.filetools import find_easyconfigs, is_patch_file, locate_files |
| 57 | +from easybuild.tools.filetools import read_file, resolve_path, which, write_file |
| 58 | +from easybuild.tools.github import fetch_easyconfigs_from_pr, fetch_files_from_pr, download_repo |
58 | 59 | from easybuild.tools.multidiff import multidiff |
59 | 60 | from easybuild.tools.py2vs3 import OrderedDict |
60 | 61 | from easybuild.tools.toolchain.toolchain import is_system_toolchain |
@@ -348,44 +349,13 @@ def det_easyconfig_paths(orig_paths): |
348 | 349 | ec_files = [path for path in pr_files if path.endswith('.eb')] |
349 | 350 |
|
350 | 351 | if ec_files and robot_path: |
351 | | - # look for easyconfigs with relative paths in robot search path, |
352 | | - # unless they were found at the given relative paths |
353 | | - |
354 | | - # determine which easyconfigs files need to be found, if any |
355 | | - ecs_to_find = [] |
356 | | - for idx, ec_file in enumerate(ec_files): |
357 | | - if ec_file == os.path.basename(ec_file) and not os.path.exists(ec_file): |
358 | | - ecs_to_find.append((idx, ec_file)) |
359 | | - _log.debug("List of easyconfig files to find: %s" % ecs_to_find) |
360 | | - |
361 | | - # find missing easyconfigs by walking paths in robot search path |
362 | | - for path in robot_path: |
363 | | - _log.debug("Looking for missing easyconfig files (%d left) in %s..." % (len(ecs_to_find), path)) |
364 | | - for (subpath, dirnames, filenames) in os.walk(path, topdown=True): |
365 | | - for idx, orig_path in ecs_to_find[:]: |
366 | | - if orig_path in filenames: |
367 | | - full_path = os.path.join(subpath, orig_path) |
368 | | - _log.info("Found %s in %s: %s" % (orig_path, path, full_path)) |
369 | | - ec_files[idx] = full_path |
370 | | - # if file was found, stop looking for it (first hit wins) |
371 | | - ecs_to_find.remove((idx, orig_path)) |
372 | | - |
373 | | - # stop os.walk insanity as soon as we have all we need (os.walk loop) |
374 | | - if not ecs_to_find: |
375 | | - break |
376 | | - |
377 | | - # ignore subdirs specified to be ignored by replacing items in dirnames list used by os.walk |
378 | | - dirnames[:] = [d for d in dirnames if d not in build_option('ignore_dirs')] |
379 | | - |
380 | | - # ignore archived easyconfigs, unless specified otherwise |
381 | | - if not build_option('consider_archived_easyconfigs'): |
382 | | - dirnames[:] = [d for d in dirnames if d != EASYCONFIGS_ARCHIVE_DIR] |
383 | | - |
384 | | - # stop os.walk insanity as soon as we have all we need (outer loop) |
385 | | - if not ecs_to_find: |
386 | | - break |
387 | | - |
388 | | - return [os.path.abspath(ec_file) for ec_file in ec_files] |
| 352 | + ignore_subdirs = build_option('ignore_dirs') |
| 353 | + if not build_option('consider_archived_easyconfigs'): |
| 354 | + ignore_subdirs.append(EASYCONFIGS_ARCHIVE_DIR) |
| 355 | + |
| 356 | + ec_files = locate_files(ec_files, robot_path, ignore_subdirs=ignore_subdirs) |
| 357 | + |
| 358 | + return ec_files |
389 | 359 |
|
390 | 360 |
|
391 | 361 | def parse_easyconfigs(paths, validate=True): |
@@ -728,3 +698,65 @@ def avail_easyblocks(): |
728 | 698 | easyblock_mod_name, easyblocks[easyblock_mod_name]['loc'], path) |
729 | 699 |
|
730 | 700 | return easyblocks |
| 701 | + |
| 702 | + |
| 703 | +def det_copy_ec_specs(orig_paths, from_pr): |
| 704 | + """Determine list of paths + target directory for --copy-ec.""" |
| 705 | + |
| 706 | + target_path, paths = None, [] |
| 707 | + |
| 708 | + # if only one argument is specified, use current directory as target directory |
| 709 | + if len(orig_paths) == 1: |
| 710 | + target_path = os.getcwd() |
| 711 | + paths = orig_paths[:] |
| 712 | + |
| 713 | + # if multiple arguments are specified, assume that last argument is target location, |
| 714 | + # and remove that from list of paths to copy |
| 715 | + elif orig_paths: |
| 716 | + target_path = orig_paths[-1] |
| 717 | + paths = orig_paths[:-1] |
| 718 | + |
| 719 | + # if --from-pr was used in combination with --copy-ec, some extra care must be taken |
| 720 | + if from_pr: |
| 721 | + # pull in the paths to all the changed files in the PR, |
| 722 | + # which includes easyconfigs but also patch files (& maybe more); |
| 723 | + # do this in a dedicated subdirectory of the working tmpdir, |
| 724 | + # to avoid potential trouble with already existing files in the working tmpdir |
| 725 | + # (note: we use a fixed subdirectory in the working tmpdir here rather than a unique random subdirectory, |
| 726 | + # to ensure that the caching for fetch_files_from_pr works across calls for the same PR) |
| 727 | + tmpdir = os.path.join(tempfile.gettempdir(), 'fetch_files_from_pr_%s' % from_pr) |
| 728 | + pr_paths = fetch_files_from_pr(pr=from_pr, path=tmpdir) |
| 729 | + |
| 730 | + # assume that files need to be copied to current working directory for now |
| 731 | + target_path = os.getcwd() |
| 732 | + |
| 733 | + if orig_paths: |
| 734 | + last_path = orig_paths[-1] |
| 735 | + |
| 736 | + # check files touched by PR and see if the target directory for --copy-ec |
| 737 | + # corresponds to the name of one of these files; |
| 738 | + # if so we should copy the specified file(s) to the current working directory, |
| 739 | + # since interpreting the last argument as target location is very unlikely to be correct in this case |
| 740 | + pr_filenames = [os.path.basename(p) for p in pr_paths] |
| 741 | + if last_path in pr_filenames: |
| 742 | + paths = orig_paths[:] |
| 743 | + else: |
| 744 | + target_path = last_path |
| 745 | + # exclude last argument that is used as target location |
| 746 | + paths = orig_paths[:-1] |
| 747 | + |
| 748 | + # if list of files to copy is empty at this point, |
| 749 | + # we simply copy *all* files touched by the PR |
| 750 | + if not paths: |
| 751 | + paths = pr_paths |
| 752 | + |
| 753 | + # replace path for files touched by PR (no need to worry about others) |
| 754 | + for idx, path in enumerate(paths): |
| 755 | + filename = os.path.basename(path) |
| 756 | + pr_matches = [x for x in pr_paths if os.path.basename(x) == filename] |
| 757 | + if len(pr_matches) == 1: |
| 758 | + paths[idx] = pr_matches[0] |
| 759 | + elif pr_matches: |
| 760 | + raise EasyBuildError("Found multiple paths for %s in PR: %s", filename, pr_matches) |
| 761 | + |
| 762 | + return paths, target_path |
0 commit comments