Adding Arch pakage manager support#80
Conversation
Greptile SummaryThis PR extends
Confidence Score: 4/5The 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
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 ✓"]
Reviews (1): Last reviewed commit: "Linting" | Re-trigger Greptile |
| 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 |
There was a problem hiding this comment.
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.
| 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 |
There was a problem hiding this comment.
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".
| 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 |
Using the piper robot on arch,
dpkgthrows an error as it in not installed and the default package manager ispacman. I added the support for thepacmanpakage manager and the code enables the possibility to add other pakage manager with the shutil check to ensureethtoolandcan-utilsare installed.