Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(install): add --all-groups flag to install all dependency groups #9744

Merged
merged 7 commits into from
Oct 15, 2024
25 changes: 16 additions & 9 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@ You can also select optional dependency groups with the `--with` option.
poetry install --with test,docs
```

To install all dependency groups including the optional groups, use the ``--all-groups`` flag.

```bash
poetry install --all-groups
```

It's also possible to only install specific dependency groups by using the `only` option.

```bash
Expand Down Expand Up @@ -254,9 +260,10 @@ poetry install --compile
* `--sync`: Synchronize the environment with the locked packages and the specified groups.
* `--no-root`: Do not install the root package (your project).
* `--no-directory`: Skip all directory path dependencies (including transitive ones).
* `--dry-run`: Output the operations but do not execute anything (implicitly enables --verbose).
* `--dry-run`: Output the operations but do not execute anything (implicitly enables `--verbose`).
* `--extras (-E)`: Features to install (multiple values allowed).
* `--all-extras`: Install all extra features (conflicts with --extras).
* `--all-extras`: Install all extra features (conflicts with `--extras`).
* `--all-groups`: Install dependencies from all groups (conflicts with `--only`, `--with`, and `--without`).
* `--compile`: Compile Python source files to bytecode.
* `--remove-untracked`: Remove dependencies not presented in the lock file. (**Deprecated**, use `--sync` instead)

Expand Down Expand Up @@ -295,7 +302,7 @@ You can do this using the `add` command.
* `--without`: The dependency groups to ignore.
* `--with`: The optional dependency groups to include.
* `--only`: The only dependency groups to include.
* `--dry-run` : Outputs the operations but will not execute anything (implicitly enables --verbose).
* `--dry-run` : Outputs the operations but will not execute anything (implicitly enables `--verbose`).
* `--lock` : Do not perform install (only update the lockfile).
* `--sync`: Synchronize the environment with the locked packages and the specified groups.

Expand Down Expand Up @@ -456,7 +463,7 @@ about dependency groups.
* `--platform`: Platforms for which the dependency must be installed.
* `--source`: Name of the source to use to install the package.
* `--allow-prereleases`: Accept prereleases.
* `--dry-run`: Output the operations but do not execute anything (implicitly enables --verbose).
* `--dry-run`: Output the operations but do not execute anything (implicitly enables `--verbose`).
* `--lock`: Do not perform install (only update the lockfile).


Expand All @@ -482,7 +489,7 @@ about dependency groups.

* `--group (-G)`: The group to remove the dependency from.
* `--dev (-D)`: Removes a package from the development dependencies. (shortcut for `-G dev`)
* `--dry-run` : Outputs the operations but will not execute anything (implicitly enables --verbose).
* `--dry-run` : Outputs the operations but will not execute anything (implicitly enables `--verbose`).
* `--lock`: Do not perform operations (only update the lockfile).


Expand Down Expand Up @@ -991,7 +998,7 @@ poetry self add artifacts-keyring
* `--extras (-E)`: Extras to activate for the dependency. (multiple values allowed)
* `--allow-prereleases`: Accept prereleases.
* `--source`: Name of the source to use to install the package.
* `--dry-run`: Output the operations but do not execute anything (implicitly enables --verbose).
* `--dry-run`: Output the operations but do not execute anything (implicitly enables `--verbose`).

### self update

Expand All @@ -1009,7 +1016,7 @@ poetry self update
#### Options

* `--preview`: Allow the installation of pre-release versions.
* `--dry-run`: Output the operations but do not execute anything (implicitly enables --verbose).
* `--dry-run`: Output the operations but do not execute anything (implicitly enables `--verbose`).

### self lock

Expand Down Expand Up @@ -1063,7 +1070,7 @@ poetry self remove poetry-plugin-export

#### Options

* `--dry-run`: Outputs the operations but will not execute anything (implicitly enables --verbose).
* `--dry-run`: Outputs the operations but will not execute anything (implicitly enables `--verbose`).

### self install

Expand All @@ -1082,4 +1089,4 @@ poetry self install --sync
#### Options

* `--sync`: Synchronize the environment with the locked packages and the specified groups.
* `--dry-run`: Output the operations but do not execute anything (implicitly enables --verbose).
* `--dry-run`: Output the operations but do not execute anything (implicitly enables `--verbose`).
6 changes: 6 additions & 0 deletions src/poetry/console/commands/group_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ def activated_groups(self) -> set[str]:
for groups in self.option(key, "")
for group in groups.split(",")
}

if self.option("all-groups"):
groups["with"] = self.poetry.package.dependency_group_names(
include_optional=True
)

self._validate_group_options(groups)

if groups["only"] and (groups["with"] or groups["without"]):
Expand Down
20 changes: 17 additions & 3 deletions src/poetry/console/commands/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class InstallCommand(InstallerCommand):
multiple=True,
),
option("all-extras", None, "Install all extra dependencies."),
option("all-groups", None, "Install dependencies from all groups."),
option("only-root", None, "Exclude all dependencies."),
option(
"compile",
Expand Down Expand Up @@ -104,12 +105,14 @@ def handle(self) -> int:
return 1

if self.option("only-root") and any(
self.option(key) for key in {"with", "without", "only"}
self.option(key) for key in {"with", "without", "only", "all-groups"}
):
self.line_error(
"<error>The `<fg=yellow;options=bold>--with</>`,"
" `<fg=yellow;options=bold>--without</>` and"
" `<fg=yellow;options=bold>--only</>` options cannot be used with"
" `<fg=yellow;options=bold>--without</>`,"
" `<fg=yellow;options=bold>--only</>` and"
" `<fg=yellow;options=bold>--all-groups</>`"
" options cannot be used with"
" the `<fg=yellow;options=bold>--only-root</>`"
" option.</error>"
)
Expand All @@ -122,6 +125,17 @@ def handle(self) -> int:
)
return 1

if (
self.option("only") or self.option("with") or self.option("without")
) and self.option("all-groups"):
self.line_error(
"<error>You cannot specify `<fg=yellow;options=bold>--with</>`,"
" `<fg=yellow;options=bold>--without</>`, or"
" `<fg=yellow;options=bold>--only</>` when using"
" `<fg=yellow;options=bold>--all-groups</>`.</error>"
)
return 1

extras: list[str]
if self.option("all-extras"):
extras = list(self.poetry.package.extras.keys())
Expand Down
32 changes: 30 additions & 2 deletions tests/console/commands/test_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ def _project_factory(
("--without foo,bar", {MAIN_GROUP, "baz", "bim"}),
(f"--without {MAIN_GROUP}", {"foo", "bar", "baz", "bim"}),
("--with foo,bar --without baz --without bim --only bam", {"bam"}),
("--all-groups", {MAIN_GROUP, "foo", "bar", "baz", "bim", "bam"}),
# net result zero options
("--with foo", {MAIN_GROUP, "foo", "bar", "baz", "bim"}),
("--without bam", {MAIN_GROUP, "foo", "bar", "baz", "bim"}),
Expand Down Expand Up @@ -285,9 +286,10 @@ def test_extras_conflicts_all_extras(
"--without foo",
"--with foo,bar --without baz",
"--only foo",
"--all-groups",
],
)
def test_only_root_conflicts_with_without_only(
def test_only_root_conflicts_with_without_only_all_groups(
options: str,
tester: CommandTester,
mocker: MockerFixture,
Expand All @@ -300,11 +302,37 @@ def test_only_root_conflicts_with_without_only(
assert tester.status_code == 1
assert (
tester.io.fetch_error()
== "The `--with`, `--without` and `--only` options cannot be used with"
== "The `--with`, `--without`, `--only` and `--all-groups` options cannot be used with"
" the `--only-root` option.\n"
)


@pytest.mark.parametrize(
"options",
[
"--with foo",
"--without foo",
"--with foo,bar --without baz",
"--only foo",
],
)
def test_all_groups_conflicts_with_only_with_without(
options: str,
tester: CommandTester,
mocker: MockerFixture,
) -> None:
assert isinstance(tester.command, InstallerCommand)
mocker.patch.object(tester.command.installer, "run", return_value=0)

tester.execute(f"{options} --all-groups")

assert tester.status_code == 1
assert (
tester.io.fetch_error()
== "You cannot specify `--with`, `--without`, or `--only` when using `--all-groups`.\n"
)


@pytest.mark.parametrize(
("options", "valid_groups", "should_raise"),
[
Expand Down
Loading