Skip to content

Conversation

@edolstra
Copy link
Collaborator

@edolstra edolstra commented Nov 26, 2025

Motivation

If any installable fails to build in nix build or nix profile install/upgrade, Nix will print something like

# nix build /home/eelco/Dev/patchelf /home/eelco/Dev/patchelf#hydraJobs.coverage nixpkgs#hello 
✅ flake:nixpkgs#hello
❌ git+file:///home/eelco/Dev/patchelf#packages.x86_64-linux.default
error: Cannot build '/nix/store/nh2dx9cqcy9lw4d4rvd0dbsflwdsbzdy-patchelf-0.18.0.drv'.
       Reason: builder failed with exit code 2.
       ...
❓ git+file:///home/eelco/Dev/patchelf#hydraJobs.coverage (cancelled)

It doesn't print anything if all installables succeed.

Context


Add 👍 to pull requests you find important.

The Nix maintainer team uses a GitHub project board to schedule and track reviews.

Summary by CodeRabbit

  • Bug Fixes

    • Improved error handling and reporting for cancelled and failed builds; build errors are raised before results are consumed.
    • Extended status reporting with clearer "Cancelled" status.
  • Chores

    • Reworked how build outcomes are represented and propagated internally for more robust result handling.
  • Tests

    • Updated functional test expectations to reflect refined failure and cancellation reporting.

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

This denotes the result of a build that didn't succeed or fail, but
was cancelled because some other goal failed and --keep-going was not
enabled.
@coderabbitai
Copy link

coderabbitai bot commented Nov 26, 2025

Walkthrough

This PR replaces pair-based build results with a variant-wrapped InstallableWithBuildResult, updates build APIs (build2, throwBuildErrors), moves build-status-to-string helpers into BuildResult::Success/Failure, adds a Cancelled status, initializes Goal buildResult to Cancelled, and updates profile code and tests to the new result flow.

Changes

Cohort / File(s) Summary
Build result type & API (headers)
src/libcmd/include/nix/cmd/installables.hh
Adds public InstallableWithBuildResult (variant of Success/Failure + getSuccess()), changes Installable::build2() return type to std::vector<InstallableWithBuildResult>, and declares Installable::throwBuildErrors()
Build implementation
src/libcmd/installables.cc
Implements InstallableWithBuildResult, rewrites build2() to emit variant-wrapped results, implements throwBuildErrors() with updated reporting/cancellation handling, and adapts callers to extract successes via getSuccess()
Build-result helpers (header + impl)
src/libstore/include/nix/store/build-result.hh, src/libstore/build-result.cc
Adds static statusToString(Status) to BuildResult::Success and BuildResult::Failure, adds Cancelled = 16 status, and updates call sites to use the scoped helpers
Goal default initialization
src/libstore/include/nix/store/build/goal.hh
Initializes Goal::buildResult to a Failure with Cancelled status by default
Profile command integration
src/nix/profile.cc
Updates builtPathsPerInstallable() signature to accept std::vector<InstallableWithBuildResult>, and modifies CmdProfileAdd / CmdProfileUpgrade to call build2(), then throwBuildErrors(), then extract successes
Tests
tests/functional/build.sh
Adjusts fod-failing test expectations: error/cancel counts and per-derivation hash-mismatch assertions to match new error reporting behavior

Sequence Diagram(s)

sequenceDiagram
    %% Styling: subtle green for success, red for failure
    participant Caller as Caller
    participant Build2 as build2()
    participant ThrowErr as throwBuildErrors()
    participant Extract as getSuccess()
    participant Final as FinalResults

    Caller->>Build2: invoke build2(...)
    Build2-->>Caller: return [InstallableWithBuildResult{Success|Failure}, ...]
    Caller->>ThrowErr: throwBuildErrors(buildResults, store)
    alt any Failure present
        ThrowErr->>Caller: throws aggregated/first relevant error (may log cancelled)
    else all Success
        ThrowErr-->>Caller: returns normally
    end
    Caller->>Extract: for each InstallableWithBuildResult call getSuccess()
    alt variant is Success
        Extract-->>Caller: returns BuiltPathWithResult
    else variant is Failure
        Extract->>Caller: rethrows stored failure
    end
    Caller-->>Final: vector<BuiltPathWithResult>
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Areas to focus:
    • Correct construction and ownership of InstallableWithBuildResult::Success vs Failure in build paths
    • Semantics and message formatting inside throwBuildErrors() (cancellation vs other failures)
    • Failure::rethrow() fallback to status string and the new Cancelled status propagation
    • Tests adjusted for changed error counts and cancelled events

Suggested reviewers

  • cole-h

Poem

🐰 A variant snug, with success and rue,

I hop through builds and bundle each view.
No more split pairs in my carrot-filled land,
Errors get thrown by a careful pawed hand.
Hooray for clean flows — hop, leap, and stand!

Pre-merge checks and finishing touches

❌ 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 pull request title accurately summarizes the main objective: reporting failing and succeeding installables in nix build and nix profile commands.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch show-build-result

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

Copy link

@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

🧹 Nitpick comments (2)
src/libcmd/include/nix/cmd/installables.hh (1)

99-113: Clean wrapper type for build results per installable.

The InstallableWithBuildResult struct provides a well-structured way to associate build outcomes with their installables. The type aliases improve readability.

One minor observation: the comment on line 105 states that Failure "must be a BuildResult::Failure", but the type alias is just BuildResult (which contains a variant). Consider whether the type could be tightened to BuildResult::Failure directly, or if the full BuildResult is needed for additional metadata (like timing info). The current approach works but relies on the caller to uphold the invariant.

src/libcmd/installables.cc (1)

594-602: Consider using std::get for clarity.

Since the variant can only hold Success or Failure, using std::get<Success>(result) would be clearer and provide a runtime check, avoiding the nullable pointer dereference pattern.

 const BuiltPathWithResult & InstallableWithBuildResult::getSuccess() const
 {
     if (auto * failure = std::get_if<Failure>(&result)) {
         auto failure2 = failure->tryGetFailure();
         assert(failure2);
         failure2->rethrow();
-    } else
-        return *std::get_if<Success>(&result);
+    }
+    return std::get<Success>(result);
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6859aed and aef7257.

📒 Files selected for processing (7)
  • src/libcmd/include/nix/cmd/installables.hh (2 hunks)
  • src/libcmd/installables.cc (6 hunks)
  • src/libstore/build-result.cc (4 hunks)
  • src/libstore/include/nix/store/build-result.hh (3 hunks)
  • src/libstore/include/nix/store/build/goal.hh (1 hunks)
  • src/nix/profile.cc (4 hunks)
  • tests/functional/build.sh (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
src/nix/profile.cc (2)
src/libcmd/include/nix/cmd/installables.hh (2)
  • buildResults (186-186)
  • store (198-198)
src/libcmd/installables.cc (4)
  • build2 (652-763)
  • build2 (652-653)
  • throwBuildErrors (604-639)
  • throwBuildErrors (604-604)
src/libstore/build-result.cc (1)
src/libstore/include/nix/store/build-result.hh (4)
  • status (34-34)
  • status (45-49)
  • status (45-45)
  • status (83-83)
src/libstore/include/nix/store/build-result.hh (1)
src/libstore/build-result.cc (4)
  • statusToString (16-30)
  • statusToString (16-16)
  • statusToString (32-64)
  • statusToString (32-32)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build_x86_64-linux / build
  • GitHub Check: build_aarch64-darwin / build
🔇 Additional comments (18)
src/libstore/include/nix/store/build/goal.hh (1)

112-112: LGTM! Sensible default for build result.

Initializing buildResult to Cancelled ensures that goals that never complete (or are interrupted) have a well-defined failed state. This aligns with the new per-installable reporting where cancelled builds show ❓.

src/libstore/include/nix/store/build-result.hh (4)

34-35: LGTM! Clean static helper declaration.

The statusToString helper provides a well-typed way to convert status codes to strings, improving API clarity over a free function.


83-84: LGTM! Symmetric with Success::statusToString.

Provides consistent API for status-to-string conversion across both result types.


106-106: Good fallback for empty error messages.

Using statusToString(status) when errorMsg is empty ensures rethrow() always provides a meaningful error message rather than throwing an empty one.


80-80: Based on my verification, I've found important evidence about the review comment:

Key Findings:

  1. HashMismatch (value 15) in src/libstore/include/nix/store/build-result.hh has an explicit 3-line comment explaining:

    • "The protocols do not yet know about this one"
    • "change it back to OutputRejected before serialization"
  2. Serialization Fallback in src/libstore/build/derivation-building-goal.cc (lines 843-850):

    • When BuildResult::Failure::HashMismatch is encountered, it's unconditionally converted to OutputRejected
    • The comment states: "the protocols don't know about HashMismatch yet"
  3. Cancelled (value 16) has:

    • NO explanatory comment like HashMismatch
    • NO corresponding conversion/fallback in the switch statement
    • NOT handled in the serialization code
  4. Pattern Observed:

    • The switch statement at lines 843-857 handles specific statuses that need adjustment
    • Cancelled is conspicuously absent from this handling
    • The default case says "Other statuses need no adjusting"

The review comment's concern appears valid and substantiated. The question of whether Cancelled needs similar protocol compatibility handling to HashMismatch cannot be definitively answered without understanding: (1) whether Cancelled is sent to older protocol versions, and (2) whether those older versions recognize it. However, the evidence suggests this warrants investigation or clarification.


Verify protocol compatibility for Cancelled status.

Cancelled = 16 lacks the protocol compatibility documentation and serialization fallback that HashMismatch = 15 explicitly requires. HashMismatch (lines 76-78) is documented as needing conversion to OutputRejected before serialization because older protocols don't recognize it. Cancelled has no such comment or fallback in the switch statement at src/libstore/build/derivation-building-goal.cc:843-857. If Cancelled can be sent to older protocol versions, it should receive equivalent treatment.

tests/functional/build.sh (2)

170-174: LGTM! Correct error count for keep-going with 3 failing FODs.

With --keep-going, all three FODs (x1, x2, x3) are attempted and fail independently, so expecting 3 errors is correct. The individual hash mismatch assertions properly validate each failure is reported.


164-166: Based on my analysis of the code:

The test expectation of 3 cancellations is correct.

The fod-failing.nix file defines 4 derivations:

  • x1, x2, x3: Fixed-output derivations (FODs) with identical invalid hashes
  • x4: A regular derivation that depends on x2 and x3

When nix build -f fod-failing.nix is run without explicit targets (line 161), all top-level attributes are attempted:

  1. One FOD (typically x1) fails first with a hash mismatch error → generates 1 error message
  2. The remaining three derivations (x2, x3, x4) are cancelled as a result → 3 cancellations

This aligns with the modern error reporting behavior where:

  • Each installable build attempt generates one error entry
  • Dependent builds are cancelled and counted separately
  • The test correctly validates this by checking for exactly 1 error and 3 cancellations

The test structure is sound and the assertion is accurate.

src/libstore/build-result.cc (3)

16-30: LGTM! Clean implementation with exhaustive switch.

The statusToString implementation correctly covers all Success::Status enum values with unreachable() as a defensive default.


32-64: LGTM! Exhaustive handling of all failure statuses including new Cancelled.

All Failure::Status enum values are handled, with the new Cancelled case properly returning "Cancelled".


71-73: LGTM! JSON serialization updated to use the new member functions.

Using the nested statusToString helpers is cleaner than free functions and provides better API discoverability.

src/libcmd/include/nix/cmd/installables.hh (2)

179-184: LGTM! Improved return type for build2.

Returning std::vector<InstallableWithBuildResult> instead of std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> is a cleaner API that can now represent both successes and failures per installable.


186-187: LGTM! New throwBuildErrors declaration.

This provides a clean separation between collecting build results and reporting errors. Taking a non-const reference suggests it may consume or modify the results, which should be documented in the implementation.

src/nix/profile.cc (3)

315-335: LGTM!

The function correctly adapts to the new InstallableWithBuildResult type. The call to b.getSuccess() is safe here because throwBuildErrors is always invoked before this function at both call sites, ensuring only successful results remain when this code executes.


367-370: LGTM!

The two-phase flow (build → throw errors → extract paths) is clean and makes error handling explicit. This ensures users see proper success/failure reporting before the profile is updated.


772-775: LGTM!

Consistent with the CmdProfileAdd changes, applying the same two-phase build result handling pattern.

src/libcmd/installables.cc (3)

24-24: LGTM!

Required include for the Exit exception used in throwBuildErrors.


641-650: LGTM!

Clean wrapper that maintains the simpler build() API while delegating to build2() internally. The error throwing before extraction ensures getSuccess() is safe.


652-763: LGTM!

The refactored build2() cleanly separates success and failure handling using the new InstallableWithBuildResult wrapper. Failures are detected early and stored directly (lines 718-723), while successes are properly wrapped with path information.

@github-actions
Copy link

github-actions bot commented Nov 26, 2025

@github-actions github-actions bot temporarily deployed to pull request November 26, 2025 21:18 Inactive
If any installable fails to build, it will print something like

  ✅ flake:nixpkgs#hello
  ❌ git+file:///home/eelco/Dev/patchelf#packages.x86_64-linux.default
  error: Cannot build '/nix/store/nh2dx9cqcy9lw4d4rvd0dbsflwdsbzdy-patchelf-0.18.0.drv'.
         Reason: builder failed with exit code 2.
         ...
  ❓ git+file:///home/eelco/Dev/patchelf#hydraJobs.coverage (cancelled)

It doesn't print anything if all installables succeed.
@github-actions github-actions bot temporarily deployed to pull request November 26, 2025 21:32 Inactive
Copy link

@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: 0

🧹 Nitpick comments (2)
src/libcmd/installables.cc (2)

604-639: Well-structured error reporting with clear status differentiation.

The method properly reports successes first, then failures, and distinguishes between actual failures (❌) and cancelled builds (❓). The triple iteration through buildResults is clear and maintainable, though it could be consolidated into a single pass if performance becomes a concern.

Note: The method only prints per-installable status when at least one failure exists, which appears intentional to avoid noise when all builds succeed.

If you'd like to optimize the multiple passes through buildResults, consider collecting the messages in one pass:

 void Installable::throwBuildErrors(std::vector<InstallableWithBuildResult> & buildResults, const Store & store)
 {
+    std::vector<std::string> successMsgs, failureMsgs;
+    bool hasFailures = false;
+    
     for (auto & buildResult : buildResults) {
-        if (std::get_if<InstallableWithBuildResult::Failure>(&buildResult.result)) {
-            // Report success first.
-            for (auto & buildResult : buildResults) {
-                if (std::get_if<InstallableWithBuildResult::Success>(&buildResult.result))
-                    notice("✅ " ANSI_BOLD "%s" ANSI_NORMAL, buildResult.installable->what());
-            }
-
-            // Then failures.
-            for (auto & buildResult : buildResults) {
-                if (auto failure = std::get_if<InstallableWithBuildResult::Failure>(&buildResult.result)) {
-                    auto failure2 = failure->tryGetFailure();
-                    assert(failure2);
-                    if (failure2->status == BuildResult::Failure::Cancelled
-                        // FIXME: remove MiscFailure eventually
-                        || failure2->status == BuildResult::Failure::MiscFailure)
-                        notice(
-                            "❓ " ANSI_BOLD "%s" ANSI_NORMAL ANSI_FAINT " (cancelled)",
-                            buildResult.installable->what());
-                    else {
-                        printError("❌ " ANSI_RED "%s" ANSI_NORMAL, buildResult.installable->what());
-                        try {
-                            failure2->rethrow();
-                        } catch (Error & e) {
-                            logError(e.info());
-                        }
-                    }
-                }
-            }
-
-            throw Exit(1);
+        if (std::get_if<InstallableWithBuildResult::Success>(&buildResult.result)) {
+            successMsgs.push_back(buildResult.installable->what());
+        } else if (auto failure = std::get_if<InstallableWithBuildResult::Failure>(&buildResult.result)) {
+            hasFailures = true;
+            // Store failure details...
         }
     }
+    
+    if (hasFailures) {
+        // Print all collected messages
+        // ...
+        throw Exit(1);
+    }
 }

652-763: Solid implementation of variant-based build result flow.

The method correctly constructs InstallableWithBuildResult entries for all build paths, properly handling both success and failure cases across different realization modes. The distinction between modes that include actual build results (Outputs) versus those that just resolve paths (Nothing/Derivation) is clear.

There's some code duplication in constructing Success results for DerivedPath::Built vs DerivedPath::Opaque cases across different modes (lines 686-697 vs 700-703, and lines 728-742 vs 744-748). Consider extracting a helper function to reduce duplication:

auto makeSuccessResult = [&](const BuiltPath & path, const Aux & aux, 
                              std::optional<BuiltPathWithResult> buildResult = std::nullopt) {
    return InstallableWithBuildResult{
        .installable = aux.installable,
        .result = InstallableWithBuildResult::Success{
            .path = path,
            .info = aux.info,
            .result = buildResult
        }
    };
};

This would make the code more maintainable if the Success structure changes.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aef7257 and ee75a66.

📒 Files selected for processing (4)
  • src/libcmd/include/nix/cmd/installables.hh (2 hunks)
  • src/libcmd/installables.cc (6 hunks)
  • src/nix/profile.cc (4 hunks)
  • tests/functional/build.sh (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/nix/profile.cc
  • src/libcmd/include/nix/cmd/installables.hh
  • tests/functional/build.sh
🧰 Additional context used
🧬 Code graph analysis (1)
src/libcmd/installables.cc (1)
src/libcmd/include/nix/cmd/installables.hh (7)
  • buildResults (186-186)
  • evalStore (172-177)
  • evalStore (179-184)
  • evalStore (188-189)
  • evalStore (191-192)
  • evalStore (194-195)
  • evalStore (200-201)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build_aarch64-darwin / build
  • GitHub Check: build_x86_64-linux / build
🔇 Additional comments (3)
src/libcmd/installables.cc (3)

24-24: LGTM - Required for new error handling.

The new include is necessary for the Exit exception thrown in throwBuildErrors.


594-602: LGTM - Proper variant handling and error propagation.

The method correctly extracts the success result or rethrows the stored failure. The assert ensures the failure state is valid before rethrowing.


641-650: LGTM - Clean delegation and error handling.

The method properly delegates to build2(), centralizes error handling via throwBuildErrors(), and converts results by extracting successful paths. The pattern ensures that callers either get all successful results or an exception.

@cole-h cole-h self-requested a review November 26, 2025 23:14
@cole-h cole-h self-assigned this Nov 26, 2025
.level = lvlError,
.msg = failedResult->second->errorMsg,
});
// Then failures.
Copy link
Member

Choose a reason for hiding this comment

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

Would it be possible to instead make the order be:

  1. Success
  2. Cancelled
  3. Failure

(instead of Success -> interleaved Cancelled/Failure)

so that failure messages require much less scrolling up to see which thing failed? With a contrived example, I build a lot of trivial derivations, made only the first one fail, and that gave me something like:

❓ path:/tmp/tmp.ozLDnPJna5#trivial-138 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-139 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-140 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-141 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-142 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-143 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-144 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-145 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-146 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-147 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-148 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-149 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-150 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-151 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-152 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-153 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-154 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-155 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-156 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-157 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-158 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-159 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-160 (cancelled)

with the error message much higher up:

❌ path:/tmp/tmp.ozLDnPJna5#trivial-1
error: Cannot build '/nix/store/1sqqk6fp8c9gyf89l1i96g3fgdpmf5r4-trivial-1-5.drv'.
       Reason: builder failed with exit code 1.
       Output paths:
         /nix/store/0vi2yf4wkw756ijl6fq1m8wdmcqq68r3-trivial-1-5
       Last 6 log lines:
       > Running phase: patchPhase
       > Running phase: updateAutotoolsGnuConfigScriptsPhase
       > Running phase: configurePhase
       > no configure script, doing nothing
       > Running phase: buildPhase
       > Running phase: installPhase
       For full logs, run:
         nix log /nix/store/1sqqk6fp8c9gyf89l1i96g3fgdpmf5r4-trivial-1-5.drv
❓ path:/tmp/tmp.ozLDnPJna5#trivial-2 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-3 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-4 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-5 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-6 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-7 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-8 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-9 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-10 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-11 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-12 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-13 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-14 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-15 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-57 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-58 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-59 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-60 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-61 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-62 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-63 (cancelled)
❓ path:/tmp/tmp.ozLDnPJna5#trivial-64 (cancelled)

# --keep-going and FOD
out="$(nix build -f fod-failing.nix -L 2>&1)" && status=0 || status=$?
test "$status" = 1
# one "hash mismatch" error, one "build of ... failed"
Copy link
Member

Choose a reason for hiding this comment

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

nit: comment is wrong now -- one hash mismatch error, 3 cancelled errors

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.

3 participants