Skip to content

Commit

Permalink
Have --packages and --all work together (#273)
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
3 people committed Jul 22, 2023
1 parent a09fea0 commit 616618f
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
35 changes: 20 additions & 15 deletions src/pipdeptree/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,29 +61,29 @@ 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")
scope = select.add_mutually_exclusive_group()
scope.add_argument(
"-l",
"--local-only",
action="store_true",
help="if in a virtualenv that has global access do not show globally installed packages",
)
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(
select.add_argument(
"-p",
"--packages",
help="comma separated list of packages to show - wildcards are supported, like 'somepackage.*'",
metavar="P",
)
package.add_argument(
select.add_argument(
"-e",
"--exclude",
help="comma separated list of packages to not show - wildcards are supported, like 'somepackage.*'",
help="comma separated list of packages to not show - wildcards are supported, like 'somepackage.*'. "
"(cannot combine with -p or -a)",
metavar="P",
)
package.add_argument("-a", "--all", action="store_true", help="list all deps at top level")
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",
"--local-only",
action="store_true",
help="if in a virtualenv that has global access do not show globally installed packages",
)
scope.add_argument("-u", "--user-only", action="store_true", help="only show installations in the user site dir")

render = parser.add_argument_group(
title="render",
Expand Down Expand Up @@ -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__ = [
Expand Down
36 changes: 34 additions & 2 deletions tests/render/test_text.py
Original file line number Diff line number Diff line change
@@ -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(
Expand Down Expand Up @@ -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()
24 changes: 23 additions & 1 deletion tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import pytest

from pipdeptree._cli import build_parser
from pipdeptree._cli import build_parser, get_options


def test_parser_default() -> None:
Expand Down Expand Up @@ -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"

0 comments on commit 616618f

Please sign in to comment.