summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMatthew LeGendre <legendre1@llnl.gov>2015-04-20 13:27:03 -0700
committerTodd Gamblin <tgamblin@llnl.gov>2015-08-16 12:50:39 -0700
commit7ea328659f6bbaff33319427ba7c6321cc33a637 (patch)
tree2f08cb7a32c6010e642ea569220b5c322055c8ff /lib
parentc7b8d09c7f180da5922801450fe0ae6a0f802377 (diff)
downloadspack-7ea328659f6bbaff33319427ba7c6321cc33a637.tar.gz
spack-7ea328659f6bbaff33319427ba7c6321cc33a637.tar.bz2
spack-7ea328659f6bbaff33319427ba7c6321cc33a637.tar.xz
spack-7ea328659f6bbaff33319427ba7c6321cc33a637.zip
Record package repo origins in .spec files
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/packages.py35
-rw-r--r--lib/spack/spack/repo_loader.py2
-rw-r--r--lib/spack/spack/spec.py29
3 files changed, 46 insertions, 20 deletions
diff --git a/lib/spack/spack/packages.py b/lib/spack/spack/packages.py
index 79dbd60703..48705948b7 100644
--- a/lib/spack/spack/packages.py
+++ b/lib/spack/spack/packages.py
@@ -73,12 +73,12 @@ class PackageDB(object):
dir1 = list(dups)[0][1]
dir2 = dict(s)[reponame]
tty.die("Package repo %s in directory %s has the same name as the "
- "repo in directory %s" %
+ "repo in directory %s" %
(reponame, dir1, dir2))
# For each repo, create a RepoLoader
self.repo_loaders = dict([(r[0], RepoLoader(r[0], r[1])) for r in self.repos])
-
+
self.instances = {}
self.provider_index = None
@@ -87,13 +87,13 @@ class PackageDB(object):
"""For a packagerepo directory, read the repo name from the dir/reponame file"""
path = os.path.join(dir, 'reponame')
- try:
+ try:
with closing(open(path, 'r')) as reponame_file:
- name = reponame_file.read().lstrip().rstrip()
+ name = reponame_file.read().lstrip().rstrip()
if not re.match(r'[a-zA-Z][a-zA-Z0-9]+', name):
tty.die("Package repo name '%s', read from %s, is an invalid name. "
"Repo names must began with a letter and only contain letters "
- "and numbers." % (name, path))
+ "and numbers." % (name, path))
return name
except exceptions.IOError, e:
tty.die("Could not read from package repo name file %s" % path)
@@ -107,7 +107,7 @@ class PackageDB(object):
dir_string = config.get('packagerepo', 'directories')
return dir_string.split(':')
-
+
@_autospec
def get(self, spec, **kwargs):
if spec.virtual:
@@ -118,7 +118,7 @@ class PackageDB(object):
del self.instances[spec]
if not spec in self.instances:
- package_class = self.get_class_for_package_name(spec.name)
+ package_class = self.get_class_for_package_name(spec.name, spec.repo)
try:
copy = spec.copy()
self.instances[copy] = package_class(copy)
@@ -191,7 +191,7 @@ class PackageDB(object):
path = join_path(pkgrepo[1], pkg_name)
if os.path.exists(path):
return (pkgrepo[0], path)
-
+
repo_to_add_to = roots[-1]
return (repo_to_add_to[0], join_path(repo_to_add_to[1], pkg_name))
@@ -259,7 +259,7 @@ class PackageDB(object):
if os.path.isfile(pkg_file):
all_packages.add(pkg_name)
all_package_names = list(all_packages)
- all_package_names.sort()
+ all_package_names.sort()
return all_package_names
@@ -275,12 +275,12 @@ class PackageDB(object):
@memoized
- def get_class_for_package_name(self, pkg_name):
+ def get_class_for_package_name(self, pkg_name, reponame = None):
"""Get an instance of the class for a particular package."""
- repo = self.repo_for_package_name(pkg_name)
- module_name = imported_packages_module + '.' + repo[0] + '.' + pkg_name
+ (reponame, repodir) = self.repo_for_package_name(pkg_name, reponame)
+ module_name = imported_packages_module + '.' + reponame + '.' + pkg_name
- module = self.repo_loaders[repo[0]].get_module(pkg_name)
+ module = self.repo_loaders[reponame].get_module(pkg_name)
class_name = mod_to_class(pkg_name)
cls = getattr(module, class_name)
@@ -292,8 +292,13 @@ class PackageDB(object):
class UnknownPackageError(spack.error.SpackError):
"""Raised when we encounter a package spack doesn't have."""
- def __init__(self, name):
- super(UnknownPackageError, self).__init__("Package '%s' not found." % name)
+ def __init__(self, name, repo=None):
+ msg = None
+ if repo:
+ msg = "Package %s not found in packagerepo %s." % (name, repo)
+ else:
+ msg = "Package %s not found." % name
+ super(UnknownPackageError, self).__init__(msg)
self.name = name
diff --git a/lib/spack/spack/repo_loader.py b/lib/spack/spack/repo_loader.py
index 57c19a6c28..6eaa1eead2 100644
--- a/lib/spack/spack/repo_loader.py
+++ b/lib/spack/spack/repo_loader.py
@@ -100,7 +100,7 @@ class RepoLoader(types.ModuleType):
if not os.access(file_path, os.R_OK):
tty.die("Cannot read '%s'!" % file_path)
else:
- raise spack.packages.UnknownPackageError(pkg_name)
+ raise spack.packages.UnknownPackageError(pkg_name, self.reponame if self.reponame != 'original' else None)
try:
module_name = imported_packages_module + '.' + self.reponame + '.' + pkg_name
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index e1fbb84423..972ba9ccbb 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -112,6 +112,7 @@ from spack.version import *
from spack.util.string import *
from spack.util.prefix import Prefix
from spack.virtual import ProviderIndex
+from spack.repo_loader import imported_packages_module
# Valid pattern for an identifier in Spack
identifier_re = r'\w[\w-]*'
@@ -412,6 +413,7 @@ class Spec(object):
self.dependencies = other.dependencies
self.variants = other.variants
self.variants.spec = self
+ self.repo = other.repo
# Specs are by default not assumed to be normal, but in some
# cases we've read them from a file want to assume normal.
@@ -1355,6 +1357,7 @@ class Spec(object):
self.dependencies = DependencyMap()
self.variants = other.variants.copy()
self.variants.spec = self
+ self.repo = other.repo
# If we copy dependencies, preserve DAG structure in the new spec
if kwargs.get('deps', True):
@@ -1503,6 +1506,7 @@ class Spec(object):
in the format string. The format strings you can provide are::
$_ Package name
+ $. Long package name
$@ Version
$% Compiler
$%@ Compiler & compiler version
@@ -1550,6 +1554,9 @@ class Spec(object):
if c == '_':
out.write(fmt % self.name)
+ elif c == '.':
+ longname = '%s.%s.%s' % (imported_packages_module, self.repo, self.name) if self.repo else self.name
+ out.write(fmt % longname)
elif c == '@':
if self.versions and self.versions != _any_version:
write(fmt % (c + str(self.versions)), c)
@@ -1698,17 +1705,29 @@ class SpecParser(spack.parse.Parser):
def spec(self):
"""Parse a spec out of the input. If a spec is supplied, then initialize
and return it instead of creating a new one."""
- self.check_identifier()
+
+ spec_name = None
+ spec_repo = None
+ if self.token.value.startswith(imported_packages_module):
+ lst = self.token.value.split('.')
+ spec_name = lst[-1]
+ spec_repo = lst[-2]
+ else:
+ spec_name = self.token.value
+ (spec_repo, repodir) = spack.db.repo_for_package_name(spec_name)
+
+ self.check_identifier(spec_name)
# This will init the spec without calling __init__.
spec = Spec.__new__(Spec)
- spec.name = self.token.value
+ spec.name = spec_name
spec.versions = VersionList()
spec.variants = VariantMap(spec)
spec.architecture = None
spec.compiler = None
spec.dependents = DependencyMap()
spec.dependencies = DependencyMap()
+ spec.repo = spec_repo
spec._normal = False
spec._concrete = False
@@ -1802,12 +1821,14 @@ class SpecParser(spack.parse.Parser):
return compiler
- def check_identifier(self):
+ def check_identifier(self, id=None):
"""The only identifiers that can contain '.' are versions, but version
ids are context-sensitive so we have to check on a case-by-case
basis. Call this if we detect a version id where it shouldn't be.
"""
- if '.' in self.token.value:
+ if not id:
+ id = self.token.value
+ if '.' in id:
self.last_token_error("Identifier cannot contain '.'")