From ae532e1e181dc8ec77c98db881d266f15cee5759 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Randy=20D=C3=B6ring?= <30527984+radoering@users.noreply.github.com> Date: Mon, 18 Nov 2024 17:37:23 +0100 Subject: [PATCH] install: make `--sync` the default and introduce `--keep-untracked` --- docs/cli.md | 27 ++++++++++----------- docs/faq.md | 2 +- docs/managing-dependencies.md | 26 +++++--------------- src/poetry/console/commands/install.py | 7 +++--- src/poetry/console/commands/self/install.py | 2 +- src/poetry/console/commands/update.py | 7 +++--- tests/console/commands/self/test_install.py | 9 +------ tests/console/commands/test_install.py | 14 +++++++---- tests/console/commands/test_update.py | 13 +++++++--- 9 files changed, 46 insertions(+), 61 deletions(-) diff --git a/docs/cli.md b/docs/cli.md index 5d5717962a4..37b6ff93672 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -139,7 +139,8 @@ poetry init ## install The `install` command reads the `pyproject.toml` file from the current project, -resolves the dependencies, and installs them. +resolves the dependencies, and installs them. It also uninstalls packages +that are not required per default. ```bash poetry install @@ -185,19 +186,18 @@ poetry install --only-root See [Dependency groups]({{< relref "managing-dependencies#dependency-groups" >}}) for more information about dependency groups. -If you want to synchronize your environment – and ensure it matches the lock file – use the -`--sync` option. +If you want to keep untracked packages use the `--keep-untracked` option. ```bash -poetry install --sync +poetry install --keep-untracked ``` -The `--sync` can be combined with group-related options: +The `--keep-untracked` can be combined with group-related options: ```bash -poetry install --without dev --sync -poetry install --with docs --sync -poetry install --only dev --sync +poetry install --without dev --keep-untracked +poetry install --with docs --keep-untracked +poetry install --only dev --keep-untracked ``` You can also specify the extras you want installed @@ -210,7 +210,7 @@ poetry install -E mysql -E pgsql poetry install --all-extras ``` -Extras are not sensitive to `--sync`. Any extras not specified will always be removed. +Extras are not sensitive to `--keep-untracked`. Any extras not specified will always be removed. ```bash poetry install --extras "A B" # C is removed @@ -257,7 +257,7 @@ poetry install --compile * `--with`: The optional dependency groups to include. * `--only`: The only dependency groups to include. * `--only-root`: Install only the root project, exclude all dependencies. -* `--sync`: Synchronize the environment with the locked packages and the specified groups. +* `--keep-untracked`: Do not uninstall the untracked packages. * `--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`). @@ -265,7 +265,6 @@ poetry install --compile * `--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) {{% note %}} When `--only` is specified, `--with` and `--without` options are ignored. @@ -304,7 +303,7 @@ You can do this using the `add` command. * `--only`: The only dependency groups to include. * `--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. +* `--keep-untracked`: Do not uninstall the untracked packages. {{% note %}} When `--only` is specified, `--with` and `--without` options are ignored. @@ -1066,10 +1065,10 @@ is different in that the packages managed are for Poetry's runtime environment. {{% /note %}} ```bash -poetry self install --sync +poetry self install ``` #### Options -* `--sync`: Synchronize the environment with the locked packages and the specified groups. +* `--keep-untracked`: Do not uninstall the untracked packages. * `--dry-run`: Output the operations but do not execute anything (implicitly enables `--verbose`). diff --git a/docs/faq.md b/docs/faq.md index c35a92326a6..a66d631fd2f 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -119,7 +119,7 @@ Thus, dependencies are resolved by `pip`. [testenv] allowlist_externals = poetry commands_pre = - poetry install --no-root --sync + poetry install --no-root commands = poetry run pytest tests/ --import-mode importlib ``` diff --git a/docs/managing-dependencies.md b/docs/managing-dependencies.md index 67a5bb42de1..212a4c58343 100644 --- a/docs/managing-dependencies.md +++ b/docs/managing-dependencies.md @@ -213,32 +213,18 @@ poetry remove mkdocs --group docs ## Synchronizing dependencies -Poetry supports what's called dependency synchronization. Dependency synchronization ensures +Poetry promotes what is called dependency synchronization. Dependency synchronization ensures that the locked dependencies in the `poetry.lock` file are the only ones present -in the environment, removing anything that's not necessary. +in the environment, removing anything that is not necessary. -This is done by using the `--sync` option of the `install` command: +Alternatively, you can keep untracked packages by using the `--keep-untracked` option of the `install` command: ```bash -poetry install --sync +poetry install --keep-untracked ``` -The `--sync` option can be combined with any [dependency groups]({{< relref "#dependency-groups" >}}) related options -to synchronize the environment with specific groups. Note that extras are separate. Any -extras not selected for install are always removed, regardless of `--sync`. - -```bash -poetry install --without dev --sync -poetry install --with docs --sync -poetry install --only dev -``` - -{{% note %}} -The `--sync` option replaces the `--remove-untracked` option which is now deprecated. -{{% /note %}} - ## Layering optional groups -When you omit the `--sync` option, you can install any subset of optional groups without removing -those that are already installed. This is very useful, for example, in multi-stage +When you use the `--keep-untracked` option, you can install any subset of optional groups without removing +those that are already installed. This is very useful, for example, in multi-stage Docker builds, where you run `poetry install` multiple times in different build stages. diff --git a/src/poetry/console/commands/install.py b/src/poetry/console/commands/install.py index 972d04d8f77..498c3f01089 100644 --- a/src/poetry/console/commands/install.py +++ b/src/poetry/console/commands/install.py @@ -20,10 +20,9 @@ class InstallCommand(InstallerCommand): options: ClassVar[list[Option]] = [ *InstallerCommand._group_dependency_options(), option( - "sync", + "keep-untracked", None, - "Synchronize the environment with the locked packages and the specified" - " groups.", + "Do not uninstall the untracked packages.", ), option( "no-root", None, "Do not install the root package (the current project)." @@ -146,7 +145,7 @@ def handle(self) -> int: self.installer.extras(extras) - with_synchronization = self.option("sync") + with_synchronization = not self.option("keep-untracked") self.installer.only_groups(self.activated_groups) self.installer.skip_directory(self.option("no-directory")) diff --git a/src/poetry/console/commands/self/install.py b/src/poetry/console/commands/self/install.py index c0870b2280e..0bc733bec32 100644 --- a/src/poetry/console/commands/self/install.py +++ b/src/poetry/console/commands/self/install.py @@ -19,7 +19,7 @@ class SelfInstallCommand(SelfCommand, InstallCommand): "Install locked packages (incl. addons) required by this Poetry installation." ) options: ClassVar[list[Option]] = [ - o for o in InstallCommand.options if o.name in {"sync", "dry-run"} + o for o in InstallCommand.options if o.name in {"keep-untracked", "dry-run"} ] help = f"""\ The self install command ensures all additional packages specified are \ diff --git a/src/poetry/console/commands/update.py b/src/poetry/console/commands/update.py index a9eed5aa724..6347e83fe2c 100644 --- a/src/poetry/console/commands/update.py +++ b/src/poetry/console/commands/update.py @@ -26,10 +26,9 @@ class UpdateCommand(InstallerCommand): options: ClassVar[list[Option]] = [ *InstallerCommand._group_dependency_options(), option( - "sync", + "keep-untracked", None, - "Synchronize the environment with the locked packages and the specified" - " groups.", + "Do not uninstall the untracked packages.", ), option( "dry-run", @@ -49,7 +48,7 @@ def handle(self) -> int: self.installer.only_groups(self.activated_groups) self.installer.dry_run(self.option("dry-run")) - self.installer.requires_synchronization(self.option("sync")) + self.installer.requires_synchronization(not self.option("keep-untracked")) self.installer.execute_operations(not self.option("lock")) # Force update diff --git a/tests/console/commands/self/test_install.py b/tests/console/commands/self/test_install.py index b9cbbb59dc4..21167017c72 100644 --- a/tests/console/commands/self/test_install.py +++ b/tests/console/commands/self/test_install.py @@ -51,12 +51,5 @@ def test_self_install( tester.execute() - expected_output = """\ -Updating dependencies -Resolving dependencies... - -Writing lock file -""" - - assert tester.io.fetch_output() == expected_output + assert tester.io.fetch_output().endswith("Writing lock file\n") assert tester.io.fetch_error() == "" diff --git a/tests/console/commands/test_install.py b/tests/console/commands/test_install.py index ae163df3ec2..d620d070737 100644 --- a/tests/console/commands/test_install.py +++ b/tests/console/commands/test_install.py @@ -154,18 +154,22 @@ def test_group_options_are_passed_to_the_installer( assert editable_builder_mock.call_count == 0 -def test_sync_option_is_passed_to_the_installer( - tester: CommandTester, mocker: MockerFixture +@pytest.mark.parametrize("options", ["", "--keep-untracked"]) +def test_keep_untracked_option_is_passed_to_the_installer( + tester: CommandTester, mocker: MockerFixture, options: str ) -> None: """ - The --sync option is passed properly to the installer. + The --keep-untracked option is passed properly to the installer. """ assert isinstance(tester.command, InstallerCommand) mocker.patch.object(tester.command.installer, "run", return_value=1) - tester.execute("--sync") + tester.execute(options) - assert tester.command.installer._requires_synchronization + if options: + assert not tester.command.installer._requires_synchronization + else: + assert tester.command.installer._requires_synchronization @pytest.mark.parametrize("compile", [False, True]) diff --git a/tests/console/commands/test_update.py b/tests/console/commands/test_update.py index 6b48071d612..fea53312501 100644 --- a/tests/console/commands/test_update.py +++ b/tests/console/commands/test_update.py @@ -85,18 +85,23 @@ def test_update_prints_operations( assert ("Installing docker (4.3.1)" in output) is expected -def test_update_sync_option_is_passed_to_the_installer( +@pytest.mark.parametrize("options", ["", "--keep-untracked"]) +def test_update_keep_untracked_option_is_passed_to_the_installer( poetry_with_outdated_lockfile: Poetry, command_tester_factory: CommandTesterFactory, mocker: MockerFixture, + options: str, ) -> None: """ - The --sync option is passed properly to the installer from update. + The --keep-untracked option is passed properly to the installer from update. """ tester = command_tester_factory("update", poetry=poetry_with_outdated_lockfile) assert isinstance(tester.command, UpdateCommand) mocker.patch.object(tester.command.installer, "run", return_value=1) - tester.execute("--sync") + tester.execute(options) - assert tester.command.installer._requires_synchronization + if options: + assert not tester.command.installer._requires_synchronization + else: + assert tester.command.installer._requires_synchronization