Skip to content

Conversation

RossComputerGuy
Copy link
Member

@RossComputerGuy RossComputerGuy commented Sep 19, 2025

Motivation

Need to be able to read some derivation information from Rust.

Context

Summary by CodeRabbit

  • New Features

    • Public C API to parse derivations from JSON, add them to the store, enumerate outputs (with optional associated store paths), and access structured attributes; new clone/free helpers for derivation and output wrappers.
  • API Changes

    • Stronger const-safety and opaque path usage: path and realise callback parameters updated.
  • Documentation

    • Clarified callback lifetime semantics.
  • Tests

    • New test helpers, test entry point, refactored test harness, and self-contained derivation test data to validate creation and realization.

Copy link

coderabbitai bot commented Sep 19, 2025

Walkthrough

Adds C API wrappers and internal types for Derivation and DerivationOutput (create from JSON, write to store, clone/free, enumerate outputs, structured attrs), adjusts realise and is_valid_path signatures to use const StorePath *, and introduces test infra (pre-build helper, test mains, and a derivation unit test).

Changes

Cohort / File(s) Summary
C API: derivation types & ops
src/libstore-c/nix_api_store.h, src/libstore-c/nix_api_store.cc, src/libstore-c/nix_api_store_internal.h
Adds nix_derivation and nix_derivation_output wrappers; implements nix_derivation_from_json, nix_add_derivation, nix_derivation_clone, nix_derivation_free, nix_store_drv_from_path, nix_derivation_get_outputs, nix_derivation_get_outputs_and_optpaths, nix_derivation_get_structured_attrs, nix_drv_output_clone, nix_drv_output_free; updates nix_store_is_valid_path to take const StorePath * and changes nix_store_realise callback to accept const StorePath *. Header contains a typedef naming typo for the output wrapper (nix_derivatio_noutput).
Test pre-build helper & mains
src/libstore-test-support/test-main.cc, src/libstore-test-support/include/nix/store/tests/test-main.hh, src/libstore-test-support/meson.build, src/libstore-tests/main.cc, src/libstore-tests/meson.build, src/libstore-test-support/meson.build, src/libexpr-tests/main.cc
Adds nix::testMainForBuidingPre (declared in new header) and includes it in test main entry points; pre-test configuration disables buildHook/substituters and applies platform sandbox tweaks; adds test-main.cc to test-support build and exports the header.
Test harness: store test refactor
src/libstore-test-support/include/nix/store/tests/nix_api_store.hh
Splits test class into nix_api_store_test_base and derived nix_api_store_test; moves local store lifecycle to derived class, introduces open_local_store() helper, adjusts teardown and check semantics (EXPECT_NE -> EXPECT/ASSERT mix) and conditional nixDir cleanup.
Unit test: derivation test & adapter
src/libstore-tests/nix_api_store.cc
Adds build_from_json test that parses self-contained.json via the new C API, writes derivation to the store, realises it using a LambdaAdapter for the C callback (now receiving const StorePath *), validates produced paths and cleans up resources.
Test data: derivation fixture
src/libstore-tests/data/derivation/ca/self-contained.json
Adds JSON fixture describing a simple self-contained derivation ("myname") with a single output out.
Build export: test header
src/libstore-test-support/include/nix/store/tests/meson.build
Exports test-main.hh as a public header in the test-support component.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Test as Test client
  participant C_API as C API (nix_api_store)
  participant Store
  participant Callback

  Test->>C_API: nix_derivation_from_json(ctx, store, json)
  activate C_API
  C_API->>C_API: parse JSON -> nix_derivation*
  C_API-->>Test: nix_derivation* (owned)
  deactivate C_API

  Test->>C_API: nix_add_derivation(ctx, store, derivation)
  activate C_API
  C_API->>Store: writeDerivation(derivation)
  Store-->>C_API: StorePath*
  C_API-->>Test: StorePath* (wrapper)
  deactivate C_API
Loading
sequenceDiagram
  autonumber
  participant Test as Test client
  participant C_API as C API (nix_api_store)
  participant Store
  participant Callback

  Test->>C_API: nix_store_realise(ctx, store, path, userdata, cb)
  activate C_API
  C_API->>Store: realise(path)
  Store-->>C_API: event(outname, out_path)
  C_API-->>Callback: cb(userdata, outname, const StorePath * out)  %% callback now receives StorePath pointer
  deactivate C_API
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

I nibble JSON and stitch each trace,
I hop through outputs, wrap and place.
I hand you paths as pointers neat,
I clone, I free — then drum my feet.
A rabbit cheers when tests complete. 🐇

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 title "libstore-c: add derivation functions" accurately and concisely summarizes the primary change (adding derivation-related public APIs to libstore-c); it is specific, on-topic, and concise enough for a reviewer scanning history to understand the main intent of the changeset.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch RossComputerGuy/feat/expose-drvfrompath

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 02fc921 and 5962284.

📒 Files selected for processing (2)
  • src/libstore-c/nix_api_store.cc (5 hunks)
  • src/libstore-c/nix_api_store.h (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/libstore-c/nix_api_store.cc (1)
src/libstore/include/nix/store/store-api.hh (20)
  • path (318-318)
  • path (340-340)
  • path (346-346)
  • path (353-353)
  • path (357-357)
  • path (394-394)
  • path (400-400)
  • path (405-405)
  • path (415-415)
  • path (451-451)
  • path (461-464)
  • path (461-461)
  • path (474-477)
  • path (474-474)
  • path (482-482)
  • path (490-490)
  • drvPath (697-697)
  • drvPath (772-772)
  • drvPath (777-777)
  • drvPath (782-782)
src/libstore-c/nix_api_store.h (1)
src/libstore-c/nix_api_store.cc (26)
  • nix_store_is_valid_path (94-102)
  • nix_store_is_valid_path (94-94)
  • callback (132-132)
  • callback (226-226)
  • callback (244-244)
  • callback (264-265)
  • nix_derivation_from_json (182-196)
  • nix_derivation_from_json (182-182)
  • nix_add_derivation (198-208)
  • nix_add_derivation (198-198)
  • nix_derivation_free (167-170)
  • nix_derivation_free (167-167)
  • nix_derivation_clone (177-180)
  • nix_derivation_clone (177-177)
  • nix_store_drv_from_path (222-239)
  • nix_store_drv_from_path (222-227)
  • nix_derivation_get_outputs (241-258)
  • nix_derivation_get_outputs (241-245)
  • nix_derivation_get_outputs_and_optpaths (260-286)
  • nix_derivation_get_outputs_and_optpaths (260-266)
  • nix_derivation_get_structured_attrs (288-302)
  • nix_derivation_get_structured_attrs (288-289)
  • nix_derivation_output_clone (304-307)
  • nix_derivation_output_clone (304-304)
  • nix_derivation_output_free (309-312)
  • nix_derivation_output_free (309-309)
⏰ 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). (4)
  • GitHub Check: build_x86_64-linux / manual
  • GitHub Check: build_x86_64-linux / vm_tests_smoke
  • GitHub Check: build_x86_64-linux / test
  • GitHub Check: build_aarch64-darwin / build
🔇 Additional comments (15)
src/libstore-c/nix_api_store.h (5)

26-29: LGTM! Clean API additions.

The new opaque type declarations for nix_derivation and nix_derivation_output follow the established pattern in the codebase and provide clean separation between the C API and internal C++ types.


155-155: LGTM! Proper const-correctness alignment.

The parameter change from StorePath * path to const StorePath * path correctly aligns with the underlying C++ API and better expresses the intent that the path is not modified by this function.


197-197: LGTM! Consistent const-correctness in callback.

The callback signature change to use const StorePath * maintains consistency with the const-correctness improvements throughout the API.


214-246: LGTM! Well-designed derivation API additions.

The new derivation functions provide a comprehensive and well-structured API for working with derivations:

  • nix_derivation_from_json and nix_add_derivation for creation and storage
  • nix_derivation_free and nix_derivation_clone for memory management
  • All functions follow the established error handling patterns with nix_c_context

The API design is consistent and follows good C practices.


258-336: LGTM! Comprehensive derivation query API.

The new functions provide excellent coverage for derivation introspection:

  • nix_store_drv_from_path for loading derivations from store paths
  • nix_derivation_get_outputs and nix_derivation_get_outputs_and_optpaths for output enumeration
  • nix_derivation_get_structured_attrs for accessing structured attributes
  • nix_derivation_output_clone and nix_derivation_output_free for output management

All functions use appropriate callback patterns for memory safety and follow the established API conventions.

src/libstore-c/nix_api_store.cc (10)

94-94: LGTM! Proper const-correctness alignment.

The parameter change to const StorePath * path correctly aligns with the underlying store->ptr->isValidPath(path->path) call and improves API consistency.


132-132: LGTM! Improved callback signature and implementation.

The callback signature change to use const StorePath * is well-implemented. The creation of a temporary StorePath p{realisation.outPath} and passing &p to the callback ensures proper lifetime management while maintaining const-correctness.

Also applies to: 147-148


167-180: LGTM! Standard memory management functions.

The nix_derivation_free and nix_derivation_clone functions follow the established pattern for C API memory management with simple delete and copy construction.


182-196: LGTM! Robust derivation creation from JSON.

The implementation properly:

  • Parses JSON using nlohmann::json::parse
  • Creates the derivation with nix::Derivation::fromJSON
  • Writes and validates the derivation with nix::writeDerivation and checkInvariants
  • Follows proper error handling patterns

This ensures the derivation is fully validated before being returned to the caller.


198-208: LGTM! Clean derivation storage implementation.

The nix_add_derivation function correctly uses nix::writeDerivation to persist the derivation to the store and returns the resulting store path. The error handling follows the established pattern.


222-239: LGTM! Safe derivation loading with callback pattern.

The implementation correctly:

  • Uses store->ptr->derivationFromPath to load the derivation
  • Creates a temporary nix_derivation wrapper for the callback
  • Follows the established callback pattern for borrowed object lifetimes

The temporary object approach ensures memory safety while avoiding unnecessary allocations.


241-258: LGTM! Efficient output enumeration.

The function correctly iterates through drv->drv.outputs, creates temporary nix_derivation_output wrappers, and passes them to the callback. The borrowed lifetime pattern is appropriate here.


260-286: LGTM! Well-implemented outputs with optional paths.

The implementation properly:

  • Uses drv->drv.outputsAndOptPaths(store->ptr->config) to get outputs with optional paths
  • Handles both cases where store_path exists and where it's nullptr
  • Creates appropriate temporary wrappers for both output and path objects

The conditional path handling correctly reflects the optional nature of store paths for outputs.


288-302: LGTM! Proper structured attributes handling.

The function correctly checks for the existence of structuredAttrs, dumps the JSON using .dump(), and passes the string data to the callback. The callback pattern ensures the string lifetime is managed properly during the callback execution.


304-312: LGTM! Standard derivation output memory management.

The nix_derivation_output_clone and nix_derivation_output_free functions follow the established pattern with simple copy construction and deletion.


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.

Copy link

github-actions bot commented Sep 19, 2025

@github-actions github-actions bot temporarily deployed to pull request September 19, 2025 21:29 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 (10)
src/libstore-c/nix_api_store_internal.h (2)

16-20: Wrappers store full nix::Derivation by value; consider pointer semantics to avoid heavy copies.

Owning by value simplifies lifetime but can be costly to copy in callbacks and clones. Consider:

  • Make struct Derivation { std::shared_ptr<nix::Derivation> drv; }
  • Make struct DerivationOutput { std::shared_ptr<nix::DerivationOutput> drv_out; }
    This preserves C ABI (opaque pointer) while reducing copies.

21-24: Same consideration for DerivationOutput.

Storing by value copies on every callback iteration; shared ownership avoids that without changing the public C surface.

src/libstore-c/nix_api_store.cc (4)

184-201: Avoid an extra deep copy; also add basic null-arg guards.

  • Move the derived value into the wrapper to skip one copy.
  • Optional: early-return or throw on !store || !path to avoid UB via deref.

Apply:

 nix_err nix_store_drv_from_path(
@@
     try {
-        nix::Derivation drv = store->ptr->derivationFromPath(path->path);
+        if (!store || !path) { /* keep style consistent with the rest of the file if throwing */
+            throw std::invalid_argument("nix_store_drv_from_path: null store or path");
+        }
+        nix::Derivation drv = store->ptr->derivationFromPath(path->path);
         if (callback) {
-            const Derivation tmp{drv};
+            const Derivation tmp{std::move(drv)};
             callback(userdata, &tmp);
         }
     }

203-206: Cloning performs a full deep copy.

If you switch wrappers to shared_ptr, clone becomes a cheap ref bump:

-Derivation * nix_drv_clone(const Derivation * d)
-{
-    return new Derivation{d->drv};
-}
+Derivation * nix_drv_clone(const Derivation * d) {
+    return new Derivation{d->drv}; // shared_ptr copy if refactor applied
+}

If keeping value semantics, please confirm typical derivation sizes in your workloads to ensure cloning cost is acceptable.


213-230: Borrowed name lifetime not documented; potential misuse.

name.c_str() points into the derivation’s internal map. Add a doc note in the header: the name pointer is valid only during the callback.

Would you like me to patch the header comments to state this explicitly?


232-257: Same lifetime note for name and StorePath; consider avoiding per-iteration copies.

  • Document that both name and path are borrowed for the duration of the callback.
  • Optional: if wrappers move to pointer semantics, you can pass views without copying DerivationOutput and StorePath each iteration.
src/libstore-c/nix_api_store.h (4)

224-241: Clarify callback contract and nullability.

Suggest amending docs:

  • Callback may be NULL (no-op).
  • The Derivation pointer is borrowed only for the duration of the call and must not be freed; use nix_drv_clone to retain it.

Proposed doc tweak:

 /**
  * @brief Returns the derivation associated with the store path
  *
- * @note The callback borrows the Derivation only for the duration of the call.
+ * @note The callback may be NULL (no-op).
+ * @note The callback borrows the Derivation only for the duration of the call.
+ *       Do not call nix_drv_free() on this pointer; use nix_drv_clone() to retain.

242-257: Clone/free API: document ownership expectations.

Add a brief note that only objects returned by *_clone are owned and must be freed with the matching *_free.


258-273: Document name lifetime and encoding.

Add:

  • name is borrowed and valid only during the callback.
  • Encoding: UTF‑8, no NUL bytes.
  * @param[in] callback The function to call on every output
+ * @note The `name` argument is borrowed (valid only during the callback).

274-291: Document name and path lifetimes; clarify that path may be NULL.

Add:

  * @param[in] callback The function to call on every output and store path
  * @param[in] userdata The userdata to pass to the callback
+ * @note `name` and `path` are borrowed and valid only during the callback.
+ *       `path` may be NULL when the output has no associated store path.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 044c43c and 84a4ea6.

📒 Files selected for processing (3)
  • src/libstore-c/nix_api_store.cc (1 hunks)
  • src/libstore-c/nix_api_store.h (2 hunks)
  • src/libstore-c/nix_api_store_internal.h (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/libstore-c/nix_api_store.cc (1)
src/libstore/include/nix/store/store-api.hh (16)
  • path (318-318)
  • path (340-340)
  • path (346-346)
  • path (353-353)
  • path (357-357)
  • path (394-394)
  • path (400-400)
  • path (405-405)
  • path (415-415)
  • path (451-451)
  • path (461-464)
  • path (461-461)
  • path (474-477)
  • path (474-474)
  • path (482-482)
  • path (490-490)
src/libstore-c/nix_api_store.h (1)
src/libstore-c/nix_api_store.cc (18)
  • nix_store_drv_from_path (184-201)
  • nix_store_drv_from_path (184-189)
  • callback (132-132)
  • callback (188-188)
  • callback (216-216)
  • callback (236-236)
  • nix_drv_clone (203-206)
  • nix_drv_clone (203-203)
  • nix_drv_free (208-211)
  • nix_drv_free (208-208)
  • nix_drv_get_outputs (213-230)
  • nix_drv_get_outputs (213-217)
  • nix_drv_get_outputs_and_optpaths (232-257)
  • nix_drv_get_outputs_and_optpaths (232-237)
  • nix_drv_output_clone (259-262)
  • nix_drv_output_clone (259-259)
  • nix_drv_output_free (264-267)
  • nix_drv_output_free (264-264)
⏰ 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). (4)
  • GitHub Check: build_x86_64-linux / manual
  • GitHub Check: build_x86_64-linux / test
  • GitHub Check: build_x86_64-linux / vm_tests_smoke
  • GitHub Check: build_aarch64-darwin / build
🔇 Additional comments (4)
src/libstore-c/nix_api_store.cc (1)

259-267: LGTM for output clone/free.

Simple and consistent with the rest of the API.

src/libstore-c/nix_api_store.h (2)

26-29: Opaque typedefs: good addition.

Keeps the C ABI stable while allowing internal evolution.


292-306: LGTM for DerivationOutput clone/free docs and API.

Consistent with the Derivation ownership model.

src/libstore-c/nix_api_store_internal.h (1)

3-3: Include verified — header and required APIs are present.
Found src/libstore/include/nix/store/derivations.hh (and parsed-derivations.hh); Derivation and outputsAndOptPaths are defined there, and derivationFromPath is declared in src/libstore/include/nix/store/store-api.hh.

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

🧹 Nitpick comments (6)
src/libstore-test-support/include/nix/store/tests/test-main.hh (1)

11-11: Fix the typo in the function name.

There's a typo in the function name - "Buiding" should be "Building".

Apply this fix:

-int testMainForBuidingPre(int argc, char ** argv);
+int testMainForBuildingPre(int argc, char ** argv);

Note that this typo appears in multiple files across the PR and should be fixed consistently.

src/libstore-tests/nix_api_store.cc (2)

205-221: Consider simplifying the lambda adapter pattern.

While the LambdaAdapter template works, consider using std::function or a simpler approach for better readability and maintainability.

Alternative implementation using a simpler approach:

// Option 1: Direct function pointer with capture-less lambda
auto cb = [](void * userdata, const char * outname, const char * outPath) {
    auto * ctx_store = static_cast<std::pair<nix_c_context*, Store*>*>(userdata);
    StorePath sp{outPath};
    auto is_valid_path = nix_store_is_valid_path(ctx_store->first, ctx_store->second, &sp);
    ASSERT_EQ(is_valid_path, true);
};

std::pair<nix_c_context*, Store*> userdata{ctx, store};
auto ret = nix_store_realise(ctx, store, drvPath, &userdata, cb);

233-235: Add file existence check and error handling.

The test should verify the JSON file exists and handle potential I/O errors gracefully.

Improve error handling:

+    auto jsonPath = unitTestData / "derivation/ca/self-contained.json";
+    ASSERT_TRUE(std::filesystem::exists(jsonPath)) << "Test data file not found: " << jsonPath;
+    
-    std::ifstream t{unitTestData / "derivation/ca/self-contained.json"};
+    std::ifstream t{jsonPath};
+    ASSERT_TRUE(t.is_open()) << "Failed to open test data file: " << jsonPath;
     std::stringstream buffer;
     buffer << t.rdbuf();
src/libstore-test-support/test-main.cc (2)

10-10: Typo in function name: testMainForBuidingPre

The function name contains a typo - "Buiding" should be "Building".

Apply this diff to fix the typo:

-int testMainForBuidingPre(int argc, char ** argv)
+int testMainForBuildingPre(int argc, char ** argv)

Note that this will require updating all references to this function in other files, including the header declaration and any callers.


13-13: Minor: Typo in error message

The error message mentions "libexpr unit tests" but this code is part of libstore test support.

Apply this diff to fix the error message:

-        printError("test-build-remote: not supported in libexpr unit tests");
+        printError("test-build-remote: not supported in libstore unit tests");
src/libstore-c/nix_api_store.h (1)

233-233: Typo in documentation comment

Missing closing quote in the comment.

Apply this diff to fix the typo:

- * @brief Deallocate a `nix_derivation'
+ * @brief Deallocate a `nix_derivation`
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 84a4ea6 and 46af567.

📒 Files selected for processing (13)
  • src/libexpr-tests/main.cc (1 hunks)
  • src/libstore-c/nix_api_store.cc (2 hunks)
  • src/libstore-c/nix_api_store.h (3 hunks)
  • src/libstore-c/nix_api_store_internal.h (2 hunks)
  • src/libstore-test-support/include/nix/store/tests/meson.build (1 hunks)
  • src/libstore-test-support/include/nix/store/tests/nix_api_store.hh (2 hunks)
  • src/libstore-test-support/include/nix/store/tests/test-main.hh (1 hunks)
  • src/libstore-test-support/meson.build (1 hunks)
  • src/libstore-test-support/test-main.cc (1 hunks)
  • src/libstore-tests/data/derivation/ca/self-contained.json (1 hunks)
  • src/libstore-tests/main.cc (1 hunks)
  • src/libstore-tests/meson.build (1 hunks)
  • src/libstore-tests/nix_api_store.cc (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/libstore-c/nix_api_store_internal.h
🧰 Additional context used
🧬 Code graph analysis (7)
src/libstore-test-support/test-main.cc (1)
src/libutil/include/nix/util/environment-variables.hh (1)
  • setEnv (52-52)
src/libstore-tests/main.cc (2)
src/libstore-test-support/include/nix/store/tests/test-main.hh (1)
  • testMainForBuidingPre (11-11)
src/libstore-test-support/test-main.cc (2)
  • testMainForBuidingPre (10-45)
  • testMainForBuidingPre (10-10)
src/libexpr-tests/main.cc (2)
src/libstore-test-support/include/nix/store/tests/test-main.hh (1)
  • testMainForBuidingPre (11-11)
src/libstore-test-support/test-main.cc (2)
  • testMainForBuidingPre (10-45)
  • testMainForBuidingPre (10-10)
src/libstore-tests/nix_api_store.cc (2)
src/libstore-test-support/include/nix/store/tests/nix_api_store.hh (1)
  • store (95-98)
src/libstore-c/nix_api_store.cc (14)
  • nix_derivation_from_json (177-191)
  • nix_derivation_from_json (177-177)
  • nix_add_derivation (193-203)
  • nix_add_derivation (193-193)
  • nix_store_is_valid_path (94-102)
  • nix_store_is_valid_path (94-94)
  • nix_store_realise (127-154)
  • nix_store_realise (127-132)
  • nix_store_path_free (162-165)
  • nix_store_path_free (162-162)
  • nix_derivation_free (167-170)
  • nix_derivation_free (167-167)
  • nix_store_free (55-58)
  • nix_store_free (55-55)
src/libstore-c/nix_api_store.h (1)
src/libstore-c/nix_api_store.cc (16)
  • nix_derivation_from_json (177-191)
  • nix_derivation_from_json (177-177)
  • nix_add_derivation (193-203)
  • nix_add_derivation (193-193)
  • nix_derivation_free (167-170)
  • nix_derivation_free (167-167)
  • nix_store_drv_from_path (217-234)
  • nix_store_drv_from_path (217-222)
  • callback (132-132)
  • callback (221-221)
  • callback (239-239)
  • callback (259-259)
  • nix_derivation_get_outputs (236-253)
  • nix_derivation_get_outputs (236-240)
  • nix_derivation_get_outputs_and_optpaths (255-280)
  • nix_derivation_get_outputs_and_optpaths (255-260)
src/libstore-c/nix_api_store.cc (1)
src/libstore/include/nix/store/store-api.hh (4)
  • drvPath (697-697)
  • drvPath (772-772)
  • drvPath (777-777)
  • drvPath (782-782)
src/libstore-test-support/include/nix/store/tests/nix_api_store.hh (1)
src/libstore-c/nix_api_store.cc (6)
  • nix_libstore_init (13-21)
  • nix_libstore_init (13-13)
  • nix_store_open (33-53)
  • nix_store_open (33-33)
  • nix_store_free (55-58)
  • nix_store_free (55-55)
⏰ 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). (1)
  • GitHub Check: build_aarch64-darwin / build
🔇 Additional comments (8)
src/libstore-test-support/meson.build (1)

37-37: LGTM! Test main source file properly added to build.

The addition of test-main.cc to the sources list is correctly integrated with the existing build configuration.

src/libstore-tests/meson.build (1)

69-69: LGTM! Main test entry point correctly added.

The main.cc file is properly added to the test executable sources list.

src/libstore-test-support/include/nix/store/tests/meson.build (1)

12-12: LGTM! Test header properly exposed.

The test-main.hh header is correctly added to the public headers list.

src/libstore-tests/data/derivation/ca/self-contained.json (1)

1-23: LGTM! Well-structured test fixture.

The JSON derivation fixture is properly formatted and contains all necessary fields for a self-contained content-addressed derivation test case.

src/libstore-tests/nix_api_store.cc (1)

245-248: Type mismatch in the callback signature.

The callback expects const char * for the second parameter but the lambda is using const StorePath *. This type mismatch could cause undefined behavior.

Let me verify the actual callback signature expected by nix_store_realise:

Based on the search results, please ensure the callback signature matches what nix_store_realise expects. The callback should likely use const char * for both parameters.

src/libstore-tests/main.cc (1)

9-11: Fix the logic error in the return condition.

The condition is inverted. When testMainForBuidingPre returns 0 (success), the main function should continue. Currently it exits early on success.

Apply this fix:

    auto res = testMainForBuidingPre(argc, argv);
-    if (!res)
+    if (res)
        return res;

Likely an incorrect or invalid review comment.

src/libstore-test-support/test-main.cc (1)

41-41: Verify the correct function for setting environment variables

The code uses setEnv but based on the relevant code snippets, this might not be the correct function name in this context.

Let me verify the correct function name for setting environment variables in this codebase:

src/libstore-c/nix_api_store.cc (1)

184-184: Verify the intent of passing true for readOnly parameter

The code passes /* read only */ true to writeDerivation, but then the result is discarded. This seems to be for validation purposes only.

Let me verify the intent and usage of this pattern:

Comment on lines +9 to +11
auto res = testMainForBuidingPre(argc, argv);
if (!res)
return res;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix the inverted logic condition.

The condition logic appears to be inverted. When testMainForBuidingPre returns 0 (EXIT_SUCCESS), the test should continue rather than exit.

Apply this fix:

    auto res = testMainForBuidingPre(argc, argv);
-    if (!res)
+    if (res)
        return res;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
auto res = testMainForBuidingPre(argc, argv);
if (!res)
return res;
auto res = testMainForBuidingPre(argc, argv);
if (res)
return res;
🤖 Prompt for AI Agents
In src/libexpr-tests/main.cc around lines 9 to 11, the logic is inverted:
currently it returns when testMainForBuidingPre returns 0 (success). Change the
condition to return only on non-zero (error) — e.g. check if (res != 0) or if
(res) and then return res; so the test continues when res == 0.

/** @brief Nix Derivation */
typedef struct nix_derivation nix_derivation;
/** @brief Nix Derivation Output */
typedef struct nix_derivation_output nix_derivatio_noutput;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Critical typo in typedef: nix_derivatio_noutput

The typedef has a typo - it should be nix_derivation_output not nix_derivatio_noutput. This is inconsistent with how the type is used throughout the rest of the file.

Apply this diff to fix the typedef:

-typedef struct nix_derivation_output nix_derivatio_noutput;
+typedef struct nix_derivation_output nix_derivation_output;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
typedef struct nix_derivation_output nix_derivatio_noutput;
typedef struct nix_derivation_output nix_derivation_output;
🤖 Prompt for AI Agents
In src/libstore-c/nix_api_store.h around line 29, the typedef name contains a
typo: it declares nix_derivatio_noutput but should be nix_derivation_output;
change the typedef so the alias matches the correct name used elsewhere (typedef
struct nix_derivation_output nix_derivation_output;), ensuring consistency with
all other uses in the file.

Comment on lines +71 to +72
EXPECT_NE(store, nullptr) << "Could not open store: " << errMsg;
assert(store);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Error handling pattern is inconsistent

Using EXPECT_NE followed by assert(store) creates an inconsistent error handling pattern. If the store is null, EXPECT_NE will report the failure but continue execution, then assert will crash the test harness.

Apply this diff to use consistent error handling:

-            EXPECT_NE(store, nullptr) << "Could not open store: " << errMsg;
-            assert(store);
+            ASSERT_NE(store, nullptr) << "Could not open store: " << errMsg;

Using ASSERT_NE will properly fail the test and stop execution if the store is null, which is the intended behavior.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
EXPECT_NE(store, nullptr) << "Could not open store: " << errMsg;
assert(store);
ASSERT_NE(store, nullptr) << "Could not open store: " << errMsg;
🤖 Prompt for AI Agents
In src/libstore-test-support/include/nix/store/tests/nix_api_store.hh around
lines 71 to 72, the test uses EXPECT_NE(store, nullptr) followed by
assert(store) which mixes a non-fatal GoogleTest expectation with a hard abort;
replace this with a single fatal check using ASSERT_NE(store, nullptr) << "Could
not open store: " << errMsg; and remove the subsequent assert(store) so the test
fails and stops cleanly when the store is null.

Comment on lines +225 to +227
// FIXME get rid of these
nix::experimentalFeatureSettings.set("extra-experimental-features", "ca-derivations");
nix::settings.substituters = {};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Use proper settings API for test configuration.

Setting experimental features and substituters directly on global settings objects may not be thread-safe and could affect other tests.

Consider using the proper API for test isolation:

-    // FIXME get rid of these
-    nix::experimentalFeatureSettings.set("extra-experimental-features", "ca-derivations");
-    nix::settings.substituters = {};
+    // Use store-specific configuration or proper test setup
+    const char * ca_feature[] = {"experimental-features", "ca-derivations"};
+    const char * no_subst[] = {"substituters", ""};
+    const char ** kvs[] = {ca_feature, no_subst, nullptr};
+    auto * store = nix_store_open(ctx, "local", kvs);

Committable suggestion skipped: line range outside the PR's diff.


auto * store = open_local_store();

std::filesystem::path unitTestData{getenv("_NIX_TEST_UNIT_DATA")};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Potential null pointer dereference.

The environment variable _NIX_TEST_UNIT_DATA might not be set, leading to undefined behavior when passed to std::filesystem::path.

Add null check:

+    const char* test_data_env = getenv("_NIX_TEST_UNIT_DATA");
+    ASSERT_NE(test_data_env, nullptr) << "_NIX_TEST_UNIT_DATA environment variable not set";
-    std::filesystem::path unitTestData{getenv("_NIX_TEST_UNIT_DATA")};
+    std::filesystem::path unitTestData{test_data_env};
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
std::filesystem::path unitTestData{getenv("_NIX_TEST_UNIT_DATA")};
const char* test_data_env = getenv("_NIX_TEST_UNIT_DATA");
ASSERT_NE(test_data_env, nullptr) << "_NIX_TEST_UNIT_DATA environment variable not set";
std::filesystem::path unitTestData{test_data_env};
🤖 Prompt for AI Agents
In src/libstore-tests/nix_api_store.cc around line 231, the code calls
getenv("_NIX_TEST_UNIT_DATA") directly into std::filesystem::path which can
dereference a null pointer if the env var is unset; modify the code to call
getenv into a temporary char* variable, check it for nullptr, and handle the
error (e.g., log and return/throw or use a fallback path) before constructing
std::filesystem::path from the non-null value so no null pointer is passed to
the path constructor.

Use `StorePath *` not `const char *`.
@github-actions github-actions bot temporarily deployed to pull request September 19, 2025 22:16 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

♻️ Duplicate comments (4)
src/libstore-c/nix_api_store.h (3)

26-29: Fix typedef typo to expose nix_derivation_output in C

Currently the alias is misspelled, breaking C consumers (prototypes use nix_derivation_output* but no such typedef exists in C). Correct the alias.

-/** @brief Nix Derivation Output */
-typedef struct nix_derivation_output nix_derivatio_noutput;
+/** @brief Nix Derivation Output */
+typedef struct nix_derivation_output nix_derivation_output;

302-309: Header/impl mismatch: nix_derivation_output_clone vs nix_drv_output_clone

Implementation still uses nix_drv_output_clone. Rename impl to match header to avoid link errors.

I’ve proposed the corresponding .cc fix below.


310-317: Header/impl mismatch: nix_derivation_output_free vs nix_drv_output_free

Same naming mismatch for the free function.

src/libstore-c/nix_api_store.cc (1)

282-290: Rename functions to match header (nix_derivation_output_*)

These names must match the header to avoid unresolved symbols.

-nix_derivation_output * nix_drv_output_clone(const nix_derivation_output * o)
+nix_derivation_output * nix_derivation_output_clone(const nix_derivation_output * o)
 {
     return new nix_derivation_output{o->drv_out};
 }
 
-void nix_drv_output_free(nix_derivation_output * o)
+void nix_derivation_output_free(nix_derivation_output * o)
 {
     delete o;
 }
#!/bin/bash
# Verify no remaining mismatched names
rg -nP 'nix_drv_output_(clone|free)|nix_derivatio_noutput'
🧹 Nitpick comments (7)
src/libstore-c/nix_api_store.h (6)

192-198: Realise callback type is good; mark input path as const and clarify borrow

The output pointer is borrowed-only; also the input path isn’t mutated—make it const.

-nix_err nix_store_realise(
-    nix_c_context * context,
-    Store * store,
-    StorePath * path,
-    void * userdata,
-    void (*callback)(void * userdata, const char * outname, const StorePath * out));
+nix_err nix_store_realise(
+    nix_c_context * context,
+    Store * store,
+    const StorePath * path,
+    void * userdata,
+    void (*callback)(void * userdata, const char * outname, const StorePath * out));

Also consider adding: “The StorePath* passed to callback is valid only for the duration of the call.”


214-222: Document ownership and side effects for nix_derivation_from_json

Clarify that the return value must be freed and that no store write occurs (read-only check).

 /**
  * @brief Create a `nix_derivation` from a JSON representation of that derivation.
  *
  * @param[out] context Optional, stores error information.
  * @param[in] store nix store reference.
  * @param[in] json JSON of the derivation as a string.
+ * @return Owned pointer; call `nix_derivation_free` when done.
+ * @note Validates invariants without writing to the store.
  */

223-231: Explain that this writes to the store and return ownership of StorePath

Small doc tweak to set expectations.

 /**
  * @brief Add the given `nix_derivation` to the given store
  *
  * @param[out] context Optional, stores error information.
  * @param[in] store nix store reference. The derivation will be inserted here.
  * @param[in] derivation nix_derivation to insert into the given store.
+ * @return Owned `StorePath*` of the written derivation; free with `nix_store_path_free`.
+ * @note Writes the derivation to the store.
  */

232-239: Fix mismatched quote in docstring

Use matching backticks.

-/**
- * @brief Deallocate a `nix_derivation'
+/**
+ * @brief Deallocate a `nix_derivation`

268-283: Clarify name and drv_output lifetimes in callback

State explicitly that both pointers are valid only during the callback.

 /**
  * @brief Iterate through all of the outputs in a derivation
  *
- * @note The callback borrows the DerivationOutput only for the duration of the call.
+ * @note The callback borrows `name` and `drv_output` only for the duration of the call.

284-301: Document nullable path and borrow

Make it clear that path may be NULL and is borrowed.

 /**
  * @brief Iterate and get all of the derivation outputs and their store paths.
  *
- * @note The callback borrows the DerivationOutput and StorePath only for the duration of the call.
+ * @note The callback borrows the `drv_output` and `path` only for the duration of the call.
+ *       `path` may be NULL if no store path is associated.
src/libstore-c/nix_api_store.cc (1)

127-133: Make input path const to match header suggestion

The path isn’t mutated; align with proposed header change.

-nix_err nix_store_realise(
-    nix_c_context * context,
-    Store * store,
-    StorePath * path,
-    void * userdata,
-    void (*callback)(void * userdata, const char *, const StorePath *))
+nix_err nix_store_realise(
+    nix_c_context * context,
+    Store * store,
+    const StorePath * path,
+    void * userdata,
+    void (*callback)(void * userdata, const char *, const StorePath *))
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 46af567 and c14c3ca.

📒 Files selected for processing (2)
  • src/libstore-c/nix_api_store.cc (5 hunks)
  • src/libstore-c/nix_api_store.h (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/libstore-c/nix_api_store.h (1)
src/libstore-c/nix_api_store.cc (18)
  • nix_store_is_valid_path (94-102)
  • nix_store_is_valid_path (94-94)
  • callback (132-132)
  • callback (221-221)
  • callback (239-239)
  • callback (259-259)
  • nix_derivation_from_json (177-191)
  • nix_derivation_from_json (177-177)
  • nix_add_derivation (193-203)
  • nix_add_derivation (193-193)
  • nix_derivation_free (167-170)
  • nix_derivation_free (167-167)
  • nix_store_drv_from_path (217-234)
  • nix_store_drv_from_path (217-222)
  • nix_derivation_get_outputs (236-253)
  • nix_derivation_get_outputs (236-240)
  • nix_derivation_get_outputs_and_optpaths (255-280)
  • nix_derivation_get_outputs_and_optpaths (255-260)
src/libstore-c/nix_api_store.cc (1)
src/libstore/include/nix/store/store-api.hh (22)
  • path (318-318)
  • path (340-340)
  • path (346-346)
  • path (353-353)
  • path (357-357)
  • path (394-394)
  • path (400-400)
  • path (405-405)
  • path (415-415)
  • path (451-451)
  • path (461-464)
  • path (461-461)
  • path (474-477)
  • path (474-474)
  • path (482-482)
  • path (490-490)
  • drvPath (697-697)
  • drvPath (772-772)
  • drvPath (777-777)
  • drvPath (782-782)
  • name (563-570)
  • name (577-583)
⏰ 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). (3)
  • GitHub Check: build_x86_64-linux / vm_tests_smoke
  • GitHub Check: build_x86_64-linux / test
  • GitHub Check: build_aarch64-darwin / build
🔇 Additional comments (10)
src/libstore-c/nix_api_store.h (2)

155-155: Const-correctness LGTM

Using const StorePath * here is correct and matches the implementation.


250-267: API shape LGTM; borrowed lifetime note is good

Signature and const usage look correct.

src/libstore-c/nix_api_store.cc (8)

94-102: Const-correctness LGTM

Matches header and underlying API; good.


147-149: Borrowed StorePath passed to callback; ensure callers don’t retain

We construct a local StorePath and pass its address. Fine as a borrow, but callers must not store the pointer.

Please confirm downstream callbacks don’t capture or retain out beyond the call.


167-171: Destructor wrapper LGTM

Ownership and behavior are correct.


177-191: JSON -> derivation flow LGTM

Good use of fromJSON, read-only write for path, and invariant checks with proper error handling.


193-204: Store insertion LGTM

Straightforward write and return an owned StorePath.


217-234: Borrowed nix_derivation in callback LGTM

Borrowing semantics are clear; error handling consistent.


236-253: Outputs iteration LGTM

Pattern is correct and safe under borrow semantics.


255-279: Outputs + optional paths LGTM

Null handling and temp wrappers are sound under borrow semantics.

@github-actions github-actions bot temporarily deployed to pull request September 19, 2025 22:48 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: 1

♻️ Duplicate comments (1)
src/libstore-c/nix_api_store.h (1)

26-29: Fix typedef typo: breaks C callers using nix_derivation_output

Header uses nix_derivation_output in APIs but the typedef declares nix_derivatio_noutput, so C code will fail to compile without struct keyword. Correct the alias.

-/** @brief Nix Derivation Output */
-typedef struct nix_derivation_output nix_derivatio_noutput;
+/** @brief Nix Derivation Output */
+typedef struct nix_derivation_output nix_derivation_output;
🧹 Nitpick comments (4)
src/libstore-c/nix_api_store.h (4)

192-198: Make input path const for realise API, to match callback and intent

The callback now receives const StorePath * out (good). The input path should also be const StorePath * for consistency and to signal no mutation.

 nix_err nix_store_realise(
     nix_c_context * context,
     Store * store,
-    StorePath * path,
+    const StorePath * path,
     void * userdata,
     void (*callback)(void * userdata, const char * outname, const StorePath * out));

223-231: Clarify ownership of returned StorePath

Document that the returned StorePath * must be freed by the caller (via nix_store_path_free). Avoids leaks for C consumers.

 /**
  * @brief Add the given `nix_derivation` to the given store
  *
  * @param[out] context Optional, stores error information.
  * @param[in] store nix store reference. The derivation will be inserted here.
  * @param[in] derivation nix_derivation to insert into the given store.
+ * @note The returned StorePath is owned by the caller and must be freed with nix_store_path_free().
  */
 StorePath * nix_add_derivation(nix_c_context * context, Store * store, nix_derivation * derivation);

268-283: Document borrow semantics for name argument in outputs callback

Like the output object, name is only valid during the callback. Add a brief note to prevent misuse.

 /**
  * @brief Iterate through all of the outputs in a derivation
  *
- * @note The callback borrows the DerivationOutput only for the duration of the call.
+ * @note The callback borrows the DerivationOutput and the `name` string only for the duration of the call.
  *
  * @param[out] context Optional, stores error information
  * @param[in] drv The derivation
  * @param[in] callback The function to call on every output
  * @param[in] userdata Userdata to pass to the callback
  */

284-301: Explicitly state that path may be NULL

The API name says “optpaths”; make it explicit in the docs that path can be NULL.

 /**
  * @brief Iterate and get all of the derivation outputs and their store paths.
  *
- * @note The callback borrows the DerivationOutput and StorePath only for the duration of the call.
+ * @note The callback borrows the DerivationOutput and StorePath only for the duration of the call.
+ *       The StorePath pointer may be NULL if the output has no store path.
  *
  * @param[out] context Optional, stores error information
  * @param[in] drv The derivation
  * @param[in] store The nix store
  * @param[in] callback The function to call on every output and store path
  * @param[in] userdata The userdata to pass to the callback
  */
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c14c3ca and 6f6f94a.

📒 Files selected for processing (2)
  • src/libstore-c/nix_api_store.cc (5 hunks)
  • src/libstore-c/nix_api_store.h (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/libstore-c/nix_api_store.cc
🧰 Additional context used
🧬 Code graph analysis (1)
src/libstore-c/nix_api_store.h (1)
src/libstore-c/nix_api_store.cc (20)
  • nix_store_is_valid_path (94-102)
  • nix_store_is_valid_path (94-94)
  • callback (132-132)
  • callback (221-221)
  • callback (239-239)
  • callback (259-259)
  • nix_derivation_from_json (177-191)
  • nix_derivation_from_json (177-177)
  • nix_add_derivation (193-203)
  • nix_add_derivation (193-193)
  • nix_derivation_free (167-170)
  • nix_derivation_free (167-167)
  • nix_store_drv_from_path (217-234)
  • nix_store_drv_from_path (217-222)
  • nix_derivation_get_outputs (236-253)
  • nix_derivation_get_outputs (236-240)
  • nix_derivation_get_outputs_and_optpaths (255-280)
  • nix_derivation_get_outputs_and_optpaths (255-260)
  • nix_derivation_get_structured_attrs (282-295)
  • nix_derivation_get_structured_attrs (282-284)
⏰ 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). (3)
  • GitHub Check: build_aarch64-darwin / manual
  • GitHub Check: build_x86_64-linux / vm_tests_smoke
  • GitHub Check: build_x86_64-linux / test
🔇 Additional comments (5)
src/libstore-c/nix_api_store.h (5)

155-155: Const-correctness improvement LGTM

Switching nix_store_is_valid_path to take const StorePath * is correct and consistent with read-only semantics.


238-238: Free function LGTM

nix_derivation_free matches the ownership model introduced by the new constructor.


250-267: API shape LGTM; good borrowing semantics note

The borrow-lifetime note for nix_store_drv_from_path is clear and safe for stack-backed wrapper usage in the implementation.


312-319: Clone API LGTM

Clear ownership and symmetry with free.


320-327: Free API LGTM

Consistent with other object lifetimes in this header.

@github-actions github-actions bot temporarily deployed to pull request September 19, 2025 23:14 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

♻️ Duplicate comments (1)
src/libstore-c/nix_api_store.h (1)

26-29: Fix typedef: alias name typo breaks build

nix_derivation_output functions below rely on a proper typedef, but Line 29 defines nix_derivation_noutput. This prevents use of the unqualified name in prototypes and will fail to compile.

Apply:

-/** @brief Nix Derivation Output */
-typedef struct nix_derivation_output nix_derivation_noutput;
+/** @brief Nix Derivation Output */
+typedef struct nix_derivation_output nix_derivation_output;
🧹 Nitpick comments (5)
src/libstore-c/nix_api_store.h (3)

192-198: Document borrowed lifetime for out in realise callback

The callback now receives const StorePath *. Like other APIs here, the pointer is a borrowed view valid only during the callback, but this isn’t documented for nix_store_realise.

Proposed doc tweak:

  /**
   * @brief Realise a Nix store path
   *
   * Blocking, calls callback once for each realised output.
   *
   * @note When working with expressions, consider using e.g. nix_string_realise to get the output. `.drvPath` may not be
   * accurate or available in the future. See https://github.com/NixOS/nix/issues/6507
+  *
+  * @note The `out` StorePath passed to the callback is borrowed and only valid
+  *       for the duration of the callback. Clone it if you need to retain it.
   *
   * @param[out] context Optional, stores error information

223-231: Const-qualify the derivation parameter

nix_add_derivation does not mutate derivation. Prefer const nix_derivation * for API clarity.

Header change:

-StorePath * nix_add_derivation(nix_c_context * context, Store * store, nix_derivation * derivation);
+StorePath * nix_add_derivation(nix_c_context * context, Store * store, const nix_derivation * derivation);

I’ve included the matching .cc change in a later comment.


303-313: Define behavior when structured attrs are absent; fix minor param-name inconsistency

When structuredAttrs is missing, the implementation currently does nothing and still returns NIX_OK. Please specify behavior (e.g., call back with "null" or return a not-found error) to avoid ambiguity for callers. Also, docs mention user_data but the parameter is userdata elsewhere.

I’ve included a concrete .cc diff to emit "null" below. If preferred, we can document the “no callback on absence” rule instead.

src/libstore-c/nix_api_store.cc (2)

193-203: Const-qualify derivation parameter to mirror header suggestion

No mutation occurs; const is appropriate.

-StorePath * nix_add_derivation(nix_c_context * context, Store * store, nix_derivation * derivation)
+StorePath * nix_add_derivation(nix_c_context * context, Store * store, const nix_derivation * derivation)

283-297: Emit explicit value when structuredAttrs is absent

Currently returns NIX_OK but never invokes the callback if attrs are missing. Consider invoking the callback with "null" to make absence explicit and keep behavior uniform.

 nix_err nix_derivation_get_structured_attrs(
     nix_c_context * context, const nix_derivation * drv, nix_get_string_callback callback, void * userdata)
 {
     if (context)
         context->last_err_code = NIX_OK;
     try {
-        if (auto structuredAttrs = drv->drv.structuredAttrs) {
-            if (callback) {
-                auto result = structuredAttrs->structuredAttrs.dump();
-                callback(result.data(), result.size(), userdata);
-            }
-        }
+        if (auto structuredAttrs = drv->drv.structuredAttrs) {
+            if (callback) {
+                auto result = structuredAttrs->structuredAttrs.dump();
+                callback(result.data(), result.size(), userdata);
+            }
+        } else if (callback) {
+            static const char null_json[] = "null";
+            callback(null_json, sizeof null_json - 1, userdata);
+        }
     }
     NIXC_CATCH_ERRS
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6f6f94a and 02fc921.

📒 Files selected for processing (2)
  • src/libstore-c/nix_api_store.cc (5 hunks)
  • src/libstore-c/nix_api_store.h (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/libstore-c/nix_api_store.h (1)
src/libstore-c/nix_api_store.cc (24)
  • nix_store_is_valid_path (94-102)
  • nix_store_is_valid_path (94-94)
  • callback (132-132)
  • callback (221-221)
  • callback (239-239)
  • callback (259-260)
  • nix_derivation_from_json (177-191)
  • nix_derivation_from_json (177-177)
  • nix_add_derivation (193-203)
  • nix_add_derivation (193-193)
  • nix_derivation_free (167-170)
  • nix_derivation_free (167-167)
  • nix_store_drv_from_path (217-234)
  • nix_store_drv_from_path (217-222)
  • nix_derivation_get_outputs (236-253)
  • nix_derivation_get_outputs (236-240)
  • nix_derivation_get_outputs_and_optpaths (255-281)
  • nix_derivation_get_outputs_and_optpaths (255-261)
  • nix_derivation_get_structured_attrs (283-297)
  • nix_derivation_get_structured_attrs (283-284)
  • nix_derivation_output_clone (299-302)
  • nix_derivation_output_clone (299-299)
  • nix_derivation_output_free (304-307)
  • nix_derivation_output_free (304-304)
src/libstore-c/nix_api_store.cc (1)
src/libstore/include/nix/store/store-api.hh (20)
  • path (318-318)
  • path (340-340)
  • path (346-346)
  • path (353-353)
  • path (357-357)
  • path (394-394)
  • path (400-400)
  • path (405-405)
  • path (415-415)
  • path (451-451)
  • path (461-464)
  • path (461-461)
  • path (474-477)
  • path (474-474)
  • path (482-482)
  • path (490-490)
  • drvPath (697-697)
  • drvPath (772-772)
  • drvPath (777-777)
  • drvPath (782-782)
⏰ 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 / manual
  • GitHub Check: build_x86_64-linux / test
🔇 Additional comments (14)
src/libstore-c/nix_api_store.h (6)

155-155: Const-correctness on path parameter — looks good

Changing nix_store_is_valid_path to take const StorePath * is correct and matches usage in the implementation.


214-222: Clarify side effects of nix_derivation_from_json

Header says “Create a nix_derivation from JSON,” but the implementation parses JSON and calls writeDerivation (read-only mode) and checkInvariants. Please confirm and document whether this function is guaranteed to be side‑effect free with respect to the store (i.e., does not persist anything) and that insertion should happen only via nix_add_derivation.


250-267: Borrowed-lifetime contract is clear — LGTM

The API notes the derivation is only borrowed during the callback. Matches the implementation pattern.


278-283: Output iteration API — LGTM

Callback shape and borrowing semantics look consistent.


295-302: Outputs + optional paths — LGTM

Good use of const Store * and explicit “borrowed” note.


320-328: Clone/free wrappers — LGTM

Names and signatures now match the header; simple ownership semantics.

src/libstore-c/nix_api_store.cc (8)

94-102: isValidPath wrapper — LGTM

Matches the new const StorePath * signature and returns false on exceptions via NIXC_CATCH_ERRS_RES(false).


127-149: Realise callback receives StorePath * — implementation OK

Passing a stack StorePath to the callback is fine given the synchronous, borrowed-lifetime contract. No change requested.

Please ensure downstream callbacks do not stash the StorePath * beyond the call.


167-171: Destructor — LGTM

Simple delete wrapper; no issues.


177-191: Confirm from_json store side effects

This parses JSON, invokes writeDerivation with /* read only */ true, then checks invariants. Please confirm that this does not write to the store and is intended purely for validation + wrapping. If so, consider adding a note in the header.


217-234: Derivation-from-path callback — LGTM

Temporary wrapper and borrowed-lifetime behavior are correct and documented in the header.


236-253: Outputs iteration — LGTM

Straightforward mapping to drv.outputs; good.


255-281: Outputs + opt paths — LGTM

Correctly handles both present and absent paths.


299-307: Clone/free — LGTM

Names now align with the header; ownership is clear.

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.

2 participants