def __init__(self, name, dependencies, dependency_types, conditions=None, versions=None): self.name = name self.spec = None self.dependencies = ordereddict_backport.OrderedDict() assert len(dependencies) == len(dependency_types) for dep, dtype in zip(dependencies, dependency_types): d = Dependency(self, Spec(dep.name), type=dtype) if not conditions or dep.name not in conditions: self.dependencies[dep.name] = {Spec(name): d} else: dep_conditions = conditions[dep.name] dep_conditions = dict( (Spec(x), Dependency(self, Spec(y), type=dtype)) for x, y in dep_conditions.items()) self.dependencies[dep.name] = dep_conditions if versions: self.versions = versions else: versions = list(Version(x) for x in [1, 2, 3]) self.versions = dict((x, {'preferred': False}) for x in versions) self.variants = {} self.provided = {} self.conflicts = {} self.patches = {}
def _depends_on(pkg, spec, when=None, type=default_deptype, patches=None): when_spec = make_when_spec(when) if not when_spec: return dep_spec = spack.spec.Spec(spec) if pkg.name == dep_spec.name: raise CircularReferenceError("Package '%s' cannot depend on itself." % pkg.name) type = canonical_deptype(type) conditions = pkg.dependencies.setdefault(dep_spec.name, {}) # call this patches here for clarity -- we want patch to be a list, # but the caller doesn't have to make it one. # Note: we cannot check whether a package is virtual in a directive # because directives are run as part of class instantiation, and specs # instantiate the package class as part of the `virtual` check. # To be technical, specs only instantiate the package class as part of the # virtual check if the provider index hasn't been created yet. # TODO: There could be a cache warming strategy that would allow us to # ensure `Spec.virtual` is a valid thing to call in a directive. # For now, we comment out the following check to allow for virtual packages # with package files. # if patches and dep_spec.virtual: # raise DependencyPatchError("Cannot patch a virtual dependency.") # ensure patches is a list if patches is None: patches = [] elif not isinstance(patches, (list, tuple)): patches = [patches] # auto-call patch() directive on any strings in patch list patches = [ patch(p) if isinstance(p, six.string_types) else p for p in patches ] assert all(callable(p) for p in patches) # this is where we actually add the dependency to this package if when_spec not in conditions: dependency = Dependency(pkg, dep_spec, type=type) conditions[when_spec] = dependency else: dependency = conditions[when_spec] dependency.spec.constrain(dep_spec, deps=False) dependency.type |= set(type) # apply patches to the dependency for execute_patch in patches: execute_patch(dependency)
def _mock(pkg_name, spec, deptypes=all_deptypes): """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.repo.get(pkg_name) if pkg_name not in saved_deps: saved_deps[pkg_name] = (pkg, pkg.dependencies.copy()) cond = Spec(pkg.name) dependency = Dependency(pkg, spec, type=deptypes) pkg.dependencies[spec.name] = {cond: dependency}
def _mock(pkg_name, spec, deptypes=all_deptypes): """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_cls = spack.repo.path.get_pkg_class(pkg_name) if pkg_name not in saved_deps: saved_deps[pkg_name] = (pkg_cls, pkg_cls.dependencies.copy()) cond = Spec(pkg_cls.name) dependency = Dependency(pkg_cls, spec, type=deptypes) monkeypatch.setitem(pkg_cls.dependencies, spec.name, {cond: dependency})
def _depends_on(pkg, spec, when=None, type=default_deptype, patches=None): # If when is False do nothing if when is False: return # If when is None or True make sure the condition is always satisfied if when is None or when is True: when = pkg.name when_spec = spack.spec.parse_anonymous_spec(when, pkg.name) dep_spec = spack.spec.Spec(spec) if pkg.name == dep_spec.name: raise CircularReferenceError("Package '%s' cannot depend on itself." % pkg.name) type = canonical_deptype(type) conditions = pkg.dependencies.setdefault(dep_spec.name, {}) # call this patches here for clarity -- we want patch to be a list, # but the caller doesn't have to make it one. if patches and dep_spec.virtual: raise DependencyPatchError("Cannot patch a virtual dependency.") # ensure patches is a list if patches is None: patches = [] elif not isinstance(patches, (list, tuple)): patches = [patches] # auto-call patch() directive on any strings in patch list patches = [patch(p) if isinstance(p, string_types) else p for p in patches] assert all(callable(p) for p in patches) # this is where we actually add the dependency to this package if when_spec not in conditions: dependency = Dependency(pkg, dep_spec, type=type) conditions[when_spec] = dependency else: dependency = conditions[when_spec] dependency.spec.constrain(dep_spec, deps=False) dependency.type |= set(type) # apply patches to the dependency for execute_patch in patches: execute_patch(dependency)
def add_package(self, name, dependencies=None, dependency_types=None, conditions=None): """Factory method for creating mock packages. This creates a new subclass of ``MockPackageBase``, ensures that its ``name`` and ``__name__`` properties are set up correctly, and returns a new instance. We use a factory function here because many functions and properties of packages need to be class functions. Args: name (str): name of the new package dependencies (list): list of mock packages to be dependencies for this new package (optional; no deps if not provided) dependency_type (list): list of deptypes for each dependency (optional; will be default_deptype if not provided) conditions (list): condition specs for each dependency (optional) """ if not dependencies: dependencies = [] if not dependency_types: dependency_types = [spack.dependency.default_deptype ] * len(dependencies) assert len(dependencies) == len(dependency_types) # new class for the mock package class MockPackage(MockPackageBase): pass MockPackage.__name__ = spack.util.naming.mod_to_class(name) MockPackage.name = name MockPackage._repo = self # set up dependencies MockPackage.dependencies = ordereddict_backport.OrderedDict() for dep, dtype in zip(dependencies, dependency_types): d = Dependency(MockPackage, Spec(dep.name), type=dtype) if not conditions or dep.name not in conditions: MockPackage.dependencies[dep.name] = {Spec(name): d} else: dep_conditions = conditions[dep.name] dep_conditions = dict( (Spec(x), Dependency(MockPackage, Spec(y), type=dtype)) for x, y in dep_conditions.items()) MockPackage.dependencies[dep.name] = dep_conditions # each package has some fake versions versions = list(Version(x) for x in [1, 2, 3]) MockPackage.versions = dict((x, { 'preferred': False }) for x in versions) MockPackage.variants = {} MockPackage.provided = {} MockPackage.conflicts = {} MockPackage.patches = {} mock_package = MockPackage(dependencies, dependency_types, conditions, versions) self.spec_to_pkg[name] = mock_package self.spec_to_pkg["mockrepo." + name] = mock_package return mock_package