def _do_refresh(self) -> int: from poetry.puzzle.solver import Solver # Checking extras for extra in self._extras: if extra not in self._package.extras: raise ValueError(f"Extra [{extra}] is not specified.") locked_repository = self._locker.locked_repository() solver = Solver( self._package, self._pool, locked_repository.packages, locked_repository.packages, self._io, ) with solver.provider.use_source_root( source_root=self._env.path.joinpath("src")): ops = solver.solve(use_latest=[]).calculate_operations() lockfile_repo = LockfileRepository() self._populate_lockfile_repo(lockfile_repo, ops) self._write_lock_file(lockfile_repo, force=True) return 0
def handle(self): from clikit.utils.terminal import Terminal from poetry.io.null_io import NullIO from poetry.puzzle.solver import Solver from poetry.repositories.installed_repository import InstalledRepository from poetry.repositories.pool import Pool from poetry.repositories.repository import Repository from poetry.utils.helpers import get_package_version_display_string package = self.argument("package") if self.option("tree"): self.init_styles(self.io) if self.option("outdated"): self._args.set_option("latest", True) include_dev = not self.option("no-dev") locked_repo = self.poetry.locker.locked_repository(True) # Show tree view if requested if self.option("tree") and not package: requires = self.poetry.package.requires + self.poetry.package.dev_requires packages = locked_repo.packages for package in packages: for require in requires: if package.name == require.name: self.display_package_tree(self._io, package, locked_repo) break return 0 table = self.table(style="compact") # table.style.line_vc_char = "" locked_packages = locked_repo.packages pool = Pool(ignore_repository_names=True) pool.add_repository(locked_repo) solver = Solver( self.poetry.package, pool=pool, installed=Repository(), locked=locked_repo, io=NullIO(), ) solver.provider.load_deferred(False) with solver.use_environment(self.env): ops = solver.solve() required_locked_packages = set( [op.package for op in ops if not op.skipped]) if self.option("no-dev"): required_locked_packages = [ p for p in locked_packages if p.category == "main" ] if package: pkg = None for locked in locked_packages: if package.lower() == locked.name: pkg = locked break if not pkg: raise ValueError("Package {} not found".format(package)) if self.option("tree"): self.display_package_tree(self.io, pkg, locked_repo) return 0 rows = [ ["<info>name</>", " : <c1>{}</>".format(pkg.pretty_name)], [ "<info>version</>", " : <b>{}</b>".format(pkg.pretty_version) ], ["<info>description</>", " : {}".format(pkg.description)], ] table.add_rows(rows) table.render(self.io) if pkg.requires: self.line("") self.line("<info>dependencies</info>") for dependency in pkg.requires: self.line(" - <c1>{}</c1> <b>{}</b>".format( dependency.pretty_name, dependency.pretty_constraint)) return 0 show_latest = self.option("latest") show_all = self.option("all") terminal = Terminal() width = terminal.width name_length = version_length = latest_length = 0 latest_packages = {} latest_statuses = {} installed_repo = InstalledRepository.load(self.env) # Computing widths for locked in locked_packages: if locked not in required_locked_packages and not show_all: continue current_length = len(locked.pretty_name) if not self._io.output.supports_ansi(): installed_status = self.get_installed_status( locked, installed_repo) if installed_status == "not-installed": current_length += 4 if show_latest: latest = self.find_latest_package(locked, include_dev) if not latest: latest = locked latest_packages[locked.pretty_name] = latest update_status = latest_statuses[ locked.pretty_name] = self.get_update_status( latest, locked) if not self.option( "outdated") or update_status != "up-to-date": name_length = max(name_length, current_length) version_length = max( version_length, len( get_package_version_display_string( locked, root=self.poetry.file.parent)), ) latest_length = max( latest_length, len( get_package_version_display_string( latest, root=self.poetry.file.parent)), ) else: name_length = max(name_length, current_length) version_length = max( version_length, len( get_package_version_display_string( locked, root=self.poetry.file.parent)), ) write_version = name_length + version_length + 3 <= width write_latest = name_length + version_length + latest_length + 3 <= width write_description = name_length + version_length + latest_length + 24 <= width for locked in locked_packages: color = "cyan" name = locked.pretty_name install_marker = "" if locked not in required_locked_packages: if not show_all: continue color = "black;options=bold" else: installed_status = self.get_installed_status( locked, installed_repo) if installed_status == "not-installed": color = "red" if not self._io.output.supports_ansi(): # Non installed in non decorated mode install_marker = " (!)" if (show_latest and self.option("outdated") and latest_statuses[locked.pretty_name] == "up-to-date"): continue line = "<fg={}>{:{}}{}</>".format( color, name, name_length - len(install_marker), install_marker) if write_version: line += " <b>{:{}}</b>".format( get_package_version_display_string( locked, root=self.poetry.file.parent), version_length, ) if show_latest: latest = latest_packages[locked.pretty_name] update_status = latest_statuses[locked.pretty_name] if write_latest: color = "green" if update_status == "semver-safe-update": color = "red" elif update_status == "update-possible": color = "yellow" line += " <fg={}>{:{}}</>".format( color, get_package_version_display_string( latest, root=self.poetry.file.parent), latest_length, ) if write_description: description = locked.description remaining = width - name_length - version_length - 4 if show_latest: remaining -= latest_length if len(locked.description) > remaining: description = description[:remaining - 3] + "..." line += " " + description self.line(line)
def handle(self) -> int: from cleo.io.null_io import NullIO from poetry.core.packages.project_package import ProjectPackage from poetry.factory import Factory from poetry.puzzle.solver import Solver from poetry.repositories.pool import Pool from poetry.repositories.repository import Repository from poetry.utils.env import EnvManager packages = self.argument("package") if not packages: package = self.poetry.package else: # Using current pool for determine_requirements() self._pool = self.poetry.pool package = ProjectPackage(self.poetry.package.name, self.poetry.package.version) # Silencing output verbosity = self.io.output.verbosity self.io.output.set_verbosity(Verbosity.QUIET) requirements = self._determine_requirements(packages) self.io.output.set_verbosity(verbosity) for constraint in requirements: name = constraint.pop("name") assert isinstance(name, str) extras = [] for extra in self.option("extras"): if " " in extra: extras += [e.strip() for e in extra.split(" ")] else: extras.append(extra) constraint["extras"] = extras package.add_dependency( Factory.create_dependency(name, constraint)) package.python_versions = self.option("python") or ( self.poetry.package.python_versions) pool = self.poetry.pool solver = Solver(package, pool, Repository(), Repository(), self._io) ops = solver.solve().calculate_operations() self.line("") self.line("Resolution results:") self.line("") if self.option("tree"): show_command: ShowCommand = self.application.find("show") show_command.init_styles(self.io) packages = [op.package for op in ops] repo = Repository(packages=packages) requires = package.all_requires for pkg in repo.packages: for require in requires: if pkg.name == require.name: show_command.display_package_tree(self.io, pkg, repo) break return 0 table = self.table(style="compact") table.style.set_vertical_border_chars("", " ") rows = [] if self.option("install"): env = EnvManager(self.poetry).get() pool = Pool() locked_repository = Repository() for op in ops: locked_repository.add_package(op.package) pool.add_repository(locked_repository) solver = Solver(package, pool, Repository(), Repository(), NullIO()) with solver.use_environment(env): ops = solver.solve().calculate_operations() for op in ops: if self.option("install") and op.skipped: continue pkg = op.package row = [ f"<c1>{pkg.complete_name}</c1>", f"<b>{pkg.version}</b>", ] if not pkg.marker.is_any(): row[2] = str(pkg.marker) rows.append(row) table.set_rows(rows) table.render() return 0
def handle(self) -> Optional[int]: from cleo.io.null_io import NullIO from cleo.terminal import Terminal from poetry.puzzle.solver import Solver from poetry.repositories.installed_repository import InstalledRepository from poetry.repositories.pool import Pool from poetry.repositories.repository import Repository from poetry.utils.helpers import get_package_version_display_string package = self.argument("package") if self.option("tree"): self.init_styles(self.io) if self.option("outdated"): self._io.input.set_option("latest", True) excluded_groups = [] included_groups = [] only_groups = [] if self.option("no-dev"): self.line_error( "<warning>The `<fg=yellow;options=bold>--no-dev</>` option is" " deprecated, use the `<fg=yellow;options=bold>--without dev</>`" " notation instead.</warning>" ) excluded_groups.append("dev") excluded_groups.extend( [ group.strip() for groups in self.option("without") for group in groups.split(",") ] ) included_groups.extend( [ group.strip() for groups in self.option("with") for group in groups.split(",") ] ) only_groups.extend( [ group.strip() for groups in self.option("only") for group in groups.split(",") ] ) if self.option("default"): only_groups.append("default") locked_repo = self.poetry.locker.locked_repository(True) if only_groups: root = self.poetry.package.with_dependency_groups(only_groups, only=True) else: root = self.poetry.package.with_dependency_groups( included_groups ).without_dependency_groups(excluded_groups) # Show tree view if requested if self.option("tree") and not package: requires = root.all_requires packages = locked_repo.packages for pkg in packages: for require in requires: if pkg.name == require.name: self.display_package_tree(self._io, pkg, locked_repo) break return 0 table = self.table(style="compact") locked_packages = locked_repo.packages pool = Pool(ignore_repository_names=True) pool.add_repository(locked_repo) solver = Solver( root, pool=pool, installed=Repository(), locked=locked_repo, io=NullIO(), ) solver.provider.load_deferred(False) with solver.use_environment(self.env): ops = solver.solve().calculate_operations() required_locked_packages = {op.package for op in ops if not op.skipped} if package: pkg = None for locked in locked_packages: if package.lower() == locked.name: pkg = locked break if not pkg: raise ValueError(f"Package {package} not found") if self.option("tree"): self.display_package_tree(self.io, pkg, locked_repo) return 0 required_by = {} for locked in locked_packages: dependencies = {d.name: d.pretty_constraint for d in locked.requires} if pkg.name in dependencies: required_by[locked.pretty_name] = dependencies[pkg.name] rows = [ ["<info>name</>", f" : <c1>{pkg.pretty_name}</>"], ["<info>version</>", f" : <b>{pkg.pretty_version}</b>"], ["<info>description</>", f" : {pkg.description}"], ] table.add_rows(rows) table.render() if pkg.requires: self.line("") self.line("<info>dependencies</info>") for dependency in pkg.requires: self.line( f" - <c1>{dependency.pretty_name}</c1>" f" <b>{dependency.pretty_constraint}</b>" ) if required_by: self.line("") self.line("<info>required by</info>") for parent, requires_version in required_by.items(): self.line(f" - <c1>{parent}</c1> <b>{requires_version}</b>") return 0 show_latest = self.option("latest") show_all = self.option("all") terminal = Terminal() width = terminal.width name_length = version_length = latest_length = 0 latest_packages = {} latest_statuses = {} installed_repo = InstalledRepository.load(self.env) # Computing widths for locked in locked_packages: if locked not in required_locked_packages and not show_all: continue current_length = len(locked.pretty_name) if not self._io.output.is_decorated(): installed_status = self.get_installed_status(locked, installed_repo) if installed_status == "not-installed": current_length += 4 if show_latest: latest = self.find_latest_package(locked, root) if not latest: latest = locked latest_packages[locked.pretty_name] = latest update_status = latest_statuses[ locked.pretty_name ] = self.get_update_status(latest, locked) if not self.option("outdated") or update_status != "up-to-date": name_length = max(name_length, current_length) version_length = max( version_length, len( get_package_version_display_string( locked, root=self.poetry.file.parent ) ), ) latest_length = max( latest_length, len( get_package_version_display_string( latest, root=self.poetry.file.parent ) ), ) else: name_length = max(name_length, current_length) version_length = max( version_length, len( get_package_version_display_string( locked, root=self.poetry.file.parent ) ), ) write_version = name_length + version_length + 3 <= width write_latest = name_length + version_length + latest_length + 3 <= width write_description = name_length + version_length + latest_length + 24 <= width for locked in locked_packages: color = "cyan" name = locked.pretty_name install_marker = "" if locked not in required_locked_packages: if not show_all: continue color = "black;options=bold" else: installed_status = self.get_installed_status(locked, installed_repo) if installed_status == "not-installed": color = "red" if not self._io.output.is_decorated(): # Non installed in non decorated mode install_marker = " (!)" if ( show_latest and self.option("outdated") and latest_statuses[locked.pretty_name] == "up-to-date" ): continue line = ( f"<fg={color}>" f"{name:{name_length - len(install_marker)}}{install_marker}</>" ) if write_version: version = get_package_version_display_string( locked, root=self.poetry.file.parent ) line += f" <b>{version:{version_length}}</b>" if show_latest: latest = latest_packages[locked.pretty_name] update_status = latest_statuses[locked.pretty_name] if write_latest: color = "green" if update_status == "semver-safe-update": color = "red" elif update_status == "update-possible": color = "yellow" version = get_package_version_display_string( latest, root=self.poetry.file.parent ) line += f" <fg={color}>{version:{latest_length}}</>" if write_description: description = locked.description remaining = width - name_length - version_length - 4 if show_latest: remaining -= latest_length if len(locked.description) > remaining: description = description[: remaining - 3] + "..." line += " " + description self.line(line) return None
def _do_install(self) -> int: from poetry.puzzle.solver import Solver locked_repository = Repository("poetry-locked") 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.packages, locked_repository.packages, 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) lockfile_repo = LockfileRepository() self._populate_lockfile_repo(lockfile_repo, ops) if self._update: self._write_lock_file(lockfile_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("poetry-repo") for package in lockfile_repo.packages + locked_repository.packages: if not package.is_direct_origin() and not repo.has_package( package): repo.add_package(package) pool.add_repository(repo) solver = Solver( root, pool, self._installed_repository.packages, locked_repository.packages, 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 lockfile_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, lockfile_repo) # Execute operations return self._execute(ops)
def handle(self) -> int: from cleo.io.null_io import NullIO from cleo.terminal import Terminal from poetry.puzzle.solver import Solver from poetry.repositories.installed_repository import InstalledRepository from poetry.repositories.pool import Pool from poetry.utils.helpers import get_package_version_display_string package = self.argument("package") if self.option("tree"): self.init_styles(self.io) if self.option("why"): if self.option("tree") and package is None: self.line_error( "<error>Error: --why requires a package when combined with" " --tree.</error>") return 1 if not self.option("tree") and package: self.line_error( "<error>Error: --why cannot be used without --tree when displaying" " a single package.</error>") return 1 if self.option("outdated"): self.io.input.set_option("latest", True) if not self.poetry.locker.is_locked(): self.line_error( "<error>Error: poetry.lock not found. Run `poetry lock` to create" " it.</error>") return 1 locked_repo = self.poetry.locker.locked_repository() root = self.project_with_activated_groups_only() # Show tree view if requested if self.option("tree") and package is None: requires = root.all_requires packages = locked_repo.packages for p in packages: for require in requires: if p.name == require.name: self.display_package_tree(self.io, p, packages) break return 0 table = self.table(style="compact") locked_packages = locked_repo.packages pool = Pool(ignore_repository_names=True) pool.add_repository(locked_repo) solver = Solver( root, pool=pool, installed=[], locked=locked_packages, io=NullIO(), ) solver.provider.load_deferred(False) with solver.use_environment(self.env): ops = solver.solve().calculate_operations() required_locked_packages = {op.package for op in ops if not op.skipped} if package: pkg = None for locked in locked_packages: if canonicalize_name(package) == locked.name: pkg = locked break if not pkg: raise ValueError(f"Package {package} not found") required_by = reverse_deps(pkg, locked_repo) if self.option("tree"): if self.option("why"): # The default case if there's no reverse dependencies is to query # the subtree for pkg but if any rev-deps exist we'll query for each # of them in turn packages = [pkg] if required_by: packages = [ p for p in locked_packages for r in required_by.keys() if p.name == r ] else: # if no rev-deps exist we'll make this clear as it can otherwise # look very odd for packages that also have no or few direct # dependencies self.io.write_line( f"Package {package} is a direct dependency.") for p in packages: self.display_package_tree(self.io, p, locked_packages, why_package=pkg) else: self.display_package_tree(self.io, pkg, locked_packages) return 0 rows = [ ["<info>name</>", f" : <c1>{pkg.pretty_name}</>"], ["<info>version</>", f" : <b>{pkg.pretty_version}</b>"], ["<info>description</>", f" : {pkg.description}"], ] table.add_rows(rows) table.render() if pkg.requires: self.line("") self.line("<info>dependencies</info>") for dependency in pkg.requires: self.line(f" - <c1>{dependency.pretty_name}</c1>" f" <b>{dependency.pretty_constraint}</b>") if required_by: self.line("") self.line("<info>required by</info>") for parent, requires_version in required_by.items(): self.line( f" - <c1>{parent}</c1> <b>{requires_version}</b>") return 0 show_latest = self.option("latest") show_all = self.option("all") terminal = Terminal() width = terminal.width name_length = version_length = latest_length = required_by_length = 0 latest_packages = {} latest_statuses = {} installed_repo = InstalledRepository.load(self.env) # Computing widths for locked in locked_packages: if locked not in required_locked_packages and not show_all: continue current_length = len(locked.pretty_name) if not self.io.output.is_decorated(): installed_status = self.get_installed_status( locked, installed_repo.packages) if installed_status == "not-installed": current_length += 4 if show_latest: latest = self.find_latest_package(locked, root) if not latest: latest = locked latest_packages[locked.pretty_name] = latest update_status = latest_statuses[ locked.pretty_name] = self.get_update_status( latest, locked) if not self.option( "outdated") or update_status != "up-to-date": name_length = max(name_length, current_length) version_length = max( version_length, len( get_package_version_display_string( locked, root=self.poetry.file.parent)), ) latest_length = max( latest_length, len( get_package_version_display_string( latest, root=self.poetry.file.parent)), ) if self.option("why"): required_by = reverse_deps(locked, locked_repo) required_by_length = max( required_by_length, len(" from " + ",".join(required_by.keys())), ) else: name_length = max(name_length, current_length) version_length = max( version_length, len( get_package_version_display_string( locked, root=self.poetry.file.parent)), ) if self.option("why"): required_by = reverse_deps(locked, locked_repo) required_by_length = max( required_by_length, len(" from " + ",".join(required_by.keys()))) write_version = name_length + version_length + 3 <= width write_latest = name_length + version_length + latest_length + 3 <= width why_end_column = (name_length + version_length + latest_length + required_by_length) write_why = self.option("why") and (why_end_column + 3) <= width write_description = (why_end_column + 24) <= width for locked in locked_packages: color = "cyan" name = locked.pretty_name install_marker = "" if locked not in required_locked_packages: if not show_all: continue color = "black;options=bold" else: installed_status = self.get_installed_status( locked, installed_repo.packages) if installed_status == "not-installed": color = "red" if not self.io.output.is_decorated(): # Non installed in non decorated mode install_marker = " (!)" if (show_latest and self.option("outdated") and latest_statuses[locked.pretty_name] == "up-to-date"): continue line = ( f"<fg={color}>" f"{name:{name_length - len(install_marker)}}{install_marker}</>" ) if write_version: version = get_package_version_display_string( locked, root=self.poetry.file.parent) line += f" <b>{version:{version_length}}</b>" if show_latest: latest = latest_packages[locked.pretty_name] update_status = latest_statuses[locked.pretty_name] if write_latest: color = "green" if update_status == "semver-safe-update": color = "red" elif update_status == "update-possible": color = "yellow" version = get_package_version_display_string( latest, root=self.poetry.file.parent) line += f" <fg={color}>{version:{latest_length}}</>" if write_why: required_by = reverse_deps(locked, locked_repo) if required_by: content = ",".join(required_by.keys()) # subtract 6 for ' from ' line += f" from {content:{required_by_length - 6}}" else: line += " " * required_by_length if write_description: description = locked.description remaining = (width - name_length - version_length - required_by_length - 4) if show_latest: remaining -= latest_length if len(locked.description) > remaining: description = description[:remaining - 3] + "..." line += " " + description self.line(line) return 0