spack concretize: add --reuse argument

This commit is contained in:
Massimiliano Culpo 2021-11-03 16:07:20 +01:00 committed by Todd Gamblin
parent 290f57c779
commit e2744fafa1
5 changed files with 36 additions and 17 deletions

View file

@ -4,6 +4,7 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import spack.cmd
import spack.cmd.common.arguments
import spack.environment as ev
description = 'concretize an environment and write a lockfile'
@ -12,6 +13,7 @@
def setup_parser(subparser):
spack.cmd.common.arguments.add_common_arguments(subparser, ['reuse'])
subparser.add_argument(
'-f', '--force', action='store_true',
help="Re-concretize even if already concretized.")
@ -34,6 +36,8 @@ def concretize(parser, args):
tests = False
with env.write_transaction():
concretized_specs = env.concretize(force=args.force, tests=tests)
concretized_specs = env.concretize(
force=args.force, tests=tests, reuse=args.reuse
)
ev.display_specs(concretized_specs)
env.write()

View file

@ -732,7 +732,11 @@ def concretize_specs_together(*abstract_specs, **kwargs):
def _concretize_specs_together_new(*abstract_specs, **kwargs):
import spack.solver.asp
result = spack.solver.asp.solve(abstract_specs)
concretization_kwargs = {
'tests': kwargs.get('tests', False),
'reuse': kwargs.get('reuse', False)
}
result = spack.solver.asp.solve(abstract_specs, **concretization_kwargs)
result.raise_if_unsat()
return [s.copy() for s in result.specs]
@ -768,10 +772,15 @@ def make_concretization_repository(abstract_specs):
abstract_specs = [spack.spec.Spec(s) for s in abstract_specs]
concretization_repository = make_concretization_repository(abstract_specs)
concretization_kwargs = {
'tests': kwargs.get('tests', False),
'reuse': kwargs.get('reuse', False)
}
with spack.repo.additional_repository(concretization_repository):
# Spec from a helper package that depends on all the abstract_specs
concretization_root = spack.spec.Spec('concretizationroot')
concretization_root.concretize(tests=kwargs.get('tests', False))
concretization_root.concretize(**concretization_kwargs)
# Retrieve the direct dependencies
concrete_specs = [
concretization_root[spec.name].copy() for spec in abstract_specs

View file

@ -1035,7 +1035,7 @@ def is_develop(self, spec):
"""Returns true when the spec is built from local sources"""
return spec.name in self.dev_specs
def concretize(self, force=False, tests=False):
def concretize(self, force=False, tests=False, reuse=False):
"""Concretize user_specs in this environment.
Only concretizes specs that haven't been concretized yet unless
@ -1049,6 +1049,8 @@ def concretize(self, force=False, tests=False):
already concretized
tests (bool or list or set): False to run no tests, True to test
all packages, or a list of package names to run tests for some
reuse (bool): if True try to maximize reuse of already installed
specs, if False don't account for installation status.
Returns:
List of specs that have been concretized. Each entry is a tuple of
@ -1062,14 +1064,15 @@ def concretize(self, force=False, tests=False):
# Pick the right concretization strategy
if self.concretization == 'together':
return self._concretize_together(tests=tests)
return self._concretize_together(tests=tests, reuse=reuse)
if self.concretization == 'separately':
return self._concretize_separately(tests=tests)
return self._concretize_separately(tests=tests, reuse=reuse)
msg = 'concretization strategy not implemented [{0}]'
raise SpackEnvironmentError(msg.format(self.concretization))
def _concretize_together(self, tests=False):
def _concretize_together(self, tests=False, reuse=False):
"""Concretization strategy that concretizes all the specs
in the same DAG.
"""
@ -1102,13 +1105,14 @@ def _concretize_together(self, tests=False):
self.specs_by_hash = {}
concrete_specs = spack.concretize.concretize_specs_together(
*self.user_specs, tests=tests)
*self.user_specs, tests=tests, reuse=reuse
)
concretized_specs = [x for x in zip(self.user_specs, concrete_specs)]
for abstract, concrete in concretized_specs:
self._add_concrete_spec(abstract, concrete)
return concretized_specs
def _concretize_separately(self, tests=False):
def _concretize_separately(self, tests=False, reuse=False):
"""Concretization strategy that concretizes separately one
user spec after the other.
"""
@ -1133,7 +1137,7 @@ def _concretize_separately(self, tests=False):
):
if uspec not in old_concretized_user_specs:
root_specs.append(uspec)
arguments.append((uspec_constraints, tests))
arguments.append((uspec_constraints, tests, reuse))
# Ensure we don't try to bootstrap clingo in parallel
if spack.config.get('config:concretizer') == 'clingo':
@ -1988,7 +1992,7 @@ def _tree_to_display(spec):
print('')
def _concretize_from_constraints(spec_constraints, tests=False):
def _concretize_from_constraints(spec_constraints, tests=False, reuse=False):
# Accept only valid constraints from list and concretize spec
# Get the named spec even if out of order
root_spec = [s for s in spec_constraints if s.name]
@ -2007,7 +2011,7 @@ def _concretize_from_constraints(spec_constraints, tests=False):
if c not in invalid_constraints:
s.constrain(c)
try:
return s.concretized(tests=tests)
return s.concretized(tests=tests, reuse=reuse)
except spack.spec.InvalidDependencyError as e:
invalid_deps_string = ['^' + d for d in e.invalid_deps]
invalid_deps = [c for c in spec_constraints
@ -2027,9 +2031,9 @@ def _concretize_from_constraints(spec_constraints, tests=False):
def _concretize_task(packed_arguments):
spec_constraints, tests = packed_arguments
spec_constraints, tests, reuse = packed_arguments
with tty.SuppressOutput(msg_enabled=False):
return _concretize_from_constraints(spec_constraints, tests)
return _concretize_from_constraints(spec_constraints, tests, reuse)
def make_repo_path(root):

View file

@ -2666,7 +2666,7 @@ def _mark_concrete(self, value=True):
s.clear_cached_hashes()
s._mark_root_concrete(value)
def concretized(self, tests=False):
def concretized(self, tests=False, reuse=False):
"""This is a non-destructive version of concretize().
First clones, then returns a concrete version of this package
@ -2676,9 +2676,11 @@ def concretized(self, tests=False):
tests (bool or list): if False disregard 'test' dependencies,
if a list of names activate them for the packages in the list,
if True activate 'test' dependencies for all packages.
reuse (bool): if True try to maximize reuse of already installed
specs, if False don't account for installation status.
"""
clone = self.copy(caches=True)
clone.concretize(tests=tests)
clone.concretize(tests=tests, reuse=reuse)
return clone
def flat_dependencies(self, **kwargs):

View file

@ -705,7 +705,7 @@ _spack_compilers() {
}
_spack_concretize() {
SPACK_COMPREPLY="-h --help -f --force --test"
SPACK_COMPREPLY="-h --help --reuse -f --force --test"
}
_spack_config() {