Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

feat: remove psutil#305

Merged
NSPC911 merged 3 commits into
masterNSPC911/rovr:masterfrom
anti-psutilNSPC911/rovr:anti-psutilCopy head branch name to clipboard
Jul 13, 2026
Merged

feat: remove psutil#305
NSPC911 merged 3 commits into
masterNSPC911/rovr:masterfrom
anti-psutilNSPC911/rovr:anti-psutilCopy head branch name to clipboard

Conversation

@NSPC911

@NSPC911 NSPC911 commented Jul 13, 2026

Copy link
Copy Markdown
Owner

woah 1 less dependency for 1 more dependency??


by submitting this pull request, i agree that

  • i have run poe check to check for any style issues and fixed them
  • i have tested rovr (and also ran poe test if applicable) to make sure my changes do not break anything
  • cache, logs, dotfiles and/or others were not accidentally added to git's tracking history
  • my commits (or at least the pr title) follow the conventional commits format as much as possible
  • the documentation has been updated wherever necessary (run poe gen-schema and poe gen-keys if applicable)

Summary by Sourcery

Replace psutil-based drive detection with platform-specific implementations and update dependencies and tests accordingly.

New Features:

  • Add platform-specific helpers for detecting mounted drives on Windows, Linux, and other POSIX systems.

Bug Fixes:

  • Ensure Linux drive discovery filters pseudo and non-physical filesystems and correctly decodes escaped mount paths.
  • Improve robustness of mounted drive detection by falling back between Linux and generic POSIX strategies on errors.

Enhancements:

  • Apply drive exclusion patterns to the resolved list of mounted drives using existing configuration.
  • Normalize all detected drive paths and validate they are directories before returning.

Build:

  • Remove psutil from the project dependencies.

Tests:

  • Add unit tests for path normalisation, platform-specific drive detection helpers, and drive exclusion and fallback behavior in get_mounted_drives.

Summary by CodeRabbit

  • Bug Fixes
    • Improved mounted-drive detection across Windows, Linux, and macOS-like systems.
    • Better handling of escaped mount paths and more reliable filtering of candidate mount points.
    • Stronger fallback behaviour when standard Linux mount information is unavailable.
  • Compatibility
    • Removed an unnecessary system dependency to improve Android compatibility.
  • Tests
    • Added comprehensive platform-specific tests covering drive discovery, exclusions, path normalisation, and fallback scenarios.

woah 1 less dependency for 1 more dependency??
@sourcery-ai

sourcery-ai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Reviewer's Guide

This PR removes the psutil dependency and reimplements mounted-drive discovery per-OS using standard libraries and system interfaces, adding unit tests around the new drive discovery logic.

File-Level Changes

Change Details Files
Reimplement mounted drive discovery without psutil using OS-specific helpers and standard/system APIs.
  • Introduce _get_windows_drives using ctypes.GetLogicalDrives bitmask to enumerate drive letters.
  • Introduce _get_linux_drives that parses /proc/filesystems and /proc/mounts, filtering pseudo and non-physical filesystems and decoding octal escapes in mountpoints.
  • Introduce _get_posix_drives that shells out to df -P and filters only /dev/* devices, handling multi-word mountpoints.
  • Refactor get_mounted_drives to select the appropriate helper per os_type, add Linux fallback to POSIX helpers on OSError, and normalise only existing directories.
src/rovr/functions/drive_workers.py
Remove psutil from project dependencies and add tests for drive discovery behaviour.
  • Drop psutil from pyproject.toml dependencies list.
  • Add unit tests for normalise, _get_linux_drives, _get_posix_drives, _get_windows_drives, and get_mounted_drives including exclude-pattern handling and fallbacks.
pyproject.toml
tests/test_drive_workers.py
uv.lock

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

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: cfe5d392-3d93-42e7-8c32-bfccd85ac356

📥 Commits

Reviewing files that changed from the base of the PR and between 6e2b97b and 3dbf969.

📒 Files selected for processing (1)
  • tests/test_drive_workers.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/test_drive_workers.py
📜 Recent review details
⏰ Context from checks skipped due to timeout. (14)
  • GitHub Check: Test on (windows-x64, Python 3.14)
  • GitHub Check: Test on (windows-x64, Python 3.13)
  • GitHub Check: Test on (windows-arm, Python 3.14)
  • GitHub Check: Test on (macos-arm64, Python 3.13)
  • GitHub Check: Test on (windows-arm, Python 3.13)
  • GitHub Check: Test on (macos-x64, Python 3.14)
  • GitHub Check: Test on (macos-x64, Python 3.13)
  • GitHub Check: format_and_alert
  • GitHub Check: Test on (windows-x64, Python 3.14)
  • GitHub Check: Test on (windows-arm, Python 3.14)
  • GitHub Check: Test on (windows-x64, Python 3.13)
  • GitHub Check: Test on (windows-arm, Python 3.13)
  • GitHub Check: Test on (linux-x64, Python 3.13)
  • GitHub Check: format_and_push_changes

📝 Walkthrough

Walkthrough

Changes

Drive discovery

Layer / File(s) Summary
Platform-specific drive probing
pyproject.toml, src/rovr/functions/drive_workers.py, tests/test_drive_workers.py
The psutil dependency is removed; Windows, Linux, and POSIX mount discovery helpers are added with tests for parsing, filtering, and path normalisation.
Drive aggregation and fallback
src/rovr/functions/drive_workers.py, tests/test_drive_workers.py
get_mounted_drives normalises existing mountpoints, applies exclusion patterns, and tests POSIX and root-directory fallbacks for probe failures.

Estimated code review effort: 3 (Moderate) | ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main change: removing the psutil dependency.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="tests/test_drive_workers.py" line_range="85-94" />
<code_context>
+    assert drives == ["A:/", "C:/"]
+
+
+def test_get_mounted_drives_applies_exclude_patterns(
+    monkeypatch: pytest.MonkeyPatch,
+) -> None:
+    monkeypatch.setattr(drive_workers, "_get_posix_drives", lambda: ["/", "/mnt/usb"])
+    monkeypatch.setattr(drive_workers.path, "isdir", lambda p: True)
+
+    config = cast("RovrConfig", {"settings": {"drive_exclude": ["/mnt/*"]}})
+    drives = drive_workers.get_mounted_drives("Darwin", config)
+
+    assert drives == ["/"]
+
+
</code_context>
<issue_to_address>
**suggestion (testing):** Add coverage for path.isdir filtering in get_mounted_drives to ensure non-directory mountpoints are excluded.

The current tests patch `path.isdir` to always return `True`, so the directory filtering in `get_mounted_drives` is not actually validated. Please add a test where `_get_posix_drives`/`_get_linux_drives` returns both directory and non-directory mountpoints, and `path.isdir` is patched to return `False` for the invalid ones. This will verify that non-directory entries are excluded and protect against regressions in that logic.

Suggested implementation:

```python
from typing import cast

import pytest

from rovr.classes.config import RovrConfig
from rovr.functions import drive_workers

```

```python
@pytest.fixture
def config() -> RovrConfig:
    return cast("RovrConfig", {"settings": {"drive_exclude": []}})


def test_get_mounted_drives_filters_non_directory_posix_mounts(
    monkeypatch: pytest.MonkeyPatch,
    config: RovrConfig,
) -> None:
    """
    Ensure get_mounted_drives filters out mountpoints that are not directories
    on POSIX-like systems.
    """
    # Mix of directory and non-directory mountpoints
    monkeypatch.setattr(
        drive_workers,
        "_get_posix_drives",
        lambda: ["/", "/mnt/usb", "/not_a_directory"],
    )

    def fake_isdir(path: str) -> bool:
        # Treat "/not_a_directory" as a non-directory mountpoint
        return path != "/not_a_directory"

    monkeypatch.setattr(drive_workers.path, "isdir", fake_isdir)

    drives = drive_workers.get_mounted_drives("Darwin", config)

    assert drives == ["/", "/mnt/usb"]


def test_get_mounted_drives_filters_non_directory_linux_mounts(
    monkeypatch: pytest.MonkeyPatch,
    config: RovrConfig,
) -> None:
    """
    Ensure get_mounted_drives filters out mountpoints that are not directories
    on Linux.
    """
    monkeypatch.setattr(
        drive_workers,
        "_get_linux_drives",
        lambda: ["/", "/media/usb", "/proc", "/not_a_directory"],
    )

    def fake_isdir(path: str) -> bool:
        # Simulate "/not_a_directory" being invalid
        return path != "/not_a_directory"

    monkeypatch.setattr(drive_workers.path, "isdir", fake_isdir)

    drives = drive_workers.get_mounted_drives("Linux", config)

    assert drives == ["/", "/media/usb", "/proc"]

```
</issue_to_address>

### Comment 2
<location path="tests/test_drive_workers.py" line_range="110-119" />
<code_context>
+    assert drives == ["/"]
+
+
+def test_get_mounted_drives_linux_falls_back_to_posix_on_oserror(
+    monkeypatch: pytest.MonkeyPatch, config: RovrConfig
+) -> None:
+    monkeypatch.setattr(
+        drive_workers,
+        "_get_linux_drives",
+        lambda: (_ for _ in ()).throw(OSError("no procfs")),
+    )
+    monkeypatch.setattr(drive_workers, "_get_posix_drives", lambda: ["/data"])
+    monkeypatch.setattr(drive_workers.path, "isdir", lambda p: True)
+
+    drives = drive_workers.get_mounted_drives("Linux", config)
+
+    assert drives == ["/data"]
</code_context>
<issue_to_address>
**suggestion (testing):** There is no test for get_mounted_drives behavior on Windows, only for the Windows helper.

Please add a test that calls `get_mounted_drives("Windows", config)` directly, with `_get_windows_drives` patched to return a mix of drive letters. The test should assert that the function normalises drive paths correctly and respects `path.isdir` and any exclusion patterns, so the Windows integration path is covered end-to-end.

Suggested implementation:

```python
def test_get_mounted_drives_linux_falls_back_to_posix_on_oserror(
    monkeypatch: pytest.MonkeyPatch, config: RovrConfig
) -> None:
    monkeypatch.setattr(
        drive_workers,
        "_get_linux_drives",
        lambda: (_ for _ in ()).throw(OSError("no procfs")),
    )
    monkeypatch.setattr(drive_workers, "_get_posix_drives", lambda: ["/data"])
    monkeypatch.setattr(drive_workers.path, "isdir", lambda p: True)

    drives = drive_workers.get_mounted_drives("Linux", config)

    assert drives == ["/data"]


def test_get_mounted_drives_windows_normalises_and_applies_exclusions(
    monkeypatch: pytest.MonkeyPatch,
    config: RovrConfig,
) -> None:
    # Return a mix of drive specifications, some missing trailing slashes
    # and one that should be excluded via config.
    monkeypatch.setattr(
        drive_workers,
        "_get_windows_drives",
        lambda: ["C:", "D:\\", "E:\\Data", "F:", "G:\\"],
    )

    # Only some of the normalised drives should be considered "mounted".
    def fake_isdir(path_str: str) -> bool:
        # Expect get_mounted_drives to normalise to full root paths (with backslash)
        # and preserve subdirectory paths where appropriate.
        return path_str in {"C:\\", "D:\\", "E:\\Data"}

    monkeypatch.setattr(drive_workers.path, "isdir", fake_isdir)

    # Configure an exclusion pattern so that the E:\Data drive is filtered out,
    # even though path.isdir returns True for it.
    # Adjust this attribute name/pattern to match the real RovrConfig interface.
    config.drive_exclusion_patterns = [r"^E:\\Data$"]

    drives = drive_workers.get_mounted_drives("Windows", config)

    # C and D are mounted and not excluded; E:\Data is mounted but excluded;
    # F and G are not mounted (fake_isdir returns False after normalisation).
    assert drives == ["C:\\", "D:\\"]

```

The new Windows integration test assumes:
1. `get_mounted_drives("Windows", config)` normalises drive roots to include a trailing backslash (e.g. `"C:"``"C:\\"`).
2. `RovrConfig` exposes a `drive_exclusion_patterns` attribute that is consulted by `get_mounted_drives` to filter out matches. If your config uses a different attribute name or semantics (e.g. `exclude_paths`, `windows_drive_exclusions`, etc.), update the test to set the correct field and pattern.
3. The exclusion logic operates on the already-normalised drive path strings; if it currently matches raw drive strings from `_get_windows_drives`, you may want to adjust either the implementation or the test so they align.
</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.

Comment on lines +85 to +94
def test_get_mounted_drives_applies_exclude_patterns(
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setattr(drive_workers, "_get_posix_drives", lambda: ["/", "/mnt/usb"])
monkeypatch.setattr(drive_workers.path, "isdir", lambda p: True)

config = cast("RovrConfig", {"settings": {"drive_exclude": ["/mnt/*"]}})
drives = drive_workers.get_mounted_drives("Darwin", config)

assert drives == ["/"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

suggestion (testing): Add coverage for path.isdir filtering in get_mounted_drives to ensure non-directory mountpoints are excluded.

The current tests patch path.isdir to always return True, so the directory filtering in get_mounted_drives is not actually validated. Please add a test where _get_posix_drives/_get_linux_drives returns both directory and non-directory mountpoints, and path.isdir is patched to return False for the invalid ones. This will verify that non-directory entries are excluded and protect against regressions in that logic.

Suggested implementation:

from typing import cast

import pytest

from rovr.classes.config import RovrConfig
from rovr.functions import drive_workers
@pytest.fixture
def config() -> RovrConfig:
    return cast("RovrConfig", {"settings": {"drive_exclude": []}})


def test_get_mounted_drives_filters_non_directory_posix_mounts(
    monkeypatch: pytest.MonkeyPatch,
    config: RovrConfig,
) -> None:
    """
    Ensure get_mounted_drives filters out mountpoints that are not directories
    on POSIX-like systems.
    """
    # Mix of directory and non-directory mountpoints
    monkeypatch.setattr(
        drive_workers,
        "_get_posix_drives",
        lambda: ["/", "/mnt/usb", "/not_a_directory"],
    )

    def fake_isdir(path: str) -> bool:
        # Treat "/not_a_directory" as a non-directory mountpoint
        return path != "/not_a_directory"

    monkeypatch.setattr(drive_workers.path, "isdir", fake_isdir)

    drives = drive_workers.get_mounted_drives("Darwin", config)

    assert drives == ["/", "/mnt/usb"]


def test_get_mounted_drives_filters_non_directory_linux_mounts(
    monkeypatch: pytest.MonkeyPatch,
    config: RovrConfig,
) -> None:
    """
    Ensure get_mounted_drives filters out mountpoints that are not directories
    on Linux.
    """
    monkeypatch.setattr(
        drive_workers,
        "_get_linux_drives",
        lambda: ["/", "/media/usb", "/proc", "/not_a_directory"],
    )

    def fake_isdir(path: str) -> bool:
        # Simulate "/not_a_directory" being invalid
        return path != "/not_a_directory"

    monkeypatch.setattr(drive_workers.path, "isdir", fake_isdir)

    drives = drive_workers.get_mounted_drives("Linux", config)

    assert drives == ["/", "/media/usb", "/proc"]

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Is it even possible for a mountpoint to be a file?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Short answer: in normal, well-behaved systems, mountpoints are directories – that’s what mount(2) expects, and what /proc/mounts and df report. A regular file as a mountpoint is effectively “misconfigured” and outside typical POSIX semantics.

So you’re right to be skeptical: under ordinary circumstances, you shouldn’t see file paths in the mountpoint column.

Why the isdir check still exists:

  • It’s defensive: we’re parsing text from /proc/mounts or df output. If that parsing ever regressed (e.g. bad splitting, unescaped spaces, odd platform quirk), we could end up with a bogus path.
  • It also guards against things like:
    • A mountpoint path that no longer exists (removed after mount, or stale record).
    • Symlinks or strange FUSE setups that resolve to something unexpected.

In other words, the filtering is not really about “real” filesystems mounting on regular files, but about making sure we only return paths that are currently directories on the local filesystem.

Given that, the tests I suggested are less about modeling a realistic OS state, and more about verifying that this defensive guard does what we expect if it ever needs to kick in. If you feel that’s too hypothetical, an alternative is:

  • Keep the isdir check in code (it’s cheap and safe), but
  • Add a single focused test that mocks _get_posix_drives / _get_linux_drives to return an obviously bogus path, and asserts that it’s filtered out.

I’m happy to propose a more minimal test variant if you’d prefer to avoid over-specifying unrealistic scenarios.

Comment on lines +110 to +119
def test_get_mounted_drives_linux_falls_back_to_posix_on_oserror(
monkeypatch: pytest.MonkeyPatch, config: RovrConfig
) -> None:
monkeypatch.setattr(
drive_workers,
"_get_linux_drives",
lambda: (_ for _ in ()).throw(OSError("no procfs")),
)
monkeypatch.setattr(drive_workers, "_get_posix_drives", lambda: ["/data"])
monkeypatch.setattr(drive_workers.path, "isdir", lambda p: True)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

suggestion (testing): There is no test for get_mounted_drives behavior on Windows, only for the Windows helper.

Please add a test that calls get_mounted_drives("Windows", config) directly, with _get_windows_drives patched to return a mix of drive letters. The test should assert that the function normalises drive paths correctly and respects path.isdir and any exclusion patterns, so the Windows integration path is covered end-to-end.

Suggested implementation:

def test_get_mounted_drives_linux_falls_back_to_posix_on_oserror(
    monkeypatch: pytest.MonkeyPatch, config: RovrConfig
) -> None:
    monkeypatch.setattr(
        drive_workers,
        "_get_linux_drives",
        lambda: (_ for _ in ()).throw(OSError("no procfs")),
    )
    monkeypatch.setattr(drive_workers, "_get_posix_drives", lambda: ["/data"])
    monkeypatch.setattr(drive_workers.path, "isdir", lambda p: True)

    drives = drive_workers.get_mounted_drives("Linux", config)

    assert drives == ["/data"]


def test_get_mounted_drives_windows_normalises_and_applies_exclusions(
    monkeypatch: pytest.MonkeyPatch,
    config: RovrConfig,
) -> None:
    # Return a mix of drive specifications, some missing trailing slashes
    # and one that should be excluded via config.
    monkeypatch.setattr(
        drive_workers,
        "_get_windows_drives",
        lambda: ["C:", "D:\\", "E:\\Data", "F:", "G:\\"],
    )

    # Only some of the normalised drives should be considered "mounted".
    def fake_isdir(path_str: str) -> bool:
        # Expect get_mounted_drives to normalise to full root paths (with backslash)
        # and preserve subdirectory paths where appropriate.
        return path_str in {"C:\\", "D:\\", "E:\\Data"}

    monkeypatch.setattr(drive_workers.path, "isdir", fake_isdir)

    # Configure an exclusion pattern so that the E:\Data drive is filtered out,
    # even though path.isdir returns True for it.
    # Adjust this attribute name/pattern to match the real RovrConfig interface.
    config.drive_exclusion_patterns = [r"^E:\\Data$"]

    drives = drive_workers.get_mounted_drives("Windows", config)

    # C and D are mounted and not excluded; E:\Data is mounted but excluded;
    # F and G are not mounted (fake_isdir returns False after normalisation).
    assert drives == ["C:\\", "D:\\"]

The new Windows integration test assumes:

  1. get_mounted_drives("Windows", config) normalises drive roots to include a trailing backslash (e.g. "C:""C:\\").
  2. RovrConfig exposes a drive_exclusion_patterns attribute that is consulted by get_mounted_drives to filter out matches. If your config uses a different attribute name or semantics (e.g. exclude_paths, windows_drive_exclusions, etc.), update the test to set the correct field and pattern.
  3. The exclusion logic operates on the already-normalised drive path strings; if it currently matches raw drive strings from _get_windows_drives, you may want to adjust either the implementation or the test so they align.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/rovr/functions/drive_workers.py (1)

90-106: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Docstring is stale relative to the new per-OS branching.

The Args docs still describe os_type as "Windows", "Darwin", or other, but the changed logic now special-cases "Linux" with its own OSError→POSIX fallback (lines 100-104). Worth updating the docstring so the Linux-specific fallback contract is documented for future maintainers.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/rovr/functions/drive_workers.py` around lines 90 - 106, Update the
docstring for the function containing the raw drive selection logic to document
that os_type explicitly supports Windows, Linux, and other values, and that
Linux falls back to POSIX drive detection when _get_linux_drives raises OSError.
Keep the existing behavior unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/rovr/functions/drive_workers.py`:
- Around line 69-83: The direct df invocation in _get_posix_drives must not
block indefinitely. Add a finite timeout to the subprocess.run call used by
_get_posix_drives, preserving its existing output capture, text mode, and check
behavior.

---

Nitpick comments:
In `@src/rovr/functions/drive_workers.py`:
- Around line 90-106: Update the docstring for the function containing the raw
drive selection logic to document that os_type explicitly supports Windows,
Linux, and other values, and that Linux falls back to POSIX drive detection when
_get_linux_drives raises OSError. Keep the existing behavior unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0d55c523-9bfe-4a10-a789-480cf0644100

📥 Commits

Reviewing files that changed from the base of the PR and between 0280cd2 and ea01822.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • pyproject.toml
  • src/rovr/functions/drive_workers.py
  • tests/test_drive_workers.py
💤 Files with no reviewable changes (1)
  • pyproject.toml
📜 Review details
⏰ Context from checks skipped due to timeout. (7)
  • GitHub Check: Sourcery review
  • GitHub Check: Test on (windows-arm, Python 3.14)
  • GitHub Check: Test on (macos-x64, Python 3.14)
  • GitHub Check: Test on (windows-arm, Python 3.13)
  • GitHub Check: Test on (windows-x64, Python 3.14)
  • GitHub Check: Test on (macos-x64, Python 3.13)
  • GitHub Check: Test on (windows-x64, Python 3.13)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Use Python 3.12+ for all Python source files in this project.
Use double quotes (") in Python source files.
Use 4-space indentation in Python source files.
Use ruff as the formatter for Python code; do not use Black.
Use absolute imports only in Python files; do not use relative imports.
All Python functions must have type annotations; use ty for type checking.
Do not use if TYPE_CHECKING blocks for imports.
Use the project naming conventions in Python code: CamelCase for classes, snake_case for functions and variables, UPPER_CASE for constants, and _ prefixes for private names.
Use specific exceptions in Python code; do not use bare except: blocks.
Use contextlib.suppress for expected errors in Python code.

Files:

  • src/rovr/functions/drive_workers.py
  • tests/test_drive_workers.py
src/rovr/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

In Textual-related Python code, inherit from Textual widgets with inherit_bindings=False for custom keybindings; use @on(EventType) or on_event for event handling; use @work for async background work (with thread=True for blocking tasks); use compose() for widget composition; and use call_from_thread/call_next/call_later/call_after_refresh for thread-driven widget updates.

Files:

  • src/rovr/functions/drive_workers.py
🧠 Learnings (8)
📚 Learning: 2025-12-11T03:10:54.344Z
Learnt from: NSPC911
Repo: NSPC911/rovr PR: 167
File: src/rovr/footer/process_container.py:346-346
Timestamp: 2025-12-11T03:10:54.344Z
Learning: In Python/Textual code, when calling checker_wrapper() or any other method that starts workers from within a work(thread=True) decorated method, do not wrap the call in call_from_thread. Starting workers is thread-safe in Textual and the work decorator handles threading. Only UI updates (e.g., DOM modifications) from worker threads require call_from_thread. Apply this guideline to Python files across the codebase where worker-start calls occur; do not wrap such calls with call_from_thread.

Applied to files:

  • src/rovr/functions/drive_workers.py
  • tests/test_drive_workers.py
📚 Learning: 2026-01-24T02:10:57.940Z
Learnt from: NSPC911
Repo: NSPC911/rovr PR: 203
File: src/rovr/first_launch.py:273-295
Timestamp: 2026-01-24T02:10:57.940Z
Learning: In the rovr codebase (Python/Textual), App.notify() is thread-safe and may be called directly from worker threads decorated with work(thread=True) without wrapping in call_from_thread(). Only DOM modifications require call_from_thread from worker threads. Apply this guideline to Python files across the codebase (not just a single file) and avoid unnecessary call_from_thread() wrappers when invoking App.notify() from worker threads.

Applied to files:

  • src/rovr/functions/drive_workers.py
  • tests/test_drive_workers.py
📚 Learning: 2026-01-30T13:54:15.110Z
Learnt from: NSPC911
Repo: NSPC911/rovr PR: 207
File: src/rovr/first_launch.py:96-107
Timestamp: 2026-01-30T13:54:15.110Z
Learning: In Python projects using the Textual framework, async workers decorated with work are automatically cancelled when the parent screen/widget is dismissed or unmounted. Do not add manual cancellation in cleanup/dismiss handlers for these workers; rely on Textual to cancel them. Verify this behavior against the project’s Textual version before relying on it.

Applied to files:

  • src/rovr/functions/drive_workers.py
  • tests/test_drive_workers.py
📚 Learning: 2026-02-27T09:15:49.243Z
Learnt from: NSPC911
Repo: NSPC911/rovr PR: 229
File: src/rovr/functions/system_clipboard.py:143-143
Timestamp: 2026-02-27T09:15:49.243Z
Learning: In Python files that display error messages in toast/notification UI (e.g., ClipboardError and similar exceptions), escape unescaped square brackets in the message so the toast system does not interpret them as markup. Specifically render the content with double backslashes before brackets, e.g. "\\[{type(exc).__name__}]" in the toast description. This guideline applies to all Python files that format and show exception details in toasts across the codebase.

Applied to files:

  • src/rovr/functions/drive_workers.py
  • tests/test_drive_workers.py
📚 Learning: 2025-12-11T03:11:24.387Z
Learnt from: NSPC911
Repo: NSPC911/rovr PR: 167
File: src/rovr/screens/fd_search.py:205-209
Timestamp: 2025-12-11T03:11:24.387Z
Learning: In src/rovr/screens/fd_search.py, FileSearch.FILTER_TYPES should be implemented as a class attribute (not an instance attribute) to persist filter state across all modal instances within the same session. This enables remember/restore of filter settings when the modal is dismissed and reopened. Ensure this behavior is intentional, document the session lifecycle implications, and include tests verifying persistence across modal reopenings, as well as proper reset or isolation when a new session starts. If applicable, consider thread-safety and potential memory growth due to long-lived state.

Applied to files:

  • src/rovr/functions/drive_workers.py
📚 Learning: 2025-12-11T03:11:27.833Z
Learnt from: NSPC911
Repo: NSPC911/rovr PR: 167
File: src/rovr/screens/fd_search.py:205-209
Timestamp: 2025-12-11T03:11:27.833Z
Learning: In src/rovr/screens/fd_search.py, document that the FileSearch class uses a class-level FILTER_TYPES dict to persist filter settings across multiple modal invocations within a single application session. Ensure this pattern is intentional by clarifying the lifecycle of the shared state (lifetime of the process/session) and the implications of mutable shared state (thread-safety, potential memory retention). Consider alternatives (per-instance state, dedicated session storage, explicit reset method) and add tests to verify persistence, correctness after modal reopenings, and safe reset behavior. Also mention any framework or runtime constraints that affect shared-class state.

Applied to files:

  • src/rovr/functions/drive_workers.py
📚 Learning: 2026-01-03T14:17:18.132Z
Learnt from: lazysegtree
Repo: NSPC911/rovr PR: 184
File: src/rovr/core/preview_container.py:280-283
Timestamp: 2026-01-03T14:17:18.132Z
Learning: In src/rovr/core/preview_container.py, mypy may not recognize that pdfinfo_from_path's poppler_path parameter accepts None even though the library signature is Optional[Union[str, pathlib.PurePath]]. If you encounter a type error, explicitly cast the argument to Optional[Union[str, pathlib.PurePath]] before passing it (e.g., from typing import cast; pdfinfo_from_path(path, poppler_path=cast(Optional[Union[str, pathlib.PurePath]], None)) or cast the argument to the expected type). This documents the typing limitation and provides a repeatable workaround for similar cases.

Applied to files:

  • src/rovr/functions/drive_workers.py
📚 Learning: 2026-03-01T10:35:17.682Z
Learnt from: NSPC911
Repo: NSPC911/rovr PR: 233
File: tests/test_functions_path.py:21-21
Timestamp: 2026-03-01T10:35:17.682Z
Learning: In Python test files (using the Textual framework), use an assertion like Static(id=val, classes=val) to verify that the value contains only characters valid for Textual IDs and classes. The test should confirm initialization succeeds without raising BadIdentifier (do not test attribute storage). This pattern is applicable to tests that validate Textual-compatible identifier strings returned by utilities (e.g., compress/decompress). Apply this guideline to test files under the tests/ directory (e.g., tests/**/*.py) where relevant.

Applied to files:

  • tests/test_drive_workers.py
🪛 ast-grep (0.44.1)
src/rovr/functions/drive_workers.py

[error] 71-71: Command coming from incoming request
Context: subprocess.run(["df", "-P"], capture_output=True, text=True, check=True)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(subprocess-from-request)

🔇 Additional comments (4)
src/rovr/functions/drive_workers.py (3)

4-12: LGTM!


35-66: LGTM!

Verified _get_windows_drives and _get_linux_drives against the corresponding tests (bitmask decoding, /proc/filesystems "nodev" filtering with the zfs/btrfs special-case, and octal-escape unmangling) — behaviour matches exactly.


107-107: LGTM!

Confirmed the dispatch/fallback chain (Windows_get_windows_drives, Linux_get_linux_drives with OSError fallback to _get_posix_drives, else → _get_posix_drives, then normalise+isdir filtering) matches all five get_mounted_drives tests exactly.

tests/test_drive_workers.py (1)

1-124: LGTM!

Solid coverage of the new platform-specific helpers and the aggregation/fallback logic in get_mounted_drives, including the Linux OSError→POSIX fallback path.

Comment thread src/rovr/functions/drive_workers.py
@NSPC911
NSPC911 merged commit 8c68c6f into master Jul 13, 2026
32 checks passed
@NSPC911
NSPC911 deleted the anti-psutil branch July 13, 2026 09:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Morty Proxy This is a proxified and sanitized view of the page, visit original site.