diff options
-rw-r--r-- | lib/spack/spack/repo.py | 21 | ||||
-rw-r--r-- | lib/spack/spack/spec.py | 37 | ||||
-rw-r--r-- | lib/spack/spack/test/cmd/pkg.py | 3 |
3 files changed, 37 insertions, 24 deletions
diff --git a/lib/spack/spack/repo.py b/lib/spack/spack/repo.py index 52b44e0120..1534054075 100644 --- a/lib/spack/spack/repo.py +++ b/lib/spack/spack/repo.py @@ -914,8 +914,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) @@ -1060,7 +1064,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.""" @@ -1327,7 +1340,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 609f05ca03..edb2c94300 100644 --- a/lib/spack/spack/spec.py +++ b/lib/spack/spack/spec.py @@ -3148,25 +3148,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. @@ -4513,7 +4511,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 52127e8605..5319e4e288 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') |