Example #1
0
def test_it_should_calculate_operations_in_correct_order():
    transaction = Transaction(
        [Package("a", "1.0.0"),
         Package("b", "2.0.0"),
         Package("c", "3.0.0")],
        [
            (Package("a", "1.0.0"), 1),
            (Package("b", "2.1.0"), 2),
            (Package("d", "4.0.0"), 0),
        ],
    )

    check_operations(
        transaction.calculate_operations(),
        [
            {
                "job": "install",
                "package": Package("b", "2.1.0")
            },
            {
                "job": "install",
                "package": Package("a", "1.0.0")
            },
            {
                "job": "install",
                "package": Package("d", "4.0.0")
            },
        ],
    )
Example #2
0
def test_it_should_remove_installed_packages_if_required():
    transaction = Transaction(
        [Package("a", "1.0.0"), Package("b", "2.0.0"), Package("c", "3.0.0")],
        [
            (Package("a", "1.0.0"), 1),
            (Package("b", "2.1.0"), 2),
            (Package("d", "4.0.0"), 0),
        ],
        installed_packages=[
            Package("a", "1.0.0"),
            Package("b", "2.0.0"),
            Package("c", "3.0.0"),
            Package("e", "5.0.0"),
        ],
    )

    check_operations(
        transaction.calculate_operations(synchronize=True),
        [
            {"job": "remove", "package": Package("c", "3.0.0")},
            {"job": "remove", "package": Package("e", "5.0.0")},
            {
                "job": "update",
                "from": Package("b", "2.0.0"),
                "to": Package("b", "2.1.0"),
            },
            {"job": "install", "package": Package("a", "1.0.0"), "skipped": True},
            {"job": "install", "package": Package("d", "4.0.0")},
        ],
    )
Example #3
0
def test_it_should_update_installed_packages_if_sources_are_different():
    transaction = Transaction(
        [Package("a", "1.0.0")],
        [(
            Package(
                "a",
                "1.0.0",
                source_url="https://github.com/demo/demo.git",
                source_type="git",
                source_reference="main",
                source_resolved_reference="123456",
            ),
            1,
        )],
        installed_packages=[Package("a", "1.0.0")],
    )

    check_operations(
        transaction.calculate_operations(synchronize=True),
        [{
            "job":
            "update",
            "from":
            Package("a", "1.0.0"),
            "to":
            Package(
                "a",
                "1.0.0",
                source_url="https://github.com/demo/demo.git",
                source_type="git",
                source_reference="main",
                source_resolved_reference="123456",
            ),
        }],
    )
Example #4
0
    def solve(self, use_latest: list[str] | None = None) -> Transaction:
        from poetry.puzzle.transaction import Transaction

        with self._provider.progress():
            start = time.time()
            packages, depths = self._solve(use_latest=use_latest)
            end = time.time()

            if len(self._overrides) > 1:
                self._provider.debug(
                    f"Complete version solving took {end - start:.3f} seconds with"
                    f" {len(self._overrides)} overrides")
                self._provider.debug(
                    "Resolved with overrides:"
                    f" {', '.join(f'({b})' for b in self._overrides)}")

        return Transaction(
            self._locked.packages,
            list(zip(packages, depths)),
            installed_packages=self._installed.packages,
            root_package=self._package,
        )
Example #5
0
    def _do_install(self, local_repo: Repository) -> int:
        from poetry.puzzle import Solver

        locked_repository = Repository()
        if self._update:
            if self._locker.is_locked() and not self._lock:
                locked_repository = self._locker.locked_repository()

                # If no packages have been whitelisted (The ones we want to update),
                # we whitelist every package in the lock file.
                if not self._whitelist:
                    for pkg in locked_repository.packages:
                        self._whitelist.append(pkg.name)

            # Checking extras
            for extra in self._extras:
                if extra not in self._package.extras:
                    raise ValueError(f"Extra [{extra}] is not specified.")

            self._io.write_line("<info>Updating dependencies</>")
            solver = Solver(
                self._package,
                self._pool,
                self._installed_repository,
                locked_repository,
                self._io,
            )

            with solver.provider.use_source_root(
                source_root=self._env.path.joinpath("src")
            ):
                ops = solver.solve(use_latest=self._whitelist).calculate_operations()
        else:
            self._io.write_line("<info>Installing dependencies from lock file</>")

            locked_repository = self._locker.locked_repository()

            if not self._locker.is_fresh():
                self._io.write_error_line(
                    "<warning>"
                    "Warning: poetry.lock is not consistent with pyproject.toml. "
                    "You may be getting improper dependencies. "
                    "Run `poetry lock [--no-update]` to fix it."
                    "</warning>"
                )

            for extra in self._extras:
                if extra not in self._locker.lock_data.get("extras", {}):
                    raise ValueError(f"Extra [{extra}] is not specified.")

            # If we are installing from lock
            # Filter the operations by comparing it with what is
            # currently installed
            ops = self._get_operations_from_lock(locked_repository)

        self._populate_local_repo(local_repo, ops)

        if self._update:
            self._write_lock_file(local_repo)

            if self._lock:
                # If we are only in lock mode, no need to go any further
                return 0

        if self._groups is not None:
            root = self._package.with_dependency_groups(list(self._groups), only=True)
        else:
            root = self._package.without_optional_dependency_groups()

        if self._io.is_verbose():
            self._io.write_line("")
            self._io.write_line(
                "<info>Finding the necessary packages for the current system</>"
            )

        # We resolve again by only using the lock file
        pool = Pool(ignore_repository_names=True)

        # Making a new repo containing the packages
        # newly resolved and the ones from the current lock file
        repo = Repository()
        for package in local_repo.packages + locked_repository.packages:
            if not repo.has_package(package):
                repo.add_package(package)

        pool.add_repository(repo)

        solver = Solver(
            root, pool, self._installed_repository, locked_repository, NullIO()
        )
        # Everything is resolved at this point, so we no longer need
        # to load deferred dependencies (i.e. VCS, URL and path dependencies)
        solver.provider.load_deferred(False)

        with solver.use_environment(self._env):
            ops = solver.solve(use_latest=self._whitelist).calculate_operations(
                with_uninstalls=self._requires_synchronization,
                synchronize=self._requires_synchronization,
            )

        if not self._requires_synchronization:
            # If no packages synchronisation has been requested we need
            # to calculate the uninstall operations
            from poetry.puzzle.transaction import Transaction

            transaction = Transaction(
                locked_repository.packages,
                [(package, 0) for package in local_repo.packages],
                installed_packages=self._installed_repository.packages,
                root_package=root,
            )

            ops = [
                op
                for op in transaction.calculate_operations(with_uninstalls=True)
                if op.job_type == "uninstall"
            ] + ops

        # We need to filter operations so that packages
        # not compatible with the current system,
        # or optional and not requested, are dropped
        self._filter_operations(ops, local_repo)

        # Execute operations
        return self._execute(ops)