Record package repo origins in .spec files
This commit is contained in:
parent
c7b8d09c7f
commit
7ea328659f
@ -73,12 +73,12 @@ def __init__(self, default_root):
|
|||||||
dir1 = list(dups)[0][1]
|
dir1 = list(dups)[0][1]
|
||||||
dir2 = dict(s)[reponame]
|
dir2 = dict(s)[reponame]
|
||||||
tty.die("Package repo %s in directory %s has the same name as the "
|
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))
|
(reponame, dir1, dir2))
|
||||||
|
|
||||||
# For each repo, create a RepoLoader
|
# For each repo, create a RepoLoader
|
||||||
self.repo_loaders = dict([(r[0], RepoLoader(r[0], r[1])) for r in self.repos])
|
self.repo_loaders = dict([(r[0], RepoLoader(r[0], r[1])) for r in self.repos])
|
||||||
|
|
||||||
self.instances = {}
|
self.instances = {}
|
||||||
self.provider_index = None
|
self.provider_index = None
|
||||||
|
|
||||||
@ -87,13 +87,13 @@ def _read_reponame_from_directory(self, dir):
|
|||||||
"""For a packagerepo directory, read the repo name from the dir/reponame file"""
|
"""For a packagerepo directory, read the repo name from the dir/reponame file"""
|
||||||
path = os.path.join(dir, 'reponame')
|
path = os.path.join(dir, 'reponame')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with closing(open(path, 'r')) as reponame_file:
|
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):
|
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. "
|
tty.die("Package repo name '%s', read from %s, is an invalid name. "
|
||||||
"Repo names must began with a letter and only contain letters "
|
"Repo names must began with a letter and only contain letters "
|
||||||
"and numbers." % (name, path))
|
"and numbers." % (name, path))
|
||||||
return name
|
return name
|
||||||
except exceptions.IOError, e:
|
except exceptions.IOError, e:
|
||||||
tty.die("Could not read from package repo name file %s" % path)
|
tty.die("Could not read from package repo name file %s" % path)
|
||||||
@ -107,7 +107,7 @@ def _repo_list_from_config(self):
|
|||||||
dir_string = config.get('packagerepo', 'directories')
|
dir_string = config.get('packagerepo', 'directories')
|
||||||
return dir_string.split(':')
|
return dir_string.split(':')
|
||||||
|
|
||||||
|
|
||||||
@_autospec
|
@_autospec
|
||||||
def get(self, spec, **kwargs):
|
def get(self, spec, **kwargs):
|
||||||
if spec.virtual:
|
if spec.virtual:
|
||||||
@ -118,7 +118,7 @@ def get(self, spec, **kwargs):
|
|||||||
del self.instances[spec]
|
del self.instances[spec]
|
||||||
|
|
||||||
if not spec in self.instances:
|
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:
|
try:
|
||||||
copy = spec.copy()
|
copy = spec.copy()
|
||||||
self.instances[copy] = package_class(copy)
|
self.instances[copy] = package_class(copy)
|
||||||
@ -191,7 +191,7 @@ def repo_for_package_name(self, pkg_name, packagerepo_name=None):
|
|||||||
path = join_path(pkgrepo[1], pkg_name)
|
path = join_path(pkgrepo[1], pkg_name)
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
return (pkgrepo[0], path)
|
return (pkgrepo[0], path)
|
||||||
|
|
||||||
repo_to_add_to = roots[-1]
|
repo_to_add_to = roots[-1]
|
||||||
return (repo_to_add_to[0], join_path(repo_to_add_to[1], pkg_name))
|
return (repo_to_add_to[0], join_path(repo_to_add_to[1], pkg_name))
|
||||||
|
|
||||||
@ -259,7 +259,7 @@ def all_package_names(self):
|
|||||||
if os.path.isfile(pkg_file):
|
if os.path.isfile(pkg_file):
|
||||||
all_packages.add(pkg_name)
|
all_packages.add(pkg_name)
|
||||||
all_package_names = list(all_packages)
|
all_package_names = list(all_packages)
|
||||||
all_package_names.sort()
|
all_package_names.sort()
|
||||||
return all_package_names
|
return all_package_names
|
||||||
|
|
||||||
|
|
||||||
@ -275,12 +275,12 @@ def exists(self, pkg_name):
|
|||||||
|
|
||||||
|
|
||||||
@memoized
|
@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."""
|
"""Get an instance of the class for a particular package."""
|
||||||
repo = self.repo_for_package_name(pkg_name)
|
(reponame, repodir) = self.repo_for_package_name(pkg_name, reponame)
|
||||||
module_name = imported_packages_module + '.' + repo[0] + '.' + pkg_name
|
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)
|
class_name = mod_to_class(pkg_name)
|
||||||
cls = getattr(module, class_name)
|
cls = getattr(module, class_name)
|
||||||
@ -292,8 +292,13 @@ def get_class_for_package_name(self, pkg_name):
|
|||||||
|
|
||||||
class UnknownPackageError(spack.error.SpackError):
|
class UnknownPackageError(spack.error.SpackError):
|
||||||
"""Raised when we encounter a package spack doesn't have."""
|
"""Raised when we encounter a package spack doesn't have."""
|
||||||
def __init__(self, name):
|
def __init__(self, name, repo=None):
|
||||||
super(UnknownPackageError, self).__init__("Package '%s' not found." % name)
|
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
|
self.name = name
|
||||||
|
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ def get_module(self, pkg_name):
|
|||||||
if not os.access(file_path, os.R_OK):
|
if not os.access(file_path, os.R_OK):
|
||||||
tty.die("Cannot read '%s'!" % file_path)
|
tty.die("Cannot read '%s'!" % file_path)
|
||||||
else:
|
else:
|
||||||
raise spack.packages.UnknownPackageError(pkg_name)
|
raise spack.packages.UnknownPackageError(pkg_name, self.reponame if self.reponame != 'original' else None)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
module_name = imported_packages_module + '.' + self.reponame + '.' + pkg_name
|
module_name = imported_packages_module + '.' + self.reponame + '.' + pkg_name
|
||||||
|
@ -112,6 +112,7 @@
|
|||||||
from spack.util.string import *
|
from spack.util.string import *
|
||||||
from spack.util.prefix import Prefix
|
from spack.util.prefix import Prefix
|
||||||
from spack.virtual import ProviderIndex
|
from spack.virtual import ProviderIndex
|
||||||
|
from spack.repo_loader import imported_packages_module
|
||||||
|
|
||||||
# Valid pattern for an identifier in Spack
|
# Valid pattern for an identifier in Spack
|
||||||
identifier_re = r'\w[\w-]*'
|
identifier_re = r'\w[\w-]*'
|
||||||
@ -412,6 +413,7 @@ def __init__(self, spec_like, *dep_like, **kwargs):
|
|||||||
self.dependencies = other.dependencies
|
self.dependencies = other.dependencies
|
||||||
self.variants = other.variants
|
self.variants = other.variants
|
||||||
self.variants.spec = self
|
self.variants.spec = self
|
||||||
|
self.repo = other.repo
|
||||||
|
|
||||||
# Specs are by default not assumed to be normal, but in some
|
# Specs are by default not assumed to be normal, but in some
|
||||||
# cases we've read them from a file want to assume normal.
|
# cases we've read them from a file want to assume normal.
|
||||||
@ -1355,6 +1357,7 @@ def _dup(self, other, **kwargs):
|
|||||||
self.dependencies = DependencyMap()
|
self.dependencies = DependencyMap()
|
||||||
self.variants = other.variants.copy()
|
self.variants = other.variants.copy()
|
||||||
self.variants.spec = self
|
self.variants.spec = self
|
||||||
|
self.repo = other.repo
|
||||||
|
|
||||||
# If we copy dependencies, preserve DAG structure in the new spec
|
# If we copy dependencies, preserve DAG structure in the new spec
|
||||||
if kwargs.get('deps', True):
|
if kwargs.get('deps', True):
|
||||||
@ -1503,6 +1506,7 @@ def format(self, format_string='$_$@$%@$+$=', **kwargs):
|
|||||||
in the format string. The format strings you can provide are::
|
in the format string. The format strings you can provide are::
|
||||||
|
|
||||||
$_ Package name
|
$_ Package name
|
||||||
|
$. Long package name
|
||||||
$@ Version
|
$@ Version
|
||||||
$% Compiler
|
$% Compiler
|
||||||
$%@ Compiler & compiler version
|
$%@ Compiler & compiler version
|
||||||
@ -1550,6 +1554,9 @@ def write(s, c):
|
|||||||
|
|
||||||
if c == '_':
|
if c == '_':
|
||||||
out.write(fmt % self.name)
|
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 == '@':
|
elif c == '@':
|
||||||
if self.versions and self.versions != _any_version:
|
if self.versions and self.versions != _any_version:
|
||||||
write(fmt % (c + str(self.versions)), c)
|
write(fmt % (c + str(self.versions)), c)
|
||||||
@ -1698,17 +1705,29 @@ def parse_compiler(self, text):
|
|||||||
def spec(self):
|
def spec(self):
|
||||||
"""Parse a spec out of the input. If a spec is supplied, then initialize
|
"""Parse a spec out of the input. If a spec is supplied, then initialize
|
||||||
and return it instead of creating a new one."""
|
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__.
|
# This will init the spec without calling __init__.
|
||||||
spec = Spec.__new__(Spec)
|
spec = Spec.__new__(Spec)
|
||||||
spec.name = self.token.value
|
spec.name = spec_name
|
||||||
spec.versions = VersionList()
|
spec.versions = VersionList()
|
||||||
spec.variants = VariantMap(spec)
|
spec.variants = VariantMap(spec)
|
||||||
spec.architecture = None
|
spec.architecture = None
|
||||||
spec.compiler = None
|
spec.compiler = None
|
||||||
spec.dependents = DependencyMap()
|
spec.dependents = DependencyMap()
|
||||||
spec.dependencies = DependencyMap()
|
spec.dependencies = DependencyMap()
|
||||||
|
spec.repo = spec_repo
|
||||||
|
|
||||||
spec._normal = False
|
spec._normal = False
|
||||||
spec._concrete = False
|
spec._concrete = False
|
||||||
@ -1802,12 +1821,14 @@ def compiler(self):
|
|||||||
return compiler
|
return compiler
|
||||||
|
|
||||||
|
|
||||||
def check_identifier(self):
|
def check_identifier(self, id=None):
|
||||||
"""The only identifiers that can contain '.' are versions, but version
|
"""The only identifiers that can contain '.' are versions, but version
|
||||||
ids are context-sensitive so we have to check on a case-by-case
|
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.
|
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 '.'")
|
self.last_token_error("Identifier cannot contain '.'")
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user