Commit 692bdaa9 by Mathieu Kniewallner Committed by GitHub

Refactor `show` command a bit (#5738)

Refactor `show` command a tiny bit to separate the different cases into
dedicated functions, since right now `handle` method is 300 lines long.
This also has the advantage of making some imports necessary only on a
specific variant of the command.

The package named is also canonicalized only once, for a minor performance
improvement/to avoid extra work.
parent 88ba18d5
......@@ -69,15 +69,6 @@ lists all packages available."""
colors = ["cyan", "yellow", "green", "magenta", "blue"]
def handle(self) -> int:
import shutil
from cleo.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.utils.helpers import get_package_version_display_string
package = self.argument("package")
if self.option("tree"):
......@@ -111,24 +102,104 @@ lists all packages available."""
return 1
locked_repo = self.poetry.locker.locked_repository()
if package:
return self._display_single_package_information(package, locked_repo)
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
if self.option("tree"):
return self._display_packages_tree_information(locked_repo, root)
return self._display_packages_information(locked_repo, root)
def _display_single_package_information(
self, package: str, locked_repository: Repository
) -> int:
locked_packages = locked_repository.packages
canonicalized_package = canonicalize_name(package)
pkg = None
for locked in locked_packages:
if locked.name == canonicalized_package:
pkg = locked
break
if not pkg:
raise ValueError(f"Package {package} not found")
required_by = reverse_deps(pkg, locked_repository)
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
table = self.table(style="compact")
locked_packages = locked_repo.packages
rows = [
["<info>name</>", f" : <c1>{pkg.pretty_name}</>"],
["<info>version</>", f" : <b>{pkg.pretty_version}</b>"],
["<info>description</>", f" : {pkg.description}"],
]
self.table(rows=rows, style="compact").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
def _display_packages_information(
self, locked_repository: Repository, root: ProjectPackage
) -> int:
import shutil
from cleo.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.utils.helpers import get_package_version_display_string
locked_packages = locked_repository.packages
pool = Pool(ignore_repository_names=True)
pool.add_repository(locked_repo)
pool.add_repository(locked_repository)
solver = Solver(
root,
pool=pool,
......@@ -142,73 +213,6 @@ lists all packages available."""
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")
width = shutil.get_terminal_size().columns
......@@ -261,7 +265,7 @@ lists all packages available."""
)
if self.option("why"):
required_by = reverse_deps(locked, locked_repo)
required_by = reverse_deps(locked, locked_repository)
required_by_length = max(
required_by_length,
len(" from " + ",".join(required_by.keys())),
......@@ -278,7 +282,7 @@ lists all packages available."""
)
if self.option("why"):
required_by = reverse_deps(locked, locked_repo)
required_by = reverse_deps(locked, locked_repository)
required_by_length = max(
required_by_length, len(" from " + ",".join(required_by.keys()))
)
......@@ -345,7 +349,7 @@ lists all packages available."""
line += f" <fg={color}>{version:{latest_length}}</>"
if write_why:
required_by = reverse_deps(locked, locked_repo)
required_by = reverse_deps(locked, locked_repository)
if required_by:
content = ",".join(required_by.keys())
# subtract 6 for ' from '
......@@ -371,6 +375,19 @@ lists all packages available."""
return 0
def _display_packages_tree_information(
self, locked_repository: Repository, root: ProjectPackage
) -> int:
packages = locked_repository.packages
for p in packages:
for require in root.all_requires:
if p.name == require.name:
self.display_package_tree(self.io, p, packages)
break
return 0
def display_package_tree(
self,
io: IO,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment