Skip to content

Conversation

@QaidVoid
Copy link
Member

@QaidVoid QaidVoid commented Jan 15, 2026

Summary by CodeRabbit

  • New Features
    • Added global --system (-S) flag to manage system-wide packages
    • System-wide package management now requires root privileges with automatic privilege escalation

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 15, 2026

Warning

Rate limit exceeded

@QaidVoid has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 2 minutes and 33 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 5343341 and 770b7cc.

📒 Files selected for processing (1)
  • crates/soar-core/src/package/remove.rs
📝 Walkthrough

Walkthrough

This PR adds system-wide package management capability to soar by introducing a global system mode flag, a new --system CLI option, privilege escalation handling, and updates directory resolution functions to be system-mode aware across multiple crates.

Changes

Cohort / File(s) Summary
Dependency & CLI Setup
crates/soar-cli/Cargo.toml, crates/soar-cli/src/cli.rs
Added nix workspace dependency; introduced pub system: bool field with --system / -S global CLI flag for root privilege mode.
System Mode Configuration
crates/soar-config/src/config.rs
Added thread-safe SYSTEM_MODE lazy static, public accessors (is_system_mode(), enable_system_mode(), system_root()), and conditional SOAR_ROOT/CONFIG_PATH resolution based on system mode.
Main Entry Point
crates/soar-cli/src/main.rs
Added handle_system_mode() function for privilege escalation via doas/sudo; invoked at CLI startup when --system flag is set; re-exports enable_system_mode.
Path Utilities
crates/soar-utils/src/path.rs
Updated desktop_dir() and icons_dir() function signatures to accept system: bool parameter; returns system paths (/usr/local/share/{applications,icons/hicolor}) when true, user paths otherwise.
Package Operations
crates/soar-cli/src/health.rs, crates/soar-core/src/package/install.rs, crates/soar-core/src/package/remove.rs, crates/soar-core/src/utils.rs
Updated directory lookups to pass is_system_mode() to desktop_dir() and icons_dir() calls; adds system-aware path traversal.
Package Formats
crates/soar-package/src/formats/common.rs
Updated symlink path resolution to use icons_dir(is_system_mode()) and desktop_dir(is_system_mode()) instead of static lookups.

Sequence Diagram

sequenceDiagram
    participant User as User/CLI
    participant Main as main.rs
    participant Config as soar_config
    participant PkgOps as Package Ops
    participant Paths as Path Utils

    User->>Main: soar --system [args]
    Main->>Main: Check system flag (args.system)
    alt System flag set
        Main->>Main: handle_system_mode()
        Main->>Main: Check for root privileges
        alt Not root
            Main->>Main: Escalate with doas/sudo
            Main->>Main: Re-execute process
        end
    end
    Main->>Config: enable_system_mode()
    Config->>Config: Set SYSTEM_MODE = true
    Config->>Config: Update CONFIG_PATH to /etc/soar
    PkgOps->>Config: is_system_mode()
    Config-->>PkgOps: Returns true/false
    PkgOps->>Paths: desktop_dir(is_system_mode())
    Paths->>Paths: Return system or user path
    Paths-->>PkgOps: Path based on system mode
    PkgOps->>PkgOps: Process packages with system paths
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 A hoppy little tale of system-wide cheer:

With --system flag and privilege near,
The soar takes flight where /usr/local gleams,
Root access granted through doas dreams,
System packages now within our reach! 🚀

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(cli): add system-wide package management' clearly and concisely summarizes the main change: adding system-wide package management functionality to the CLI, which is the core objective reflected across all modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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


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.

@codecov
Copy link

codecov bot commented Jan 15, 2026

@QaidVoid
Copy link
Member Author

@coderabbitai

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 15, 2026

@QaidVoid: I'll review the changes in this PR.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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 `@crates/soar-core/src/package/remove.rs`:
- Line 12: CI failed rustfmt on the single-line import in remove.rs; reformat
the use statement for soar_utils so it conforms to rustfmt (either run cargo fmt
or expand the import across multiple lines) and ensure the identifiers
FileSystemResult, walk_dir, and the nested path items desktop_dir and icons_dir
are correctly grouped under soar_utils::path; keep the same imported symbols but
adjust spacing/line breaks to satisfy rustfmt.
🧹 Nitpick comments (3)
crates/soar-config/src/config.rs (2)

110-113: Consider documenting panic behavior for poisoned lock.

The .unwrap() on RwLock::read() is acceptable here since lock poisoning typically indicates a panic in another thread, which is a programming error. However, for a public API, consider adding a doc comment noting this behavior or using .expect() with a descriptive message for clearer debugging.

♻️ Optional: Add descriptive expect message
 pub fn is_system_mode() -> bool {
-    *SYSTEM_MODE.read().unwrap()
+    *SYSTEM_MODE.read().expect("SYSTEM_MODE lock poisoned")
 }

115-123: The ordering is already correct, but add documentation as a safeguard.

The code already calls enable_system_mode() (via handle_system_mode() at line 126 in main.rs) before config::init() (line 175), so the hypothetical issue of loading from the user path does not occur in the current implementation. However, the suggested documentation improvement is still valuable to prevent accidental future changes that could introduce this problem.

📝 Suggested documentation improvement
+/// Enable system mode and set appropriate paths.
+///
+/// **Important**: This must be called before `init()` or `Config::new()` to ensure
+/// the system configuration path is used.
 pub fn enable_system_mode() {
crates/soar-cli/src/main.rs (1)

68-76: Improve privilege escalation tool detection.

The current detection runs doas true and sudo true which will prompt for a password just to check availability. If the first tool fails authentication, the user may be prompted again for the second tool.

Consider checking for the existence of the executable instead:

♻️ Proposed improvement
-    let escalation_cmd = if Command::new("doas").arg("true").status().is_ok() {
-        "doas"
-    } else if Command::new("sudo").arg("true").status().is_ok() {
-        "sudo"
-    } else {
+    let escalation_cmd = if which::which("doas").is_ok() {
+        "doas"
+    } else if which::which("sudo").is_ok() {
+        "sudo"
+    } else {
         return Err(SoarError::Custom(
             "System mode requires root privileges. Neither 'doas' nor 'sudo' found.".into(),
         ));
     };

Alternatively, if you don't want to add the which crate dependency:

-    let escalation_cmd = if Command::new("doas").arg("true").status().is_ok() {
-        "doas"
-    } else if Command::new("sudo").arg("true").status().is_ok() {
-        "sudo"
-    } else {
+    let escalation_cmd = if Command::new("which").arg("doas").status().map(|s| s.success()).unwrap_or(false) {
+        "doas"
+    } else if Command::new("which").arg("sudo").status().map(|s| s.success()).unwrap_or(false) {
+        "sudo"
+    } else {
         return Err(SoarError::Custom(
             "System mode requires root privileges. Neither 'doas' nor 'sudo' found.".into(),
         ));
     };
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a776d61 and 5343341.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (10)
  • crates/soar-cli/Cargo.toml
  • crates/soar-cli/src/cli.rs
  • crates/soar-cli/src/health.rs
  • crates/soar-cli/src/main.rs
  • crates/soar-config/src/config.rs
  • crates/soar-core/src/package/install.rs
  • crates/soar-core/src/package/remove.rs
  • crates/soar-core/src/utils.rs
  • crates/soar-package/src/formats/common.rs
  • crates/soar-utils/src/path.rs
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: QaidVoid
Repo: pkgforge/soar PR: 137
File: crates/soar-cli/src/apply.rs:149-153
Timestamp: 2026-01-09T16:14:21.516Z
Learning: In crates/soar-cli/src/apply.rs, for URL packages, passing non-installed records (is_installed=false) as existing_install is intentional. The query filters by repo_name, pkg_name, and pkg_id, ensuring the record is for the same package. This allows resuming partial installs and preserving settings (portable paths, profile) from previous installs.
📚 Learning: 2026-01-09T16:14:21.516Z
Learnt from: QaidVoid
Repo: pkgforge/soar PR: 137
File: crates/soar-cli/src/apply.rs:149-153
Timestamp: 2026-01-09T16:14:21.516Z
Learning: In crates/soar-cli/src/apply.rs, for URL packages, passing non-installed records (is_installed=false) as existing_install is intentional. The query filters by repo_name, pkg_name, and pkg_id, ensuring the record is for the same package. This allows resuming partial installs and preserving settings (portable paths, profile) from previous installs.

Applied to files:

  • crates/soar-core/src/package/install.rs
🧬 Code graph analysis (6)
crates/soar-core/src/package/remove.rs (3)
crates/soar-config/src/config.rs (2)
  • get_config (144-156)
  • is_system_mode (111-113)
crates/soar-utils/src/fs.rs (1)
  • walk_dir (172-206)
crates/soar-utils/src/path.rs (2)
  • desktop_dir (141-147)
  • icons_dir (150-156)
crates/soar-package/src/formats/common.rs (2)
crates/soar-config/src/config.rs (1)
  • is_system_mode (111-113)
crates/soar-utils/src/path.rs (2)
  • icons_dir (150-156)
  • desktop_dir (141-147)
crates/soar-config/src/config.rs (1)
crates/soar-utils/src/path.rs (1)
  • xdg_data_home (115-119)
crates/soar-cli/src/main.rs (1)
crates/soar-config/src/config.rs (16)
  • enable_system_mode (116-123)
  • get_config (144-156)
  • set_current_profile (165-173)
  • Config (140-140)
  • Config (523-523)
  • Config (544-544)
  • Config (553-553)
  • Config (570-570)
  • Config (590-590)
  • Config (619-619)
  • Config (635-635)
  • Config (646-646)
  • Config (659-659)
  • Config (682-682)
  • Config (699-699)
  • Config (710-710)
crates/soar-cli/src/health.rs (2)
crates/soar-config/src/config.rs (2)
  • get_config (144-156)
  • is_system_mode (111-113)
crates/soar-utils/src/path.rs (2)
  • desktop_dir (141-147)
  • icons_dir (150-156)
crates/soar-core/src/utils.rs (3)
crates/soar-config/src/config.rs (2)
  • get_config (144-156)
  • is_system_mode (111-113)
crates/soar-utils/src/fs.rs (1)
  • walk_dir (172-206)
crates/soar-utils/src/path.rs (2)
  • desktop_dir (141-147)
  • icons_dir (150-156)
🪛 GitHub Actions: CI
crates/soar-core/src/package/remove.rs

[error] 9-9: cargo fmt --all -- --check failed. Formatting changes are available. Run 'cargo fmt' to fix code style issues.

🔇 Additional comments (15)
crates/soar-cli/Cargo.toml (1)

26-26: LGTM!

The nix crate addition is appropriate for implementing system-wide package management, as it provides Unix-specific functionality needed for privilege checks and system operations.

crates/soar-config/src/config.rs (2)

125-128: LGTM!

The system_root() function returns /usr/lib/soar, which follows Linux FHS conventions for application data. This is appropriate for system-wide package installations.


178-183: LGTM!

The branching logic correctly handles both system and user modes while maintaining backward compatibility. The SOAR_ROOT environment variable override works in both modes, providing flexibility for custom deployments.

crates/soar-utils/src/path.rs (2)

140-156: LGTM!

The path resolution correctly follows Linux conventions:

  • User mode uses XDG Base Directory paths (~/.local/share/...)
  • System mode uses /usr/local/share/... which is the appropriate location for locally-installed (non-distro-packaged) system-wide applications per FHS

The implementation is clean and the boolean parameter provides a clear interface.


458-480: LGTM!

The tests properly cover both user mode (system = false) and system mode (system = true) paths, ensuring the branching logic works correctly.

crates/soar-package/src/formats/common.rs (3)

16-16: LGTM!

The import change correctly adds is_system_mode to access the global system mode state.


108-108: LGTM!

The icons_dir(is_system_mode()) call correctly passes the system mode flag to determine the appropriate icons directory.


188-189: Privilege escalation for system-mode symlink creation is already handled.

The handle_system_mode() function (crates/soar-cli/src/main.rs, lines 59-89) checks for root privileges and re-executes the entire command with sudo or doas if needed, returning an error if neither is available. This is called before any system mode operations proceed (line 126), ensuring the process runs with root privileges by the time the symlink is created at lines 188-189 in common.rs. No action needed.

crates/soar-cli/src/cli.rs (1)

58-60: The -S short option does not conflict with the sync command alias.

The --system flag is properly implemented. The -S short option and the sync command's visible_alias = "S" operate in different parsing contexts—flags require the dash prefix (e.g., soar -S sync), while subcommand aliases don't (e.g., soar S). Clap handles these separately, so there is no conflict or user confusion risk.

Likely an incorrect or invalid review comment.

crates/soar-cli/src/health.rs (1)

4-4: LGTM!

The import of is_system_mode and its usage in desktop_dir() and icons_dir() calls is consistent with the system-mode feature being added across the codebase. The broken symlinks detection will now correctly scan the appropriate directories based on whether system mode is enabled.

Also applies to: 137-138

crates/soar-core/src/utils.rs (1)

8-8: LGTM!

The remove_broken_symlinks function now correctly uses is_system_mode() to determine which directories to scan, ensuring consistency with the system-mode feature across the codebase.

Also applies to: 85-86

crates/soar-core/src/package/remove.rs (1)

164-175: LGTM!

The package removal logic now correctly uses is_system_mode() to determine the appropriate desktop and icons directories for cleanup. The log message improvement ("removing icon symlink") also adds clarity.

crates/soar-core/src/package/install.rs (1)

13-13: LGTM!

The installation recording logic now correctly uses is_system_mode() when cleaning up symlinks from alternate packages. This ensures proper directory targeting based on the installation context.

Also applies to: 837-837, 847-847

crates/soar-cli/src/main.rs (2)

125-127: Consider order of operations: system mode vs config path.

The --system flag handling (lines 125-127) occurs before custom --config processing (lines 129-142). However, enable_system_mode() sets CONFIG_PATH to /etc/soar/config.toml. If a user specifies both --system and --config, the custom config path will correctly override the system default due to the ordering.

If the intent is for --system to always use /etc/soar/config.toml regardless of --config, consider adding a note or adjusting the logic. The current behavior allows --config to override, which may or may not be desired.


59-89: Overall system mode handling looks good.

The privilege escalation logic correctly:

  • Checks if already running as root before attempting escalation
  • Re-executes the entire command with the escalation tool
  • Exits with the appropriate status code after re-execution

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@QaidVoid QaidVoid merged commit f8d4f1c into main Jan 15, 2026
6 of 7 checks passed
@QaidVoid QaidVoid mentioned this pull request Jan 15, 2026
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