WIP for Matt's branch

This commit is contained in:
Todd Gamblin 2015-09-17 00:21:33 -07:00
parent 360b307f68
commit 6dff42be09
9 changed files with 68 additions and 40 deletions

View file

@ -113,8 +113,8 @@ def main():
spack.spack_working_dir = working_dir spack.spack_working_dir = working_dir
if args.mock: if args.mock:
from spack.packages import PackageDB from spack.packages import PackageFinder
spack.db = PackageDB(spack.mock_packages_path) spack.db.swap(PackageFinder(spack.mock_packages_path))
# If the user asked for it, don't check ssl certs. # If the user asked for it, don't check ssl certs.
if args.insecure: if args.insecure:

View file

@ -240,11 +240,11 @@ def patch(pkg, url_or_filename, level=1, when=None):
when_spec = parse_anonymous_spec(when, pkg.name) when_spec = parse_anonymous_spec(when, pkg.name)
if when_spec not in pkg.patches: if when_spec not in pkg.patches:
pkg.patches[when_spec] = [Patch(pkg.name, url_or_filename, level)] pkg.patches[when_spec] = [Patch(pkg, pkg.name, url_or_filename, level)]
else: else:
# if this spec is identical to some other, then append this # if this spec is identical to some other, then append this
# patch to the existing list. # patch to the existing list.
pkg.patches[when_spec].append(Patch(pkg.name, url_or_filename, level)) pkg.patches[when_spec].append(Patch(pkg, pkg.name, url_or_filename, level))
@directive('variants') @directive('variants')

View file

@ -712,6 +712,12 @@ def do_patch(self):
tty.msg("Patched %s" % self.name) tty.msg("Patched %s" % self.name)
@property
def namespace(self):
namespace, dot, module = self.__module__.rpartition('.')
return namespace
def do_fake_install(self): def do_fake_install(self):
"""Make a fake install directory contaiing a 'fake' file in bin.""" """Make a fake install directory contaiing a 'fake' file in bin."""
mkdirp(self.prefix.bin) mkdirp(self.prefix.bin)

View file

@ -172,7 +172,7 @@ def all_packages(self):
def providers_for(self, vpkg_name): def providers_for(self, vpkg_name):
# TODO: USE MORE THAN FIRST REPO # TODO: THIS IS WRONG; shoudl use more than first repo
return self.repos[0].providers_for(vpkg_name) return self.repos[0].providers_for(vpkg_name)
@ -252,14 +252,22 @@ def load_module(self, fullname):
return module return module
@_autospec def _find_repo_for_spec(self, spec):
def get(self, spec, new=False): """Find a repo that contains the supplied spec's package.
Raises UnknownPackageErrorfor if not found.
"""
for repo in self.repos: for repo in self.repos:
if spec.name in repo: if spec.name in repo:
return repo.get(spec, new) return repo
raise UnknownPackageError(spec.name) raise UnknownPackageError(spec.name)
@_autospec
def get(self, spec, new=False):
return self._find_repo_for_spec(spec).get(spec, new)
def get_repo(self, namespace): def get_repo(self, namespace):
if namespace in self.by_namespace: if namespace in self.by_namespace:
repo = self.by_namespace[namespace] repo = self.by_namespace[namespace]
@ -343,7 +351,7 @@ def get(self, spec, new=False):
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, spec.repo) package_class = self.get_class_for_package_name(spec.name, spec.namespace)
try: try:
copy = spec.copy() copy = spec.copy()
self._instances[copy] = package_class(copy) self._instances[copy] = package_class(copy)

View file

@ -41,7 +41,11 @@ class Patch(object):
"""This class describes a patch to be applied to some expanded """This class describes a patch to be applied to some expanded
source code.""" source code."""
def __init__(self, pkg_name, path_or_url, level): def __init__(self, pkg, pkg_name, path_or_url, level):
print pkg, pkg.name, type(pkg)
print "pkg:", dir(pkg.__module__)
print "NAMESPACE", pkg.namespace()
self.pkg_name = pkg_name self.pkg_name = pkg_name
self.path_or_url = path_or_url self.path_or_url = path_or_url
self.path = None self.path = None

View file

@ -112,7 +112,6 @@
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-]*'
@ -413,7 +412,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 self.namespace = other.namespace
# 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.
@ -1357,7 +1356,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 self.namespace = other.namespace
# 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):
@ -1555,7 +1554,7 @@ def write(s, c):
if c == '_': if c == '_':
out.write(fmt % self.name) out.write(fmt % self.name)
elif c == '.': elif c == '.':
longname = '%s.%s.%s' % (imported_packages_module, self.repo, self.name) if self.repo else self.name longname = '%s.%s.%s' % (self.namespace, self.name) if self.namespace else self.name
out.write(fmt % longname) out.write(fmt % longname)
elif c == '@': elif c == '@':
if self.versions and self.versions != _any_version: if self.versions and self.versions != _any_version:
@ -1706,15 +1705,9 @@ 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."""
spec_name = None spec_namespace, dot, spec_name = self.token.value.rpartition('.')
spec_repo = None if not spec_namespace:
if self.token.value.startswith(imported_packages_module): spec_namespace = None
lst = self.token.value.split('.')
spec_name = lst[-1]
spec_repo = lst[-2]
else:
spec_name = self.token.value
spec_repo = 'gov.llnl.spack'
self.check_identifier(spec_name) self.check_identifier(spec_name)
@ -1727,7 +1720,7 @@ def spec(self):
spec.compiler = None spec.compiler = None
spec.dependents = DependencyMap() spec.dependents = DependencyMap()
spec.dependencies = DependencyMap() spec.dependencies = DependencyMap()
spec.repo = spec_repo spec.namespace = spec_namespace
spec._normal = False spec._normal = False
spec._concrete = False spec._concrete = False

View file

@ -31,14 +31,6 @@
from spack.spec import Spec from spack.spec import Spec
def set_pkg_dep(pkg, spec):
"""Alters dependence information for a package.
Use this to mock up constraints.
"""
spec = Spec(spec)
spack.db.get(pkg).dependencies[spec.name] = { Spec(pkg) : spec }
class MockPackagesTest(unittest.TestCase): class MockPackagesTest(unittest.TestCase):
def initmock(self): def initmock(self):
# Use the mock packages database for these tests. This allows # Use the mock packages database for these tests. This allows
@ -53,14 +45,39 @@ def initmock(self):
('site', spack.mock_site_config), ('site', spack.mock_site_config),
('user', spack.mock_user_config)] ('user', spack.mock_user_config)]
# Store changes to the package's dependencies so we can
# restore later.
self.saved_deps = {}
def set_pkg_dep(self, pkg_name, spec):
"""Alters dependence information for a package.
Adds a dependency on <spec> to pkg.
Use this to mock up constraints.
"""
spec = Spec(spec)
# Save original dependencies before making any changes.
pkg = spack.db.get(pkg_name)
if pkg_name not in self.saved_deps:
self.saved_deps[pkg_name] = (pkg, pkg.dependencies.copy())
# Change dep spec
pkg.dependencies[spec.name] = { Spec(pkg_name) : spec }
def cleanmock(self): def cleanmock(self):
"""Restore the real packages path after any test.""" """Restore the real packages path after any test."""
spack.db.swap(self.db) spack.db.swap(self.db)
spack.config.config_scopes = self.real_scopes spack.config.config_scopes = self.real_scopes
spack.config.clear_config_caches() spack.config.clear_config_caches()
# Restore dependency changes that happened during the test
for pkg_name, (pkg, deps) in self.saved_deps.items():
pkg.dependencies.clear()
pkg.dependencies.update(deps)
def setUp(self): def setUp(self):
self.initmock() self.initmock()

View file

@ -29,7 +29,7 @@
import spack import spack
import spack.url as url import spack.url as url
from spack.packages import PackageDB from spack.packages import PackageFinder
class PackageSanityTest(unittest.TestCase): class PackageSanityTest(unittest.TestCase):

View file

@ -40,8 +40,8 @@
class SpecDagTest(MockPackagesTest): class SpecDagTest(MockPackagesTest):
def test_conflicting_package_constraints(self): def test_conflicting_package_constraints(self):
set_pkg_dep('mpileaks', 'mpich@1.0') self.set_pkg_dep('mpileaks', 'mpich@1.0')
set_pkg_dep('callpath', 'mpich@2.0') self.set_pkg_dep('callpath', 'mpich@2.0')
spec = Spec('mpileaks ^mpich ^callpath ^dyninst ^libelf ^libdwarf') spec = Spec('mpileaks ^mpich ^callpath ^dyninst ^libelf ^libdwarf')
@ -223,25 +223,25 @@ def test_dependents_and_dependencies_are_correct(self):
def test_unsatisfiable_version(self): def test_unsatisfiable_version(self):
set_pkg_dep('mpileaks', 'mpich@1.0') self.set_pkg_dep('mpileaks', 'mpich@1.0')
spec = Spec('mpileaks ^mpich@2.0 ^callpath ^dyninst ^libelf ^libdwarf') spec = Spec('mpileaks ^mpich@2.0 ^callpath ^dyninst ^libelf ^libdwarf')
self.assertRaises(spack.spec.UnsatisfiableVersionSpecError, spec.normalize) self.assertRaises(spack.spec.UnsatisfiableVersionSpecError, spec.normalize)
def test_unsatisfiable_compiler(self): def test_unsatisfiable_compiler(self):
set_pkg_dep('mpileaks', 'mpich%gcc') self.set_pkg_dep('mpileaks', 'mpich%gcc')
spec = Spec('mpileaks ^mpich%intel ^callpath ^dyninst ^libelf ^libdwarf') spec = Spec('mpileaks ^mpich%intel ^callpath ^dyninst ^libelf ^libdwarf')
self.assertRaises(spack.spec.UnsatisfiableCompilerSpecError, spec.normalize) self.assertRaises(spack.spec.UnsatisfiableCompilerSpecError, spec.normalize)
def test_unsatisfiable_compiler_version(self): def test_unsatisfiable_compiler_version(self):
set_pkg_dep('mpileaks', 'mpich%gcc@4.6') self.set_pkg_dep('mpileaks', 'mpich%gcc@4.6')
spec = Spec('mpileaks ^mpich%gcc@4.5 ^callpath ^dyninst ^libelf ^libdwarf') spec = Spec('mpileaks ^mpich%gcc@4.5 ^callpath ^dyninst ^libelf ^libdwarf')
self.assertRaises(spack.spec.UnsatisfiableCompilerSpecError, spec.normalize) self.assertRaises(spack.spec.UnsatisfiableCompilerSpecError, spec.normalize)
def test_unsatisfiable_architecture(self): def test_unsatisfiable_architecture(self):
set_pkg_dep('mpileaks', 'mpich=bgqos_0') self.set_pkg_dep('mpileaks', 'mpich=bgqos_0')
spec = Spec('mpileaks ^mpich=sles_10_ppc64 ^callpath ^dyninst ^libelf ^libdwarf') spec = Spec('mpileaks ^mpich=sles_10_ppc64 ^callpath ^dyninst ^libelf ^libdwarf')
self.assertRaises(spack.spec.UnsatisfiableArchitectureSpecError, spec.normalize) self.assertRaises(spack.spec.UnsatisfiableArchitectureSpecError, spec.normalize)