Skip to content

Commit

Permalink
Warning when invalid groups are referenced
Browse files Browse the repository at this point in the history
  • Loading branch information
samypr100 committed Feb 17, 2023
1 parent c8945eb commit ed4c0ba
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 1 deletion.
10 changes: 9 additions & 1 deletion docs/managing-dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,16 @@ the `--only` option.
poetry install --only docs
```

{{% warning %}}

Groups provided to `--with`, `--without`, and `--only` should at least be declared in `pyproject.toml`.
Poetry will display a **Warning** if a group that is not declared is used, letting the user know of a
potential mistake.

{{% /warning %}}

{{% note %}}
If you only want to install the project's runtime dependencies, you can do so with the
If you only want to install the project's runtime dependencies, you can do so with the
`--only main` notation:

```bash
Expand Down
32 changes: 32 additions & 0 deletions src/poetry/console/commands/group_command.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

from collections import defaultdict
from typing import TYPE_CHECKING

from cleo.helpers import option
Expand Down Expand Up @@ -78,6 +79,7 @@ def activated_groups(self) -> set[str]:
for groups in self.option(key, "")
for group in groups.split(",")
}
self.validate_groups(groups)

for opt, new, group in [
("no-dev", "only", MAIN_GROUP),
Expand Down Expand Up @@ -107,3 +109,33 @@ def project_with_activated_groups_only(self) -> ProjectPackage:
return self.poetry.package.with_dependency_groups(
list(self.activated_groups), only=True
)

def validate_groups(self, group_options: dict[str, set[str]]) -> bool:
"""
Currently issues a warning if it detects that a group is
not part of pyproject.toml
Can be overridden to adapt behavior.
"""
invalid_options = defaultdict(set)
for opt, groups in group_options.items():
for group in groups:
try:
self.poetry.package.dependency_group(group)
except ValueError:
invalid_options[opt].add(group)
if invalid_options:
line_err = (
"<warning>The <fg=yellow;options=bold>--with</>, "
"<fg=yellow;options=bold>--without</>, "
"and <fg=yellow;options=bold>--only</> "
"options may only have valid groups."
)
for opt, invalid_groups in invalid_options.items():
line_err += (
" <fg=red;options=bold>Invalid"
f" {','.join(sorted(invalid_groups))} provided to --{opt}.</>"
)
line_err += "</warning>"
self.line_error(line_err)
return len(invalid_options) == 0
36 changes: 36 additions & 0 deletions tests/console/commands/test_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,42 @@ def test_only_root_conflicts_with_without_only(
)


@pytest.mark.parametrize(
("options", "valid_groups"),
[
({"--with": MAIN_GROUP}, {MAIN_GROUP}),
({"--with": "spam"}, set()),
({"--with": "spam,foo"}, {"foo"}),
({"--without": "spam"}, set()),
({"--without": "spam,bar"}, {"bar"}),
({"--with": "eggs,ham", "--without": "spam"}, set()),
({"--with": "eggs,ham", "--without": "spam,baz"}, {"baz"}),
({"--only": "spam"}, set()),
({"--only": "bim"}, {"bim"}),
({"--only": MAIN_GROUP}, {MAIN_GROUP}),
],
)
def test_invalid_groups_with_without_only(
tester: CommandTester,
mocker: MockerFixture,
options: dict[str, str],
valid_groups: set[str],
):
mocker.patch.object(tester.command.installer, "run", return_value=0)

cmd_args = " ".join(f"{flag} {groups}" for (flag, groups) in options.items())
tester.execute(cmd_args)

assert tester.status_code == 0

io_error = tester.io.fetch_error()
for opt, groups in options.items():
group_list = groups.split(",")
invalid_groups = ",".join(sorted(set(group_list) - valid_groups))
if invalid_groups:
assert f"Invalid {invalid_groups} provided to {opt}." in io_error


def test_remove_untracked_outputs_deprecation_warning(
tester: CommandTester,
mocker: MockerFixture,
Expand Down

0 comments on commit ed4c0ba

Please sign in to comment.