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

View File

@ -732,7 +732,11 @@ def concretize_specs_together(*abstract_specs, **kwargs):
def _concretize_specs_together_new(*abstract_specs, **kwargs): def _concretize_specs_together_new(*abstract_specs, **kwargs):
import spack.solver.asp 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() result.raise_if_unsat()
return [s.copy() for s in result.specs] 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] abstract_specs = [spack.spec.Spec(s) for s in abstract_specs]
concretization_repository = make_concretization_repository(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): with spack.repo.additional_repository(concretization_repository):
# Spec from a helper package that depends on all the abstract_specs # Spec from a helper package that depends on all the abstract_specs
concretization_root = spack.spec.Spec('concretizationroot') concretization_root = spack.spec.Spec('concretizationroot')
concretization_root.concretize(tests=kwargs.get('tests', False)) concretization_root.concretize(**concretization_kwargs)
# Retrieve the direct dependencies # Retrieve the direct dependencies
concrete_specs = [ concrete_specs = [
concretization_root[spec.name].copy() for spec in abstract_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""" """Returns true when the spec is built from local sources"""
return spec.name in self.dev_specs 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. """Concretize user_specs in this environment.
Only concretizes specs that haven't been concretized yet unless Only concretizes specs that haven't been concretized yet unless
@ -1049,6 +1049,8 @@ def concretize(self, force=False, tests=False):
already concretized already concretized
tests (bool or list or set): False to run no tests, True to test 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 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: Returns:
List of specs that have been concretized. Each entry is a tuple of 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 # Pick the right concretization strategy
if self.concretization == 'together': if self.concretization == 'together':
return self._concretize_together(tests=tests) return self._concretize_together(tests=tests, reuse=reuse)
if self.concretization == 'separately': if self.concretization == 'separately':
return self._concretize_separately(tests=tests) return self._concretize_separately(tests=tests, reuse=reuse)
msg = 'concretization strategy not implemented [{0}]' msg = 'concretization strategy not implemented [{0}]'
raise SpackEnvironmentError(msg.format(self.concretization)) 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 """Concretization strategy that concretizes all the specs
in the same DAG. in the same DAG.
""" """
@ -1102,13 +1105,14 @@ def _concretize_together(self, tests=False):
self.specs_by_hash = {} self.specs_by_hash = {}
concrete_specs = spack.concretize.concretize_specs_together( 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)] concretized_specs = [x for x in zip(self.user_specs, concrete_specs)]
for abstract, concrete in concretized_specs: for abstract, concrete in concretized_specs:
self._add_concrete_spec(abstract, concrete) self._add_concrete_spec(abstract, concrete)
return concretized_specs return concretized_specs
def _concretize_separately(self, tests=False): def _concretize_separately(self, tests=False, reuse=False):
"""Concretization strategy that concretizes separately one """Concretization strategy that concretizes separately one
user spec after the other. user spec after the other.
""" """
@ -1133,7 +1137,7 @@ def _concretize_separately(self, tests=False):
): ):
if uspec not in old_concretized_user_specs: if uspec not in old_concretized_user_specs:
root_specs.append(uspec) 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 # Ensure we don't try to bootstrap clingo in parallel
if spack.config.get('config:concretizer') == 'clingo': if spack.config.get('config:concretizer') == 'clingo':
@ -1988,7 +1992,7 @@ def _tree_to_display(spec):
print('') 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 # Accept only valid constraints from list and concretize spec
# Get the named spec even if out of order # Get the named spec even if out of order
root_spec = [s for s in spec_constraints if s.name] 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: if c not in invalid_constraints:
s.constrain(c) s.constrain(c)
try: try:
return s.concretized(tests=tests) return s.concretized(tests=tests, reuse=reuse)
except spack.spec.InvalidDependencyError as e: except spack.spec.InvalidDependencyError as e:
invalid_deps_string = ['^' + d for d in e.invalid_deps] invalid_deps_string = ['^' + d for d in e.invalid_deps]
invalid_deps = [c for c in spec_constraints 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): def _concretize_task(packed_arguments):
spec_constraints, tests = packed_arguments spec_constraints, tests, reuse = packed_arguments
with tty.SuppressOutput(msg_enabled=False): 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): def make_repo_path(root):

View File

@ -2666,7 +2666,7 @@ def _mark_concrete(self, value=True):
s.clear_cached_hashes() s.clear_cached_hashes()
s._mark_root_concrete(value) 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(). """This is a non-destructive version of concretize().
First clones, then returns a concrete version of this package 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, tests (bool or list): if False disregard 'test' dependencies,
if a list of names activate them for the packages in the list, if a list of names activate them for the packages in the list,
if True activate 'test' dependencies for all packages. 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 = self.copy(caches=True)
clone.concretize(tests=tests) clone.concretize(tests=tests, reuse=reuse)
return clone return clone
def flat_dependencies(self, **kwargs): def flat_dependencies(self, **kwargs):

View File

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