Skip to content

Commit 8592d75

Browse files
committed
add support for --copy-ec
1 parent f8a1da6 commit 8592d75

File tree

3 files changed

+96
-5
lines changed

3 files changed

+96
-5
lines changed

easybuild/main.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
from easybuild.tools.config import find_last_log, get_repository, get_repositorypath, build_option
5757
from easybuild.tools.containers.common import containerize
5858
from easybuild.tools.docs import list_software
59-
from easybuild.tools.filetools import adjust_permissions, cleanup, read_file, write_file
59+
from easybuild.tools.filetools import adjust_permissions, cleanup, copy_file, copy_files, read_file, write_file
6060
from easybuild.tools.github import check_github, close_pr, new_branch_github, find_easybuild_easyconfig
6161
from easybuild.tools.github import install_github_token, list_prs, new_pr, new_pr_from_branch, merge_pr
6262
from easybuild.tools.github import sync_branch_with_develop, sync_pr_with_develop, update_branch, update_pr
@@ -291,6 +291,9 @@ def main(args=None, logfile=None, do_build=None, testing=False, modtool=None):
291291
eb_file = find_easybuild_easyconfig()
292292
orig_paths.append(eb_file)
293293

294+
# last path is target when --copy-ec is used, so remove that from the list
295+
target_path = orig_paths.pop() if options.copy_ec else None
296+
294297
categorized_paths = categorize_files_by_type(orig_paths)
295298

296299
# command line options that do not require any easyconfigs to be specified
@@ -302,9 +305,17 @@ def main(args=None, logfile=None, do_build=None, testing=False, modtool=None):
302305
# determine paths to easyconfigs
303306
determined_paths = det_easyconfig_paths(categorized_paths['easyconfigs'])
304307

305-
if options.fix_deprecated_easyconfigs or options.show_ec:
306-
if options.fix_deprecated_easyconfigs:
308+
if options.copy_ec or options.fix_deprecated_easyconfigs or options.show_ec:
309+
310+
if options.copy_ec:
311+
if len(determined_paths) == 1:
312+
copy_file(determined_paths[0], target_path)
313+
else:
314+
copy_files(determined_paths, target_path)
315+
316+
elif options.fix_deprecated_easyconfigs:
307317
fix_deprecated_easyconfigs(determined_paths)
318+
308319
elif options.show_ec:
309320
for path in determined_paths:
310321
print_msg("Contents of %s:" % path)

easybuild/tools/options.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ def override_options(self):
342342
{'metavar': 'WHEN'}),
343343
'consider-archived-easyconfigs': ("Also consider archived easyconfigs", None, 'store_true', False),
344344
'containerize': ("Generate container recipe/image", None, 'store_true', False, 'C'),
345+
'copy-ec': ("Copy specified easyconfig(s) to specified location", None, 'store_true', False),
345346
'debug-lmod': ("Run Lmod modules tool commands in debug module", None, 'store_true', False),
346347
'default-opt-level': ("Specify default optimisation level", 'choice', 'store', DEFAULT_OPT_LEVEL,
347348
Compiler.COMPILER_OPT_FLAGS),

test/framework/options.py

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@
4949
from easybuild.tools.config import DEFAULT_MODULECLASSES
5050
from easybuild.tools.config import find_last_log, get_build_log_path, get_module_syntax, module_classes
5151
from easybuild.tools.environment import modify_env
52-
from easybuild.tools.filetools import copy_dir, copy_file, download_file, mkdir, read_file, remove_file
53-
from easybuild.tools.filetools import which, write_file
52+
from easybuild.tools.filetools import change_dir, copy_dir, copy_file, download_file, mkdir, read_file
53+
from easybuild.tools.filetools import remove_dir, remove_file, which, write_file
5454
from easybuild.tools.github import GITHUB_RAW, GITHUB_EB_MAIN, GITHUB_EASYCONFIGS_REPO
5555
from easybuild.tools.github import URL_SEPARATOR, fetch_github_token
5656
from easybuild.tools.modules import Lmod
@@ -828,6 +828,85 @@ def test_show_ec(self):
828828
regex = re.compile(pattern, re.M)
829829
self.assertTrue(regex.search(stdout), "Pattern '%s' found in: %s" % (regex.pattern, stdout))
830830

831+
def test_copy_ec(self):
832+
"""Test --copy-ec."""
833+
834+
topdir = os.path.dirname(os.path.abspath(__file__))
835+
test_easyconfigs_dir = os.path.join(topdir, 'easyconfigs', 'test_ecs')
836+
837+
toy_ec_txt = read_file(os.path.join(test_easyconfigs_dir, 't', 'toy', 'toy-0.0.eb'))
838+
bzip2_ec_txt = read_file(os.path.join(test_easyconfigs_dir, 'b', 'bzip2', 'bzip2-1.0.6-GCC-4.9.2.eb'))
839+
840+
# basic test: copying one easyconfig file to a non-existing absolute path
841+
test_ec = os.path.join(self.test_prefix, 'test.eb')
842+
args = ['--copy-ec', 'toy-0.0.eb', test_ec]
843+
self.eb_main(args)
844+
845+
self.assertTrue(os.path.exists(test_ec))
846+
self.assertEqual(toy_ec_txt, read_file(test_ec))
847+
848+
remove_file(test_ec)
849+
850+
# basic test: copying one easyconfig file to a non-existing relative path
851+
cwd = change_dir(self.test_prefix)
852+
target_fn = 'test.eb'
853+
self.assertFalse(os.path.exists(target_fn))
854+
855+
args = ['--copy-ec', 'toy-0.0.eb', target_fn]
856+
self.eb_main(args)
857+
858+
change_dir(cwd)
859+
860+
self.assertTrue(os.path.exists(test_ec))
861+
self.assertEqual(toy_ec_txt, read_file(test_ec))
862+
863+
# copying one easyconfig into an existing directory
864+
test_target_dir = os.path.join(self.test_prefix, 'test_target_dir')
865+
mkdir(test_target_dir)
866+
args = ['--copy-ec', 'toy-0.0.eb', test_target_dir]
867+
self.eb_main(args)
868+
869+
copied_toy_ec = os.path.join(test_target_dir, 'toy-0.0.eb')
870+
self.assertTrue(os.path.exists(copied_toy_ec))
871+
self.assertEqual(toy_ec_txt, read_file(copied_toy_ec))
872+
873+
remove_dir(test_target_dir)
874+
875+
def check_copied_files():
876+
"""Helper function to check result of copying multiple easyconfigs."""
877+
self.assertTrue(os.path.exists(test_target_dir))
878+
self.assertEqual(sorted(os.listdir(test_target_dir)), ['bzip2-1.0.6-GCC-4.9.2.eb', 'toy-0.0.eb'])
879+
copied_toy_ec = os.path.join(test_target_dir, 'toy-0.0.eb')
880+
self.assertTrue(os.path.exists(copied_toy_ec))
881+
self.assertEqual(toy_ec_txt, read_file(copied_toy_ec))
882+
copied_bzip2_ec = os.path.join(test_target_dir, 'bzip2-1.0.6-GCC-4.9.2.eb')
883+
self.assertTrue(os.path.exists(copied_bzip2_ec))
884+
self.assertEqual(bzip2_ec_txt, read_file(copied_bzip2_ec))
885+
886+
# copying multiple easyconfig files to a non-existing target directory (which is created automatically)
887+
args = ['--copy-ec', 'toy-0.0.eb', 'bzip2-1.0.6-GCC-4.9.2.eb', test_target_dir]
888+
self.eb_main(args)
889+
890+
check_copied_files()
891+
892+
remove_dir(test_target_dir)
893+
894+
# same but with relative path for target dir
895+
change_dir(self.test_prefix)
896+
args[-1] = os.path.basename(test_target_dir)
897+
self.assertFalse(os.path.exists(args[-1]))
898+
899+
self.eb_main(args)
900+
901+
check_copied_files()
902+
903+
# copying multiple easyconfig to an existing target file resuts in an error
904+
target = os.path.join(self.test_prefix, 'test.eb')
905+
self.assertTrue(os.path.isfile(target))
906+
args = ['--copy-ec', 'toy-0.0.eb', 'bzip2-1.0.6-GCC-4.9.2.eb', target]
907+
error_pattern = ".*/test.eb exists but is not a directory"
908+
self.assertErrorRegex(EasyBuildError, error_pattern, self.eb_main, args, raise_error=True)
909+
831910
def test_dry_run(self):
832911
"""Test dry run (long format)."""
833912
fd, dummylogfn = tempfile.mkstemp(prefix='easybuild-dummy', suffix='.log')

0 commit comments

Comments
 (0)