Exemple #1
0
    def test_conflicting_dependencies(self):
        # Given
        packages_definition = textwrap.dedent("""
        MKL 10.3-1
        MKL 11.4.1-1
        numpy 1.9.2-1; depends (MKL == 10.3-1)
        numpy 1.10.4-1; depends (MKL == 11.4.1-1)
        scipy 0.16.0-1; depends (MKL == 10.3-1, numpy ^= 1.9.2)
        scipy 0.17.0-1; depends (MKL == 11.4.1-1, numpy ^= 1.10.4)
        """)
        packages = packages_from_definition(packages_definition)

        def callback(requirements):
            return requirements_are_satisfiable(packages,
                                                requirements).is_satisfiable

        r_min_unsat = [
            Requirement._from_string("MKL < 11"),
            Requirement._from_string("scipy >= 0.17.0"),
        ]

        # When
        requirements = [
            Requirement._from_string("MKL < 11"),
            Requirement._from_string("numpy"),
            Requirement._from_string("scipy >= 0.17.0"),
        ]
        min_unsat = minimal_unsatisfiable_subset(requirements, callback)

        # Then
        six.assertCountEqual(self, min_unsat, r_min_unsat)
Exemple #2
0
    def test_simple(self):
        # Given
        packages_definition = textwrap.dedent("""\
        MKL 10.3-1
        MKL 11.4.1-1
        numpy 1.9.2-1; depends (MKL == 10.3-1)
        numpy 1.10.4-1; depends (MKL == 11.4.1-1)
        """)
        packages = packages_from_definition(packages_definition)

        def callback(requirements):
            return requirements_are_satisfiable(packages,
                                                requirements).is_satisfiable

        r_min_unsat = [
            Requirement._from_string("numpy < 1.10"),
            Requirement._from_string("MKL >= 11")
        ]

        # When
        requirements = [
            Requirement._from_string("numpy < 1.10"),
            Requirement._from_string("MKL >= 11")
        ]
        min_unsat = minimal_unsatisfiable_subset(requirements, callback)

        # Then
        six.assertCountEqual(self, min_unsat, r_min_unsat)
    def from_yaml(cls, file_or_filename):
        if isinstance(file_or_filename, six.string_types):
            with open(file_or_filename) as fp:
                data = yaml.load(fp, Loader=_UnicodeLoader)
        else:
            data = yaml.load(file_or_filename, Loader=_UnicodeLoader)

        scenario_requests = data.get("request", [])

        marked = list(data.get("marked", []))

        request = Request()

        for kind, values in data.get("modifiers", {}).items():
            for value in values:
                getattr(request, kind)(value)

        update_all = False

        for s_request in scenario_requests:
            kind = s_request["operation"]
            if kind == 'update_all':
                update_all = True
                continue
            requirement = Requirement._from_string(s_request["requirement"])
            try:
                marked.remove(requirement.name)
            except ValueError:
                pass
            getattr(request, kind)(requirement)

        if update_all:
            request_job = request.hard_update
        else:
            request_job = request.install

        for package_str in marked:
            request_job(Requirement._from_string(package_str))

        decisions = data.get("decisions", {})

        operations = cls._operations_from_transaction_list(
            data.get("transaction", []))

        pretty_operations = cls._operations_from_transaction_list(
            data.get("pretty_transaction", []))

        failure = data.get('failure')

        packages = collections.OrderedDict(
            parse_package_list(data.get("packages", [])))

        return cls(packages, [remote_repository(data, packages)],
                   installed_repository(data, packages),
                   request,
                   decisions,
                   operations,
                   pretty_operations,
                   failure=failure)
Exemple #4
0
    def from_yaml(cls, file_or_filename):
        if isinstance(file_or_filename, six.string_types):
            with open(file_or_filename) as fp:
                data = yaml.load(fp, Loader=_UnicodeLoader)
        else:
            data = yaml.load(file_or_filename, Loader=_UnicodeLoader)

        scenario_requests = data.get("request", [])

        marked = list(data.get("marked", []))

        request = Request()

        for kind, values in data.get("modifiers", {}).items():
            for value in values:
                getattr(request, kind)(value)

        update_all = False

        for s_request in scenario_requests:
            kind = s_request["operation"]
            if kind == 'update_all':
                update_all = True
                continue
            requirement = Requirement._from_string(s_request["requirement"])
            try:
                marked.remove(requirement.name)
            except ValueError:
                pass
            getattr(request, kind)(requirement)

        if update_all:
            request_job = request.hard_update
        else:
            request_job = request.install

        for package_str in marked:
            request_job(Requirement._from_string(package_str))

        decisions = data.get("decisions", {})

        operations = cls._operations_from_transaction_list(
            data.get("transaction", []))

        pretty_operations = cls._operations_from_transaction_list(
            data.get("pretty_transaction", []))

        failure = data.get('failure')

        packages = collections.OrderedDict(
            parse_package_list(data.get("packages", [])))

        return cls(packages, [remote_repository(data, packages)],
                   installed_repository(data, packages), request,
                   decisions, operations, pretty_operations, failure=failure)
Exemple #5
0
    def test_constraint_modifiers(self):
        # Given
        packages_definition = textwrap.dedent("""
        MKL 10.3-1
        MKL 11.4.1-1
        numpy 1.9.2-1; depends (MKL == 10.3-1)
        numpy 1.10.4-1; depends (MKL == 11.4.1-1)
        """)
        packages = packages_from_definition(packages_definition)

        requirements = [
            Requirement._from_string("numpy < 1.10"),
            Requirement._from_string("MKL >= 11")
        ]
        modifiers = ConstraintModifiers(allow_newer=("MKL", ))

        # When/Then
        result = requirements_are_satisfiable(packages, requirements)
        self.assertFalse(result.is_satisfiable)
        result = requirements_are_satisfiable(packages, requirements,
                                              modifiers)
        self.assertTrue(result.is_satisfiable)
Exemple #6
0
    def _solve(self, top_core, flags={}, only_matching_vlnv=False):
        def eq_vln(this, that):
            return \
                this.vendor  == that.vendor and \
                this.library == that.library and \
                this.name    == that.name

        repo = Repository()
        _flags = flags.copy()
        cores = [x['core'] for x in self._cores.values()]
        for core in cores:
            if only_matching_vlnv:
                if not eq_vln(core.name, top_core):
                    continue

            package_str = "{} {}-{}".format(self._package_name(core.name),
                                            core.name.version,
                                            core.name.revision)
            if not only_matching_vlnv:
                _flags['is_toplevel'] = (core.name == top_core)
                _depends = core.get_depends(_flags)
                if _depends:
                    _s = "; depends ( {} )"
                    package_str += _s.format(self._parse_depend(_depends))
            parser = PrettyPackageStringParser(EnpkgVersion.from_string)

            package = parser.parse_to_package(package_str)
            package.core = core

            repo.add_package(package)

        request = Request()
        _top_dep = "{} {} {}".format(self._package_name(top_core),
                                     top_core.relation,
                                     self._package_version(top_core))
        requirement = Requirement._from_string(_top_dep)
        request.install(requirement)
        installed_repository = Repository()
        pool = Pool([repo])
        pool.add_repository(installed_repository)
        solver = DependencySolver(pool, [repo], installed_repository)

        try:
            transaction = solver.solve(request)
        except SatisfiabilityError as e:
            raise DependencyError(top_core.name,
                                  msg=e.unsat.to_string(pool))
        except NoPackageFound as e:
            raise DependencyError(top_core.name)

        return [op.package.core for op in transaction.operations]
Exemple #7
0
def dependency_to_string(dependency):
    req = Requirement.from_legacy_requirement_string(dependency)
    constraints = list(req._constraints._constraints)
    assert len(constraints) == 1
    assert isinstance(constraints[0],
                      (EnpkgUpstreamMatch, Any, Equal))
    constraint = constraints[0]
    if isinstance(constraint, Any):
        return req.name
    elif isinstance(constraint, Equal):
        return "{0} == {1}".format(req.name, str(constraint.version))
    else:  # EnpkgUpstreamMatch
        assert isinstance(constraint.version, EnpkgVersion)
        return "{0} ~= {1}".format(req.name, str(constraint.version.upstream))
Exemple #8
0
    def solve(self, top_core, tool):
        repo = Repository()
        for core in self._cores.values():
            package_str = "{} {}-{}".format(self._package_name(core.name),
                                            core.name.version,
                                            core.name.revision)
            _depends = core.depend
            try:
                _depends += getattr(core, tool).depend
            except (AttributeError, KeyError):
                pass

            if _depends:
                _s = "; depends ( {} )"
                package_str += _s.format(self._parse_depend(_depends))
            parser = PrettyPackageStringParser(EnpkgVersion.from_string)

            package = parser.parse_to_package(package_str)
            package.core = core

            repo.add_package(package)

        request = Request()
        _top_dep = "{} {} {}".format(self._package_name(top_core),
                                     top_core.relation,
                                     self._package_version(top_core))
        requirement = Requirement._from_string(_top_dep)
        request.install(requirement)
        installed_repository = Repository()
        pool = Pool([repo])
        pool.add_repository(installed_repository)
        solver = DependencySolver(pool, repo, installed_repository)

        try:
            transaction = solver.solve(request)
        except SatisfiabilityError as e:
            msg = "UNSATISFIABLE: {}"
            raise RuntimeError(msg.format(e.unsat.to_string(pool)))
        except NoPackageFound as e:
            raise DependencyError(top_core.name)

        return [op.package.core for op in transaction.operations]
Exemple #9
0
    def add_repository(self, repository):
        """ Add the repository to this pool.

        Parameters
        ----------
        repository : Repository
            The repository to add
        """
        self._repositories.append(repository)
        for package in repository:
            current_id = self._id
            self._id += 1
            self._id_to_package_[current_id] = package
            self._package_to_id_[package] = current_id
            for constraints in package.provides:
                req = Requirement.from_constraints(constraints)
                if req.has_any_version_constraint:
                    msg = ('Version constraints are not supported for'
                           ' package.provides metadata: {}')
                    raise InvalidConstraint(msg.format(req))
                self._packages_by_name_[req.name].append(package)
Exemple #10
0
    def add_repository(self, repository):
        """ Add the repository to this pool.

        Parameters
        ----------
        repository : Repository
            The repository to add
        """
        self._repositories.append(repository)
        for package in repository:
            current_id = self._id
            self._id += 1
            self._id_to_package_[current_id] = package
            self._package_to_id_[package] = current_id
            for constraints in package.provides:
                req = Requirement.from_constraints(constraints)
                if req.has_any_version_constraint:
                    msg = ('Version constraints are not supported for'
                           ' package.provides metadata: {}')
                    raise InvalidConstraint(msg.format(req))
                self._packages_by_name_[req.name].append(package)
Exemple #11
0
    def _solve(self, top_core, flags={}, only_matching_vlnv=False):
        def eq_vln(this, that):
            return (
                this.vendor == that.vendor
                and this.library == that.library
                and this.name == that.name
            )

        # Try to return a cached result
        solver_cache_key = (top_core, self._hash_flags_dict(flags), only_matching_vlnv)
        cached_solution = self._solver_cache_lookup(solver_cache_key)
        if cached_solution:
            return cached_solution

        repo = Repository()
        _flags = flags.copy()
        cores = [x["core"] for x in self._cores.values()]
        for core in cores:
            if only_matching_vlnv:
                if not eq_vln(core.name, top_core):
                    continue

            package_str = "{} {}-{}".format(
                self._package_name(core.name), core.name.version, core.name.revision
            )
            if not only_matching_vlnv:
                _flags["is_toplevel"] = core.name == top_core
                _depends = core.get_depends(_flags)
                if _depends:
                    _s = "; depends ( {} )"
                    package_str += _s.format(self._parse_depend(_depends))
            parser = PrettyPackageStringParser(EnpkgVersion.from_string)

            package = parser.parse_to_package(package_str)
            package.core = core

            repo.add_package(package)

        request = Request()
        simplevlnvs = top_core.simpleVLNVs()
        for sv in simplevlnvs:
            _top_dep = "{} {} {}".format(
                self._package_name(top_core),
                top_core.relation,
                self._package_version(top_core),
            )
            request.install(Requirement._from_string(_top_dep))

        installed_repository = Repository()
        pool = Pool([repo])
        pool.add_repository(installed_repository)
        solver = DependencySolver(pool, [repo], installed_repository)

        try:
            transaction = solver.solve(request)
        except SatisfiabilityError as e:
            raise DependencyError(top_core.name, msg=e.unsat.to_string(pool))
        except NoPackageFound as e:
            raise DependencyError(top_core.name)

        objdict = {}
        depdict = {}
        if len(transaction.operations) > 1:
            for op in transaction.operations:
                objdict[op.package._name] = str(op.package.core.name)
                depdict[str(op.package.core.name)] = [
                    objdict[n[0]] for n in op.package.install_requires
                ]
                op.package.core.direct_deps = [
                    objdict[n[0]] for n in op.package.install_requires
                ]
        result = [op.package.core for op in transaction.operations]

        # Cache the solution for further lookups
        self._solver_cache_store(solver_cache_key, result)

        return result
Exemple #12
0
    def from_yaml(cls, file_or_filename):
        if isinstance(file_or_filename, six.string_types):
            with open(file_or_filename) as fp:
                data = yaml.load(fp, Loader=_UnicodeLoader)
        else:
            data = yaml.load(file_or_filename, Loader=_UnicodeLoader)

        packages = collections.OrderedDict(
            parse_package_list(data.get("packages", []))
        )
        scenario_requests = data.get("request", [])

        marked = list(data.get("marked", []))

        request = Request()

        update_all = False

        for s_request in scenario_requests:
            kind = s_request["operation"]
            if kind == 'update_all':
                update_all = True
                continue
            requirement = Requirement._from_string(s_request["requirement"])
            try:
                marked.remove(requirement.name)
            except ValueError:
                pass
            getattr(request, kind)(requirement)

        if update_all:
            request_job = request.update
        else:
            request_job = request.install

        for package_str in marked:
            request_job(Requirement._from_string(package_str))

        decisions = data.get("decisions", {})

        def P(p):
            return next(parse_package_list([p]))[1]

        operations = []
        for operation in data.get("transaction", []):
            if operation["kind"] == "install":
                operations.append(InstallOperation(P(operation["package"])))
            elif operation["kind"] == "update":
                operations.append(UpdateOperation(P(operation["to"]),
                                                  P(operation["from"])))
            elif operation["kind"] == "remove":
                operations.append(RemoveOperation(P(operation["package"])))
            else:
                msg = "invalid operation kind {!r}".format(operation["kind"])
                raise ValueError(msg)

        failure = data.get('failure')

        return cls(packages, [remote_repository(data, packages)],
                   installed_repository(data, packages), request,
                   decisions, operations, failure)