Skip to content

Commit c564e1c

Browse files
authored
feat: add --lock option to remove command (#7917)
1 parent ee567a7 commit c564e1c

File tree

5 files changed

+59
-14
lines changed

5 files changed

+59
-14
lines changed

docs/cli.md

+1
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,7 @@ about dependency groups.
471471
* `--group (-G)`: The group to remove the dependency from.
472472
* `--dev (-D)`: Removes a package from the development dependencies. (**Deprecated**, use `-G dev` instead)
473473
* `--dry-run` : Outputs the operations but will not execute anything (implicitly enables --verbose).
474+
* `--lock`: Do not perform operations (only update the lockfile).
474475

475476

476477
## show

src/poetry/console/commands/remove.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class RemoveCommand(InstallerCommand):
3535
"(implicitly enables --verbose)."
3636
),
3737
),
38+
option("lock", None, "Do not perform operations (only update the lockfile)."),
3839
]
3940

4041
help = """The <info>remove</info> command removes a package from the current
@@ -108,15 +109,13 @@ def handle(self) -> int:
108109
)
109110

110111
# Refresh the locker
111-
self.poetry.set_locker(
112-
self.poetry.locker.__class__(self.poetry.locker.lock, poetry_content)
113-
)
112+
self.poetry.locker.set_local_config(poetry_content)
114113
self.installer.set_locker(self.poetry.locker)
115-
116114
self.installer.set_package(self.poetry.package)
117115
self.installer.dry_run(self.option("dry-run", False))
118116
self.installer.verbose(self.io.is_verbose())
119117
self.installer.update(True)
118+
self.installer.execute_operations(not self.option("lock"))
120119
self.installer.whitelist(removed_set)
121120

122121
status = self.installer.run()

src/poetry/packages/locker.py

+4
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ def is_fresh(self) -> bool:
9090

9191
return False
9292

93+
def set_local_config(self, local_config: dict[str, Any]) -> None:
94+
self._local_config = local_config
95+
self._content_hash = self._get_content_hash()
96+
9397
def locked_repository(self) -> LockfileRepository:
9498
"""
9599
Searches and returns a repository of locked packages.

tests/console/commands/test_remove.py

+50-5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from poetry.core.packages.package import Package
1111

1212
from poetry.factory import Factory
13+
from tests.helpers import TestLocker
1314
from tests.helpers import get_package
1415

1516

@@ -33,12 +34,16 @@ def poetry_with_up_to_date_lockfile(
3334
) -> Poetry:
3435
source = fixture_dir("up_to_date_lock")
3536

36-
return project_factory(
37+
poetry = project_factory(
3738
name="foobar",
3839
pyproject_content=(source / "pyproject.toml").read_text(encoding="utf-8"),
3940
poetry_lock_content=(source / "poetry.lock").read_text(encoding="utf-8"),
4041
)
4142

43+
assert isinstance(poetry.locker, TestLocker)
44+
poetry.locker.locked(True)
45+
return poetry
46+
4247

4348
@pytest.fixture()
4449
def tester(command_tester_factory: CommandTesterFactory) -> CommandTester:
@@ -49,7 +54,6 @@ def test_remove_without_specific_group_removes_from_all_groups(
4954
tester: CommandTester,
5055
app: PoetryTestApplication,
5156
repo: TestRepository,
52-
command_tester_factory: CommandTesterFactory,
5357
installed: Repository,
5458
) -> None:
5559
"""
@@ -108,7 +112,6 @@ def test_remove_without_specific_group_removes_from_specific_groups(
108112
tester: CommandTester,
109113
app: PoetryTestApplication,
110114
repo: TestRepository,
111-
command_tester_factory: CommandTesterFactory,
112115
installed: Repository,
113116
) -> None:
114117
"""
@@ -166,7 +169,6 @@ def test_remove_does_not_live_empty_groups(
166169
tester: CommandTester,
167170
app: PoetryTestApplication,
168171
repo: TestRepository,
169-
command_tester_factory: CommandTesterFactory,
170172
installed: Repository,
171173
) -> None:
172174
"""
@@ -213,7 +215,6 @@ def test_remove_canonicalized_named_removes_dependency_correctly(
213215
tester: CommandTester,
214216
app: PoetryTestApplication,
215217
repo: TestRepository,
216-
command_tester_factory: CommandTesterFactory,
217218
installed: Repository,
218219
) -> None:
219220
"""
@@ -308,3 +309,47 @@ def test_remove_with_dry_run_keep_files_intact(
308309
assert (
309310
poetry_with_up_to_date_lockfile._locker.lock_data == original_lockfile_content
310311
)
312+
313+
314+
def test_remove_performs_uninstall_op(
315+
poetry_with_up_to_date_lockfile: Poetry,
316+
command_tester_factory: CommandTesterFactory,
317+
installed: Repository,
318+
) -> None:
319+
installed.add_package(get_package("docker", "4.3.1"))
320+
tester = command_tester_factory("remove", poetry=poetry_with_up_to_date_lockfile)
321+
322+
tester.execute("docker")
323+
324+
expected = """\
325+
Updating dependencies
326+
Resolving dependencies...
327+
328+
Package operations: 0 installs, 0 updates, 1 removal
329+
330+
• Removing docker (4.3.1)
331+
332+
Writing lock file
333+
"""
334+
335+
assert tester.io.fetch_output() == expected
336+
337+
338+
def test_remove_with_lock_does_not_perform_uninstall_op(
339+
poetry_with_up_to_date_lockfile: Poetry,
340+
command_tester_factory: CommandTesterFactory,
341+
installed: Repository,
342+
) -> None:
343+
installed.add_package(get_package("docker", "4.3.1"))
344+
tester = command_tester_factory("remove", poetry=poetry_with_up_to_date_lockfile)
345+
346+
tester.execute("docker --lock")
347+
348+
expected = """\
349+
Updating dependencies
350+
Resolving dependencies...
351+
352+
Writing lock file
353+
"""
354+
355+
assert tester.io.fetch_output() == expected

tests/helpers.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -187,12 +187,8 @@ class TestLocker(Locker):
187187
__test__ = False
188188

189189
def __init__(self, lock: Path, local_config: dict[str, Any]) -> None:
190-
self._lock = lock
191-
self._local_config = local_config
192-
self._lock_data = None
193-
self._content_hash = self._get_content_hash()
190+
super().__init__(lock, local_config)
194191
self._locked = False
195-
self._lock_data = None
196192
self._write = False
197193

198194
def write(self, write: bool = True) -> None:

0 commit comments

Comments
 (0)