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") }, ], )
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")}, ], )
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", ), }], )
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, )
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)