Have --packages and --all work together (#273)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Bernát Gábor <bgabor8@bloomberg.net>
This commit is contained in:
Kemal Zebari 2023-07-22 09:51:53 -07:00 committed by GitHub
parent a09fea075b
commit 616618fd7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 79 additions and 20 deletions

View File

@ -24,7 +24,7 @@ repos:
- id: prettier
args: ["--print-width=120", "--prose-wrap=always"]
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.0.278"
rev: "v0.0.280"
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]

View File

@ -61,6 +61,21 @@ def build_parser() -> ArgumentParser:
select = parser.add_argument_group(title="select", description="choose what to render")
select.add_argument("--python", default=sys.executable, help="Python interpreter to inspect")
select.add_argument(
"-p",
"--packages",
help="comma separated list of packages to show - wildcards are supported, like 'somepackage.*'",
metavar="P",
)
select.add_argument(
"-e",
"--exclude",
help="comma separated list of packages to not show - wildcards are supported, like 'somepackage.*'. "
"(cannot combine with -p or -a)",
metavar="P",
)
select.add_argument("-a", "--all", action="store_true", help="list all deps at top level")
scope = select.add_mutually_exclusive_group()
scope.add_argument(
"-l",
@ -70,21 +85,6 @@ def build_parser() -> ArgumentParser:
)
scope.add_argument("-u", "--user-only", action="store_true", help="only show installations in the user site dir")
package = select.add_mutually_exclusive_group()
package.add_argument(
"-p",
"--packages",
help="comma separated list of packages to show - wildcards are supported, like 'somepackage.*'",
metavar="P",
)
package.add_argument(
"-e",
"--exclude",
help="comma separated list of packages to not show - wildcards are supported, like 'somepackage.*'",
metavar="P",
)
package.add_argument("-a", "--all", action="store_true", help="list all deps at top level")
render = parser.add_argument_group(
title="render",
description="choose how to render the dependency tree (by default will use text mode)",
@ -137,7 +137,12 @@ def build_parser() -> ArgumentParser:
def get_options(args: Sequence[str] | None) -> Options:
parser = build_parser()
return cast(Options, parser.parse_args(args))
parsed_args = parser.parse_args(args)
if parsed_args.exclude and (parsed_args.all or parsed_args.packages):
return parser.error("cannot use --exclude with --packages or --all")
return cast(Options, parsed_args)
__all__ = [

View File

@ -1,13 +1,16 @@
from __future__ import annotations
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Callable, Iterator
import pytest
from pipdeptree._models import PackageDAG
from pipdeptree._render.text import render_text
if TYPE_CHECKING:
from pipdeptree._models import PackageDAG
from unittest.mock import Mock
from tests.our_types import MockGraph
@pytest.mark.parametrize(
@ -506,3 +509,32 @@ def test_render_text_encoding(
render_text(example_dag, max_depth=level, encoding=encoding, list_all=True, frozen=False)
captured = capsys.readouterr()
assert "\n".join(expected_output).strip() == captured.out.strip()
def test_render_text_list_all_and_packages_options_used(
capsys: pytest.CaptureFixture[str],
mock_pkgs: Callable[[MockGraph], Iterator[Mock]],
) -> None:
graph: dict[tuple[str, str], list[tuple[str, list[tuple[str, str]]]]] = {
("examplePy", "1.2.3"): [("hellopy", [(">=", "2.0.0")]), ("worldpy", [(">=", "0.0.2")])],
("HelloPy", "2.0.0"): [],
("worldpy", "0.0.2"): [],
("anotherpy", "0.1.2"): [("hellopy", [(">=", "2.0.0")])],
("YetAnotherPy", "3.1.2"): [],
}
package_dag = PackageDAG.from_pkgs(list(mock_pkgs(graph)))
# NOTE: Mimicking the --packages option being used here.
package_dag = package_dag.filter_nodes({"examplePy"}, None)
render_text(package_dag, max_depth=float("inf"), encoding="utf-8", list_all=True, frozen=False)
captured = capsys.readouterr()
expected_output = [
"examplePy==1.2.3",
"├── HelloPy [required: >=2.0.0, installed: 2.0.0]",
"└── worldpy [required: >=0.0.2, installed: 0.0.2]",
"HelloPy==2.0.0",
"worldpy==0.0.2",
]
assert "\n".join(expected_output).strip() == captured.out.strip()

View File

@ -2,7 +2,7 @@ from __future__ import annotations
import pytest
from pipdeptree._cli import build_parser
from pipdeptree._cli import build_parser, get_options
def test_parser_default() -> None:
@ -75,3 +75,25 @@ def test_parser_depth(should_be_error: bool, depth_arg: list[str], expected_valu
else:
args = parser.parse_args(depth_arg)
assert args.depth == expected_value
@pytest.mark.parametrize(
"args",
[
pytest.param(["--exclude", "py", "--all"], id="exclude-all"),
pytest.param(["-e", "py", "--packages", "py2"], id="exclude-packages"),
pytest.param(["-e", "py", "-p", "py2", "-a"], id="exclude-packages-all"),
],
)
def test_parser_get_options_exclude_combine_not_supported(args: list[str], capsys: pytest.CaptureFixture[str]) -> None:
with pytest.raises(SystemExit, match="2"):
get_options(args)
out, err = capsys.readouterr()
assert not out
assert "cannot use --exclude with --packages or --all" in err
def test_parser_get_options_exclude_only() -> None:
parsed_args = get_options(["--exclude", "py"])
assert parsed_args.exclude == "py"