Skip to content

Commit 0007b0e

Browse files
committed
cli/env: handle removal of in-project venv
Resolves: #2124
1 parent 374babb commit 0007b0e

File tree

4 files changed

+34
-7
lines changed

4 files changed

+34
-7
lines changed

docs/managing-environments.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,12 @@ poetry env remove --all
160160
```
161161

162162
If you remove the currently activated virtual environment, it will be automatically deactivated.
163+
164+
{{% note %}}
165+
If you use the [`virtualenvs.in-project`]({{< relref "configuration#virtualenvsin-project" >}}) configuration, you
166+
can simply use the command as shown below.
167+
168+
```bash
169+
poetry env remove
170+
```
171+
{{% /note %}}

src/poetry/console/commands/env/remove.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,24 +39,30 @@ class EnvRemoveCommand(Command):
3939
def handle(self) -> int:
4040
from poetry.utils.env import EnvManager
4141

42+
is_in_project = self.poetry.config.get("virtualenvs.in-project")
43+
4244
pythons = self.argument("python")
43-
all = self.option("all")
44-
if not (pythons or all):
45+
remove_all_envs = self.option("all")
46+
47+
if not (pythons or remove_all_envs or is_in_project):
4548
self.line("No virtualenv provided.")
4649

4750
manager = EnvManager(self.poetry)
4851
# TODO: refactor env.py to allow removal with one loop
4952
for python in pythons:
5053
venv = manager.remove(python)
5154
self.line(f"Deleted virtualenv: <comment>{venv.path}</comment>")
52-
if all:
55+
if remove_all_envs or is_in_project:
5356
for venv in manager.list():
54-
manager.remove_venv(venv.path)
55-
self.line(f"Deleted virtualenv: <comment>{venv.path}</comment>")
57+
if not is_in_project or venv.path.is_relative_to(
58+
self.poetry.pyproject_path.parent
59+
):
60+
manager.remove_venv(venv.path)
61+
self.line(f"Deleted virtualenv: <comment>{venv.path}</comment>")
5662
# Since we remove all the virtualenvs, we can also remove the entry
5763
# in the envs file. (Strictly speaking, we should do this explicitly,
5864
# in case it points to a virtualenv that had been removed manually before.)
59-
if manager.envs_file.exists():
65+
if remove_all_envs and manager.envs_file.exists():
6066
manager.envs_file.remove_section(manager.base_env_name)
6167

6268
return 0

tests/console/commands/env/conftest.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ def venvs_in_project_dir(app: PoetryTestApplication) -> Iterator[Path]:
6565
try:
6666
yield venv_dir
6767
finally:
68-
venv_dir.rmdir()
68+
if venv_dir.exists():
69+
venv_dir.rmdir()
6970

7071

7172
@pytest.fixture

tests/console/commands/env/test_remove.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,14 @@ def test_remove_multiple(
137137
for name in remaining_envs:
138138
assert (venv_cache / name).exists()
139139
assert set(tester.io.fetch_output().split("\n")) == expected
140+
141+
142+
def test_remove_in_project(tester: CommandTester, venvs_in_project_dir: Path) -> None:
143+
assert venvs_in_project_dir.exists()
144+
145+
tester.execute()
146+
147+
assert not venvs_in_project_dir.exists()
148+
149+
expected = f"Deleted virtualenv: {venvs_in_project_dir}\n"
150+
assert tester.io.fetch_output() == expected

0 commit comments

Comments
 (0)