From ea0c7810c76c70f842056f052f56c2d848a6a74a Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Fri, 19 Sep 2025 14:25:46 -0700 Subject: [PATCH 01/13] libstore-c: add derivation functions --- src/libstore-c/nix_api_store.cc | 85 ++++++++++++++++++++++++ src/libstore-c/nix_api_store.h | 88 +++++++++++++++++++++++++ src/libstore-c/nix_api_store_internal.h | 11 ++++ 3 files changed, 184 insertions(+) diff --git a/src/libstore-c/nix_api_store.cc b/src/libstore-c/nix_api_store.cc index 0360427b643..7e6b3f5e064 100644 --- a/src/libstore-c/nix_api_store.cc +++ b/src/libstore-c/nix_api_store.cc @@ -208,3 +208,88 @@ nix_err nix_store_get_fs_closure( } NIXC_CATCH_ERRS } + +nix_err nix_store_drv_from_path( + nix_c_context * context, + Store * store, + const StorePath * path, + void (*callback)(void * userdata, const Derivation * drv), + void * userdata) +{ + if (context) + context->last_err_code = NIX_OK; + try { + nix::Derivation drv = store->ptr->derivationFromPath(path->path); + if (callback) { + const Derivation tmp{drv}; + callback(userdata, &tmp); + } + } + NIXC_CATCH_ERRS +} + +Derivation * nix_drv_clone(const Derivation * d) +{ + return new Derivation{d->drv}; +} + +void nix_drv_free(Derivation * d) +{ + delete d; +} + +nix_err nix_drv_get_outputs( + nix_c_context * context, + const Derivation * drv, + void (*callback)(void * userdata, const char * name, const DerivationOutput * drv_output), + void * userdata) +{ + if (context) + context->last_err_code = NIX_OK; + try { + if (callback) { + for (const auto & [name, result] : drv->drv.outputs) { + const DerivationOutput tmp{result}; + callback(userdata, name.c_str(), &tmp); + } + } + } + NIXC_CATCH_ERRS +} + +nix_err nix_drv_get_outputs_and_optpaths( + nix_c_context * context, + const Derivation * drv, + const Store * store, + void (*callback)(void * userdata, const char * name, const DerivationOutput * drv_output, const StorePath * path), + void * userdata) +{ + if (context) + context->last_err_code = NIX_OK; + try { + auto value = drv->drv.outputsAndOptPaths(store->ptr->config); + if (callback) { + for (const auto & [name, result] : value) { + const DerivationOutput tmp_output{result.first}; + + if (auto store_path = result.second) { + const StorePath tmp_path{*store_path}; + callback(userdata, name.c_str(), &tmp_output, &tmp_path); + } else { + callback(userdata, name.c_str(), &tmp_output, nullptr); + } + } + } + } + NIXC_CATCH_ERRS +} + +DerivationOutput * nix_drv_output_clone(const DerivationOutput * o) +{ + return new DerivationOutput{o->drv_out}; +} + +void nix_drv_output_free(DerivationOutput * o) +{ + delete o; +} diff --git a/src/libstore-c/nix_api_store.h b/src/libstore-c/nix_api_store.h index c1e94ed255f..451b80c3b3b 100644 --- a/src/libstore-c/nix_api_store.h +++ b/src/libstore-c/nix_api_store.h @@ -23,6 +23,10 @@ extern "C" { typedef struct Store Store; /** @brief Nix store path */ typedef struct StorePath StorePath; +/** @brief Nix Derivation */ +typedef struct Derivation Derivation; +/** @brief Nix Derivation Output */ +typedef struct DerivationOutput DerivationOutput; /** * @brief Initializes the Nix store library @@ -241,6 +245,90 @@ nix_err nix_store_get_fs_closure( void * userdata, void (*callback)(void * userdata, const StorePath * store_path)); +/* + * @brief Returns the derivation associated with the store path + * + * @note The callback borrows the Derivation only for the duration of the call. + * + * @param[out] context Optional, stores error information + * @param[in] store The nix store + * @param[in] path The nix store path + * @param[in] callback The callback to call + * @param[in] userdata The userdata to pass to the callback + */ +nix_err nix_store_drv_from_path( + nix_c_context * context, + Store * store, + const StorePath * path, + void (*callback)(void * userdata, const Derivation * drv), + void * userdata); + +/** + * @brief Copy of a Derivation + * + * @param[in] d the derivation to copy + * @return a new Derivation + */ +Derivation * nix_drv_clone(const Derivation * d); + +/** + * @brief Deallocate a Derivation + * + * Does not fail. + * @param[in] p the derivation to free + */ +void nix_drv_free(Derivation * d); + +/** + * @brief Iterate through all of the outputs in a derivation + * + * @note The callback borrows the DerivationOutput 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 + */ +nix_err nix_drv_get_outputs( + nix_c_context * context, + const Derivation * drv, + void (*callback)(void * userdata, const char * name, const DerivationOutput * drv_output), + void * userdata); + +/** + * @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. + * + * @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 + */ +nix_err nix_drv_get_outputs_and_optpaths( + nix_c_context * context, + const Derivation * drv, + const Store * store, + void (*callback)(void * userdata, const char * name, const DerivationOutput * drv_output, const StorePath * path), + void * userdata); + +/** + * @brief Copy of a DerivationOutput + * + * @param[in] o the derivation output to copy + * @return a new DerivationOutput + */ +DerivationOutput * nix_drv_output_clone(const DerivationOutput * o); + +/** + * @brief Deallocate a DerivationOutput + * + * Does not fail. + * @param[in] o the derivation output to free + */ +void nix_drv_output_free(DerivationOutput * o); + // cffi end #ifdef __cplusplus } diff --git a/src/libstore-c/nix_api_store_internal.h b/src/libstore-c/nix_api_store_internal.h index b0194bfd3ad..7e1ee12ea08 100644 --- a/src/libstore-c/nix_api_store_internal.h +++ b/src/libstore-c/nix_api_store_internal.h @@ -1,5 +1,6 @@ #ifndef NIX_API_STORE_INTERNAL_H #define NIX_API_STORE_INTERNAL_H +#include "nix/store/derivations.hh" #include "nix/store/store-api.hh" struct Store @@ -12,4 +13,14 @@ struct StorePath nix::StorePath path; }; +struct Derivation +{ + nix::Derivation drv; +}; + +struct DerivationOutput +{ + nix::DerivationOutput drv_out; +}; + #endif From ff7618a2e49a54353e241227306add481edf1f09 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Tue, 2 Sep 2025 11:20:51 -0400 Subject: [PATCH 02/13] Add new C API for working with derivations Also test the APIs we just added. --- src/libexpr-tests/main.cc | 39 ++--------- src/libstore-c/nix_api_store.cc | 69 ++++++++++++------ src/libstore-c/nix_api_store.h | 70 +++++++++++-------- src/libstore-c/nix_api_store_internal.h | 6 +- .../include/nix/store/tests/meson.build | 1 + .../include/nix/store/tests/nix_api_store.hh | 51 ++++++++++---- .../include/nix/store/tests/test-main.hh | 13 ++++ src/libstore-test-support/meson.build | 1 + src/libstore-test-support/test-main.cc | 47 +++++++++++++ .../data/derivation/ca/self-contained.json | 23 ++++++ src/libstore-tests/main.cc | 15 ++++ src/libstore-tests/meson.build | 1 + src/libstore-tests/nix_api_store.cc | 59 ++++++++++++++++ 13 files changed, 292 insertions(+), 103 deletions(-) create mode 100644 src/libstore-test-support/include/nix/store/tests/test-main.hh create mode 100644 src/libstore-test-support/test-main.cc create mode 100644 src/libstore-tests/data/derivation/ca/self-contained.json create mode 100644 src/libstore-tests/main.cc diff --git a/src/libexpr-tests/main.cc b/src/libexpr-tests/main.cc index 61b40e8349f..d6b0d0ab93f 100644 --- a/src/libexpr-tests/main.cc +++ b/src/libexpr-tests/main.cc @@ -1,43 +1,14 @@ #include -#include -#include "nix/store/globals.hh" -#include "nix/util/logging.hh" + +#include "nix/store/tests/test-main.hh" using namespace nix; int main(int argc, char ** argv) { - if (argc > 1 && std::string_view(argv[1]) == "__build-remote") { - printError("test-build-remote: not supported in libexpr unit tests"); - return 1; - } - - // Disable build hook. We won't be testing remote builds in these unit tests. If we do, fix the above build hook. - settings.buildHook = {}; - -#ifdef __linux__ // should match the conditional around sandboxBuildDir declaration. - - // When building and testing nix within the host's Nix sandbox, our store dir will be located in the host's - // sandboxBuildDir, e.g.: Host - // storeDir = /nix/store - // sandboxBuildDir = /build - // This process - // storeDir = /build/foo/bar/store - // sandboxBuildDir = /build - // However, we have a rule that the store dir must not be inside the storeDir, so we need to pick a different - // sandboxBuildDir. - settings.sandboxBuildDir = "/test-build-dir-instead-of-usual-build-dir"; -#endif - -#ifdef __APPLE__ - // Avoid this error, when already running in a sandbox: - // sandbox-exec: sandbox_apply: Operation not permitted - settings.sandboxMode = smDisabled; - setEnv("_NIX_TEST_NO_SANDBOX", "1"); -#endif - - // For pipe operator tests in trivial.cc - experimentalFeatureSettings.set("experimental-features", "pipe-operators"); + auto res = testMainForBuidingPre(argc, argv); + if (!res) + return res; ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/src/libstore-c/nix_api_store.cc b/src/libstore-c/nix_api_store.cc index 7e6b3f5e064..abc9c7ea0b2 100644 --- a/src/libstore-c/nix_api_store.cc +++ b/src/libstore-c/nix_api_store.cc @@ -164,11 +164,44 @@ void nix_store_path_free(StorePath * sp) delete sp; } +void nix_derivation_free(nix_derivation * drv) +{ + delete drv; +} + StorePath * nix_store_path_clone(const StorePath * p) { return new StorePath{p->path}; } +nix_derivation * nix_derivation_from_json(nix_c_context * context, Store * store, const char * json) +{ + if (context) + context->last_err_code = NIX_OK; + try { + auto drv = nix::Derivation::fromJSON(*store->ptr, nlohmann::json::parse(json)); + + auto drvPath = nix::writeDerivation(*store->ptr, drv, nix::NoRepair, /* read only */ true); + + drv.checkInvariants(*store->ptr, drvPath); + + return new nix_derivation{drv}; + } + NIXC_CATCH_ERRS_NULL +} + +StorePath * nix_add_derivation(nix_c_context * context, Store * store, nix_derivation * derivation) +{ + if (context) + context->last_err_code = NIX_OK; + try { + auto ret = nix::writeDerivation(*store->ptr, derivation->drv, nix::NoRepair); + + return new StorePath{ret}; + } + NIXC_CATCH_ERRS_NULL +} + nix_err nix_store_copy_closure(nix_c_context * context, Store * srcStore, Store * dstStore, StorePath * path) { if (context) @@ -213,7 +246,7 @@ nix_err nix_store_drv_from_path( nix_c_context * context, Store * store, const StorePath * path, - void (*callback)(void * userdata, const Derivation * drv), + void (*callback)(void * userdata, const nix_derivation * drv), void * userdata) { if (context) @@ -221,27 +254,17 @@ nix_err nix_store_drv_from_path( try { nix::Derivation drv = store->ptr->derivationFromPath(path->path); if (callback) { - const Derivation tmp{drv}; + const nix_derivation tmp{drv}; callback(userdata, &tmp); } } NIXC_CATCH_ERRS } -Derivation * nix_drv_clone(const Derivation * d) -{ - return new Derivation{d->drv}; -} - -void nix_drv_free(Derivation * d) -{ - delete d; -} - -nix_err nix_drv_get_outputs( +nix_err nix_derivation_get_outputs( nix_c_context * context, - const Derivation * drv, - void (*callback)(void * userdata, const char * name, const DerivationOutput * drv_output), + const nix_derivation * drv, + void (*callback)(void * userdata, const char * name, const nix_derivation_output * drv_output), void * userdata) { if (context) @@ -249,7 +272,7 @@ nix_err nix_drv_get_outputs( try { if (callback) { for (const auto & [name, result] : drv->drv.outputs) { - const DerivationOutput tmp{result}; + const nix_derivation_output tmp{result}; callback(userdata, name.c_str(), &tmp); } } @@ -257,11 +280,11 @@ nix_err nix_drv_get_outputs( NIXC_CATCH_ERRS } -nix_err nix_drv_get_outputs_and_optpaths( +nix_err nix_derivation_get_outputs_and_optpaths( nix_c_context * context, - const Derivation * drv, + const nix_derivation * drv, const Store * store, - void (*callback)(void * userdata, const char * name, const DerivationOutput * drv_output, const StorePath * path), + void (*callback)(void * userdata, const char * name, const nix_derivation_output * drv_output, const StorePath * path), void * userdata) { if (context) @@ -270,7 +293,7 @@ nix_err nix_drv_get_outputs_and_optpaths( auto value = drv->drv.outputsAndOptPaths(store->ptr->config); if (callback) { for (const auto & [name, result] : value) { - const DerivationOutput tmp_output{result.first}; + const nix_derivation_output tmp_output{result.first}; if (auto store_path = result.second) { const StorePath tmp_path{*store_path}; @@ -284,12 +307,12 @@ nix_err nix_drv_get_outputs_and_optpaths( NIXC_CATCH_ERRS } -DerivationOutput * nix_drv_output_clone(const DerivationOutput * o) +nix_derivation_output * nix_drv_output_clone(const nix_derivation_output * o) { - return new DerivationOutput{o->drv_out}; + return new nix_derivation_output{o->drv_out}; } -void nix_drv_output_free(DerivationOutput * o) +void nix_drv_output_free(nix_derivation_output * o) { delete o; } diff --git a/src/libstore-c/nix_api_store.h b/src/libstore-c/nix_api_store.h index 451b80c3b3b..f27b1d8b7d7 100644 --- a/src/libstore-c/nix_api_store.h +++ b/src/libstore-c/nix_api_store.h @@ -24,9 +24,9 @@ typedef struct Store Store; /** @brief Nix store path */ typedef struct StorePath StorePath; /** @brief Nix Derivation */ -typedef struct Derivation Derivation; +typedef struct nix_derivation nix_derivation; /** @brief Nix Derivation Output */ -typedef struct DerivationOutput DerivationOutput; +typedef struct nix_derivation_output nix_derivatio_noutput; /** * @brief Initializes the Nix store library @@ -211,6 +211,32 @@ nix_err nix_store_realise( nix_err nix_store_get_version(nix_c_context * context, Store * store, nix_get_string_callback callback, void * user_data); +/** + * @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. + */ +nix_derivation * nix_derivation_from_json(nix_c_context * context, Store * store, const char * json); + +/** + * @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. + */ +StorePath * nix_add_derivation(nix_c_context * context, Store * store, nix_derivation * derivation); + +/** + * @brief Deallocate a `nix_derivation' + * + * Does not fail. + * @param[in] drv the derivation to free + */ +void nix_derivation_free(nix_derivation * drv); + /** * @brief Copy the closure of `path` from `srcStore` to `dstStore`. * @@ -260,25 +286,9 @@ nix_err nix_store_drv_from_path( nix_c_context * context, Store * store, const StorePath * path, - void (*callback)(void * userdata, const Derivation * drv), + void (*callback)(void * userdata, const nix_derivation * drv), void * userdata); -/** - * @brief Copy of a Derivation - * - * @param[in] d the derivation to copy - * @return a new Derivation - */ -Derivation * nix_drv_clone(const Derivation * d); - -/** - * @brief Deallocate a Derivation - * - * Does not fail. - * @param[in] p the derivation to free - */ -void nix_drv_free(Derivation * d); - /** * @brief Iterate through all of the outputs in a derivation * @@ -289,10 +299,10 @@ void nix_drv_free(Derivation * d); * @param[in] callback The function to call on every output * @param[in] userdata Userdata to pass to the callback */ -nix_err nix_drv_get_outputs( +nix_err nix_derivation_get_outputs( nix_c_context * context, - const Derivation * drv, - void (*callback)(void * userdata, const char * name, const DerivationOutput * drv_output), + const nix_derivation * drv, + void (*callback)(void * userdata, const char * name, const nix_derivation_output * drv_output), void * userdata); /** @@ -306,28 +316,28 @@ nix_err nix_drv_get_outputs( * @param[in] callback The function to call on every output and store path * @param[in] userdata The userdata to pass to the callback */ -nix_err nix_drv_get_outputs_and_optpaths( +nix_err nix_derivation_get_outputs_and_optpaths( nix_c_context * context, - const Derivation * drv, + const nix_derivation * drv, const Store * store, - void (*callback)(void * userdata, const char * name, const DerivationOutput * drv_output, const StorePath * path), + void (*callback)(void * userdata, const char * name, const nix_derivation_output * drv_output, const StorePath * path), void * userdata); /** - * @brief Copy of a DerivationOutput + * @brief Copy of a 'nix_derivation_output' * * @param[in] o the derivation output to copy - * @return a new DerivationOutput + * @return a new 'nix_derivation_output' */ -DerivationOutput * nix_drv_output_clone(const DerivationOutput * o); +nix_derivation_output * nix_derivation_output_clone(const nix_derivation_output * o); /** - * @brief Deallocate a DerivationOutput + * @brief Deallocate a 'nix_derivation_output' * * Does not fail. * @param[in] o the derivation output to free */ -void nix_drv_output_free(DerivationOutput * o); +void nix_derivation_output_free(nix_derivation_output * o); // cffi end #ifdef __cplusplus diff --git a/src/libstore-c/nix_api_store_internal.h b/src/libstore-c/nix_api_store_internal.h index 7e1ee12ea08..070bb1229cd 100644 --- a/src/libstore-c/nix_api_store_internal.h +++ b/src/libstore-c/nix_api_store_internal.h @@ -1,7 +1,7 @@ #ifndef NIX_API_STORE_INTERNAL_H #define NIX_API_STORE_INTERNAL_H -#include "nix/store/derivations.hh" #include "nix/store/store-api.hh" +#include "nix/store/derivations.hh" struct Store { @@ -13,12 +13,12 @@ struct StorePath nix::StorePath path; }; -struct Derivation +struct nix_derivation { nix::Derivation drv; }; -struct DerivationOutput +struct nix_derivation_output { nix::DerivationOutput drv_out; }; diff --git a/src/libstore-test-support/include/nix/store/tests/meson.build b/src/libstore-test-support/include/nix/store/tests/meson.build index f79769d4102..33524de3851 100644 --- a/src/libstore-test-support/include/nix/store/tests/meson.build +++ b/src/libstore-test-support/include/nix/store/tests/meson.build @@ -9,4 +9,5 @@ headers = files( 'outputs-spec.hh', 'path.hh', 'protocol.hh', + 'test-main.hh', ) diff --git a/src/libstore-test-support/include/nix/store/tests/nix_api_store.hh b/src/libstore-test-support/include/nix/store/tests/nix_api_store.hh index 608aa63d65e..7ecc5603b6a 100644 --- a/src/libstore-test-support/include/nix/store/tests/nix_api_store.hh +++ b/src/libstore-test-support/include/nix/store/tests/nix_api_store.hh @@ -12,33 +12,32 @@ #include namespace nixC { -class nix_api_store_test : public nix_api_util_context + +class nix_api_store_test_base : public nix_api_util_context { public: - nix_api_store_test() + nix_api_store_test_base() { nix_libstore_init(ctx); - init_local_store(); }; - ~nix_api_store_test() override + ~nix_api_store_test_base() override { - nix_store_free(store); - - for (auto & path : std::filesystem::recursive_directory_iterator(nixDir)) { - std::filesystem::permissions(path, std::filesystem::perms::owner_all); + if (exists(std::filesystem::path{nixDir})) { + for (auto & path : std::filesystem::recursive_directory_iterator(nixDir)) { + std::filesystem::permissions(path, std::filesystem::perms::owner_all); + } + std::filesystem::remove_all(nixDir); } - std::filesystem::remove_all(nixDir); } - Store * store; std::string nixDir; std::string nixStoreDir; std::string nixStateDir; std::string nixLogDir; protected: - void init_local_store() + Store * open_local_store() { #ifdef _WIN32 // no `mkdtemp` with MinGW @@ -66,11 +65,37 @@ protected: const char ** params[] = {p1, p2, p3, nullptr}; - store = nix_store_open(ctx, "local", params); + auto * store = nix_store_open(ctx, "local", params); if (!store) { std::string errMsg = nix_err_msg(nullptr, ctx, nullptr); - ASSERT_NE(store, nullptr) << "Could not open store: " << errMsg; + EXPECT_NE(store, nullptr) << "Could not open store: " << errMsg; + assert(store); }; + return store; } }; + +class nix_api_store_test : public nix_api_store_test_base +{ +public: + nix_api_store_test() + : nix_api_store_test_base{} + { + init_local_store(); + }; + + ~nix_api_store_test() override + { + nix_store_free(store); + } + + Store * store; + +protected: + void init_local_store() + { + store = open_local_store(); + } +}; + } // namespace nixC diff --git a/src/libstore-test-support/include/nix/store/tests/test-main.hh b/src/libstore-test-support/include/nix/store/tests/test-main.hh new file mode 100644 index 00000000000..3a1897469de --- /dev/null +++ b/src/libstore-test-support/include/nix/store/tests/test-main.hh @@ -0,0 +1,13 @@ +#pragma once + +///@file + +namespace nix { + +/** + * Call this for a GTest test suite that will including performing Nix + * builds, before running tests. + */ +int testMainForBuidingPre(int argc, char ** argv); + +} // namespace nix diff --git a/src/libstore-test-support/meson.build b/src/libstore-test-support/meson.build index b2977941f86..2cb2a70d697 100644 --- a/src/libstore-test-support/meson.build +++ b/src/libstore-test-support/meson.build @@ -34,6 +34,7 @@ sources = files( 'derived-path.cc', 'outputs-spec.cc', 'path.cc', + 'test-main.cc', ) subdir('include/nix/store/tests') diff --git a/src/libstore-test-support/test-main.cc b/src/libstore-test-support/test-main.cc new file mode 100644 index 00000000000..0b9072dc08f --- /dev/null +++ b/src/libstore-test-support/test-main.cc @@ -0,0 +1,47 @@ +#include + +#include "nix/store/globals.hh" +#include "nix/util/logging.hh" + +#include "nix/store/tests/test-main.hh" + +namespace nix { + +int testMainForBuidingPre(int argc, char ** argv) +{ + if (argc > 1 && std::string_view(argv[1]) == "__build-remote") { + printError("test-build-remote: not supported in libexpr unit tests"); + return EXIT_FAILURE; + } + + // Disable build hook. We won't be testing remote builds in these unit tests. If we do, fix the above build hook. + settings.buildHook = {}; + + // No substituters, unless a test specifically requests. + settings.substituters = {}; + +#ifdef __linux__ // should match the conditional around sandboxBuildDir declaration. + + // When building and testing nix within the host's Nix sandbox, our store dir will be located in the host's + // sandboxBuildDir, e.g.: Host + // storeDir = /nix/store + // sandboxBuildDir = /build + // This process + // storeDir = /build/foo/bar/store + // sandboxBuildDir = /build + // However, we have a rule that the store dir must not be inside the storeDir, so we need to pick a different + // sandboxBuildDir. + settings.sandboxBuildDir = "/test-build-dir-instead-of-usual-build-dir"; +#endif + +#ifdef __APPLE__ + // Avoid this error, when already running in a sandbox: + // sandbox-exec: sandbox_apply: Operation not permitted + settings.sandboxMode = smDisabled; + setEnv("_NIX_TEST_NO_SANDBOX", "1"); +#endif + + return EXIT_SUCCESS; +} + +} // namespace nix diff --git a/src/libstore-tests/data/derivation/ca/self-contained.json b/src/libstore-tests/data/derivation/ca/self-contained.json new file mode 100644 index 00000000000..c4ca280ef66 --- /dev/null +++ b/src/libstore-tests/data/derivation/ca/self-contained.json @@ -0,0 +1,23 @@ +{ + "args": [ + "-c", + "echo $name foo > $out" + ], + "builder": "/bin/sh", + "env": { + "builder": "/bin/sh", + "name": "myname", + "out": "/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9", + "system": "x86_64-linux" + }, + "inputDrvs": {}, + "inputSrcs": [], + "name": "myname", + "outputs": { + "out": { + "hashAlgo": "sha256", + "method": "nar" + } + }, + "system": "x86_64-linux" +} diff --git a/src/libstore-tests/main.cc b/src/libstore-tests/main.cc new file mode 100644 index 00000000000..ffe9816134f --- /dev/null +++ b/src/libstore-tests/main.cc @@ -0,0 +1,15 @@ +#include + +#include "nix/store/tests/test-main.hh" + +using namespace nix; + +int main(int argc, char ** argv) +{ + auto res = testMainForBuidingPre(argc, argv); + if (res) + return res; + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/libstore-tests/meson.build b/src/libstore-tests/meson.build index fced202696e..31c20bef1b6 100644 --- a/src/libstore-tests/meson.build +++ b/src/libstore-tests/meson.build @@ -66,6 +66,7 @@ sources = files( 'local-overlay-store.cc', 'local-store.cc', 'machines.cc', + 'main.cc', 'nar-info-disk-cache.cc', 'nar-info.cc', 'nix_api_store.cc', diff --git a/src/libstore-tests/nix_api_store.cc b/src/libstore-tests/nix_api_store.cc index c7146f977a5..70b0ec9dc45 100644 --- a/src/libstore-tests/nix_api_store.cc +++ b/src/libstore-tests/nix_api_store.cc @@ -1,9 +1,12 @@ +#include + #include "nix_api_util.h" #include "nix_api_util_internal.h" #include "nix_api_store.h" #include "nix_api_store_internal.h" #include "nix/store/tests/nix_api_store.hh" +#include "nix/store/globals.hh" #include "nix/util/tests/string_callback.hh" #include "nix/util/url.hh" @@ -199,4 +202,60 @@ TEST_F(nix_api_util_context, nix_store_real_path_binary_cache) ASSERT_STREQ(path_raw.c_str(), rp.c_str()); } +template +struct LambdaAdapter +{ + F fun; + + template + static inline auto call(LambdaAdapter * ths, Args... args) + { + return ths->fun(args...); + } + + template + static auto call_void(void * ths, Args... args) + { + return call(static_cast *>(ths), args...); + } +}; + +TEST_F(nix_api_store_test_base, build_from_json) +{ + // FIXME get rid of these + nix::experimentalFeatureSettings.set("extra-experimental-features", "ca-derivations"); + nix::settings.substituters = {}; + + auto * store = open_local_store(); + + std::filesystem::path unitTestData{getenv("_NIX_TEST_UNIT_DATA")}; + + std::ifstream t{unitTestData / "derivation/ca/self-contained.json"}; + std::stringstream buffer; + buffer << t.rdbuf(); + + auto * drv = nix_derivation_from_json(ctx, store, buffer.str().c_str()); + assert_ctx_ok(); + ASSERT_NE(drv, nullptr); + + auto * drvPath = nix_add_derivation(ctx, store, drv); + assert_ctx_ok(); + ASSERT_NE(drv, nullptr); + + auto cb = LambdaAdapter{.fun = [&](const char * outname, const StorePath * outPath) { + auto is_valid_path = nix_store_is_valid_path(ctx, store, outPath); + ASSERT_EQ(is_valid_path, true); + }}; + + auto ret = nix_store_realise( + ctx, store, drvPath, static_cast(&cb), decltype(cb)::call_void); + assert_ctx_ok(); + ASSERT_EQ(ret, NIX_OK); + + // Clean up + nix_store_path_free(drvPath); + nix_derivation_free(drv); + nix_store_free(store); +} + } // namespace nixC From 77dd7a00be2b4ebd05b04dd95a9428c25494ccb8 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Tue, 2 Sep 2025 01:54:27 -0400 Subject: [PATCH 03/13] `nix_store_is_valid_path` param `path` should be `const` --- src/libstore-c/nix_api_store.cc | 2 +- src/libstore-c/nix_api_store.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstore-c/nix_api_store.cc b/src/libstore-c/nix_api_store.cc index abc9c7ea0b2..4b0b124ef2b 100644 --- a/src/libstore-c/nix_api_store.cc +++ b/src/libstore-c/nix_api_store.cc @@ -91,7 +91,7 @@ nix_store_get_version(nix_c_context * context, Store * store, nix_get_string_cal NIXC_CATCH_ERRS } -bool nix_store_is_valid_path(nix_c_context * context, Store * store, StorePath * path) +bool nix_store_is_valid_path(nix_c_context * context, Store * store, const StorePath * path) { if (context) context->last_err_code = NIX_OK; diff --git a/src/libstore-c/nix_api_store.h b/src/libstore-c/nix_api_store.h index f27b1d8b7d7..19a6651adae 100644 --- a/src/libstore-c/nix_api_store.h +++ b/src/libstore-c/nix_api_store.h @@ -152,7 +152,7 @@ void nix_store_path_free(StorePath * p); * @param[in] path Path to check * @return true or false, error info in context */ -bool nix_store_is_valid_path(nix_c_context * context, Store * store, StorePath * path); +bool nix_store_is_valid_path(nix_c_context * context, Store * store, const StorePath * path); /** * @brief Get the physical location of a store path From ffe1d46529c9322831aa30d95dd93130976d7aae Mon Sep 17 00:00:00 2001 From: John Ericson Date: Tue, 2 Sep 2025 11:17:26 -0400 Subject: [PATCH 04/13] `nix_store_realise`: Improve typing of store path Use `StorePath *` not `const char *`. --- src/libstore-c/nix_api_store.cc | 6 +++--- src/libstore-c/nix_api_store.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libstore-c/nix_api_store.cc b/src/libstore-c/nix_api_store.cc index 4b0b124ef2b..494c47da434 100644 --- a/src/libstore-c/nix_api_store.cc +++ b/src/libstore-c/nix_api_store.cc @@ -129,7 +129,7 @@ nix_err nix_store_realise( Store * store, StorePath * path, void * userdata, - void (*callback)(void * userdata, const char *, const char *)) + void (*callback)(void * userdata, const char *, const StorePath *)) { if (context) context->last_err_code = NIX_OK; @@ -144,8 +144,8 @@ nix_err nix_store_realise( if (callback) { for (const auto & result : results) { for (const auto & [outputName, realisation] : result.builtOutputs) { - auto op = store->ptr->printStorePath(realisation.outPath); - callback(userdata, outputName.c_str(), op.c_str()); + StorePath p{realisation.outPath}; + callback(userdata, outputName.c_str(), &p); } } } diff --git a/src/libstore-c/nix_api_store.h b/src/libstore-c/nix_api_store.h index 19a6651adae..cb5fcf7c645 100644 --- a/src/libstore-c/nix_api_store.h +++ b/src/libstore-c/nix_api_store.h @@ -194,7 +194,7 @@ nix_err nix_store_realise( Store * store, StorePath * path, void * userdata, - void (*callback)(void * userdata, const char * outname, const char * out)); + void (*callback)(void * userdata, const char * outname, const StorePath * out)); /** * @brief get the version of a nix store. From c1b766e1956c257d34ec0cd3f085f8a1fa420bfb Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Fri, 19 Sep 2025 15:44:35 -0700 Subject: [PATCH 05/13] libstore-c: add nix_derivation_get_structured_attrs --- src/libstore-c/nix_api_store.cc | 15 +++++++++++++++ src/libstore-c/nix_api_store.h | 10 ++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/libstore-c/nix_api_store.cc b/src/libstore-c/nix_api_store.cc index 494c47da434..7da59b72f02 100644 --- a/src/libstore-c/nix_api_store.cc +++ b/src/libstore-c/nix_api_store.cc @@ -307,6 +307,21 @@ nix_err nix_derivation_get_outputs_and_optpaths( NIXC_CATCH_ERRS } +const char * nix_derivation_get_structured_attrs( + nix_c_context * context, + const nix_derivation * drv) +{ + if (context) + context->last_err_code = NIX_OK; + try { + if (auto structuredAttrs = drv->drv.structuredAttrs) { + return structuredAttrs->structuredAttrs.dump().c_str(); + } + return nullptr; + } + NIXC_CATCH_ERRS_NULL +} + nix_derivation_output * nix_drv_output_clone(const nix_derivation_output * o) { return new nix_derivation_output{o->drv_out}; diff --git a/src/libstore-c/nix_api_store.h b/src/libstore-c/nix_api_store.h index cb5fcf7c645..4f5e8337af5 100644 --- a/src/libstore-c/nix_api_store.h +++ b/src/libstore-c/nix_api_store.h @@ -323,6 +323,16 @@ nix_err nix_derivation_get_outputs_and_optpaths( void (*callback)(void * userdata, const char * name, const nix_derivation_output * drv_output, const StorePath * path), void * userdata); +/** + * @brief Return the structured attrs of derivation as a JSON string + * + * @param[out] context Optional, stores error information + * @param[in] drv The derivation + */ +const char * nix_derivation_get_structured_attrs( + nix_c_context * context, + const nix_derivation * drv); + /** * @brief Copy of a 'nix_derivation_output' * From 04dd0c7e4f20f3dfea4ef34eec2e57f4b7b327c3 Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Fri, 19 Sep 2025 15:52:51 -0700 Subject: [PATCH 06/13] libstore-c: fix typo --- src/libstore-c/nix_api_store.cc | 20 +++++++++++--------- src/libstore-c/nix_api_store.h | 14 ++++++++------ 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/libstore-c/nix_api_store.cc b/src/libstore-c/nix_api_store.cc index 7da59b72f02..647a53094d7 100644 --- a/src/libstore-c/nix_api_store.cc +++ b/src/libstore-c/nix_api_store.cc @@ -284,7 +284,8 @@ nix_err nix_derivation_get_outputs_and_optpaths( nix_c_context * context, const nix_derivation * drv, const Store * store, - void (*callback)(void * userdata, const char * name, const nix_derivation_output * drv_output, const StorePath * path), + void (*callback)( + void * userdata, const char * name, const nix_derivation_output * drv_output, const StorePath * path), void * userdata) { if (context) @@ -307,27 +308,28 @@ nix_err nix_derivation_get_outputs_and_optpaths( NIXC_CATCH_ERRS } -const char * nix_derivation_get_structured_attrs( - nix_c_context * context, - const nix_derivation * drv) +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) { - return structuredAttrs->structuredAttrs.dump().c_str(); + if (callback) { + auto result = structuredAttrs->structuredAttrs.dump(); + callback(result.data(), result.size(), userdata); + } } - return nullptr; } - NIXC_CATCH_ERRS_NULL + NIXC_CATCH_ERRS } -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; } diff --git a/src/libstore-c/nix_api_store.h b/src/libstore-c/nix_api_store.h index 4f5e8337af5..e145a37383e 100644 --- a/src/libstore-c/nix_api_store.h +++ b/src/libstore-c/nix_api_store.h @@ -26,7 +26,7 @@ typedef struct StorePath StorePath; /** @brief Nix Derivation */ typedef struct nix_derivation nix_derivation; /** @brief Nix Derivation Output */ -typedef struct nix_derivation_output nix_derivatio_noutput; +typedef struct nix_derivation_output nix_derivation_noutput; /** * @brief Initializes the Nix store library @@ -320,18 +320,20 @@ nix_err nix_derivation_get_outputs_and_optpaths( nix_c_context * context, const nix_derivation * drv, const Store * store, - void (*callback)(void * userdata, const char * name, const nix_derivation_output * drv_output, const StorePath * path), + void (*callback)( + void * userdata, const char * name, const nix_derivation_output * drv_output, const StorePath * path), void * userdata); /** - * @brief Return the structured attrs of derivation as a JSON string + * @brief Gets the structured attrs of derivation as a JSON string * * @param[out] context Optional, stores error information * @param[in] drv The derivation + * @param[in] callback Called with the JSON string + * @param[in] user_data Arbitrary data passed to the callback */ -const char * nix_derivation_get_structured_attrs( - nix_c_context * context, - const nix_derivation * drv); +nix_err nix_derivation_get_structured_attrs( + nix_c_context * context, const nix_derivation * drv, nix_get_string_callback callback, void * userdata); /** * @brief Copy of a 'nix_derivation_output' From b3184a6be648d5b23a0c389e0b6021e7136bb647 Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Fri, 19 Sep 2025 17:04:03 -0700 Subject: [PATCH 07/13] libstore-c: add derivation clone function --- src/libstore-c/nix_api_store.cc | 44 +++++++++++++++++++++++++++------ src/libstore-c/nix_api_store.h | 35 +++++++++++++++++++++++--- 2 files changed, 69 insertions(+), 10 deletions(-) diff --git a/src/libstore-c/nix_api_store.cc b/src/libstore-c/nix_api_store.cc index 647a53094d7..fd09a3e6263 100644 --- a/src/libstore-c/nix_api_store.cc +++ b/src/libstore-c/nix_api_store.cc @@ -174,6 +174,11 @@ StorePath * nix_store_path_clone(const StorePath * p) return new StorePath{p->path}; } +nix_derivation * nix_derivation_clone(const nix_derivation * d) +{ + return new nix_derivation{d->drv}; +} + nix_derivation * nix_derivation_from_json(nix_c_context * context, Store * store, const char * json) { if (context) @@ -261,6 +266,29 @@ nix_err nix_store_drv_from_path( NIXC_CATCH_ERRS } +nix_err nix_store_query_path_info( + nix_c_context * context, + Store * store, + const StorePath * store_path, + void * userdata, + void (*callback)(void * userdata, const StorePath * derived_path)) +{ + if (context) + context->last_err_code = NIX_OK; + try { + auto info = store->ptr->queryPathInfo(store_path->path); + if (callback) { + if (auto deriver = info->deriver) { + const StorePath deriver_tmp{*info->deriver}; + callback(userdata, &deriver_tmp); + } else { + callback(userdata, nullptr); + } + } + } + NIXC_CATCH_ERRS +} + nix_err nix_derivation_get_outputs( nix_c_context * context, const nix_derivation * drv, @@ -308,17 +336,19 @@ nix_err nix_derivation_get_outputs_and_optpaths( NIXC_CATCH_ERRS } -nix_err nix_derivation_get_structured_attrs( - nix_c_context * context, const nix_derivation * drv, nix_get_string_callback callback, void * userdata) +nix_err nix_derivation_to_json( + nix_c_context * context, + const nix_derivation * drv, + const Store * store, + 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); - } + auto result = drv->drv.toJSON(store->ptr->config).dump(); + if (callback) { + callback(result.data(), result.size(), userdata); } } NIXC_CATCH_ERRS diff --git a/src/libstore-c/nix_api_store.h b/src/libstore-c/nix_api_store.h index e145a37383e..a999ab32ef8 100644 --- a/src/libstore-c/nix_api_store.h +++ b/src/libstore-c/nix_api_store.h @@ -237,6 +237,14 @@ StorePath * nix_add_derivation(nix_c_context * context, Store * store, nix_deriv */ void nix_derivation_free(nix_derivation * drv); +/** + * @brief Copy a `nix_derivation` + * + * @param[in] d the derivation to copy + * @return a new `nix_derivation` + */ +nix_derivation * nix_derivation_clone(const nix_derivation * d); + /** * @brief Copy the closure of `path` from `srcStore` to `dstStore`. * @@ -289,6 +297,22 @@ nix_err nix_store_drv_from_path( void (*callback)(void * userdata, const nix_derivation * drv), void * userdata); +/** + * @brief Queries for the nix store path info. + * + * @param[out] context Optional, stores error information + * @param[in] store nix store reference + * @param[in] path A store path + * @param[in] userdata The data to pass to the callback + * @param[in] callback Called for when the path info is resolved + */ +nix_err nix_store_query_path_info( + nix_c_context * context, + Store * store, + const StorePath * store_path, + void * userdata, + void (*callback)(void * userdata, const StorePath * derived_path)); + /** * @brief Iterate through all of the outputs in a derivation * @@ -325,15 +349,20 @@ nix_err nix_derivation_get_outputs_and_optpaths( void * userdata); /** - * @brief Gets the structured attrs of derivation as a JSON string + * @brief Gets the derivation as a JSON string * * @param[out] context Optional, stores error information * @param[in] drv The derivation + * @param[in] store The nix store * @param[in] callback Called with the JSON string * @param[in] user_data Arbitrary data passed to the callback */ -nix_err nix_derivation_get_structured_attrs( - nix_c_context * context, const nix_derivation * drv, nix_get_string_callback callback, void * userdata); +nix_err nix_derivation_to_json( + nix_c_context * context, + const nix_derivation * drv, + const Store * store, + nix_get_string_callback callback, + void * userdata); /** * @brief Copy of a 'nix_derivation_output' From d30a11cb739c2b98637b201ec1d1717be920d829 Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Mon, 22 Sep 2025 16:21:21 -0700 Subject: [PATCH 08/13] libstore-c: add nix_derivation_make_paths function --- src/libstore-c/nix_api_store.cc | 25 +++++++++++++++++++++++++ src/libstore-c/nix_api_store.h | 16 ++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/libstore-c/nix_api_store.cc b/src/libstore-c/nix_api_store.cc index fd09a3e6263..a6272aa16f4 100644 --- a/src/libstore-c/nix_api_store.cc +++ b/src/libstore-c/nix_api_store.cc @@ -195,6 +195,31 @@ nix_derivation * nix_derivation_from_json(nix_c_context * context, Store * store NIXC_CATCH_ERRS_NULL } +nix_err nix_derivation_make_outputs( + nix_c_context * context, + Store * store, + const char * json, + void (*callback)(void * userdata, const char * output_name, const char * path), + void * userdata) +{ + if (context) + context->last_err_code = NIX_OK; + try { + auto drv = nix::Derivation::fromJSON(*store->ptr, nlohmann::json::parse(json)); + auto hashesModulo = hashDerivationModulo(*store->ptr, drv, true); + + for (auto & output : drv.outputs) { + nix::Hash h = hashesModulo.hashes.at(output.first); + auto outPath = store->ptr->makeOutputPath(output.first, h, drv.name); + + if (callback) { + callback(userdata, output.first.c_str(), store->ptr->printStorePath(outPath).c_str()); + } + } + } + NIXC_CATCH_ERRS +} + StorePath * nix_add_derivation(nix_c_context * context, Store * store, nix_derivation * derivation) { if (context) diff --git a/src/libstore-c/nix_api_store.h b/src/libstore-c/nix_api_store.h index a999ab32ef8..6d03f1967ba 100644 --- a/src/libstore-c/nix_api_store.h +++ b/src/libstore-c/nix_api_store.h @@ -220,6 +220,22 @@ nix_store_get_version(nix_c_context * context, Store * store, nix_get_string_cal */ nix_derivation * nix_derivation_from_json(nix_c_context * context, Store * store, const char * json); +/** + * @brief Hashes the derivation and gives the output paths + * + * @param[in] context Optional, stores error information. + * @param[in] store nix store reference. + * @param[in] json JSON of the derivation as a string. + * @param[in] callback Called for every output to provide the output path. + * @param[in] userdata User data to pass to the callback. + */ +nix_err nix_derivation_make_outputs( + nix_c_context * context, + Store * store, + const char * json, + void (*callback)(void * userdata, const char * output_name, const char * path), + void * userdata); + /** * @brief Add the given `nix_derivation` to the given store * From 3375bb0d7100503d2ddd311e4273e95633802d1f Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Tue, 23 Sep 2025 09:31:25 -0700 Subject: [PATCH 09/13] libstore-c: add nix_store_build_paths function --- src/libstore-c/nix_api_store.cc | 29 +++++++++++++++++++++++++++++ src/libstore-c/nix_api_store.h | 21 +++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/libstore-c/nix_api_store.cc b/src/libstore-c/nix_api_store.cc index a6272aa16f4..f8303edd330 100644 --- a/src/libstore-c/nix_api_store.cc +++ b/src/libstore-c/nix_api_store.cc @@ -314,6 +314,35 @@ nix_err nix_store_query_path_info( NIXC_CATCH_ERRS } +nix_err nix_store_build_paths( + nix_c_context * context, + Store * store, + const StorePath ** store_paths, + unsigned int num_store_paths, + void (*callback)(void * userdata, const char * path, const char * result), + void * userdata) +{ + if (context) + context->last_err_code = NIX_OK; + try { + std::vector derived_paths; + for (size_t i = 0; i < num_store_paths; i++) { + const StorePath * store_path = store_paths[i]; + derived_paths.push_back(nix::SingleDerivedPath::Opaque{store_path->path}); + } + + auto results = store->ptr->buildPathsWithResults(derived_paths); + for (auto & result : results) { + if (callback) { + nlohmann::json json; + nix::to_json(json, result); + callback(userdata, result.path.to_string(store->ptr->config).c_str(), json.dump().c_str()); + } + } + } + NIXC_CATCH_ERRS +} + nix_err nix_derivation_get_outputs( nix_c_context * context, const nix_derivation * drv, diff --git a/src/libstore-c/nix_api_store.h b/src/libstore-c/nix_api_store.h index 6d03f1967ba..ff5f49ca5b2 100644 --- a/src/libstore-c/nix_api_store.h +++ b/src/libstore-c/nix_api_store.h @@ -329,6 +329,27 @@ nix_err nix_store_query_path_info( void * userdata, void (*callback)(void * userdata, const StorePath * derived_path)); +/** + * @brief Builds the paths, if they are a derivation then they get built. + * + * @note Path and result for the callback only exist for the lifetime of + * the call. Result is a string containing the build result in JSON. + * + * @param[out] context Optional, stores error information + * @param[in] store nix store reference + * @param[in] store_paths Pointer to list of nix store paths + * @param[in] num_store_paths Number of nix store paths + * @param[in] callback The callback to trigger for build results + * @param[in] userdata User data to pass to the callback + */ +nix_err nix_store_build_paths( + nix_c_context * context, + Store * store, + const StorePath ** store_paths, + unsigned int num_store_paths, + void (*callback)(void * userdata, const char * path, const char * result), + void * userdata); + /** * @brief Iterate through all of the outputs in a derivation * From 6555f3337560d87b9923b3611c5e6fc9303eeb10 Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Tue, 23 Sep 2025 10:00:55 -0700 Subject: [PATCH 10/13] libstore-c: fix typos --- src/libstore-c/nix_api_store.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libstore-c/nix_api_store.h b/src/libstore-c/nix_api_store.h index ff5f49ca5b2..37226cbac0d 100644 --- a/src/libstore-c/nix_api_store.h +++ b/src/libstore-c/nix_api_store.h @@ -26,7 +26,7 @@ typedef struct StorePath StorePath; /** @brief Nix Derivation */ typedef struct nix_derivation nix_derivation; /** @brief Nix Derivation Output */ -typedef struct nix_derivation_output nix_derivation_noutput; +typedef struct nix_derivation_output nix_derivation_output; /** * @brief Initializes the Nix store library @@ -295,7 +295,7 @@ nix_err nix_store_get_fs_closure( void * userdata, void (*callback)(void * userdata, const StorePath * store_path)); -/* +/** * @brief Returns the derivation associated with the store path * * @note The callback borrows the Derivation only for the duration of the call. @@ -392,7 +392,7 @@ nix_err nix_derivation_get_outputs_and_optpaths( * @param[in] drv The derivation * @param[in] store The nix store * @param[in] callback Called with the JSON string - * @param[in] user_data Arbitrary data passed to the callback + * @param[in] userdata Arbitrary data passed to the callback */ nix_err nix_derivation_to_json( nix_c_context * context, From b2fff1560cc2fced15f31281738fbe97e42f44f8 Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Tue, 23 Sep 2025 16:05:12 -0700 Subject: [PATCH 11/13] libstore-c: make nix_derivation_to_json not require store --- src/libstore-c/nix_api_store.cc | 14 +++++--------- src/libstore-c/nix_api_store.h | 7 +------ src/libstore-c/nix_api_store_internal.h | 1 + 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/libstore-c/nix_api_store.cc b/src/libstore-c/nix_api_store.cc index f8303edd330..60fd6e5df12 100644 --- a/src/libstore-c/nix_api_store.cc +++ b/src/libstore-c/nix_api_store.cc @@ -176,7 +176,7 @@ StorePath * nix_store_path_clone(const StorePath * p) nix_derivation * nix_derivation_clone(const nix_derivation * d) { - return new nix_derivation{d->drv}; + return new nix_derivation{d->drv, d->store}; } nix_derivation * nix_derivation_from_json(nix_c_context * context, Store * store, const char * json) @@ -190,7 +190,7 @@ nix_derivation * nix_derivation_from_json(nix_c_context * context, Store * store drv.checkInvariants(*store->ptr, drvPath); - return new nix_derivation{drv}; + return new nix_derivation{drv, store}; } NIXC_CATCH_ERRS_NULL } @@ -284,7 +284,7 @@ nix_err nix_store_drv_from_path( try { nix::Derivation drv = store->ptr->derivationFromPath(path->path); if (callback) { - const nix_derivation tmp{drv}; + const nix_derivation tmp{drv, store}; callback(userdata, &tmp); } } @@ -391,16 +391,12 @@ nix_err nix_derivation_get_outputs_and_optpaths( } nix_err nix_derivation_to_json( - nix_c_context * context, - const nix_derivation * drv, - const Store * store, - nix_get_string_callback callback, - void * userdata) + nix_c_context * context, const nix_derivation * drv, nix_get_string_callback callback, void * userdata) { if (context) context->last_err_code = NIX_OK; try { - auto result = drv->drv.toJSON(store->ptr->config).dump(); + auto result = drv->drv.toJSON(drv->store->ptr->config).dump(); if (callback) { callback(result.data(), result.size(), userdata); } diff --git a/src/libstore-c/nix_api_store.h b/src/libstore-c/nix_api_store.h index 37226cbac0d..2fe4088b34a 100644 --- a/src/libstore-c/nix_api_store.h +++ b/src/libstore-c/nix_api_store.h @@ -390,16 +390,11 @@ nix_err nix_derivation_get_outputs_and_optpaths( * * @param[out] context Optional, stores error information * @param[in] drv The derivation - * @param[in] store The nix store * @param[in] callback Called with the JSON string * @param[in] userdata Arbitrary data passed to the callback */ nix_err nix_derivation_to_json( - nix_c_context * context, - const nix_derivation * drv, - const Store * store, - nix_get_string_callback callback, - void * userdata); + nix_c_context * context, const nix_derivation * drv, nix_get_string_callback callback, void * userdata); /** * @brief Copy of a 'nix_derivation_output' diff --git a/src/libstore-c/nix_api_store_internal.h b/src/libstore-c/nix_api_store_internal.h index 070bb1229cd..26456a02329 100644 --- a/src/libstore-c/nix_api_store_internal.h +++ b/src/libstore-c/nix_api_store_internal.h @@ -16,6 +16,7 @@ struct StorePath struct nix_derivation { nix::Derivation drv; + Store * store; }; struct nix_derivation_output From d7ce10113790158d36f550fbec34d4d50cfc7974 Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Fri, 26 Sep 2025 14:11:37 -0700 Subject: [PATCH 12/13] libstore-c: make nix_store_query_path_info return json formatted --- src/libstore-c/nix_api_store.cc | 10 +++------- src/libstore-c/nix_api_store.h | 2 +- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/libstore-c/nix_api_store.cc b/src/libstore-c/nix_api_store.cc index 60fd6e5df12..3f4a912486f 100644 --- a/src/libstore-c/nix_api_store.cc +++ b/src/libstore-c/nix_api_store.cc @@ -296,19 +296,15 @@ nix_err nix_store_query_path_info( Store * store, const StorePath * store_path, void * userdata, - void (*callback)(void * userdata, const StorePath * derived_path)) + nix_get_string_callback callback) { if (context) context->last_err_code = NIX_OK; try { auto info = store->ptr->queryPathInfo(store_path->path); if (callback) { - if (auto deriver = info->deriver) { - const StorePath deriver_tmp{*info->deriver}; - callback(userdata, &deriver_tmp); - } else { - callback(userdata, nullptr); - } + auto result = info->toJSON(store->ptr->config, true, nix::HashFormat::Nix32).dump(); + callback(result.data(), result.size(), userdata); } } NIXC_CATCH_ERRS diff --git a/src/libstore-c/nix_api_store.h b/src/libstore-c/nix_api_store.h index 2fe4088b34a..4077262f841 100644 --- a/src/libstore-c/nix_api_store.h +++ b/src/libstore-c/nix_api_store.h @@ -327,7 +327,7 @@ nix_err nix_store_query_path_info( Store * store, const StorePath * store_path, void * userdata, - void (*callback)(void * userdata, const StorePath * derived_path)); + nix_get_string_callback callback); /** * @brief Builds the paths, if they are a derivation then they get built. From ad566a9e8b86e7273b98e048916f38dc2495dfc2 Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Tue, 30 Sep 2025 14:38:57 -0700 Subject: [PATCH 13/13] libstore-c: remove nix_derivation_output --- src/libstore-c/nix_api_store.cc | 38 ++-------------------- src/libstore-c/nix_api_store.h | 43 +++---------------------- src/libstore-c/nix_api_store_internal.h | 5 --- 3 files changed, 7 insertions(+), 79 deletions(-) diff --git a/src/libstore-c/nix_api_store.cc b/src/libstore-c/nix_api_store.cc index 3f4a912486f..338600599e8 100644 --- a/src/libstore-c/nix_api_store.cc +++ b/src/libstore-c/nix_api_store.cc @@ -339,31 +339,11 @@ nix_err nix_store_build_paths( NIXC_CATCH_ERRS } -nix_err nix_derivation_get_outputs( - nix_c_context * context, - const nix_derivation * drv, - void (*callback)(void * userdata, const char * name, const nix_derivation_output * drv_output), - void * userdata) -{ - if (context) - context->last_err_code = NIX_OK; - try { - if (callback) { - for (const auto & [name, result] : drv->drv.outputs) { - const nix_derivation_output tmp{result}; - callback(userdata, name.c_str(), &tmp); - } - } - } - NIXC_CATCH_ERRS -} - nix_err nix_derivation_get_outputs_and_optpaths( nix_c_context * context, const nix_derivation * drv, const Store * store, - void (*callback)( - void * userdata, const char * name, const nix_derivation_output * drv_output, const StorePath * path), + void (*callback)(void * userdata, const char * name, const StorePath * path), void * userdata) { if (context) @@ -372,13 +352,11 @@ nix_err nix_derivation_get_outputs_and_optpaths( auto value = drv->drv.outputsAndOptPaths(store->ptr->config); if (callback) { for (const auto & [name, result] : value) { - const nix_derivation_output tmp_output{result.first}; - if (auto store_path = result.second) { const StorePath tmp_path{*store_path}; - callback(userdata, name.c_str(), &tmp_output, &tmp_path); + callback(userdata, name.c_str(), &tmp_path); } else { - callback(userdata, name.c_str(), &tmp_output, nullptr); + callback(userdata, name.c_str(), nullptr); } } } @@ -399,13 +377,3 @@ nix_err nix_derivation_to_json( } NIXC_CATCH_ERRS } - -nix_derivation_output * nix_derivation_output_clone(const nix_derivation_output * o) -{ - return new nix_derivation_output{o->drv_out}; -} - -void nix_derivation_output_free(nix_derivation_output * o) -{ - delete o; -} diff --git a/src/libstore-c/nix_api_store.h b/src/libstore-c/nix_api_store.h index 4077262f841..64ef7061459 100644 --- a/src/libstore-c/nix_api_store.h +++ b/src/libstore-c/nix_api_store.h @@ -25,8 +25,6 @@ typedef struct Store Store; typedef struct StorePath StorePath; /** @brief Nix Derivation */ typedef struct nix_derivation nix_derivation; -/** @brief Nix Derivation Output */ -typedef struct nix_derivation_output nix_derivation_output; /** * @brief Initializes the Nix store library @@ -318,7 +316,7 @@ nix_err nix_store_drv_from_path( * * @param[out] context Optional, stores error information * @param[in] store nix store reference - * @param[in] path A store path + * @param[in] store_path A store path * @param[in] userdata The data to pass to the callback * @param[in] callback Called for when the path info is resolved */ @@ -351,25 +349,9 @@ nix_err nix_store_build_paths( void * userdata); /** - * @brief Iterate through all of the outputs in a derivation + * @brief Iterate and get all of the store paths for each output. * - * @note The callback borrows the DerivationOutput 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 - */ -nix_err nix_derivation_get_outputs( - nix_c_context * context, - const nix_derivation * drv, - void (*callback)(void * userdata, const char * name, const nix_derivation_output * drv_output), - void * userdata); - -/** - * @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 StorePath only for the duration of the call. * * @param[out] context Optional, stores error information * @param[in] drv The derivation @@ -381,8 +363,7 @@ nix_err nix_derivation_get_outputs_and_optpaths( nix_c_context * context, const nix_derivation * drv, const Store * store, - void (*callback)( - void * userdata, const char * name, const nix_derivation_output * drv_output, const StorePath * path), + void (*callback)(void * userdata, const char * name, const StorePath * path), void * userdata); /** @@ -396,22 +377,6 @@ nix_err nix_derivation_get_outputs_and_optpaths( nix_err nix_derivation_to_json( nix_c_context * context, const nix_derivation * drv, nix_get_string_callback callback, void * userdata); -/** - * @brief Copy of a 'nix_derivation_output' - * - * @param[in] o the derivation output to copy - * @return a new 'nix_derivation_output' - */ -nix_derivation_output * nix_derivation_output_clone(const nix_derivation_output * o); - -/** - * @brief Deallocate a 'nix_derivation_output' - * - * Does not fail. - * @param[in] o the derivation output to free - */ -void nix_derivation_output_free(nix_derivation_output * o); - // cffi end #ifdef __cplusplus } diff --git a/src/libstore-c/nix_api_store_internal.h b/src/libstore-c/nix_api_store_internal.h index 26456a02329..73c751791d0 100644 --- a/src/libstore-c/nix_api_store_internal.h +++ b/src/libstore-c/nix_api_store_internal.h @@ -19,9 +19,4 @@ struct nix_derivation Store * store; }; -struct nix_derivation_output -{ - nix::DerivationOutput drv_out; -}; - #endif