summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/spack/spack/repo.py21
-rw-r--r--lib/spack/spack/spec.py37
-rw-r--r--lib/spack/spack/test/cmd/pkg.py3
3 files changed, 37 insertions, 24 deletions
diff --git a/lib/spack/spack/repo.py b/lib/spack/spack/repo.py
index b103ac1caf..61f5e1d28c 100644
--- a/lib/spack/spack/repo.py
+++ b/lib/spack/spack/repo.py
@@ -918,8 +918,12 @@ class Repo(object):
@autospec
def get(self, spec):
"""Returns the package associated with the supplied spec."""
- if not self.exists(spec.name):
- raise UnknownPackageError(spec.name)
+ # NOTE: we only check whether the package is None here, not whether it
+ # actually exists, because we have to load it anyway, and that ends up
+ # checking for existence. We avoid constructing FastPackageChecker,
+ # which will stat all packages.
+ if spec.name is None:
+ raise UnknownPackageError(None, self)
if spec.namespace and spec.namespace != self.namespace:
raise UnknownPackageError(spec.name, self.namespace)
@@ -1064,7 +1068,16 @@ class Repo(object):
def exists(self, pkg_name):
"""Whether a package with the supplied name exists."""
- return pkg_name in self._pkg_checker
+ if pkg_name is None:
+ return False
+
+ # if the FastPackageChecker is already constructed, use it
+ if self._fast_package_checker:
+ return pkg_name in self._pkg_checker
+
+ # if not, check for the package.py file
+ path = self.filename_for_package_name(pkg_name)
+ return os.path.exists(path)
def last_mtime(self):
"""Time a package file in this repo was last updated."""
@@ -1331,7 +1344,7 @@ class UnknownPackageError(UnknownEntityError):
long_msg = None
if name:
if repo:
- msg = "Package '{0}' not found in repository '{1}'"
+ msg = "Package '{0}' not found in repository '{1.root}'"
msg = msg.format(name, repo)
else:
msg = "Package '{0}' not found.".format(name)
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index aceceda081..609b20e238 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -3193,25 +3193,23 @@ class Spec(object):
if other.concrete:
return self.concrete and self.dag_hash() == other.dag_hash()
- # A concrete provider can satisfy a virtual dependency.
- if not self.virtual and other.virtual:
- try:
- pkg = spack.repo.get(self.fullname)
- except spack.repo.UnknownEntityError:
- # If we can't get package info on this spec, don't treat
- # it as a provider of this vdep.
- return False
-
- if pkg.provides(other.name):
- for provided, when_specs in pkg.provided.items():
- if any(self.satisfies(when_spec, deps=False, strict=strict)
- for when_spec in when_specs):
- if provided.satisfies(other):
- return True
- return False
-
- # Otherwise, first thing we care about is whether the name matches
+ # If the names are different, we need to consider virtuals
if self.name != other.name and self.name and other.name:
+ # A concrete provider can satisfy a virtual dependency.
+ if not self.virtual and other.virtual:
+ try:
+ pkg = spack.repo.get(self.fullname)
+ except spack.repo.UnknownEntityError:
+ # If we can't get package info on this spec, don't treat
+ # it as a provider of this vdep.
+ return False
+
+ if pkg.provides(other.name):
+ for provided, when_specs in pkg.provided.items():
+ if any(self.satisfies(when, deps=False, strict=strict)
+ for when in when_specs):
+ if provided.satisfies(other):
+ return True
return False
# namespaces either match, or other doesn't require one.
@@ -4639,7 +4637,8 @@ class SpecParser(spack.parse.Parser):
break
elif self.accept(HASH):
- # Get spec by hash and confirm it matches what we already have
+ # Get spec by hash and confirm it matches any constraints we
+ # already read in
hash_spec = self.spec_by_hash()
if hash_spec.satisfies(spec):
spec._dup(hash_spec)
diff --git a/lib/spack/spack/test/cmd/pkg.py b/lib/spack/spack/test/cmd/pkg.py
index 4f4293d004..f9311b14bc 100644
--- a/lib/spack/spack/test/cmd/pkg.py
+++ b/lib/spack/spack/test/cmd/pkg.py
@@ -129,7 +129,8 @@ def test_pkg_add(mock_pkg_git_repo):
finally:
shutil.rmtree('pkg-e')
# Removing a package mid-run disrupts Spack's caching
- spack.repo.path.repos[0]._fast_package_checker.invalidate()
+ if spack.repo.path.repos[0]._fast_package_checker:
+ spack.repo.path.repos[0]._fast_package_checker.invalidate()
with pytest.raises(spack.main.SpackCommandError):
pkg('add', 'does-not-exist')