Skip to content

Commit

Permalink
Allow removing multiple (and all) environments at once (#3212)
Browse files Browse the repository at this point in the history
Co-authored-by: Arun Babu Neelicattu <arun.neelicattu@gmail.com>
Co-authored-by: Bjorn Neergaard <bjorn@neersighted.com>
  • Loading branch information
3 people committed Nov 14, 2021
1 parent f7bbd54 commit 089ff9d
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 5 deletions.
9 changes: 9 additions & 0 deletions docs/managing-environments.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,13 @@ poetry env remove 3.7
poetry env remove test-O3eWbxRl-py3.7
```

You can delete more than one environment at a time.
```bash
poetry env remove python3.6 python3.7 python3.8
```
Use the `--all` option to delete all virtual environments at once.
```bash
poetry env remove --all
```

If you remove the currently activated virtual environment, it will be automatically deactivated.
34 changes: 29 additions & 5 deletions poetry/console/commands/env/remove.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,45 @@
from cleo.helpers import argument
from cleo.helpers import option

from ..command import Command


class EnvRemoveCommand(Command):

name = "env remove"
description = "Removes a specific virtualenv associated with the project."
description = "Remove virtual environments associated with the project."

arguments = [
argument("python", "The python executable to remove the virtualenv for.")
argument(
"python",
"The python executables associated with, or names of the virtual environments which are to "
"be removed.",
optional=True,
multiple=True,
)
]
options = [
option(
"all",
description="Remove all managed virtual environments associated with the "
"project.",
),
]

def handle(self) -> None:
from poetry.utils.env import EnvManager

manager = EnvManager(self.poetry)
venv = manager.remove(self.argument("python"))
pythons = self.argument("python")
all = self.option("all")
if not (pythons or all):
self.line("No virtualenv provided.")

self.line("Deleted virtualenv: <comment>{}</comment>".format(venv.path))
manager = EnvManager(self.poetry)
# TODO: refactor env.py to allow removal with one loop
for python in pythons:
venv = manager.remove(python)
self.line("Deleted virtualenv: <comment>{}</comment>".format(venv.path))
if all:
for venv in manager.list():
manager.remove_venv(venv.path)
self.line("Deleted virtualenv: <comment>{}</comment>".format(venv.path))
31 changes: 31 additions & 0 deletions tests/console/commands/env/test_remove.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,34 @@ def test_remove_by_name(tester, venvs_in_cache_dirs, venv_name, venv_cache):
expected += "Deleted virtualenv: {}\n".format((venv_cache / name))

assert expected == tester.io.fetch_output()


def test_remove_all(tester, venvs_in_cache_dirs, venv_name, venv_cache):
expected = {""}
tester.execute("--all")
for name in venvs_in_cache_dirs:
assert not (venv_cache / name).exists()
expected.add("Deleted virtualenv: {}".format((venv_cache / name)))
assert expected == set(tester.io.fetch_output().split("\n"))


def test_remove_all_and_version(tester, venvs_in_cache_dirs, venv_name, venv_cache):
expected = {""}
tester.execute("--all {}".format(venvs_in_cache_dirs[0]))
for name in venvs_in_cache_dirs:
assert not (venv_cache / name).exists()
expected.add("Deleted virtualenv: {}".format((venv_cache / name)))
assert expected == set(tester.io.fetch_output().split("\n"))


def test_remove_multiple(tester, venvs_in_cache_dirs, venv_name, venv_cache):
expected = {""}
removed_envs = venvs_in_cache_dirs[0:2]
remaining_envs = venvs_in_cache_dirs[2:]
tester.execute(" ".join(removed_envs))
for name in removed_envs:
assert not (venv_cache / name).exists()
expected.add("Deleted virtualenv: {}".format((venv_cache / name)))
for name in remaining_envs:
assert (venv_cache / name).exists()
assert expected == set(tester.io.fetch_output().split("\n"))

0 comments on commit 089ff9d

Please sign in to comment.