New, cleaner package repository structure.
Package repositories now look like this: top-level-dir/ repo.yaml packages/ libelf/ package.py mpich/ package.py ... This leaves room at the top level for additional metadata, source, per-repo configs, indexes, etc., and it makes it easy to see that something is a spack repo (just look for repo.yaml and packages).
This commit is contained in:
parent
04f032d6e3
commit
89d5127900
285 changed files with 137 additions and 64 deletions
|
@ -43,7 +43,7 @@
|
||||||
hooks_path = join_path(module_path, "hooks")
|
hooks_path = join_path(module_path, "hooks")
|
||||||
var_path = join_path(spack_root, "var", "spack")
|
var_path = join_path(spack_root, "var", "spack")
|
||||||
stage_path = join_path(var_path, "stage")
|
stage_path = join_path(var_path, "stage")
|
||||||
packages_path = join_path(var_path, "packages")
|
repos_path = join_path(var_path, "repos")
|
||||||
share_path = join_path(spack_root, "share", "spack")
|
share_path = join_path(spack_root, "share", "spack")
|
||||||
|
|
||||||
prefix = spack_root
|
prefix = spack_root
|
||||||
|
@ -58,8 +58,12 @@
|
||||||
_repo_paths = spack.config.get_repos_config()
|
_repo_paths = spack.config.get_repos_config()
|
||||||
if not _repo_paths:
|
if not _repo_paths:
|
||||||
tty.die("Spack configuration contains no package repositories.")
|
tty.die("Spack configuration contains no package repositories.")
|
||||||
repo = spack.repository.RepoPath(*_repo_paths)
|
|
||||||
sys.meta_path.append(repo)
|
try:
|
||||||
|
repo = spack.repository.RepoPath(*_repo_paths)
|
||||||
|
sys.meta_path.append(repo)
|
||||||
|
except spack.repository.BadRepoError, e:
|
||||||
|
tty.die('Bad repository. %s' % e.message)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Set up the installed packages database
|
# Set up the installed packages database
|
||||||
|
@ -68,9 +72,10 @@
|
||||||
installed_db = Database(install_path)
|
installed_db = Database(install_path)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Paths to mock files for testing.
|
# Paths to built-in Spack repositories.
|
||||||
#
|
#
|
||||||
mock_packages_path = join_path(var_path, "mock_packages")
|
packages_path = join_path(repos_path, "builtin")
|
||||||
|
mock_packages_path = join_path(repos_path, "builtin.mock")
|
||||||
|
|
||||||
mock_config_path = join_path(var_path, "mock_configs")
|
mock_config_path = join_path(var_path, "mock_configs")
|
||||||
mock_site_config = join_path(mock_config_path, "site_spackconfig")
|
mock_site_config = join_path(mock_config_path, "site_spackconfig")
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
import spack.spec
|
import spack.spec
|
||||||
import spack.config
|
import spack.config
|
||||||
from spack.util.environment import get_path
|
from spack.util.environment import get_path
|
||||||
from spack.repository import repo_config_filename
|
from spack.repository import repo_config_name
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import exceptions
|
import exceptions
|
||||||
|
|
|
@ -26,28 +26,32 @@
|
||||||
import exceptions
|
import exceptions
|
||||||
import sys
|
import sys
|
||||||
import inspect
|
import inspect
|
||||||
import glob
|
|
||||||
import imp
|
import imp
|
||||||
import re
|
import re
|
||||||
import itertools
|
|
||||||
import traceback
|
import traceback
|
||||||
from bisect import bisect_left
|
from bisect import bisect_left
|
||||||
from external import yaml
|
from external import yaml
|
||||||
|
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
from llnl.util.filesystem import join_path
|
from llnl.util.filesystem import join_path
|
||||||
from llnl.util.lang import *
|
|
||||||
|
|
||||||
import spack.error
|
import spack.error
|
||||||
import spack.spec
|
import spack.spec
|
||||||
from spack.virtual import ProviderIndex
|
from spack.virtual import ProviderIndex
|
||||||
from spack.util.naming import *
|
from spack.util.naming import *
|
||||||
|
|
||||||
# Filename for package repo names
|
#
|
||||||
repo_config_filename = '_repo.yaml'
|
# Super-namespace for all packages.
|
||||||
|
# Package modules are imported as spack.pkg.<namespace>.<pkg-name>.
|
||||||
|
#
|
||||||
|
repo_namespace = 'spack.pkg'
|
||||||
|
|
||||||
# Filename for packages in repos.
|
#
|
||||||
package_file_name = 'package.py'
|
# These names describe how repos should be laid out in the filesystem.
|
||||||
|
#
|
||||||
|
repo_config_name = 'repo.yaml' # Top-level filename for repo config.
|
||||||
|
packages_dir_name = 'packages' # Top-level repo directory containing pkgs.
|
||||||
|
package_file_name = 'package.py' # Filename for packages in a repository.
|
||||||
|
|
||||||
def _autospec(function):
|
def _autospec(function):
|
||||||
"""Decorator that automatically converts the argument of a single-arg
|
"""Decorator that automatically converts the argument of a single-arg
|
||||||
|
@ -74,7 +78,10 @@ class RepoPath(object):
|
||||||
combined results of the Repos in its list instead of on a
|
combined results of the Repos in its list instead of on a
|
||||||
single package repository.
|
single package repository.
|
||||||
"""
|
"""
|
||||||
def __init__(self, *repo_dirs):
|
def __init__(self, *repo_dirs, **kwargs):
|
||||||
|
# super-namespace for all packages in the RepoPath
|
||||||
|
self.super_namespace = kwargs.get('namespace', repo_namespace)
|
||||||
|
|
||||||
self.repos = []
|
self.repos = []
|
||||||
self.by_namespace = NamespaceTrie()
|
self.by_namespace = NamespaceTrie()
|
||||||
self.by_path = {}
|
self.by_path = {}
|
||||||
|
@ -82,11 +89,9 @@ def __init__(self, *repo_dirs):
|
||||||
self._all_package_names = []
|
self._all_package_names = []
|
||||||
self._provider_index = None
|
self._provider_index = None
|
||||||
|
|
||||||
|
# Add each repo to this path.
|
||||||
for root in repo_dirs:
|
for root in repo_dirs:
|
||||||
# Try to make it a repo if it's not one.
|
repo = Repo(root, self.super_namespace)
|
||||||
if not isinstance(root, Repo):
|
|
||||||
repo = Repo(root)
|
|
||||||
# Add the repo to the path.
|
|
||||||
self.put_last(repo)
|
self.put_last(repo)
|
||||||
|
|
||||||
|
|
||||||
|
@ -120,11 +125,11 @@ def _add(self, repo):
|
||||||
repo, self.by_path[repo.root])
|
repo, self.by_path[repo.root])
|
||||||
|
|
||||||
if repo.namespace in self.by_namespace:
|
if repo.namespace in self.by_namespace:
|
||||||
raise DuplicateRepoError("Package repos cannot have the same name",
|
raise DuplicateRepoError("Package repos cannot provide the same namespace",
|
||||||
repo, self.by_namespace[repo.namespace])
|
repo, self.by_namespace[repo.namespace])
|
||||||
|
|
||||||
# Add repo to the pkg indexes
|
# Add repo to the pkg indexes
|
||||||
self.by_namespace[repo.namespace] = repo
|
self.by_namespace[repo.full_namespace] = repo
|
||||||
self.by_path[repo.root] = repo
|
self.by_path[repo.root] = repo
|
||||||
|
|
||||||
# add names to the cached name list
|
# add names to the cached name list
|
||||||
|
@ -185,10 +190,10 @@ def find_module(self, fullname, path=None):
|
||||||
# If it's a module in some repo, or if it is the repo's
|
# If it's a module in some repo, or if it is the repo's
|
||||||
# namespace, let the repo handle it.
|
# namespace, let the repo handle it.
|
||||||
for repo in self.repos:
|
for repo in self.repos:
|
||||||
if namespace == repo.namespace:
|
if namespace == repo.full_namespace:
|
||||||
if repo.real_name(module_name):
|
if repo.real_name(module_name):
|
||||||
return repo
|
return repo
|
||||||
elif fullname == repo.namespace:
|
elif fullname == repo.full_namespace:
|
||||||
return repo
|
return repo
|
||||||
|
|
||||||
# No repo provides the namespace, but it is a valid prefix of
|
# No repo provides the namespace, but it is a valid prefix of
|
||||||
|
@ -200,13 +205,14 @@ def find_module(self, fullname, path=None):
|
||||||
|
|
||||||
|
|
||||||
def load_module(self, fullname):
|
def load_module(self, fullname):
|
||||||
"""Loads containing namespaces when necessary.
|
"""Handles loading container namespaces when necessary.
|
||||||
|
|
||||||
See ``Repo`` for how actual package modules are loaded.
|
See ``Repo`` for how actual package modules are loaded.
|
||||||
"""
|
"""
|
||||||
if fullname in sys.modules:
|
if fullname in sys.modules:
|
||||||
return sys.modules[fullname]
|
return sys.modules[fullname]
|
||||||
|
|
||||||
|
|
||||||
# partition fullname into prefix and module name.
|
# partition fullname into prefix and module name.
|
||||||
namespace, dot, module_name = fullname.rpartition('.')
|
namespace, dot, module_name = fullname.rpartition('.')
|
||||||
|
|
||||||
|
@ -252,41 +258,67 @@ class Repo(object):
|
||||||
"""Class representing a package repository in the filesystem.
|
"""Class representing a package repository in the filesystem.
|
||||||
|
|
||||||
Each package repository must have a top-level configuration file
|
Each package repository must have a top-level configuration file
|
||||||
called `_repo.yaml`.
|
called `repo.yaml`.
|
||||||
|
|
||||||
Currently, `_repo.yaml` this must define:
|
Currently, `repo.yaml` this must define:
|
||||||
|
|
||||||
`namespace`:
|
`namespace`:
|
||||||
A Python namespace where the repository's packages should live.
|
A Python namespace where the repository's packages should live.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, root):
|
def __init__(self, root, namespace=repo_namespace):
|
||||||
"""Instantiate a package repository from a filesystem path."""
|
"""Instantiate a package repository from a filesystem path.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
root The root directory of the repository.
|
||||||
|
|
||||||
|
namespace A super-namespace that will contain the repo-defined
|
||||||
|
namespace (this is generally jsut `spack.pkg`). The
|
||||||
|
super-namespace is Spack's way of separating repositories
|
||||||
|
from other python namespaces.
|
||||||
|
|
||||||
|
"""
|
||||||
# Root directory, containing _repo.yaml and package dirs
|
# Root directory, containing _repo.yaml and package dirs
|
||||||
self.root = root
|
self.root = root
|
||||||
|
|
||||||
# Config file in <self.root>/_repo.yaml
|
# super-namespace for all packages in the Repo
|
||||||
self.config_file = os.path.join(self.root, repo_config_filename)
|
self.super_namespace = namespace
|
||||||
|
|
||||||
# Read configuration from _repo.yaml
|
# check and raise BadRepoError on fail.
|
||||||
|
def check(condition, msg):
|
||||||
|
if not condition: raise BadRepoError(msg)
|
||||||
|
|
||||||
|
# Validate repository layout.
|
||||||
|
self.config_file = join_path(self.root, repo_config_name)
|
||||||
|
check(os.path.isfile(self.config_file),
|
||||||
|
"No %s found in '%s'" % (repo_config_name, root))
|
||||||
|
self.packages_path = join_path(self.root, packages_dir_name)
|
||||||
|
check(os.path.isdir(self.packages_path),
|
||||||
|
"No directory '%s' found in '%s'" % (repo_config_name, root))
|
||||||
|
|
||||||
|
# Read configuration and validate namespace
|
||||||
config = self._read_config()
|
config = self._read_config()
|
||||||
if not 'namespace' in config:
|
check('namespace' in config, '%s must define a namespace.'
|
||||||
tty.die('Package repo in %s must define a namespace in %s.'
|
% join_path(self.root, repo_config_name))
|
||||||
% (self.root, repo_config_filename))
|
|
||||||
|
|
||||||
# Check namespace in the repository configuration.
|
|
||||||
self.namespace = config['namespace']
|
self.namespace = config['namespace']
|
||||||
if not re.match(r'[a-zA-Z][a-zA-Z0-9_.]+', self.namespace):
|
check(re.match(r'[a-zA-Z][a-zA-Z0-9_.]+', self.namespace),
|
||||||
tty.die(("Invalid namespace '%s' in '%s'. Namespaces must be "
|
("Invalid namespace '%s' in repo '%s'. " % (self.namespace, self.root)) +
|
||||||
"valid python identifiers separated by '.'")
|
"Namespaces must be valid python identifiers separated by '.'")
|
||||||
% (self.namespace, self.root))
|
|
||||||
self._names = self.namespace.split('.')
|
# Set up 'full_namespace' to include the super-namespace
|
||||||
|
if self.super_namespace:
|
||||||
|
self.full_namespace = "%s.%s" % (self.super_namespace, self.namespace)
|
||||||
|
else:
|
||||||
|
self.full_namespace = self.namespace
|
||||||
|
|
||||||
|
# Keep name components around for checking prefixes.
|
||||||
|
self._names = self.full_namespace.split('.')
|
||||||
|
|
||||||
# These are internal cache variables.
|
# These are internal cache variables.
|
||||||
self._modules = {}
|
self._modules = {}
|
||||||
self._classes = {}
|
self._classes = {}
|
||||||
self._instances = {}
|
self._instances = {}
|
||||||
|
|
||||||
self._provider_index = None
|
self._provider_index = None
|
||||||
self._all_package_names = None
|
self._all_package_names = None
|
||||||
|
|
||||||
|
@ -301,11 +333,27 @@ def _create_namespace(self):
|
||||||
we don't get runtime warnings from Python's module system.
|
we don't get runtime warnings from Python's module system.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
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])
|
ns = '.'.join(self._names[:l])
|
||||||
if not ns in sys.modules:
|
if not ns in sys.modules:
|
||||||
sys.modules[ns] = _make_namespace_module(ns)
|
module = _make_namespace_module(ns)
|
||||||
sys.modules[ns].__loader__ = self
|
module.__loader__ = self
|
||||||
|
sys.modules[ns] = module
|
||||||
|
|
||||||
|
# Ensure the namespace is an atrribute of its parent,
|
||||||
|
# if it has not been set by something else already.
|
||||||
|
#
|
||||||
|
# This ensures that we can do things like:
|
||||||
|
# import spack.pkg.builtin.mpich as mpich
|
||||||
|
if parent:
|
||||||
|
modname = self._names[l-1]
|
||||||
|
if not hasattr(parent, modname):
|
||||||
|
setattr(parent, modname, module)
|
||||||
|
else:
|
||||||
|
# no need to set up a module, but keep track of the parent.
|
||||||
|
module = sys.modules[ns]
|
||||||
|
parent = module
|
||||||
|
|
||||||
|
|
||||||
def real_name(self, import_name):
|
def real_name(self, import_name):
|
||||||
|
@ -349,7 +397,7 @@ def find_module(self, fullname, path=None):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
namespace, dot, module_name = fullname.rpartition('.')
|
namespace, dot, module_name = fullname.rpartition('.')
|
||||||
if namespace == self.namespace:
|
if namespace == self.full_namespace:
|
||||||
if self.real_name(module_name):
|
if self.real_name(module_name):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
@ -369,14 +417,14 @@ def load_module(self, fullname):
|
||||||
if self.is_prefix(fullname):
|
if self.is_prefix(fullname):
|
||||||
module = _make_namespace_module(fullname)
|
module = _make_namespace_module(fullname)
|
||||||
|
|
||||||
elif namespace == self.namespace:
|
elif namespace == self.full_namespace:
|
||||||
real_name = self.real_name(module_name)
|
real_name = self.real_name(module_name)
|
||||||
if not real_name:
|
if not real_name:
|
||||||
raise ImportError("No module %s in repo %s" % (module_name, namespace))
|
raise ImportError("No module %s in %s" % (module_name, self))
|
||||||
module = self._get_pkg_module(real_name)
|
module = self._get_pkg_module(real_name)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise ImportError("No module %s in repo %s" % (fullname, self.namespace))
|
raise ImportError("No module %s in %s" % (fullname, self))
|
||||||
|
|
||||||
module.__loader__ = self
|
module.__loader__ = self
|
||||||
sys.modules[fullname] = module
|
sys.modules[fullname] = module
|
||||||
|
@ -392,7 +440,7 @@ def _read_config(self):
|
||||||
if (not yaml_data or 'repo' not in yaml_data or
|
if (not yaml_data or 'repo' not in yaml_data or
|
||||||
not isinstance(yaml_data['repo'], dict)):
|
not isinstance(yaml_data['repo'], dict)):
|
||||||
tty.die("Invalid %s in repository %s"
|
tty.die("Invalid %s in repository %s"
|
||||||
% (repo_config_filename, self.root))
|
% (repo_config_name, self.root))
|
||||||
|
|
||||||
return yaml_data['repo']
|
return yaml_data['repo']
|
||||||
|
|
||||||
|
@ -446,7 +494,7 @@ def extensions_for(self, extendee_spec):
|
||||||
def dirname_for_package_name(self, pkg_name):
|
def dirname_for_package_name(self, pkg_name):
|
||||||
"""Get the directory name for a particular package. This is the
|
"""Get the directory name for a particular package. This is the
|
||||||
directory that contains its package.py file."""
|
directory that contains its package.py file."""
|
||||||
return join_path(self.root, pkg_name)
|
return join_path(self.packages_path, pkg_name)
|
||||||
|
|
||||||
|
|
||||||
def filename_for_package_name(self, pkg_name):
|
def filename_for_package_name(self, pkg_name):
|
||||||
|
@ -460,7 +508,6 @@ def filename_for_package_name(self, pkg_name):
|
||||||
"""
|
"""
|
||||||
validate_module_name(pkg_name)
|
validate_module_name(pkg_name)
|
||||||
pkg_dir = self.dirname_for_package_name(pkg_name)
|
pkg_dir = self.dirname_for_package_name(pkg_name)
|
||||||
|
|
||||||
return join_path(pkg_dir, package_file_name)
|
return join_path(pkg_dir, package_file_name)
|
||||||
|
|
||||||
|
|
||||||
|
@ -469,12 +516,25 @@ def all_package_names(self):
|
||||||
if self._all_package_names is None:
|
if self._all_package_names is None:
|
||||||
self._all_package_names = []
|
self._all_package_names = []
|
||||||
|
|
||||||
for pkg_name in os.listdir(self.root):
|
for pkg_name in os.listdir(self.packages_path):
|
||||||
pkg_dir = join_path(self.root, pkg_name)
|
# Skip non-directories in the package root.
|
||||||
pkg_file = join_path(pkg_dir, package_file_name)
|
pkg_dir = join_path(self.packages_path, pkg_name)
|
||||||
if os.path.isfile(pkg_file):
|
if not os.path.isdir(pkg_dir):
|
||||||
self._all_package_names.append(pkg_name)
|
continue
|
||||||
|
|
||||||
|
# Skip directories without a package.py in them.
|
||||||
|
pkg_file = join_path(self.packages_path, pkg_name, package_file_name)
|
||||||
|
if not os.path.isfile(pkg_file):
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Warn about invalid names that look like packages.
|
||||||
|
if not valid_module_name(pkg_name):
|
||||||
|
tty.warn("Skipping package at %s. '%s' is not a valid Spack module name."
|
||||||
|
% (pkg_dir, pkg_name))
|
||||||
|
continue
|
||||||
|
|
||||||
|
# All checks passed. Add it to the list.
|
||||||
|
self._all_package_names.append(pkg_name)
|
||||||
self._all_package_names.sort()
|
self._all_package_names.sort()
|
||||||
|
|
||||||
return self._all_package_names
|
return self._all_package_names
|
||||||
|
@ -489,7 +549,8 @@ def exists(self, pkg_name):
|
||||||
"""Whether a package with the supplied name exists."""
|
"""Whether a package with the supplied name exists."""
|
||||||
# This does a binary search in the sorted list.
|
# This does a binary search in the sorted list.
|
||||||
idx = bisect_left(self.all_package_names(), pkg_name)
|
idx = bisect_left(self.all_package_names(), pkg_name)
|
||||||
return self._all_package_names[idx] == pkg_name
|
return (idx < len(self._all_package_names) and
|
||||||
|
self._all_package_names[idx] == pkg_name)
|
||||||
|
|
||||||
|
|
||||||
def _get_pkg_module(self, pkg_name):
|
def _get_pkg_module(self, pkg_name):
|
||||||
|
@ -505,7 +566,7 @@ def _get_pkg_module(self, pkg_name):
|
||||||
file_path = self.filename_for_package_name(pkg_name)
|
file_path = self.filename_for_package_name(pkg_name)
|
||||||
|
|
||||||
if not os.path.exists(file_path):
|
if not os.path.exists(file_path):
|
||||||
raise UnknownPackageError(pkg_name, self.namespace)
|
raise UnknownPackageError(pkg_name, self)
|
||||||
|
|
||||||
if not os.path.isfile(file_path):
|
if not os.path.isfile(file_path):
|
||||||
tty.die("Something's wrong. '%s' is not a file!" % file_path)
|
tty.die("Something's wrong. '%s' is not a file!" % file_path)
|
||||||
|
@ -513,10 +574,11 @@ def _get_pkg_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)
|
||||||
|
|
||||||
fullname = "%s.%s" % (self.namespace, pkg_name)
|
# e.g., spack.pkg.builtin.mpich
|
||||||
|
fullname = "%s.%s" % (self.full_namespace, pkg_name)
|
||||||
|
|
||||||
module = imp.load_source(fullname, file_path)
|
module = imp.load_source(fullname, file_path)
|
||||||
module.__package__ = self.namespace
|
module.__package__ = self.full_namespace
|
||||||
module.__loader__ = self
|
module.__loader__ = self
|
||||||
self._modules[pkg_name] = module
|
self._modules[pkg_name] = module
|
||||||
|
|
||||||
|
@ -541,7 +603,7 @@ def _get_pkg_class(self, pkg_name):
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "<Repo '%s' from '%s'>" % (self.namespace, self.root)
|
return "[Repo '%s' at '%s']" % (self.namespace, self.root)
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -597,12 +659,18 @@ def installed_known_package_specs(self):
|
||||||
yield spec
|
yield spec
|
||||||
|
|
||||||
|
|
||||||
|
class BadRepoError(spack.error.SpackError):
|
||||||
|
"""Raised when repo layout is invalid."""
|
||||||
|
def __init__(self, msg):
|
||||||
|
super(BadRepoError, self).__init__(msg)
|
||||||
|
|
||||||
|
|
||||||
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, repo=None):
|
def __init__(self, name, repo=None):
|
||||||
msg = None
|
msg = None
|
||||||
if repo:
|
if repo:
|
||||||
msg = "Package %s not found in packagerepo %s." % (name, repo)
|
msg = "Package %s not found in repository %s." % (name, repo)
|
||||||
else:
|
else:
|
||||||
msg = "Package %s not found." % name
|
msg = "Package %s not found." % name
|
||||||
super(UnknownPackageError, self).__init__(msg)
|
super(UnknownPackageError, self).__init__(msg)
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
repo:
|
|
||||||
namespace: gov.llnl.spack.mock
|
|
|
@ -1,2 +0,0 @@
|
||||||
repo:
|
|
||||||
namespace: gov.llnl.spack
|
|
2
var/spack/repos/builtin.mock/repo.yaml
Normal file
2
var/spack/repos/builtin.mock/repo.yaml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
repo:
|
||||||
|
namespace: builtin.mock
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue