Skip to content

Commit

Permalink
Console: Add "--top-level" flag to show command. (#7415)
Browse files Browse the repository at this point in the history
  • Loading branch information
KGB33 authored Apr 19, 2023
1 parent a4c9535 commit 6b4b539
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,7 @@ required by
* `--latest (-l)`: Show the latest version.
* `--outdated (-o)`: Show the latest version but only for packages that are outdated.
* `--all (-a)`: Show all packages (even those not compatible with current system).
* `--top-level (-T)`: Only show explicitly defined packages.

{{% note %}}
When `--only` is specified, `--with` and `--without` options are ignored.
Expand Down
24 changes: 24 additions & 0 deletions src/poetry/console/commands/show.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class ShowCommand(GroupCommand, EnvCommand):
"a",
"Show all packages (even those not compatible with current system).",
),
option("top-level", "T", "Show only top-level dependencies."),
]

help = """The show command displays detailed information about a package, or
Expand All @@ -77,6 +78,20 @@ def handle(self) -> int:
if self.option("tree"):
self.init_styles(self.io)

if self.option("top-level"):
if self.option("tree"):
self.line_error(
"<error>Error: Cannot use --tree and --top-level at the same"
" time.</error>"
)
return 1
if package is not None:
self.line_error(
"<error>Error: Cannot use --top-level when displaying a single"
" package.</error>"
)
return 1

if self.option("why"):
if self.option("tree") and package is None:
self.line_error(
Expand Down Expand Up @@ -215,6 +230,7 @@ def _display_packages_information(

show_latest = self.option("latest")
show_all = self.option("all")
show_top_level = self.option("top-level")
width = shutil.get_terminal_size().columns
name_length = version_length = latest_length = required_by_length = 0
latest_packages = {}
Expand Down Expand Up @@ -296,10 +312,18 @@ def _display_packages_information(
write_why = self.option("why") and (why_end_column + 3) <= width
write_description = (why_end_column + 24) <= width

requires = root.all_requires

for locked in locked_packages:
color = "cyan"
name = locked.pretty_name
install_marker = ""

if show_top_level and not any(
locked.is_same_package_as(r) for r in requires
):
continue

if locked not in required_locked_packages:
if not show_all:
continue
Expand Down
119 changes: 119 additions & 0 deletions tests/console/commands/test_show.py
Original file line number Diff line number Diff line change
Expand Up @@ -2082,6 +2082,125 @@ def test_url_dependency_is_not_outdated_by_repository_package(
assert tester.io.fetch_output() == ""


def test_show_top_level(
tester: CommandTester, poetry: Poetry, installed: Repository
) -> None:
poetry.package.add_dependency(Factory.create_dependency("cachy", "^0.2.0"))

cachy2 = get_package("cachy", "0.2.0")
cachy2.add_dependency(Factory.create_dependency("msgpack-python", ">=0.5 <0.6"))

installed.add_package(cachy2)

poetry.locker.mock_lock_data(
{
"package": [
{
"name": "cachy",
"version": "0.2.0",
"description": "",
"category": "main",
"optional": False,
"platform": "*",
"python-versions": "*",
"checksum": [],
"dependencies": {"msgpack-python": ">=0.5 <0.6"},
},
{
"name": "msgpack-python",
"version": "0.5.1",
"description": "",
"category": "main",
"optional": False,
"platform": "*",
"python-versions": "*",
"checksum": [],
},
],
"metadata": {
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"files": {"cachy": [], "msgpack-python": []},
},
}
)

tester.execute("--top-level")

expected = """cachy 0.2.0 \n"""

assert tester.io.fetch_output() == expected


def test_show_top_level_with_explicitly_defined_depenancy(
tester: CommandTester, poetry: Poetry, installed: Repository
) -> None:
poetry.package.add_dependency(Factory.create_dependency("a", "^0.1.0"))
poetry.package.add_dependency(Factory.create_dependency("b", "^0.2.0"))

a = get_package("a", "0.1.0")
a.add_dependency(Factory.create_dependency("b", "0.2.0"))
b = get_package("b", "0.2.0")

installed.add_package(a)
installed.add_package(b)

poetry.locker.mock_lock_data(
{
"package": [
{
"name": "a",
"version": "0.1.0",
"description": "",
"category": "main",
"optional": False,
"platform": "*",
"python-versions": "*",
"checksum": [],
"dependencies": {"b": "0.2.0"},
},
{
"name": "b",
"version": "0.2.0",
"description": "",
"category": "main",
"optional": False,
"platform": "*",
"python-versions": "*",
"checksum": [],
},
],
"metadata": {
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"files": {"a": [], "b": []},
},
}
)

tester.execute("--top-level")

expected = """a 0.1.0 \nb 0.2.0 \n"""

assert tester.io.fetch_output() == expected


def test_show_error_top_level_with_tree(tester: CommandTester) -> None:
expected = "Error: Cannot use --tree and --top-level at the same time.\n"
tester.execute("--top-level --tree")
assert tester.io.fetch_error() == expected
assert tester.status_code == 1


def test_show_error_top_level_with_single_package(tester: CommandTester) -> None:
expected = "Error: Cannot use --top-level when displaying a single package.\n"
tester.execute("--top-level some_package_name")
assert tester.io.fetch_error() == expected
assert tester.status_code == 1


@pytest.mark.parametrize(
("project_directory", "required_fixtures"),
[
Expand Down

0 comments on commit 6b4b539

Please sign in to comment.