Skip to content

Conversation

@Jack251970
Copy link
Member

@Jack251970 Jack251970 commented Feb 4, 2026

  • Added TryDeleteDirectoryRobust to delete directories with retries and remove read-only attributes; returns whether deletion fully succeeded.
  • Updated PluginConfig to use the robust deletion; if partial, recreates the NeedDelete marker and logs a warning so deletion retries on next startup.
  • Added unit tests for non-existent, empty, nested, files-present, and read-only scenarios.

Test:

  • A plugin with one locked file in its plugin directory will be delete after lock is released.

Copilot AI and others added 5 commits February 4, 2026 04:19
Refactored the process for recreating the marker file when a plugin directory is not fully deleted. Removed unnecessary try-catch and nested checks, now directly checking for file existence and creating it if missing. This streamlines the code and removes redundant error handling.
…letion

Fix incomplete plugin directory deletion on uninstall
Copilot AI review requested due to automatic review settings February 4, 2026 04:53
@prlabeler prlabeler bot added the bug Something isn't working label Feb 4, 2026
@github-actions github-actions bot added this to the 2.1.0 milestone Feb 4, 2026
@github-actions

This comment has been minimized.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 4, 2026

📝 Walkthrough

Walkthrough

Replaces the previous direct directory deletion with a new robust deletion routine (FilesFolders.TryDeleteDirectoryRobust). PluginConfig now uses that routine, logs a warning and writes a plugin-delete marker if deletion is incomplete. PluginManager removes the marker on successful install. Adds tests for the new utility.

Changes

Cohort / File(s) Summary
Plugin deletion flow
Flow.Launcher.Core/Plugin/PluginConfig.cs, Flow.Launcher.Core/Plugin/PluginManager.cs
Replace direct Directory.Delete(..., true) with FilesFolders.TryDeleteDirectoryRobust(..., maxRetries: 3, retryDelayMs: 200). If deletion is incomplete, log via PublicApi.Instance.LogWarn and create DataLocation.PluginDeleteFile marker (if missing). PluginManager removes the marker during install.
Deletion utility
Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs
Add public TryDeleteDirectoryRobust(string path, int maxRetries = 3, int retryDelayMs = 100) implementing per-file retries, read‑only attribute handling, deep→shallow empty-directory removal, and returning bool indicating full deletion success or partial failure.
Tests
Flow.Launcher.Test/FilesFoldersTest.cs
Add unit tests covering non-existent directory, empty directory, files, nested structures, and read-only file scenarios for TryDeleteDirectoryRobust.

Sequence Diagram

sequenceDiagram
    participant PC as PluginConfig
    participant FD as FilesFolders.TryDeleteDirectoryRobust
    participant FS as FileSystem
    participant DL as DataLocation
    participant PA as PublicApi

    PC->>FD: Request delete directory(path)
    FD->>FS: Enumerate files & subdirs
    loop per-file retries
        FD->>FS: Remove read-only attribute (if set)
        FD->>FS: Attempt file delete
        alt delete succeeds
            FS-->>FD: file removed
        else retryable failure
            FD-->>FS: wait retryDelay and retry
        else non-retryable failure
            FS-->>FD: failure
        end
    end
    FD->>FS: Delete empty subdirs (deep → shallow)
    FD->>FS: Delete root directory
    alt all deleted
        FS-->>FD: success
        FD-->>PC: return true
    else partial/failure
        FS-->>FD: partial/failure
        FD-->>PC: return false
    end

    alt deletion returned false
        PC->>DL: Create PluginDeleteFile marker (if missing)
        PC->>PA: LogWarn about deferred deletion
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Possibly related PRs

Suggested reviewers

  • jjw24
  • taooceros
  • VictoriousRaptor
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: introducing robust directory deletion for incomplete plugin uninstalls.
Description check ✅ Passed The description clearly relates to the changeset, detailing the robust deletion feature, integration into plugin uninstall logic, and test coverage.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

No actionable comments were generated in the recent review. 🎉


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request enhances plugin directory deletion in Flow Launcher by introducing a robust deletion mechanism that handles locked and read-only files more gracefully. The changes ensure that incomplete deletions are retried on subsequent application startups.

Changes:

  • Added TryDeleteDirectoryRobust method with retry logic for handling locked/read-only files during deletion
  • Updated plugin configuration to use the new robust deletion method and implement marker file recreation for retry logic
  • Added comprehensive unit tests covering various deletion scenarios

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs Implements new TryDeleteDirectoryRobust method with retry logic and read-only file handling
Flow.Launcher.Core/Plugin/PluginConfig.cs Updates deletion logic to use robust method, adds marker file recreation and warning logging for incomplete deletions
Flow.Launcher.Test/FilesFoldersTest.cs Adds unit tests for various deletion scenarios including empty directories, files, nested structures, and read-only files

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

@cubic-dev-ai cubic-dev-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.

1 issue found across 3 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs">

<violation number="1" location="Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs:209">
P2: `Directory.Delete` will throw an `IOException` if the directory itself is marked ReadOnly. The current implementation clears the ReadOnly attribute for files but not for directories. If a directory is ReadOnly, this method will permanently fail to delete it, causing infinite retries on subsequent startups.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Jack251970 and others added 2 commits February 7, 2026 18:31
Simplified the warning log when a directory is not fully deleted, removing extra details about remaining files and retrying deletion. Marker file recreation logic is unchanged.
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@Flow.Launcher.Core/Plugin/PluginManager.cs`:
- Around line 934-944: The log message in the catch for deleting the plugin
marker file uses a duplicated word ("Failed to delete delete mark file"); update
the message to something like "Failed to delete marker file" and include the
plugin path for diagnostics; modify the PublicApi.Instance.LogException call in
the try/catch around File.Delete (referencing ClassName, markerFilePath,
newPluginPath and DataLocation.PluginDeleteFile) to log the corrected message
and append newPluginPath (or markerFilePath) so the exception includes the
file/path context.

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@github-actions

This comment has been minimized.

@github-actions
Copy link

github-actions bot commented Feb 9, 2026

@check-spelling-bot Report

🔴 Please review

See the 📂 files view, the 📜action log, or 📝 job summary for details.

❌ Errors and Warnings Count
❌ forbidden-pattern 1
⚠️ non-alpha-in-dictionary 2

See ❌ Event descriptions for more information.

Forbidden patterns 🙅 (1)

In order to address this, you could change the content to not match the forbidden patterns (comments before forbidden patterns may help explain why they're forbidden), add patterns for acceptable instances, or adjust the forbidden patterns themselves.

These forbidden patterns matched content:

Pattern

\b[Nn]o[nt][- ]existent\b
If the flagged items are 🤯 false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it,
    try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants