Skip to content

Commit e72d2ee

Browse files
committed
cache clear: make cache name optional to clear all caches
People have already used the workaround `poetry cache clear --all .`. Let's have an official (and more obvious option).
1 parent 9e1062a commit e72d2ee

File tree

3 files changed

+84
-9
lines changed

3 files changed

+84
-9
lines changed

docs/cli.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,15 @@ The `cache` command groups subcommands to interact with Poetry's cache.
231231

232232
### cache clear
233233

234-
The `cache clear` command removes packages from a cached repository.
234+
The `cache clear` command removes packages from cached repositories.
235235

236-
For example, to clear the whole cache of packages from the `PyPI` repository, run:
236+
For example, to clear the whole cache of packages from all repositories, run:
237+
238+
```bash
239+
poetry cache clear --all
240+
```
241+
242+
To only clear all packages from the `PyPI` repository, run:
237243

238244
```bash
239245
poetry cache clear PyPI --all

src/poetry/console/commands/cache/clear.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@
2121

2222
class CacheClearCommand(Command):
2323
name = "cache clear"
24-
description = "Clears a Poetry cache by name."
24+
description = "Clear Poetry's caches."
2525

2626
arguments: ClassVar[list[Argument]] = [
27-
argument("cache", description="The name of the cache to clear.")
27+
argument("cache", description="The name of the cache to clear.", optional=True)
2828
]
2929
options: ClassVar[list[Option]] = [
3030
option("all", description="Clear all entries in the cache.")
@@ -33,8 +33,12 @@ class CacheClearCommand(Command):
3333
def handle(self) -> int:
3434
cache = self.argument("cache")
3535

36-
parts = cache.split(":")
37-
root = parts[0]
36+
if cache:
37+
parts = cache.split(":")
38+
root = parts[0]
39+
else:
40+
parts = []
41+
root = ""
3842

3943
config = Config.create()
4044
cache_dir = config.repository_cache_directory / root
@@ -46,14 +50,16 @@ def handle(self) -> int:
4650

4751
cache = FileCache(cache_dir)
4852

49-
if len(parts) == 1:
53+
if len(parts) < 2:
5054
if not self.option("all"):
5155
raise RuntimeError(
52-
f"Add the --all option if you want to clear all {parts[0]} caches"
56+
"Add the --all option if you want to clear all cache entries"
5357
)
5458

5559
if not cache_dir.exists():
56-
self.line(f"No cache entries for {parts[0]}")
60+
self.line(
61+
f"No cache entries for {root}" if root else "No cache entries"
62+
)
5763
return 0
5864

5965
# Calculate number of entries

tests/console/commands/cache/test_clear.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,36 @@ def test_cache_clear_all(
3434
repository_dirs: list[Path],
3535
caches: list[FileCache[dict[str, str]]],
3636
inputs: str,
37+
) -> None:
38+
exit_code = tester.execute("cache clear --all", inputs=inputs)
39+
40+
assert exit_code == 0
41+
assert tester.io.fetch_output() == ""
42+
43+
if inputs == "yes":
44+
assert not repository_dirs[0].exists() or not any(repository_dirs[0].iterdir())
45+
assert not repository_dirs[1].exists() or not any(repository_dirs[1].iterdir())
46+
assert not caches[0].has("cachy:0.1")
47+
assert not caches[0].has("cleo:0.2")
48+
assert not caches[1].has("cachy:0.1")
49+
assert not caches[1].has("cashy:0.2")
50+
else:
51+
assert any((repository_cache_dir / repositories[0]).iterdir())
52+
assert any((repository_cache_dir / repositories[1]).iterdir())
53+
assert caches[0].has("cachy:0.1")
54+
assert caches[0].has("cleo:0.2")
55+
assert caches[1].has("cachy:0.1")
56+
assert caches[1].has("cashy:0.2")
57+
58+
59+
@pytest.mark.parametrize("inputs", ["yes", "no"])
60+
def test_cache_clear_all_one_cache(
61+
tester: ApplicationTester,
62+
repository_cache_dir: Path,
63+
repositories: list[str],
64+
repository_dirs: list[Path],
65+
caches: list[FileCache[dict[str, str]]],
66+
inputs: str,
3767
) -> None:
3868
exit_code = tester.execute(f"cache clear {repositories[0]} --all", inputs=inputs)
3969

@@ -54,6 +84,39 @@ def test_cache_clear_all(
5484
assert caches[1].has("cashy:0.2")
5585

5686

87+
def test_cache_clear_all_no_entries(tester: ApplicationTester) -> None:
88+
exit_code = tester.execute("cache clear --all")
89+
90+
assert exit_code == 0
91+
assert tester.io.fetch_output().strip() == "No cache entries"
92+
93+
94+
def test_cache_clear_all_one_cache_no_entries(
95+
tester: ApplicationTester,
96+
repository_cache_dir: Path,
97+
repositories: list[str],
98+
) -> None:
99+
exit_code = tester.execute(f"cache clear {repositories[0]} --all")
100+
101+
assert exit_code == 0
102+
103+
assert tester.io.fetch_output().strip() == f"No cache entries for {repositories[0]}"
104+
105+
106+
@pytest.mark.parametrize("with_repo", [False, True])
107+
def test_cache_clear_missing_option(
108+
tester: ApplicationTester, repositories: list[str], with_repo: bool
109+
) -> None:
110+
command = f"cache clear {repositories[0]}" if with_repo else "cache clear"
111+
exit_code = tester.execute(command)
112+
113+
assert exit_code == 1
114+
assert (
115+
"Add the --all option if you want to clear all cache entries"
116+
in tester.io.fetch_error()
117+
)
118+
119+
57120
@pytest.mark.parametrize("inputs", ["yes", "no"])
58121
@pytest.mark.parametrize("package_name", ["cachy", "Cachy"])
59122
def test_cache_clear_pkg(

0 commit comments

Comments
 (0)