Skip to content

Commit dcd5ae1

Browse files
authored
feat(install): add --all-groups flag to install all dependency groups (#9744)
1 parent 46f3ede commit dcd5ae1

File tree

4 files changed

+69
-14
lines changed

4 files changed

+69
-14
lines changed

Diff for: docs/cli.md

+16-9
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,12 @@ You can also select optional dependency groups with the `--with` option.
164164
poetry install --with test,docs
165165
```
166166

167+
To install all dependency groups including the optional groups, use the ``--all-groups`` flag.
168+
169+
```bash
170+
poetry install --all-groups
171+
```
172+
167173
It's also possible to only install specific dependency groups by using the `only` option.
168174

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

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

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

462469

@@ -482,7 +489,7 @@ about dependency groups.
482489

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

488495

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

9961003
### self update
9971004

@@ -1009,7 +1016,7 @@ poetry self update
10091016
#### Options
10101017

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

10141021
### self lock
10151022

@@ -1063,7 +1070,7 @@ poetry self remove poetry-plugin-export
10631070

10641071
#### Options
10651072

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

10681075
### self install
10691076

@@ -1082,4 +1089,4 @@ poetry self install --sync
10821089
#### Options
10831090

10841091
* `--sync`: Synchronize the environment with the locked packages and the specified groups.
1085-
* `--dry-run`: Output the operations but do not execute anything (implicitly enables --verbose).
1092+
* `--dry-run`: Output the operations but do not execute anything (implicitly enables `--verbose`).

Diff for: src/poetry/console/commands/group_command.py

+6
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ def activated_groups(self) -> set[str]:
7979
for groups in self.option(key, "")
8080
for group in groups.split(",")
8181
}
82+
83+
if self.option("all-groups"):
84+
groups["with"] = self.poetry.package.dependency_group_names(
85+
include_optional=True
86+
)
87+
8288
self._validate_group_options(groups)
8389

8490
if groups["only"] and (groups["with"] or groups["without"]):

Diff for: src/poetry/console/commands/install.py

+17-3
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class InstallCommand(InstallerCommand):
5050
multiple=True,
5151
),
5252
option("all-extras", None, "Install all extra dependencies."),
53+
option("all-groups", None, "Install dependencies from all groups."),
5354
option("only-root", None, "Exclude all dependencies."),
5455
option(
5556
"compile",
@@ -104,12 +105,14 @@ def handle(self) -> int:
104105
return 1
105106

106107
if self.option("only-root") and any(
107-
self.option(key) for key in {"with", "without", "only"}
108+
self.option(key) for key in {"with", "without", "only", "all-groups"}
108109
):
109110
self.line_error(
110111
"<error>The `<fg=yellow;options=bold>--with</>`,"
111-
" `<fg=yellow;options=bold>--without</>` and"
112-
" `<fg=yellow;options=bold>--only</>` options cannot be used with"
112+
" `<fg=yellow;options=bold>--without</>`,"
113+
" `<fg=yellow;options=bold>--only</>` and"
114+
" `<fg=yellow;options=bold>--all-groups</>`"
115+
" options cannot be used with"
113116
" the `<fg=yellow;options=bold>--only-root</>`"
114117
" option.</error>"
115118
)
@@ -122,6 +125,17 @@ def handle(self) -> int:
122125
)
123126
return 1
124127

128+
if (
129+
self.option("only") or self.option("with") or self.option("without")
130+
) and self.option("all-groups"):
131+
self.line_error(
132+
"<error>You cannot specify `<fg=yellow;options=bold>--with</>`,"
133+
" `<fg=yellow;options=bold>--without</>`, or"
134+
" `<fg=yellow;options=bold>--only</>` when using"
135+
" `<fg=yellow;options=bold>--all-groups</>`.</error>"
136+
)
137+
return 1
138+
125139
extras: list[str]
126140
if self.option("all-extras"):
127141
extras = list(self.poetry.package.extras.keys())

Diff for: tests/console/commands/test_install.py

+30-2
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ def _project_factory(
104104
("--without foo,bar", {MAIN_GROUP, "baz", "bim"}),
105105
(f"--without {MAIN_GROUP}", {"foo", "bar", "baz", "bim"}),
106106
("--with foo,bar --without baz --without bim --only bam", {"bam"}),
107+
("--all-groups", {MAIN_GROUP, "foo", "bar", "baz", "bim", "bam"}),
107108
# net result zero options
108109
("--with foo", {MAIN_GROUP, "foo", "bar", "baz", "bim"}),
109110
("--without bam", {MAIN_GROUP, "foo", "bar", "baz", "bim"}),
@@ -285,9 +286,10 @@ def test_extras_conflicts_all_extras(
285286
"--without foo",
286287
"--with foo,bar --without baz",
287288
"--only foo",
289+
"--all-groups",
288290
],
289291
)
290-
def test_only_root_conflicts_with_without_only(
292+
def test_only_root_conflicts_with_without_only_all_groups(
291293
options: str,
292294
tester: CommandTester,
293295
mocker: MockerFixture,
@@ -300,11 +302,37 @@ def test_only_root_conflicts_with_without_only(
300302
assert tester.status_code == 1
301303
assert (
302304
tester.io.fetch_error()
303-
== "The `--with`, `--without` and `--only` options cannot be used with"
305+
== "The `--with`, `--without`, `--only` and `--all-groups` options cannot be used with"
304306
" the `--only-root` option.\n"
305307
)
306308

307309

310+
@pytest.mark.parametrize(
311+
"options",
312+
[
313+
"--with foo",
314+
"--without foo",
315+
"--with foo,bar --without baz",
316+
"--only foo",
317+
],
318+
)
319+
def test_all_groups_conflicts_with_only_with_without(
320+
options: str,
321+
tester: CommandTester,
322+
mocker: MockerFixture,
323+
) -> None:
324+
assert isinstance(tester.command, InstallerCommand)
325+
mocker.patch.object(tester.command.installer, "run", return_value=0)
326+
327+
tester.execute(f"{options} --all-groups")
328+
329+
assert tester.status_code == 1
330+
assert (
331+
tester.io.fetch_error()
332+
== "You cannot specify `--with`, `--without`, or `--only` when using `--all-groups`.\n"
333+
)
334+
335+
308336
@pytest.mark.parametrize(
309337
("options", "valid_groups", "should_raise"),
310338
[

0 commit comments

Comments
 (0)