Skip to content

Adding Arch pakage manager support#80

Open
PrLeoTournesol wants to merge 2 commits into
Reimagine-Robotics:mainfrom
PrLeoTournesol:pacman-support
Open

Adding Arch pakage manager support#80
PrLeoTournesol wants to merge 2 commits into
Reimagine-Robotics:mainfrom
PrLeoTournesol:pacman-support

Conversation

@PrLeoTournesol

Copy link
Copy Markdown

Using the piper robot on arch, dpkg throws an error as it in not installed and the default package manager is pacman. I added the support for the pacman pakage manager and the code enables the possibility to add other pakage manager with the shutil check to ensure ethtool and can-utils are installed.

@greptile-apps

greptile-apps Bot commented May 22, 2026

Copy link
Copy Markdown

Greptile Summary

This PR extends _check_dependencies() in piper_connect.py to detect the system package manager via shutil.which before checking for ethtool and can-utils, adding explicit support for Arch Linux (pacman) alongside the existing Debian/Ubuntu (dpkg/apt) path.

  • Package manager detection now uses shutil.which(\"pacman\") / shutil.which(\"dpkg\") with a descriptive RuntimeError for unsupported systems, making the check portable across distributions.
  • A backslash line-continuation inside the new f-string error message preserves all leading whitespace from the next line, producing a garbled message with a long run of spaces; splitting into two adjacent f-string literals fixes this.
  • subprocess.run() can raise FileNotFoundError (not CalledProcessError) if the executable is missing at call time, which the current except clause will not catch.

Confidence Score: 4/5

The change is straightforward and the core logic is correct; the two issues are a cosmetic error-message defect and a narrow edge-case gap in exception handling.

The package-manager detection via shutil.which is sound and the pacman/dpkg branching is correct. The backslash line-continuation bug produces a malformed error message but does not affect the detection or installation-check logic. The uncaught FileNotFoundError path is a real gap but requires an unusual runtime condition to trigger.

src/piper_control/piper_connect.py — specifically the new error-message f-string and the except clause around subprocess.run.

Important Files Changed

Filename Overview
src/piper_control/piper_connect.py Adds pacman/Arch Linux support to _check_dependencies() via shutil.which-based detection; introduces a minor error-message formatting issue (backslash line continuation leaves excess whitespace) and does not handle FileNotFoundError from subprocess.run.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["_check_dependencies() called"] --> B{"shutil.which('pacman')?"}
    B -- Yes --> C["query_cmd = pacman -Q\ninstall_cmd = sudo pacman -S"]
    B -- No --> D{"shutil.which('dpkg')?"}
    D -- Yes --> E["query_cmd = dpkg -s\ninstall_cmd = sudo apt install"]
    D -- No --> F["raise RuntimeError\n(Unsupported package manager)"]
    C --> G["For pkg in ethtool, can-utils"]
    E --> G
    G --> H["subprocess.run(query_cmd(pkg))"]
    H -- "exit 0" --> I{"More packages?"}
    H -- "CalledProcessError" --> J["raise RuntimeError\n(Missing dependency: pkg)"]
    H -- "FileNotFoundError\n(not caught!)" --> K["Unhandled exception propagates"]
    I -- Yes --> G
    I -- No --> L["Dependencies OK ✓"]
Loading

Fix All in Claude Code Fix All in Codex

Reviews (1): Last reviewed commit: "Linting" | Re-trigger Greptile

Comment on lines +124 to 134
subprocess.run(
query_cmd(pkg),
check=True,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
except subprocess.CalledProcessError as exc:
raise RuntimeError(
f"Missing dependency: {pkg}. Please install with `sudo apt install "
f"{pkg}`."
f"Missing dependency: {pkg}. \
Please install with `{install_cmd} {pkg}`."
) from exc

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Unhandled FileNotFoundError from subprocess.run

subprocess.run() raises FileNotFoundError (a subclass of OSError, not CalledProcessError) when the executable itself cannot be found — e.g. if pacman or dpkg disappears between the shutil.which() call and the subprocess.run() call, or if PATH is altered by the time the process is spawned. This exception is not caught by the current except subprocess.CalledProcessError handler and will propagate as an unhandled error with a confusing message unrelated to the missing dependency.

Fix in Claude Code Fix in Codex

Comment on lines 131 to 134
raise RuntimeError(
f"Missing dependency: {pkg}. Please install with `sudo apt install "
f"{pkg}`."
f"Missing dependency: {pkg}. \
Please install with `{install_cmd} {pkg}`."
) from exc

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 The backslash line-continuation inside the f-string does not strip leading whitespace from the next physical line — it simply removes the newline character, leaving all the indentation spaces intact. The resulting error message will read something like "Missing dependency: ethtool. Please install with …" with a large gap of spaces between the period and "Please".

Suggested change
raise RuntimeError(
f"Missing dependency: {pkg}. Please install with `sudo apt install "
f"{pkg}`."
f"Missing dependency: {pkg}. \
Please install with `{install_cmd} {pkg}`."
) from exc
raise RuntimeError(
f"Missing dependency: {pkg}. "
f"Please install with `{install_cmd} {pkg}`."
) from exc

Fix in Claude Code Fix in Codex

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