def _filter_operations(self, ops, repo ): # type: (List[Operation], Repository) -> None extra_packages = [p.name for p in self._get_extra_packages(repo)] for op in ops: if isinstance(op, Update): package = op.target_package else: package = op.package if op.job_type == 'uninstall': continue parser = VersionParser() python = '.'.join([str(i) for i in self._venv.version_info[:3]]) if 'python' in package.requirements: python_constraint = parser.parse_constraints( package.requirements['python'] ) if not python_constraint.matches(Constraint('=', python)): # Incompatible python versions op.skip('Not needed for the current python version') continue if not package.python_constraint.matches(Constraint('=', python)): op.skip('Not needed for the current python version') continue if 'platform' in package.requirements: platform_constraint = GenericConstraint.parse( package.requirements['platform'] ) if not platform_constraint.matches( GenericConstraint('=', sys.platform) ): # Incompatible systems op.skip('Not needed for the current platform') continue if self._update: extras = {} for extra, deps in self._package.extras.items(): extras[extra] = [dep.name for dep in deps] else: extras = {} for extra, deps in self._locker.lock_data.get('extras', {}).items(): extras[extra] = [dep.lower() for dep in deps] # If a package is optional and not requested # in any extra we skip it if package.optional: if package.name not in extra_packages: op.skip('Not required') # If the package is a dev package and dev packages # are not requests, we skip it if package.category == 'dev' and not self.is_dev_mode(): op.skip('Dev dependencies not requested')
def _filter_operations( self, ops, repo): # type: (List[Operation], Repository) -> None extra_packages = [p.name for p in self._get_extra_packages(repo)] for op in ops: if isinstance(op, Update): package = op.target_package else: package = op.package if op.job_type == "uninstall": continue if package.name in self._develop and package.source_type == "directory": package.develop = True if op.skipped: op.unskip() python = Version.parse(".".join( [str(i) for i in self._venv.version_info[:3]])) if "python" in package.requirements: python_constraint = parse_constraint( package.requirements["python"]) if not python_constraint.allows(python): # Incompatible python versions op.skip("Not needed for the current python version") continue if not package.python_constraint.allows(python): op.skip("Not needed for the current python version") continue if "platform" in package.requirements: platform_constraint = GenericConstraint.parse( package.requirements["platform"]) if not platform_constraint.matches( GenericConstraint("=", sys.platform)): # Incompatible systems op.skip("Not needed for the current platform") continue if self._update: extras = {} for extra, deps in self._package.extras.items(): extras[extra] = [dep.name for dep in deps] else: extras = {} for extra, deps in self._locker.lock_data.get("extras", {}).items(): extras[extra] = [dep.lower() for dep in deps] # If a package is optional and not requested # in any extra we skip it if package.optional: if package.name not in extra_packages: op.skip("Not required") # If the package is a dev package and dev packages # are not requests, we skip it if package.category == "dev" and not self.is_dev_mode(): op.skip("Dev dependencies not requested")
def _get_tags_for_package(self, package, graph, depth=0): categories = ["dev"] optionals = [True] python_versions = [] platforms = [] _depths = [0] children = graph["children"] found = False for child in children: if child["name"] == package.name: category = child["category"] optional = child["optional"] python_version = child["python_version"] platform = child["platform"] _depths.append(depth) else: ( category, optional, python_version, platform, _depth, ) = self._get_tags_for_package(package, child, depth=depth + 1) _depths.append(_depth) categories.append(category) optionals.append(optional) if python_version is not None: python_versions.append(python_version) if platform is not None: platforms.append(platform) if "main" in categories: category = "main" else: category = "dev" optional = all(optionals) if not python_versions: python_version = None else: # Find the least restrictive constraint python_version = python_versions[0] for constraint in python_versions[1:]: previous = parse_constraint(python_version) current = parse_constraint(constraint) if python_version == "*": continue elif constraint == "*": python_version = constraint elif current.allows_all(previous): python_version = constraint if not platforms: platform = None else: platform = platforms[0] for constraint in platforms[1:]: previous = GenericConstraint.parse(platform) current = GenericConstraint.parse(constraint) if platform == "*": continue elif constraint == "*": platform = constraint elif current.matches(previous): platform = constraint depth = max(*(_depths + [0])) return category, optional, python_version, platform, depth
def _build_graph( self, package, packages, previous=None, previous_dep=None, dep=None ): if not previous: category = "dev" optional = True python_version = "*" platform = "*" else: category = dep.category optional = dep.is_optional() and not dep.is_activated() python_version = str( parse_constraint(previous["python_version"]).intersect( previous_dep.python_constraint ) ) platform = str( previous_dep.platform if GenericConstraint.parse(previous["platform"]).matches( previous_dep.platform_constraint ) and previous_dep.platform != "*" else previous["platform"] ) graph = { "name": package.name, "category": category, "optional": optional, "python_version": python_version, "platform": platform, "children": [], } if previous_dep and previous_dep is not dep and previous_dep.name == dep.name: return graph for dependency in package.all_requires: if dependency.is_optional(): if not package.is_root() and ( not previous_dep or not previous_dep.extras ): continue is_activated = False for group, extras in package.extras.items(): if dep: extras = previous_dep.extras elif package.is_root(): extras = package.extras else: extras = [] if group in extras: is_activated = True break if not is_activated: continue for pkg in packages: if pkg.name == dependency.name: # If there is already a child with this name # we merge the requirements existing = None for child in graph["children"]: if ( child["name"] == pkg.name and child["category"] == dependency.category ): existing = child continue child_graph = self._build_graph( pkg, packages, graph, dependency, dep or dependency ) if existing: existing["python_version"] = str( parse_constraint(existing["python_version"]).union( parse_constraint(child_graph["python_version"]) ) ) continue graph["children"].append(child_graph) return graph
def _get_tags_for_vertex(self, vertex, requested): category = 'dev' optional = True python_version = None platform = None if not vertex.incoming_edges: # Original dependency for req in requested: if vertex.payload.name == req.name: category = req.category optional = req.is_optional() python_version = str(req.python_constraint) platform = str(req.platform_constraint) break return category, optional, python_version, platform parser = VersionParser() python_versions = [] platforms = [] for edge in vertex.incoming_edges: python_version = None platform = None for req in edge.origin.payload.requires: if req.name == vertex.payload.name: python_version = req.python_versions platform = req.platform break (top_category, top_optional, top_python_version, top_platform) = self._get_tags_for_vertex( edge.origin, requested ) if top_category == 'main': category = top_category optional = optional and top_optional # Take the most restrictive constraints if top_python_version is not None: if python_version is not None: previous = parser.parse_constraints(python_version) current = parser.parse_constraints(top_python_version) if top_python_version != '*' and previous.matches(current): python_versions.append(top_python_version) else: python_versions.append(python_version) else: python_versions.append(top_python_version) elif python_version is not None: python_versions.append(python_version) if top_platform is not None: if platform is not None: previous = GenericConstraint.parse(platform) current = GenericConstraint.parse(top_platform) if top_platform != '*' and previous.matches(current): platforms.append(top_platform) else: platforms.append(platform) else: platforms.append(top_platform) elif platform is not None: platforms.append(platform) if not python_versions: python_version = None else: # Find the least restrictive constraint python_version = python_versions[0] previous = parser.parse_constraints(python_version) for constraint in python_versions[1:]: current = parser.parse_constraints(constraint) if python_version == '*': continue elif constraint == '*': python_version = constraint elif current.matches(previous): python_version = constraint if not platforms: platform = None else: platform = platforms[0] previous = GenericConstraint.parse(platform) for constraint in platforms[1:]: current = GenericConstraint.parse(constraint) if platform == '*': continue elif constraint == '*': platform = constraint elif current.matches(previous): platform = constraint return category, optional, python_version, platform
def _get_tags_for_package(self, package, graph): categories = ["dev"] optionals = [True] python_versions = [] platforms = [] children = graph["children"] for child in children: if child["name"] == package.name: category = child["category"] optional = child["optional"] python_version = child["python_version"] platform = child["platform"] else: ( category, optional, python_version, platform, ) = self._get_tags_for_package(package, child) categories.append(category) optionals.append(optional) if python_version is not None: python_versions.append(python_version) if platform is not None: platforms.append(platform) if "main" in categories: category = "main" else: category = "dev" optional = all(optionals) if not python_versions: python_version = None else: # Find the least restrictive constraint python_version = python_versions[0] for constraint in python_versions[1:]: previous = parse_constraint(python_version) current = parse_constraint(constraint) if python_version == "*": continue elif constraint == "*": python_version = constraint elif current.allows_all(previous): python_version = constraint if not platforms: platform = None else: platform = platforms[0] for constraint in platforms[1:]: previous = GenericConstraint.parse(platform) current = GenericConstraint.parse(constraint) if platform == "*": continue elif constraint == "*": platform = constraint elif current.matches(previous): platform = constraint return category, optional, python_version, platform
def _build_graph(self, package, packages, previous=None, previous_dep=None, dep=None): if not previous: category = "dev" optional = True python_version = "*" platform = "*" else: category = dep.category optional = dep.is_optional() and not dep.is_activated() python_version = str( parse_constraint(previous["python_version"]).intersect( previous_dep.python_constraint)) platform = str(previous_dep.platform if GenericConstraint.parse( previous["platform"]).matches(previous_dep.platform_constraint) and previous_dep.platform != "*" else previous["platform"]) graph = { "name": package.name, "category": category, "optional": optional, "python_version": python_version, "platform": platform, "children": [], } if previous_dep and previous_dep is not dep and previous_dep.name == dep.name: return graph for dependency in package.all_requires: if dependency.is_optional(): if not package.is_root() and (not previous_dep or not previous_dep.extras): continue is_activated = False for group, extras in package.extras.items(): if dep: extras = previous_dep.extras elif package.is_root(): extras = package.extras else: extras = [] if group in extras: is_activated = True break if not is_activated: continue for pkg in packages: if pkg.name == dependency.name: # If there is already a child with this name # we merge the requirements existing = None for child in graph["children"]: if (child["name"] == pkg.name and child["category"] == dependency.category): existing = child continue child_graph = self._build_graph(pkg, packages, graph, dependency, dep or dependency) if existing: existing["python_version"] = str( parse_constraint(existing["python_version"]).union( parse_constraint( child_graph["python_version"]))) continue graph["children"].append(child_graph) return graph
def handle(self): from poetry.packages.constraints.generic_constraint import GenericConstraint from poetry.repositories.installed_repository import InstalledRepository from poetry.semver import Version from poetry.semver import parse_constraint package = self.argument("package") if self.option("tree"): self.init_styles() if self.option("outdated"): self.input.set_option("latest", True) 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(package, locked_repo) break return 0 table = self.table(style="compact") table.get_style().set_vertical_border_char("") locked_packages = locked_repo.packages 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(pkg, locked_repo) return 0 rows = [ ["<info>name</>", " : <fg=cyan>{}</>".format(pkg.pretty_name)], ["<info>version</>", " : <comment>{}</>".format(pkg.pretty_version)], ["<info>description</>", " : {}".format(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( " - {} <comment>{}</>".format( dependency.pretty_name, dependency.pretty_constraint ) ) return 0 show_latest = self.option("latest") show_all = self.option("all") terminal = self.get_application().terminal width = terminal.width name_length = version_length = latest_length = 0 latest_packages = {} installed_repo = InstalledRepository.load(self.venv) skipped = [] platform = sys.platform python = Version.parse(".".join([str(i) for i in self._venv.version_info[:3]])) # Computing widths for locked in locked_packages: python_constraint = parse_constraint(locked.requirements.get("python", "*")) platform_constraint = GenericConstraint.parse( locked.requirements.get("platform", "*") ) if not python_constraint.allows(python) or not platform_constraint.matches( GenericConstraint("=", platform) ): skipped.append(locked) if not show_all: continue current_length = len(locked.pretty_name) if not self.output.is_decorated(): installed_status = self.get_installed_status(locked, installed_repo) if installed_status == "not-installed": current_length += 4 name_length = max(name_length, current_length) version_length = max(version_length, len(locked.full_pretty_version)) if show_latest: latest = self.find_latest_package(locked) if not latest: latest = locked latest_packages[locked.pretty_name] = latest latest_length = max(latest_length, len(latest.full_pretty_version)) 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 = "green" name = locked.pretty_name install_marker = "" if locked in skipped: 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.output.is_decorated(): # Non installed in non decorated mode install_marker = " (!)" line = "<fg={}>{:{}}{}</>".format( color, name, name_length - len(install_marker), install_marker ) if write_version: line += " <comment>{:{}}</comment>".format( locked.full_pretty_version, version_length ) if show_latest and write_latest: latest = latest_packages[locked.pretty_name] update_status = self.get_update_status(latest, locked) color = "green" if update_status == "semver-safe-update": color = "red" elif update_status == "update-possible": color = "yellow" line += " <fg={}>{:{}}</>".format( color, latest.pretty_version, latest_length ) if self.option("outdated") and update_status == "up-to-date": continue 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): from poetry.packages.constraints.generic_constraint import GenericConstraint from poetry.repositories.installed_repository import InstalledRepository from poetry.semver import Version from poetry.semver import parse_constraint package = self.argument("package") if self.option("tree"): self.init_styles() if self.option("outdated"): self.input.set_option("latest", True) 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(package, locked_repo) break return 0 table = self.table(style="compact") table.get_style().set_vertical_border_char("") locked_packages = locked_repo.packages 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(pkg, locked_repo) return 0 rows = [ ["<info>name</>", " : <fg=cyan>{}</>".format(pkg.pretty_name)], [ "<info>version</>", " : <comment>{}</>".format(pkg.pretty_version) ], ["<info>description</>", " : {}".format(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(" - {} <comment>{}</>".format( dependency.pretty_name, dependency.pretty_constraint)) return 0 show_latest = self.option("latest") show_all = self.option("all") terminal = self.get_application().terminal width = terminal.width name_length = version_length = latest_length = 0 latest_packages = {} installed_repo = InstalledRepository.load(self.venv) skipped = [] platform = sys.platform python = Version.parse(".".join( [str(i) for i in self._venv.version_info[:3]])) # Computing widths for locked in locked_packages: python_constraint = parse_constraint( locked.requirements.get("python", "*")) platform_constraint = GenericConstraint.parse( locked.requirements.get("platform", "*")) if not python_constraint.allows( python) or not platform_constraint.matches( GenericConstraint("=", platform)): skipped.append(locked) if not show_all: continue current_length = len(locked.pretty_name) if not self.output.is_decorated(): installed_status = self.get_installed_status( locked, installed_repo) if installed_status == "not-installed": current_length += 4 name_length = max(name_length, current_length) version_length = max(version_length, len(locked.full_pretty_version)) if show_latest: latest = self.find_latest_package(locked) if not latest: latest = locked latest_packages[locked.pretty_name] = latest latest_length = max(latest_length, len(latest.full_pretty_version)) 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 = "green" name = locked.pretty_name install_marker = "" if locked in skipped: 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.output.is_decorated(): # Non installed in non decorated mode install_marker = " (!)" line = "<fg={}>{:{}}{}</>".format( color, name, name_length - len(install_marker), install_marker) if write_version: line += " <comment>{:{}}</comment>".format( locked.full_pretty_version, version_length) if show_latest and write_latest: latest = latest_packages[locked.pretty_name] update_status = self.get_update_status(latest, locked) color = "green" if update_status == "semver-safe-update": color = "red" elif update_status == "update-possible": color = "yellow" line += " <fg={}>{:{}}</>".format(color, latest.pretty_version, latest_length) if self.option("outdated") and update_status == "up-to-date": continue 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 _filter_operations( self, ops, repo ): # type: (List[Operation], Repository) -> None extra_packages = [p.name for p in self._get_extra_packages(repo)] for op in ops: if isinstance(op, Update): package = op.target_package else: package = op.package if op.job_type == "uninstall": continue if package.name in self._develop and package.source_type == "directory": package.develop = True if op.skipped: op.unskip() python = Version.parse( ".".join([str(i) for i in self._venv.version_info[:3]]) ) if "python" in package.requirements: python_constraint = parse_constraint(package.requirements["python"]) if not python_constraint.allows(python): # Incompatible python versions op.skip("Not needed for the current python version") continue if not package.python_constraint.allows(python): op.skip("Not needed for the current python version") continue if "platform" in package.requirements: platform_constraint = GenericConstraint.parse( package.requirements["platform"] ) if not platform_constraint.matches( GenericConstraint("=", sys.platform) ): # Incompatible systems op.skip("Not needed for the current platform") continue if self._update: extras = {} for extra, deps in self._package.extras.items(): extras[extra] = [dep.name for dep in deps] else: extras = {} for extra, deps in self._locker.lock_data.get("extras", {}).items(): extras[extra] = [dep.lower() for dep in deps] # If a package is optional and not requested # in any extra we skip it if package.optional: if package.name not in extra_packages: op.skip("Not required") # If the package is a dev package and dev packages # are not requests, we skip it if package.category == "dev" and not self.is_dev_mode(): op.skip("Dev dependencies not requested")
def _get_tags_from_graph(self, graph, packages): category = graph['category'] optional = graph['optional'] python_version = graph['python_version'] platform = graph['platform'] if not graph['parents']: # Root dependency return category, optional, python_version, platform python_versions = [] platforms = [] for parent_name, parent_graph in graph['parents'].items(): dep_python_version = graph['dependencies'][parent_name][ 'python_version'] dep_platform = graph['dependencies'][parent_name]['platform'] for pkg in packages: if pkg.name == parent_name: (top_category, top_optional, top_python_version, top_platform) = self._get_tags_from_graph( parent_graph, packages) if category is None or category != 'main': category = top_category optional = optional and top_optional # Take the most restrictive constraints if top_python_version is not None: if dep_python_version is not None: previous = parse_constraint(dep_python_version) current = parse_constraint(top_python_version) if previous.allows_all(current): python_versions.append(top_python_version) else: python_versions.append(dep_python_version) else: python_versions.append(top_python_version) elif dep_python_version is not None: python_versions.append(dep_python_version) if top_platform is not None: if dep_platform is not None: previous = GenericConstraint.parse(dep_platform) current = GenericConstraint.parse(top_platform) if top_platform != '*' and previous.matches( current): platforms.append(top_platform) else: platforms.append(dep_platform) else: platforms.append(top_platform) elif dep_platform is not None: platforms.append(dep_platform) break if not python_versions: python_version = None else: # Find the least restrictive constraint python_version = python_versions[0] previous = parse_constraint(python_version) for constraint in python_versions[1:]: current = parse_constraint(constraint) if python_version == '*': continue elif constraint == '*': python_version = constraint elif current.allows_all(previous): python_version = constraint if not platforms: platform = None else: platform = platforms[0] previous = GenericConstraint.parse(platform) for constraint in platforms[1:]: current = GenericConstraint.parse(constraint) if platform == '*': continue elif constraint == '*': platform = constraint elif current.matches(previous): platform = constraint return category, optional, python_version, platform