Enable install of multiple specs from yaml files (#6984)
This commit is contained in:
parent
8bc5916b68
commit
1f39afe475
2 changed files with 53 additions and 22 deletions
|
@ -92,7 +92,8 @@ def setup_parser(subparser):
|
||||||
'--fake', action='store_true',
|
'--fake', action='store_true',
|
||||||
help="fake install for debug purposes.")
|
help="fake install for debug purposes.")
|
||||||
subparser.add_argument(
|
subparser.add_argument(
|
||||||
'-f', '--file', action='store_true',
|
'-f', '--file', action='append', default=[],
|
||||||
|
dest='specfiles', metavar='SPEC_YAML_FILE',
|
||||||
help="install from file. Read specs to install from .yaml files")
|
help="install from file. Read specs to install from .yaml files")
|
||||||
|
|
||||||
cd_group = subparser.add_mutually_exclusive_group()
|
cd_group = subparser.add_mutually_exclusive_group()
|
||||||
|
@ -377,8 +378,8 @@ def install_spec(cli_args, kwargs, spec):
|
||||||
|
|
||||||
|
|
||||||
def install(parser, args, **kwargs):
|
def install(parser, args, **kwargs):
|
||||||
if not args.package:
|
if not args.package and not args.specfiles:
|
||||||
tty.die("install requires at least one package argument")
|
tty.die("install requires at least one package argument or yaml file")
|
||||||
|
|
||||||
if args.jobs is not None:
|
if args.jobs is not None:
|
||||||
if args.jobs <= 0:
|
if args.jobs <= 0:
|
||||||
|
@ -405,6 +406,7 @@ def install(parser, args, **kwargs):
|
||||||
if args.run_tests:
|
if args.run_tests:
|
||||||
tty.warn("Deprecated option: --run-tests: use --test=all instead")
|
tty.warn("Deprecated option: --run-tests: use --test=all instead")
|
||||||
|
|
||||||
|
# 1. Abstract specs from cli
|
||||||
specs = spack.cmd.parse_specs(args.package)
|
specs = spack.cmd.parse_specs(args.package)
|
||||||
if args.test == 'all' or args.run_tests:
|
if args.test == 'all' or args.run_tests:
|
||||||
spack.package_testing.test_all()
|
spack.package_testing.test_all()
|
||||||
|
@ -412,23 +414,21 @@ def install(parser, args, **kwargs):
|
||||||
for spec in specs:
|
for spec in specs:
|
||||||
spack.package_testing.test(spec.name)
|
spack.package_testing.test(spec.name)
|
||||||
|
|
||||||
# Spec from cli
|
specs = spack.cmd.parse_specs(args.package, concretize=True)
|
||||||
specs = []
|
|
||||||
if args.file:
|
|
||||||
for file in args.package:
|
|
||||||
with open(file, 'r') as f:
|
|
||||||
s = spack.spec.Spec.from_yaml(f)
|
|
||||||
|
|
||||||
if s.concretized().dag_hash() != s.dag_hash():
|
# 2. Concrete specs from yaml files
|
||||||
msg = 'skipped invalid file "{0}". '
|
for file in args.specfiles:
|
||||||
msg += 'The file does not contain a concrete spec.'
|
with open(file, 'r') as f:
|
||||||
tty.warn(msg.format(file))
|
s = spack.spec.Spec.from_yaml(f)
|
||||||
continue
|
|
||||||
|
|
||||||
specs.append(s.concretized())
|
if s.concretized().dag_hash() != s.dag_hash():
|
||||||
|
msg = 'skipped invalid file "{0}". '
|
||||||
|
msg += 'The file does not contain a concrete spec.'
|
||||||
|
tty.warn(msg.format(file))
|
||||||
|
continue
|
||||||
|
|
||||||
|
specs.append(s.concretized())
|
||||||
|
|
||||||
else:
|
|
||||||
specs = spack.cmd.parse_specs(args.package, concretize=True)
|
|
||||||
if len(specs) == 0:
|
if len(specs) == 0:
|
||||||
tty.die('The `spack install` command requires a spec to install.')
|
tty.die('The `spack install` command requires a spec to install.')
|
||||||
|
|
||||||
|
|
|
@ -259,10 +259,41 @@ def test_install_from_file(spec, concretize, error_code, tmpdir):
|
||||||
if concretize:
|
if concretize:
|
||||||
spec.concretize()
|
spec.concretize()
|
||||||
|
|
||||||
with fs.working_dir(str(tmpdir)):
|
specfile = tmpdir.join('spec.yaml')
|
||||||
# A non-concrete spec will fail to be installed
|
|
||||||
with open('spec.yaml', 'w') as f:
|
|
||||||
spec.to_yaml(f)
|
|
||||||
install('-f', 'spec.yaml', fail_on_error=False)
|
|
||||||
|
|
||||||
|
with specfile.open('w') as f:
|
||||||
|
spec.to_yaml(f)
|
||||||
|
|
||||||
|
# Relative path to specfile (regression for #6906)
|
||||||
|
with fs.working_dir(specfile.dirname):
|
||||||
|
# A non-concrete spec will fail to be installed
|
||||||
|
install('-f', specfile.basename, fail_on_error=False)
|
||||||
assert install.returncode == error_code
|
assert install.returncode == error_code
|
||||||
|
|
||||||
|
# Absolute path to specfile (regression for #6983)
|
||||||
|
install('-f', str(specfile), fail_on_error=False)
|
||||||
|
assert install.returncode == error_code
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures('noop_install', 'config')
|
||||||
|
@pytest.mark.parametrize('clispecs,filespecs', [
|
||||||
|
[[], ['mpi']],
|
||||||
|
[[], ['mpi', 'boost']],
|
||||||
|
[['cmake'], ['mpi']],
|
||||||
|
[['cmake', 'libelf'], []],
|
||||||
|
[['cmake', 'libelf'], ['mpi', 'boost']],
|
||||||
|
])
|
||||||
|
def test_install_mix_cli_and_files(clispecs, filespecs, tmpdir):
|
||||||
|
|
||||||
|
args = clispecs
|
||||||
|
|
||||||
|
for spec in filespecs:
|
||||||
|
filepath = tmpdir.join(spec + '.yaml')
|
||||||
|
args = ['-f', str(filepath)] + args
|
||||||
|
s = Spec(spec)
|
||||||
|
s.concretize()
|
||||||
|
with filepath.open('w') as f:
|
||||||
|
s.to_yaml(f)
|
||||||
|
|
||||||
|
install(*args, fail_on_error=False)
|
||||||
|
assert install.returncode == 0
|
||||||
|
|
Loading…
Reference in a new issue