summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorscheibelp <scheibel1@llnl.gov>2017-10-25 12:08:03 -0700
committerTodd Gamblin <tgamblin@llnl.gov>2017-10-25 21:08:03 +0200
commitdcdd16b35e128c5cdc22ea12324dcd5a619db4f7 (patch)
treeb7a82d95d88d272f44858fadce9e3f9c9927db65 /lib
parentdd39862a80700998752b3e499102cca136433dba (diff)
downloadspack-dcdd16b35e128c5cdc22ea12324dcd5a619db4f7.tar.gz
spack-dcdd16b35e128c5cdc22ea12324dcd5a619db4f7.tar.bz2
spack-dcdd16b35e128c5cdc22ea12324dcd5a619db4f7.tar.xz
spack-dcdd16b35e128c5cdc22ea12324dcd5a619db4f7.zip
Check for namespace-qualified packages in repo_for_pkg (#5787)
* Fixes #5754 Previously when RepoPath.repo_for_pkg was invoked with a string, it did not check if the string included a namespace. Any namespace-qualified package provided as a string would not be found (at which point the behavior was to return the highest-precedence repository). * handle nested namespaces for packages specified as strings in repo_for_pkg * add preliminary repository tests * add test which replicates #5754 * refactor repo tests with fixtures * define repo_path equivalent at test-level scope for repo tests * add tests for unknown namespace/package * rename fixture function (no longer prefixed with 'test_')
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/repository.py22
-rw-r--r--lib/spack/spack/test/repo.py76
2 files changed, 88 insertions, 10 deletions
diff --git a/lib/spack/spack/repository.py b/lib/spack/spack/repository.py
index dedab9f51c..474dd4127e 100644
--- a/lib/spack/spack/repository.py
+++ b/lib/spack/spack/repository.py
@@ -542,19 +542,21 @@ class RepoPath(object):
"""Given a spec, get the repository for its package."""
# We don't @_autospec this function b/c it's called very frequently
# and we want to avoid parsing str's into Specs unnecessarily.
+ namespace = None
if isinstance(spec, spack.spec.Spec):
- # If the spec already has a namespace, then return the
- # corresponding repo if we know about it.
- if spec.namespace:
- fullspace = '%s.%s' % (self.super_namespace, spec.namespace)
- if fullspace not in self.by_namespace:
- raise UnknownNamespaceError(spec.namespace)
- return self.by_namespace[fullspace]
+ namespace = spec.namespace
name = spec.name
-
else:
# handle strings directly for speed instead of @_autospec'ing
- name = spec
+ namespace, _, name = spec.rpartition('.')
+
+ # If the spec already has a namespace, then return the
+ # corresponding repo if we know about it.
+ if namespace:
+ fullspace = '%s.%s' % (self.super_namespace, namespace)
+ if fullspace not in self.by_namespace:
+ raise UnknownNamespaceError(spec.namespace)
+ return self.by_namespace[fullspace]
# If there's no namespace, search in the RepoPath.
for repo in self.repos:
@@ -818,7 +820,7 @@ class Repo(object):
@_autospec
def get(self, spec, new=False):
- if spec.virtual:
+ if not self.exists(spec.name):
raise UnknownPackageError(spec.name)
if spec.namespace and spec.namespace != self.namespace:
diff --git a/lib/spack/spack/test/repo.py b/lib/spack/spack/test/repo.py
new file mode 100644
index 0000000000..8e1af931f0
--- /dev/null
+++ b/lib/spack/spack/test/repo.py
@@ -0,0 +1,76 @@
+##############################################################################
+# Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the NOTICE and LICENSE files for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+import spack
+
+import pytest
+
+
+# Unlike the repo_path fixture defined in conftest, this has a test-level
+# scope rather than a session level scope, since we want to edit the
+# given RepoPath
+@pytest.fixture()
+def repo_for_test():
+ return spack.repository.RepoPath(spack.mock_packages_path)
+
+
+@pytest.fixture()
+def extra_repo(tmpdir_factory):
+ repo_namespace = 'extra_test_repo'
+ repo_dir = tmpdir_factory.mktemp(repo_namespace)
+ repo_dir.ensure('packages', dir=True)
+
+ with open(str(repo_dir.join('repo.yaml')), 'w') as F:
+ F.write("""
+repo:
+ namespace: extra_test_repo
+""")
+ return spack.repository.Repo(str(repo_dir))
+
+
+def test_repo_getpkg(repo_for_test):
+ repo_for_test.get('a')
+ repo_for_test.get('builtin.mock.a')
+
+
+def test_repo_multi_getpkg(repo_for_test, extra_repo):
+ repo_for_test.put_first(extra_repo)
+ repo_for_test.get('a')
+ repo_for_test.get('builtin.mock.a')
+
+
+def test_repo_multi_getpkgclass(repo_for_test, extra_repo):
+ repo_for_test.put_first(extra_repo)
+ repo_for_test.get_pkg_class('a')
+ repo_for_test.get_pkg_class('builtin.mock.a')
+
+
+def test_repo_pkg_with_unknown_namespace(repo_for_test):
+ with pytest.raises(spack.repository.UnknownNamespaceError):
+ repo_for_test.get('unknown.a')
+
+
+def test_repo_unknown_pkg(repo_for_test):
+ with pytest.raises(spack.repository.UnknownPackageError):
+ repo_for_test.get('builtin.mock.nonexistentpackage')