nh icon indicating copy to clipboard operation
nh copied to clipboard

darwin: fix activation without darwin-rebuild

Open andre4ik3 opened this issue 3 months ago • 5 comments

As part of supporting the new nix-darwin activation style in https://github.com/nix-community/nh/pull/238, there was a breaking change made to use darwin-rebuild instead of calling the activation scripts directly. Unfortunately this change meant it was no longer meant to use nh as a darwin-rebuild replacement, as it would depend on darwin-rebuild itself. So if darwin-rebuild was disabled (e.g. by setting system.tools.enable = false), nh would fail to activate the system with an error like the following:

> Comparing changes
<<< /run/current-system
>>> /var/folders/h7/34fnxyx94lv_hkg1fmg658fr0000gn/T/nh-osusP10v/result
No version or selection state changes.
Closure size: 2055 -> 2055 (0 paths added, 0 paths removed, delta +0, disk usage +0B).
> Activating configuration
env: ‘/var/folders/h7/34fnxyx94lv_hkg1fmg658fr0000gn/T/nh-osusP10v/result/sw/bin/darwin-rebuild’: No such file or directory

This PR simply adds a check whether darwin-rebuild exists, and if not, falls back to the old behavior.

(If it's undesirable for this configuration to be supported then perhaps a warning should be added when activate is used, but I think compatibility should be kept at least for now, because it was done in a minor release, and breaking changes should only happen in major releases according to semver (which is why marked it as a bug fix, since it's fixing a regression from a semver point of view))

Tested in the following cases:

  • Ensure it invokes darwin-rebuild by default
  • Ensure it falls back to activate if darwin-rebuild doesn't exist
  • Ensure it also invokes activate-user if it's the non-deprecated version and it invoked activate

Sanity Checking

  • [x] I have updated the changelog as per my changes
  • [x] I have tested, and self-reviewed my code
  • Style and consistency
    • [ ] I ran nix fmt to format my Nix code
    • [x] I ran cargo fmt to format my Rust code
    • [ ] I have added appropriate docunentation to new code
    • [x] My changes are consistent with the rest of the codebase
  • Correctness
    • [x] I ran cargo clippy and fixed any new linter warnings.
  • If new changes are particularly complex:
    • [ ] My code includes comments in particularly complex areas to explain the logic
    • [ ] I have documented the motive for those changes in the PR body or commit description.
  • Tested on platform(s)
    • [ ] x86_64-linux
    • [ ] aarch64-linux
    • [ ] x86_64-darwin
    • [x] aarch64-darwin

Add a :+1: reaction to pull requests you find important.

Summary by CodeRabbit

  • Bug Fixes

    • macOS activation is more resilient: if the standard rebuild tool isn’t available, activation falls back to direct activation and may perform a user-level activation step.
    • Automatically selects appropriate activation method and elevation based on the environment.
    • Provides clearer, more specific error messages for activation and user activation failures.
  • Documentation

    • Added an Unreleased entry documenting the macOS activation fallback behavior.

andre4ik3 avatar Sep 10 '25 10:09 andre4ik3

Walkthrough

Detects darwin-rebuild presence and new vs legacy activation in src/darwin.rs, conditionally runs either darwin-rebuild activate or out_path/activate, optionally runs activate-user for legacy flow, adjusts elevation logic and error contexts. Updates CHANGELOG.md to document the Darwin fallback. No public API changes.

Changes

Cohort / File(s) Summary
Documentation
CHANGELOG.md
Added Unreleased -> Fixed entry documenting Darwin-specific fallback: when darwin-rebuild is absent, activation falls back to executing activate (and activate-user when applicable). Documentation-only.
Darwin activation logic
src/darwin.rs
Added detection for darwin-rebuild (has_darwin_rebuild) and activation-style detection (uses_new_activation); select activation command conditionally (darwin-rebuild activate vs out_path/activate); compute should_elevate and apply elevation accordingly; run legacy activate-user when needed; improved error contexts and distinct failure messages. No public signatures changed.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant CLI as CLI
  participant FS as Filesystem
  participant Sudo as Elevation
  participant Shell as System Shell

  User->>CLI: trigger activation
  CLI->>FS: stat `darwin-rebuild`
  alt darwin-rebuild exists
    CLI->>FS: inspect `activate-user` (detect new activation)
    CLI->>CLI: set uses_new_activation, should_elevate
    alt should_elevate
      CLI->>Sudo: run `darwin-rebuild activate`
      Sudo->>Shell: execute activation
    else
      CLI->>Shell: run `darwin-rebuild activate`
    end
  else darwin-rebuild missing
    CLI->>FS: inspect `out_path/activate` and `activate-user`
    CLI->>CLI: set uses_new_activation=false, should_elevate=true
    CLI->>Sudo: run `out_path/activate`
    Sudo->>Shell: execute activation
    opt legacy user activation (not uses_new_activation)
      CLI->>Shell: run `out_path/activate-user`
    end
  end

  note over CLI,Shell: Errors include contextual messages for activation vs user activation failures

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45–60 minutes

Pre-merge checks (2 passed, 1 warning)

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title “darwin: fix activation without darwin-rebuild” accurately and concisely captures the primary change—restoring activation fallback on macOS when the darwin-rebuild tool is unavailable—without extraneous detail, making it clear to reviewers scanning the pull request history.

[!TIP]

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.

✨ Finishing Touches
  • [ ] 📝 Generate Docstrings
🧪 Generate unit tests
  • [ ] Create PR with unit tests
  • [ ] Post copyable unit tests in a comment

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

coderabbitai[bot] avatar Sep 10 '25 10:09 coderabbitai[bot]

Made the comment shorter so it passes the format CI check. Idk what all this AI stuff is I've never seen it before, not sure what I'm supposed to do with it exactly.

andre4ik3 avatar Sep 10 '25 10:09 andre4ik3

You may disregard the AI comments. I'm currently looking to see if it provides helpful comments that help guide my reviews (as the sole maintainer) or if it creates useless noise. Outlook not so good.

I'll take a review later today. Please feel free to remind me with a ping if I forget. Also CC @khaneliman as someone more aware of nix-darwin's internals.

NotAShelf avatar Sep 10 '25 10:09 NotAShelf

I mean, it was a deliberate choice https://github.com/nix-community/nh/pull/238#discussion_r2003366687

khaneliman avatar Sep 15 '25 04:09 khaneliman

I see. So should I add a warning about it and mark that it will be removed in the future? (v5.0.0)

andre4ik3 avatar Sep 15 '25 06:09 andre4ik3