diff options
Diffstat (limited to 'lib/spack/spack/repository.py')
-rw-r--r-- | lib/spack/spack/repository.py | 110 |
1 files changed, 37 insertions, 73 deletions
diff --git a/lib/spack/spack/repository.py b/lib/spack/spack/repository.py index a0904a2cde..eada10f7cb 100644 --- a/lib/spack/spack/repository.py +++ b/lib/spack/spack/repository.py @@ -38,7 +38,6 @@ from types import ModuleType import yaml import llnl.util.tty as tty -from llnl.util.lock import Lock from llnl.util.filesystem import * import spack @@ -142,7 +141,6 @@ class RepoPath(object): "To remove the bad repository, run this command:", " spack repo rm %s" % root) - def swap(self, other): """Convenience function to make swapping repostiories easier. @@ -160,7 +158,6 @@ class RepoPath(object): setattr(self, attr, getattr(other, attr)) setattr(other, attr, tmp) - def _add(self, repo): """Add a repository to the namespace and path indexes. @@ -174,31 +171,28 @@ class RepoPath(object): if repo.namespace in self.by_namespace: raise DuplicateRepoError( "Package repos '%s' and '%s' both provide namespace %s" - % (repo.root, self.by_namespace[repo.namespace].root, repo.namespace)) + % (repo.root, self.by_namespace[repo.namespace].root, + repo.namespace)) # Add repo to the pkg indexes self.by_namespace[repo.full_namespace] = repo self.by_path[repo.root] = repo - def put_first(self, repo): """Add repo first in the search path.""" self._add(repo) self.repos.insert(0, repo) - def put_last(self, repo): """Add repo last in the search path.""" self._add(repo) self.repos.append(repo) - def remove(self, repo): """Remove a repo from the search path.""" if repo in self.repos: self.repos.remove(repo) - def get_repo(self, namespace, default=NOT_PROVIDED): """Get a repository by namespace. Arguments @@ -218,12 +212,10 @@ class RepoPath(object): return default return self.by_namespace[fullspace] - def first_repo(self): """Get the first repo in precedence order.""" return self.repos[0] if self.repos else None - def all_package_names(self): """Return all unique package names in all repositories.""" if self._all_package_names is None: @@ -231,15 +223,13 @@ class RepoPath(object): for repo in self.repos: for name in repo.all_package_names(): all_pkgs.add(name) - self._all_package_names = sorted(all_pkgs, key=lambda n:n.lower()) + self._all_package_names = sorted(all_pkgs, key=lambda n: n.lower()) return self._all_package_names - def all_packages(self): for name in self.all_package_names(): yield self.get(name) - @property def provider_index(self): """Merged ProviderIndex from all Repos in the RepoPath.""" @@ -250,7 +240,6 @@ class RepoPath(object): return self._provider_index - @_autospec def providers_for(self, vpkg_spec): providers = self.provider_index.providers_for(vpkg_spec) @@ -258,12 +247,10 @@ class RepoPath(object): raise UnknownPackageError(vpkg_spec.name) return providers - @_autospec def extensions_for(self, extendee_spec): return [p for p in self.all_packages() if p.extends(extendee_spec)] - def find_module(self, fullname, path=None): """Implements precedence for overlaid namespaces. @@ -290,7 +277,6 @@ class RepoPath(object): return None - def load_module(self, fullname): """Handles loading container namespaces when necessary. @@ -307,7 +293,6 @@ class RepoPath(object): sys.modules[fullname] = module return module - @_autospec def repo_for_pkg(self, spec): """Given a spec, get the repository for its package.""" @@ -329,7 +314,6 @@ class RepoPath(object): # that can operate on packages that don't exist yet. return self.first_repo() - @_autospec def get(self, spec, new=False): """Find a repo that contains the supplied spec's package. @@ -338,12 +322,10 @@ class RepoPath(object): """ return self.repo_for_pkg(spec).get(spec) - def get_pkg_class(self, pkg_name): """Find a class for the spec's package and return the class object.""" return self.repo_for_pkg(pkg_name).get_pkg_class(pkg_name) - @_autospec def dump_provenance(self, spec, path): """Dump provenance information for a spec to a particular path. @@ -353,24 +335,19 @@ class RepoPath(object): """ return self.repo_for_pkg(spec).dump_provenance(spec, path) - def dirname_for_package_name(self, pkg_name): return self.repo_for_pkg(pkg_name).dirname_for_package_name(pkg_name) - def filename_for_package_name(self, pkg_name): return self.repo_for_pkg(pkg_name).filename_for_package_name(pkg_name) - def exists(self, pkg_name): return any(repo.exists(pkg_name) for repo in self.repos) - def __contains__(self, pkg_name): return self.exists(pkg_name) - class Repo(object): """Class representing a package repository in the filesystem. @@ -404,7 +381,8 @@ class Repo(object): # check and raise BadRepoError on fail. def check(condition, msg): - if not condition: raise BadRepoError(msg) + if not condition: + raise BadRepoError(msg) # Validate repository layout. self.config_file = join_path(self.root, repo_config_name) @@ -422,12 +400,14 @@ class Repo(object): self.namespace = config['namespace'] check(re.match(r'[a-zA-Z][a-zA-Z0-9_.]+', self.namespace), - ("Invalid namespace '%s' in repo '%s'. " % (self.namespace, self.root)) + + ("Invalid namespace '%s' in repo '%s'. " + % (self.namespace, self.root)) + "Namespaces must be valid python identifiers separated by '.'") # Set up 'full_namespace' to include the super-namespace if self.super_namespace: - self.full_namespace = "%s.%s" % (self.super_namespace, self.namespace) + self.full_namespace = "%s.%s" % ( + self.super_namespace, self.namespace) else: self.full_namespace = self.namespace @@ -462,10 +442,10 @@ class Repo(object): """ parent = None - for l in range(1, len(self._names)+1): + for l in range(1, len(self._names) + 1): ns = '.'.join(self._names[:l]) - if not ns in sys.modules: + if ns not in sys.modules: module = SpackNamespace(ns) module.__loader__ = self sys.modules[ns] = module @@ -476,7 +456,7 @@ class Repo(object): # This ensures that we can do things like: # import spack.pkg.builtin.mpich as mpich if parent: - modname = self._names[l-1] + modname = self._names[l - 1] setattr(parent, modname, module) else: # no need to set up a module @@ -485,7 +465,6 @@ class Repo(object): # but keep track of the parent in this loop parent = module - def real_name(self, import_name): """Allow users to import Spack packages using Python identifiers. @@ -511,13 +490,11 @@ class Repo(object): return name return None - def is_prefix(self, fullname): """True if fullname is a prefix of this Repo's namespace.""" parts = fullname.split('.') return self._names[:len(parts)] == parts - def find_module(self, fullname, path=None): """Python find_module import hook. @@ -533,7 +510,6 @@ class Repo(object): return None - def load_module(self, fullname): """Python importer load hook. @@ -565,7 +541,6 @@ class Repo(object): return module - def _read_config(self): """Check for a YAML config file in this db's root directory.""" try: @@ -573,40 +548,39 @@ class Repo(object): yaml_data = yaml.load(reponame_file) if (not yaml_data or 'repo' not in yaml_data or - not isinstance(yaml_data['repo'], dict)): - tty.die("Invalid %s in repository %s" - % (repo_config_name, self.root)) + not isinstance(yaml_data['repo'], dict)): + tty.die("Invalid %s in repository %s" % ( + repo_config_name, self.root)) return yaml_data['repo'] - except exceptions.IOError, e: + except exceptions.IOError: tty.die("Error reading %s when opening %s" % (self.config_file, self.root)) - @_autospec def get(self, spec, new=False): if spec.virtual: raise UnknownPackageError(spec.name) if spec.namespace and spec.namespace != self.namespace: - raise UnknownPackageError("Repository %s does not contain package %s" - % (self.namespace, spec.fullname)) + raise UnknownPackageError( + "Repository %s does not contain package %s" + % (self.namespace, spec.fullname)) key = hash(spec) if new or key not in self._instances: package_class = self.get_pkg_class(spec.name) try: - copy = spec.copy() # defensive copy. Package owns its spec. + copy = spec.copy() # defensive copy. Package owns its spec. self._instances[key] = package_class(copy) - except Exception, e: + except Exception: if spack.debug: sys.excepthook(*sys.exc_info()) raise FailedConstructorError(spec.fullname, *sys.exc_info()) return self._instances[key] - @_autospec def dump_provenance(self, spec, path): """Dump provenance information for a spec to a particular path. @@ -619,8 +593,9 @@ class Repo(object): raise UnknownPackageError(spec.name) if spec.namespace and spec.namespace != self.namespace: - raise UnknownPackageError("Repository %s does not contain package %s." - % (self.namespace, spec.fullname)) + raise UnknownPackageError( + "Repository %s does not contain package %s." + % (self.namespace, spec.fullname)) # Install any patch files needed by packages. mkdirp(path) @@ -635,12 +610,10 @@ class Repo(object): # Install the package.py file itself. install(self.filename_for_package_name(spec), path) - def purge(self): """Clear entire package instance cache.""" self._instances.clear() - def _update_provider_index(self): # Check modification dates of all packages self._fast_package_check() @@ -669,7 +642,6 @@ class Repo(object): self._provider_index.to_yaml(new) - @property def provider_index(self): """A provider index with names *specific* to this repo.""" @@ -677,7 +649,6 @@ class Repo(object): self._update_provider_index() return self._provider_index - @_autospec def providers_for(self, vpkg_spec): providers = self.provider_index.providers_for(vpkg_spec) @@ -685,18 +656,15 @@ class Repo(object): raise UnknownPackageError(vpkg_spec.name) return providers - @_autospec def extensions_for(self, extendee_spec): return [p for p in self.all_packages() if p.extends(extendee_spec)] - def _check_namespace(self, spec): """Check that the spec's namespace is the same as this repository's.""" if spec.namespace and spec.namespace != self.namespace: raise UnknownNamespaceError(spec.namespace) - @_autospec def dirname_for_package_name(self, spec): """Get the directory name for a particular package. This is the @@ -704,7 +672,6 @@ class Repo(object): self._check_namespace(spec) return join_path(self.packages_path, spec.name) - @_autospec def filename_for_package_name(self, spec): """Get the filename for the module we should load for a particular @@ -719,7 +686,6 @@ class Repo(object): pkg_dir = self.dirname_for_package_name(spec.name) return join_path(pkg_dir, package_file_name) - def _fast_package_check(self): """List packages in the repo and check whether index is up to date. @@ -783,13 +749,11 @@ class Repo(object): return self._all_package_names - def all_package_names(self): """Returns a sorted list of all package names in the Repo.""" self._fast_package_check() return self._all_package_names - def all_packages(self): """Iterator over all packages in the repository. @@ -799,7 +763,6 @@ class Repo(object): for name in self.all_package_names(): yield self.get(name) - def exists(self, pkg_name): """Whether a package with the supplied name exists.""" if self._all_package_names: @@ -813,7 +776,6 @@ class Repo(object): filename = self.filename_for_package_name(pkg_name) return os.path.exists(filename) - def _get_pkg_module(self, pkg_name): """Create a module for a particular package. @@ -845,7 +807,6 @@ class Repo(object): return self._modules[pkg_name] - def get_pkg_class(self, pkg_name): """Get the class for the package out of its module. @@ -853,7 +814,6 @@ class Repo(object): package. Then extracts the package class from the module according to Spack's naming convention. """ - fullname = pkg_name namespace, _, pkg_name = pkg_name.rpartition('.') if namespace and (namespace != self.namespace): raise InvalidNamespaceError('Invalid namespace for %s repo: %s' @@ -868,15 +828,12 @@ class Repo(object): return cls - def __str__(self): return "[Repo '%s' at '%s']" % (self.namespace, self.root) - def __repr__(self): return self.__str__() - def __contains__(self, pkg_name): return self.exists(pkg_name) @@ -885,30 +842,37 @@ def create_repo(root, namespace=None): """Create a new repository in root with the specified namespace. If the namespace is not provided, use basename of root. - Return the canonicalized path and the namespace of the created repository. + Return the canonicalized path and namespace of the created repository. """ root = canonicalize_path(root) if not namespace: namespace = os.path.basename(root) if not re.match(r'\w[\.\w-]*', namespace): - raise InvalidNamespaceError("'%s' is not a valid namespace." % namespace) + raise InvalidNamespaceError( + "'%s' is not a valid namespace." % namespace) existed = False if os.path.exists(root): if os.path.isfile(root): - raise BadRepoError('File %s already exists and is not a directory' % root) + raise BadRepoError('File %s already exists and is not a directory' + % root) elif os.path.isdir(root): if not os.access(root, os.R_OK | os.W_OK): - raise BadRepoError('Cannot create new repo in %s: cannot access directory.' % root) + raise BadRepoError( + 'Cannot create new repo in %s: cannot access directory.' + % root) if os.listdir(root): - raise BadRepoError('Cannot create new repo in %s: directory is not empty.' % root) + raise BadRepoError( + 'Cannot create new repo in %s: directory is not empty.' + % root) existed = True full_path = os.path.realpath(root) parent = os.path.dirname(full_path) if not os.access(parent, os.R_OK | os.W_OK): - raise BadRepoError("Cannot create repository in %s: can't access parent!" % root) + raise BadRepoError( + "Cannot create repository in %s: can't access parent!" % root) try: config_path = os.path.join(root, repo_config_name) |