concretizer: added handling for dev_path variant

This variant is currently either set from command line, in
which case it enters the concretization, or attached from
environment after concretization.
This commit is contained in:
Massimiliano Culpo 2020-10-23 18:10:53 +02:00 committed by Todd Gamblin
parent a0e8ad7a8b
commit 8a855ddac5
3 changed files with 77 additions and 10 deletions

View file

@ -2,7 +2,6 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
from __future__ import print_function
import collections
@ -38,6 +37,7 @@
import spack.package
import spack.package_prefs
import spack.repo
import spack.variant
from spack.util.executable import which
from spack.version import ver
@ -1485,7 +1485,8 @@ def setup(self, driver, specs, tests=False):
for dep in spec.traverse():
self.gen.h2('Spec: %s' % str(dep))
# Inject dev_path from environment
_develop_specs_from_env(dep)
if dep.virtual:
for clause in self.virtual_spec_clauses(dep):
self.gen.fact(clause)
@ -1499,11 +1500,33 @@ def setup(self, driver, specs, tests=False):
# TODO: then it's also a possible value.
if clause.name == 'variant_set':
variant_name = clause.args[1]
variant_def = dep.package.variants[variant_name]
# 'dev_path' and 'patches are treated in a
# special way, as they are injected from cli
# or files
if variant_name == 'dev_path':
pkg_name = clause.args[0]
self.gen.fact(fn.variant(
pkg_name, variant_name
))
self.gen.fact(fn.variant_single_value(
pkg_name, variant_name
))
elif variant_name == 'patches':
pkg_name = clause.args[0]
self.gen.fact(fn.variant(
pkg_name, variant_name
))
else:
variant_def = dep.package.variants[
variant_name
]
variant_def.validate_or_raise(
dep.variants[variant_name],
dep.package
)
# State that this variant is a possible value
# to account for variant values that are not
# enumerated explicitly
self.gen.fact(
fn.variant_possible_value(*clause.args)
)
@ -1556,6 +1579,21 @@ def node_target(self, pkg, target):
self._arch(pkg).target = target
def variant_value(self, pkg, name, value):
# FIXME: is there a way not to special case 'dev_path' everywhere?
if name == 'dev_path':
self._specs[pkg].variants.setdefault(
name,
spack.variant.SingleValuedVariant(name, value)
)
return
if name == 'patches':
self._specs[pkg].variants.setdefault(
name,
spack.variant.MultiValuedVariant(name, value)
)
return
pkg_class = spack.repo.path.get_pkg_class(pkg)
variant = self._specs[pkg].variants.get(name)
@ -1696,6 +1734,9 @@ def build_specs(self, function_tuples):
for s in self._specs.values():
spack.spec.Spec.ensure_external_path_if_external(s)
for s in self._specs.values():
_develop_specs_from_env(s)
for s in self._specs.values():
s._mark_concrete()
@ -1738,6 +1779,24 @@ def highlight(string):
return string
def _develop_specs_from_env(spec):
env = spack.environment.get_env(None, None)
dev_info = env.dev_specs.get(spec.name, {}) if env else {}
if not dev_info:
return
path = dev_info['path']
path = path if os.path.isabs(path) else os.path.join(env.path, path)
if 'dev_path' in spec.variants:
assert spec.variants['dev_path'].value == path
else:
spec.variants.setdefault(
'dev_path', spack.variant.SingleValuedVariant('dev_path', path)
)
spec.constrain(dev_info['spec'])
#
# These are handwritten parts for the Spack ASP model.
#

View file

@ -19,6 +19,8 @@ def test_dev_build_basics(tmpdir, mock_packages, install_mockery):
spec = spack.spec.Spec('dev-build-test-install@0.0.0 dev_path=%s' % tmpdir)
spec.concretize()
assert 'dev_path' in spec.variants
with tmpdir.as_cwd():
with open(spec.package.filename, 'w') as f:
f.write(spec.package.original_string)

View file

@ -468,8 +468,9 @@ def test_init_from_yaml(tmpdir):
@pytest.mark.usefixtures('config')
def test_env_view_external_prefix(tmpdir_factory, mutable_database,
mock_packages):
def test_env_view_external_prefix(
tmpdir_factory, mutable_database, mock_packages
):
fake_prefix = tmpdir_factory.mktemp('a-prefix')
fake_bin = fake_prefix.join('bin')
fake_bin.ensure(dir=True)
@ -485,7 +486,7 @@ def test_env_view_external_prefix(tmpdir_factory, mutable_database,
packages:
a:
externals:
- spec: a
- spec: a@2.0
prefix: {a_prefix}
buildable: false
""".format(a_prefix=str(fake_prefix)))
@ -1441,6 +1442,11 @@ def test_stack_yaml_force_remove_from_matrix(tmpdir):
def test_stack_concretize_extraneous_deps(tmpdir, config, mock_packages):
# FIXME: The new concretizer doesn't handle yet soft
# FIXME: constraints for stacks
if spack.config.get('config:concretizer') == 'clingo':
pytest.skip('Clingo concretizer does not support soft constraints')
filename = str(tmpdir.join('spack.yaml'))
with open(filename, 'w') as f:
f.write("""\