summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarmen Stoppels <harmenstoppels@gmail.com>2022-04-25 17:41:48 +0200
committerGitHub <noreply@github.com>2022-04-25 08:41:48 -0700
commit3dd4999fd7bb32f94dcf686b7c205b5c942cb7a6 (patch)
tree5c55d3de9a296fdebb68a62642746cdb9f082fb0
parentc1ed51e767267422c503515789327c794bca2db6 (diff)
downloadspack-3dd4999fd7bb32f94dcf686b7c205b5c942cb7a6.tar.gz
spack-3dd4999fd7bb32f94dcf686b7c205b5c942cb7a6.tar.bz2
spack-3dd4999fd7bb32f94dcf686b7c205b5c942cb7a6.tar.xz
spack-3dd4999fd7bb32f94dcf686b7c205b5c942cb7a6.zip
spec.py: make parser select from environment (#30276)
The parser is already committing a crime of querying the database for specs when it encounters a `/hash`. It's helpful, but unfortunately not helpful when trying to install a specific spec in an environment by hash. Therefore, consider the environment first, then the database. This allows the following: ```console $ spack -e . concretize ==> Starting concretization ==> Environment concretized in 0.27 seconds. ==> Concretized diffutils - 7vangk4 diffutils@3.8%gcc@10.3.0 arch=linux-ubuntu20.04-zen2 - hyb7ehx ^libiconv@1.16%gcc@10.3.0 libs=shared,static arch=linux-ubuntu20.04-zen2 $ spack -e . install /hyb7ehx ==> Installing libiconv-1.16-hyb7ehxxyqqp2hiw56bzm5ampkw6cxws ... ==> libiconv: Successfully installed libiconv-1.16-hyb7ehxxyqqp2hiw56bzm5ampkw6cxws Fetch: 0.01s. Build: 17.54s. Total: 17.55s. [+] /tmp/tmp.VpvYApofVm/store/linux-ubuntu20.04-zen2/gcc-10.3.0/libiconv-1.16-hyb7ehxxyqqp2hiw56bzm5ampkw6cxws ```
-rw-r--r--lib/spack/spack/environment/environment.py9
-rw-r--r--lib/spack/spack/spec.py9
-rw-r--r--lib/spack/spack/test/cmd/env.py13
3 files changed, 29 insertions, 2 deletions
diff --git a/lib/spack/spack/environment/environment.py b/lib/spack/spack/environment/environment.py
index ade4fd248c..5ef53f5b72 100644
--- a/lib/spack/spack/environment/environment.py
+++ b/lib/spack/spack/environment/environment.py
@@ -1659,6 +1659,15 @@ class Environment(object):
for s, h in zip(self.concretized_user_specs, self.concretized_order):
yield (s, self.specs_by_hash[h])
+ def get_by_hash(self, dag_hash):
+ matches = {}
+ for _, root in self.concretized_specs():
+ for spec in root.traverse(root=True):
+ dep_hash = spec.dag_hash()
+ if dep_hash.startswith(dag_hash):
+ matches[dep_hash] = spec
+ return list(matches.values())
+
def matching_spec(self, spec):
"""
Given a spec (likely not concretized), find a matching concretized
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index 1283117e1d..56eb5c6254 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -5167,10 +5167,15 @@ class SpecParser(spack.parse.Parser):
return self.compiler()
def spec_by_hash(self):
+ # TODO: Remove parser dependency on active environment and database.
+ import spack.environment
self.expect(ID)
-
dag_hash = self.token.value
- matches = spack.store.db.get_by_hash(dag_hash)
+ matches = []
+ if spack.environment.active_environment():
+ matches = spack.environment.active_environment().get_by_hash(dag_hash)
+ if not matches:
+ matches = spack.store.db.get_by_hash(dag_hash)
if not matches:
raise NoSuchHashError(dag_hash)
diff --git a/lib/spack/spack/test/cmd/env.py b/lib/spack/spack/test/cmd/env.py
index cdd3e29cfb..498f0a71cf 100644
--- a/lib/spack/spack/test/cmd/env.py
+++ b/lib/spack/spack/test/cmd/env.py
@@ -2843,3 +2843,16 @@ def test_environment_view_target_already_exists(
# Make sure the dir was left untouched.
assert not os.path.lexists(view)
assert os.listdir(real_view) == ['file']
+
+
+def test_environment_query_spec_by_hash(mock_stage, mock_fetch, install_mockery):
+ env('create', 'test')
+ with ev.read('test'):
+ add('libdwarf')
+ concretize()
+ with ev.read('test') as e:
+ spec = e.matching_spec('libelf')
+ install('/{0}'.format(spec.dag_hash()))
+ with ev.read('test') as e:
+ assert not e.matching_spec('libdwarf').installed
+ assert e.matching_spec('libelf').installed