Skip to content

Conversation

@radoering
Copy link
Member

@radoering radoering commented Nov 24, 2025

People have already used the workaround poetry cache clear --all . or poetry cache clear --all ""
See #10585 (comment).

Let's have an official (and more obvious option): poetry cache clear --all

Pull Request Check List

  • Added tests for changed code.
  • Updated documentation for changed code.

Summary by Sourcery

Allow clearing Poetry caches without specifying a cache name and align messaging with the broader behavior.

New Features:

  • Support clearing all caches with poetry cache clear --all without requiring a cache name.

Enhancements:

  • Make the cache name argument optional and generalize user-facing messages when clearing caches.

Documentation:

  • Document the ability to clear all caches at once and clarify examples for clearing specific repositories.

Tests:

  • Add coverage for clearing all caches without a cache name and retain tests for clearing a single repository cache.

@sourcery-ai
Copy link

sourcery-ai bot commented Nov 24, 2025

Reviewer's Guide

Allow poetry cache clear to be called without a cache name to clear all caches, updating the cache clear command’s argument handling, error messages, behavior, docs, and adding tests for the new usage.

Sequence diagram for the updated cache clear command behavior

sequenceDiagram
    actor User
    participant CLI as Poetry_CLI
    participant Cmd as CacheClearCommand
    participant Cfg as Config
    participant FC as FileCache
    participant FS as FileSystem

    User->>CLI: poetry cache clear --all
    CLI->>Cmd: invoke handle()
    Cmd->>Cmd: cache = argument(cache) (None)
    alt cache not provided
        Cmd->>Cmd: parts = []
        Cmd->>Cmd: root = ""
    else cache provided
        Cmd->>Cmd: parts = cache.split(":")
        Cmd->>Cmd: root = parts[0]
    end

    Cmd->>Cfg: Config.create()
    Cfg-->>Cmd: config
    Cmd->>Cmd: cache_dir = config.repository_cache_directory / root
    Cmd->>FS: check cache_dir.parent exists
    FS-->>Cmd: exists or not
    alt cache_dir.parent missing
        Cmd->>FS: create cache_dir.parent
    end

    Cmd->>FC: FileCache(cache_dir)
    alt len(parts) < 2
        Cmd->>Cmd: check option(all)
        alt option all is False
            Cmd->>User: RuntimeError("Add the --all option if you want to clear all caches")
        else option all is True
            Cmd->>FS: check cache_dir exists
            FS-->>Cmd: exists or not
            alt cache_dir does not exist
                alt root is empty
                    Cmd->>User: line("No cache entries")
                else root not empty
                    Cmd->>User: line(f"No cache entries for {root}")
                end
                Cmd-->>CLI: return 0
            else cache_dir exists
                Cmd->>FS: iterate and delete cache entries
                Cmd->>User: line("Cache entries cleared")
                Cmd-->>CLI: return 0
            end
        end
    else len(parts) >= 2
        Cmd->>FC: clear subset of cache based on parts
        Cmd->>User: line("Selected cache entries cleared")
        Cmd-->>CLI: return 0
    end
Loading

Updated class diagram for cache clear command and related classes

classDiagram
    class Command {
        +str name
        +str description
        +list arguments
        +list options
        +int handle()
    }

    class CacheClearCommand {
        +str name
        +str description
        +list arguments
        +list options
        +int handle()
    }

    class Argument {
        +str name
        +str description
        +bool optional
    }

    class Option {
        +str name
        +str description
    }

    class Config {
        +Path repository_cache_directory
        +Config create()
    }

    class FileCache {
        +Path cache_dir
        +FileCache(Path cache_dir)
        +int __len__()
        +void clear_all()
        +void clear_subset(str root, list parts)
    }

    Command <|-- CacheClearCommand
    CacheClearCommand --> Argument : uses
    CacheClearCommand --> Option : uses
    CacheClearCommand --> Config : uses
    CacheClearCommand --> FileCache : uses

    CacheClearCommand : arguments = [Argument(cache, optional=True)]
    CacheClearCommand : options = [Option(all)]
    CacheClearCommand : handle()
    CacheClearCommand : - str cache
    CacheClearCommand : - list parts
    CacheClearCommand : - str root

    Argument : Argument(str name, str description, bool optional)
    Option : Option(str name, str description)
    Config : create()
    FileCache : FileCache(Path cache_dir)
    FileCache : clear_all()
    FileCache : clear_subset(str root, list parts)
Loading

File-Level Changes

Change Details Files
Support running poetry cache clear --all without specifying a cache name and adjust errors/output accordingly.
  • Made the cache argument optional for the cache clear command.
  • Adjusted parsing logic to handle a missing cache name by using an empty root and parts list.
  • Relaxed the condition that previously required a cache name by treating missing or single-part cache names uniformly.
  • Updated error message when --all is missing to mention clearing all caches rather than a specific cache.
  • Changed the no-entries message to handle both a specific cache root and the case where all caches are targeted.
src/poetry/console/commands/cache/clear.py
Extend test coverage for clearing all caches with and without specifying a cache name.
  • Added a parameterized test that runs cache clear --all without a cache name and asserts behavior for both confirmed and declined prompts.
  • Renamed or repurposed the existing all-caches test to test_cache_clear_all_one_cache to explicitly cover the single-named-cache scenario.
  • Ensured repository directories and cache entries are asserted correctly for both confirmation paths.
tests/console/commands/cache/test_clear.py
Update CLI documentation to describe the new cache clear --all behavior and clarify examples.
  • Reworded the cache clear description to refer to cached repositories in plural.
  • Documented poetry cache clear --all as the way to clear all repositories’ caches.
  • Adjusted the previous example to clarify how to clear all packages from a single repository cache (PyPI).
docs/cli.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes - here's some feedback:

  • The control flow in handle() could be clearer if you handled the "no cache argument" case early and separately (e.g., early return for cache is None), instead of relying on root = "" and parts = [] and reusing the same len(parts) < 2 logic for both cases.
  • The error message raised when a specific cache is provided without --all was changed to "Add the --all option if you want to clear all caches", which is a bit misleading in that context; consider preserving the cache name in the message to keep the guidance specific (as it was before).
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The control flow in handle() could be clearer if you handled the "no cache argument" case early and separately (e.g., early return for `cache is None`), instead of relying on `root = ""` and `parts = []` and reusing the same `len(parts) < 2` logic for both cases.
- The error message raised when a specific cache is provided without `--all` was changed to "Add the --all option if you want to clear all caches", which is a bit misleading in that context; consider preserving the cache name in the message to keep the guidance specific (as it was before).

## Individual Comments

### Comment 1
<location> `tests/console/commands/cache/test_clear.py:38` </location>
<code_context>
+def test_cache_clear_all(
</code_context>

<issue_to_address>
**suggestion (testing):** Consider adding a test for `cache clear` without a cache name and without `--all` to cover the new error path.

This new behavior now triggers the branch where `len(parts) < 2` and `--all` is not set, raising a `RuntimeError` with the message: "Add the --all option if you want to clear all caches". Please add a test (e.g. `test_cache_clear_without_all_raises`) that runs `cache clear` with no arguments, asserts that it fails, and checks this exact message to lock in the CLI behavior and avoid regressions.
</issue_to_address>

### Comment 2
<location> `tests/console/commands/cache/test_clear.py:59-60` </location>
<code_context>
+        assert caches[1].has("cashy:0.2")
+
+
[email protected]("inputs", ["yes", "no"])
+def test_cache_clear_all_one_cache(
+    tester: ApplicationTester,
+    repository_cache_dir: Path,
</code_context>

<issue_to_address>
**suggestion (testing):** Add a test for `cache clear --all` (with and without a cache name) when the cache directory does not exist to validate the "No cache entries" message.

Since the command now prints different messages depending on whether a root is provided, please add tests for both cases when the cache directory does not exist: `cache clear some-repo --all` and `cache clear --all`. Each test should assert a successful exit and that the output message matches the expected text. This will fully verify the updated behavior for non-existent caches.

Suggested implementation:

```python
    caches: list[FileCache[dict[str, str]]],
    inputs: str,
) -> None:
    exit_code = tester.execute(f"cache clear {repositories[0]} --all", inputs=inputs)


def test_cache_clear_all_with_cache_name_no_cache_dir(
    tester: ApplicationTester,
    repository_cache_dir: Path,
    repositories: list[str],
) -> None:
    # Remove the cache directory to simulate a non-existent cache for the given root
    repository_cache_dir.rmdir()

    exit_code = tester.execute(f"cache clear {repositories[0]} --all")

    assert exit_code == 0

    output = tester.io.fetch_output()
    assert "No cache entries" in output
    # The message should mention the specific cache root when one is provided
    assert repositories[0] in output


def test_cache_clear_all_without_cache_name_no_cache_dir(
    tester: ApplicationTester,
    repository_cache_dir: Path,
) -> None:
    # Remove the cache directory to simulate a non-existent cache when no root is provided
    repository_cache_dir.rmdir()

    exit_code = tester.execute("cache clear --all")

    assert exit_code == 0

    output = tester.io.fetch_output()
    assert "No cache entries" in output
    # The message should clearly indicate the absence of entries without tying it to a specific root
    assert "cache" in output or "directory" in output

```

To fully align these tests with your actual CLI messages and test helpers:

1. Verify how `ApplicationTester` exposes command output in your codebase. If it uses a different method than `tester.io.fetch_output()` (e.g. `tester.io.fetch_output().strip()` or `tester.io.fetch_error_output()`), adjust the calls accordingly.
2. Replace the loose assertions on `"cache"` / `"directory"` with checks against the exact expected messages for:
   - `cache clear some-repo --all` when the cache directory does not exist
   - `cache clear --all` when the cache directory does not exist
   For example, if the implementation prints `No cache entries for cache root "some-repo".`, assert that string (using `repositories[0]` where appropriate); and if it prints `No cache entries in cache directory.`, assert that exact text.
3. If `repository_cache_dir` might not be empty when these tests run (e.g. if a fixture pre-populates it), replace `repository_cache_dir.rmdir()` with logic that first clears its contents or uses a temporary, distinct non-existent path to simulate the missing cache directory.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

People have already used the workaround `poetry cache clear --all .`. Let's have an official (and more obvious option).
@radoering radoering added the impact/docs Contains or requires documentation changes label Nov 24, 2025
@github-actions
Copy link

Deploy preview for website ready!

✅ Preview
https://website-6mqlibhla-python-poetry.vercel.app

Built with commit e72d2ee.
This pull request is being automatically deployed with vercel-action

@radoering radoering merged commit 99dc7b2 into python-poetry:main Nov 29, 2025
66 of 68 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

impact/docs Contains or requires documentation changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant