Skip to content

Commit 64ac27b

Browse files
libstore-c: Organize, and flesh out API
libstore-c: add more derivation functions libstore-c: make nix_store_query_path_info return json formatted libstore-c: remove nix_derivation_output Co-authored-by: Tristan Ross <[email protected]>
1 parent 3645671 commit 64ac27b

File tree

8 files changed

+448
-110
lines changed

8 files changed

+448
-110
lines changed

src/libexpr/primops.cc

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1768,28 +1768,7 @@ static void derivationStrictInternal(EvalState & state, std::string_view drvName
17681768
drv.outputs.insert_or_assign(i, DerivationOutput::Deferred{});
17691769
}
17701770

1771-
auto hashModulo = hashDerivationModulo(*state.store, Derivation(drv), true);
1772-
switch (hashModulo.kind) {
1773-
case DrvHash::Kind::Regular:
1774-
for (auto & i : outputs) {
1775-
auto h = get(hashModulo.hashes, i);
1776-
if (!h)
1777-
state.error<AssertionError>("derivation produced no hash for output '%s'", i).atPos(v).debugThrow();
1778-
auto outPath = state.store->makeOutputPath(i, *h, drvName);
1779-
drv.env[i] = state.store->printStorePath(outPath);
1780-
drv.outputs.insert_or_assign(
1781-
i,
1782-
DerivationOutput::InputAddressed{
1783-
.path = std::move(outPath),
1784-
});
1785-
}
1786-
break;
1787-
;
1788-
case DrvHash::Kind::Deferred:
1789-
for (auto & i : outputs) {
1790-
drv.outputs.insert_or_assign(i, DerivationOutput::Deferred{});
1791-
}
1792-
}
1771+
drv.fillInOutputPaths(*state.store);
17931772
}
17941773

17951774
/* Write the resulting term into the Nix store directory. */

src/libstore-c/meson.build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ include_dirs = [ include_directories('.') ]
3535

3636
headers = files(
3737
'nix_api_store.h',
38+
'nix_api_store/derivation.h',
39+
'nix_api_store/store_path.h',
3840
)
3941

4042
# TODO don't install this once tests don't use it and/or move the header into `libstore`, non-`c`

src/libstore-c/nix_api_store.cc

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
#include "nix/store/globals.hh"
1313

14+
#include <span>
15+
1416
extern "C" {
1517

1618
nix_err nix_libstore_init(nix_c_context * context)
@@ -218,13 +220,20 @@ StorePath * nix_store_path_clone(const StorePath * p)
218220
return new StorePath{p->path};
219221
}
220222

223+
nix_derivation * nix_derivation_clone(const nix_derivation * d)
224+
{
225+
return new nix_derivation{d->drv};
226+
}
227+
221228
nix_derivation * nix_derivation_from_json(nix_c_context * context, Store * store, const char * json)
222229
{
223230
if (context)
224231
context->last_err_code = NIX_OK;
225232
try {
226233
auto drv = static_cast<nix::Derivation>(nlohmann::json::parse(json));
227234

235+
drv.fillInOutputPaths(*store->ptr);
236+
228237
auto drvPath = nix::writeDerivation(*store->ptr, drv, nix::NoRepair, /* read only */ true);
229238

230239
drv.checkInvariants(*store->ptr, drvPath);
@@ -234,6 +243,20 @@ nix_derivation * nix_derivation_from_json(nix_c_context * context, Store * store
234243
NIXC_CATCH_ERRS_NULL
235244
}
236245

246+
nix_err nix_derivation_to_json(
247+
nix_c_context * context, const nix_derivation * drv, nix_get_string_callback callback, void * userdata)
248+
{
249+
if (context)
250+
context->last_err_code = NIX_OK;
251+
try {
252+
auto result = static_cast<nlohmann::json>(drv->drv).dump();
253+
if (callback) {
254+
callback(result.data(), result.size(), userdata);
255+
}
256+
}
257+
NIXC_CATCH_ERRS
258+
}
259+
237260
StorePath * nix_add_derivation(nix_c_context * context, Store * store, nix_derivation * derivation)
238261
{
239262
if (context)
@@ -258,4 +281,73 @@ nix_err nix_store_copy_closure(nix_c_context * context, Store * srcStore, Store
258281
NIXC_CATCH_ERRS
259282
}
260283

284+
nix_err nix_store_drv_from_path(
285+
nix_c_context * context,
286+
Store * store,
287+
const StorePath * path,
288+
void (*callback)(void * userdata, const nix_derivation * drv),
289+
void * userdata)
290+
{
291+
if (context)
292+
context->last_err_code = NIX_OK;
293+
try {
294+
nix::Derivation drv = store->ptr->derivationFromPath(path->path);
295+
if (callback) {
296+
const nix_derivation tmp{drv};
297+
callback(userdata, &tmp);
298+
}
299+
}
300+
NIXC_CATCH_ERRS
301+
}
302+
303+
nix_err nix_store_query_path_info(
304+
nix_c_context * context,
305+
Store * store,
306+
const StorePath * store_path,
307+
void * userdata,
308+
nix_get_string_callback callback)
309+
{
310+
if (context)
311+
context->last_err_code = NIX_OK;
312+
try {
313+
auto info = store->ptr->queryPathInfo(store_path->path);
314+
if (callback) {
315+
auto result = info->toJSON(&*store->ptr, true).dump();
316+
callback(result.data(), result.size(), userdata);
317+
}
318+
}
319+
NIXC_CATCH_ERRS
320+
}
321+
322+
nix_err nix_store_build_paths(
323+
nix_c_context * context,
324+
Store * store,
325+
const StorePath ** store_paths,
326+
unsigned int num_store_paths,
327+
void (*callback)(void * userdata, const char * path, const char * result),
328+
void * userdata)
329+
{
330+
if (context)
331+
context->last_err_code = NIX_OK;
332+
try {
333+
std::span<const StorePath * const> paths_span(store_paths, num_store_paths);
334+
335+
std::vector<nix::DerivedPath> derived_paths;
336+
for (const StorePath * store_path : paths_span) {
337+
derived_paths.push_back(nix::SingleDerivedPath::Opaque{store_path->path});
338+
}
339+
340+
auto results = store->ptr->buildPathsWithResults(derived_paths);
341+
for (auto & result : results) {
342+
if (callback) {
343+
callback(
344+
userdata,
345+
result.path.to_string(store->ptr->config).c_str(),
346+
static_cast<nlohmann::json>(result).dump().c_str());
347+
}
348+
}
349+
}
350+
NIXC_CATCH_ERRS
351+
}
352+
261353
} // extern "C"

src/libstore-c/nix_api_store.h

Lines changed: 64 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
*/
1313

1414
#include "nix_api_util.h"
15+
#include "nix_api_store/store_path.h"
16+
#include "nix_api_store/derivation.h"
1517
#include <stdbool.h>
1618

1719
#ifdef __cplusplus
@@ -21,10 +23,6 @@ extern "C" {
2123

2224
/** @brief Reference to a Nix store */
2325
typedef struct Store Store;
24-
/** @brief Nix store path */
25-
typedef struct StorePath StorePath;
26-
/** @brief Nix Derivation */
27-
typedef struct nix_derivation nix_derivation;
2826

2927
/**
3028
* @brief Initializes the Nix store library
@@ -108,7 +106,7 @@ nix_err
108106
nix_store_get_storedir(nix_c_context * context, Store * store, nix_get_string_callback callback, void * user_data);
109107

110108
/**
111-
* @brief Parse a Nix store path into a StorePath
109+
* @brief Parse a Nix store path that includes the store dir into a StorePath
112110
*
113111
* @note Don't forget to free this path using nix_store_path_free()!
114112
* @param[out] context Optional, stores error information
@@ -118,30 +116,6 @@ nix_store_get_storedir(nix_c_context * context, Store * store, nix_get_string_ca
118116
*/
119117
StorePath * nix_store_parse_path(nix_c_context * context, Store * store, const char * path);
120118

121-
/**
122-
* @brief Get the path name (e.g. "name" in /nix/store/...-name)
123-
*
124-
* @param[in] store_path the path to get the name from
125-
* @param[in] callback called with the name
126-
* @param[in] user_data arbitrary data, passed to the callback when it's called.
127-
*/
128-
void nix_store_path_name(const StorePath * store_path, nix_get_string_callback callback, void * user_data);
129-
130-
/**
131-
* @brief Copy a StorePath
132-
*
133-
* @param[in] p the path to copy
134-
* @return a new StorePath
135-
*/
136-
StorePath * nix_store_path_clone(const StorePath * p);
137-
138-
/** @brief Deallocate a StorePath
139-
*
140-
* Does not fail.
141-
* @param[in] p the path to free
142-
*/
143-
void nix_store_path_free(StorePath * p);
144-
145119
/**
146120
* @brief Check if a StorePath is valid (i.e. that corresponding store object and its closure of references exists in
147121
* the store)
@@ -214,6 +188,12 @@ nix_store_get_version(nix_c_context * context, Store * store, nix_get_string_cal
214188
/**
215189
* @brief Create a `nix_derivation` from a JSON representation of that derivation.
216190
*
191+
* @note Unlike `nix_derivation_to_json`, this needs a `Store`. This is because
192+
* over time we expect the internal representation of derivations in Nix to
193+
* differ from accepted derivation formats. The store argument is here to help
194+
* any logic needed to convert from JSON to the internal representation, in
195+
* excess of just parsing.
196+
*
217197
* @param[out] context Optional, stores error information.
218198
* @param[in] store nix store reference.
219199
* @param[in] json JSON of the derivation as a string.
@@ -229,14 +209,6 @@ nix_derivation * nix_derivation_from_json(nix_c_context * context, Store * store
229209
*/
230210
StorePath * nix_add_derivation(nix_c_context * context, Store * store, nix_derivation * derivation);
231211

232-
/**
233-
* @brief Deallocate a `nix_derivation`
234-
*
235-
* Does not fail.
236-
* @param[in] drv the derivation to free
237-
*/
238-
void nix_derivation_free(nix_derivation * drv);
239-
240212
/**
241213
* @brief Copy the closure of `path` from `srcStore` to `dstStore`.
242214
*
@@ -276,6 +248,61 @@ nix_err nix_store_get_fs_closure(
276248
void * userdata,
277249
void (*callback)(nix_c_context * context, void * userdata, const StorePath * store_path));
278250

251+
/**
252+
* @brief Returns the derivation associated with the store path
253+
*
254+
* @note The callback borrows the Derivation only for the duration of the call.
255+
*
256+
* @param[out] context Optional, stores error information
257+
* @param[in] store The nix store
258+
* @param[in] path The nix store path
259+
* @param[in] callback The callback to call
260+
* @param[in] userdata The userdata to pass to the callback
261+
*/
262+
nix_err nix_store_drv_from_path(
263+
nix_c_context * context,
264+
Store * store,
265+
const StorePath * path,
266+
void (*callback)(void * userdata, const nix_derivation * drv),
267+
void * userdata);
268+
269+
/**
270+
* @brief Queries for the nix store path info JSON.
271+
*
272+
* @param[out] context Optional, stores error information
273+
* @param[in] store nix store reference
274+
* @param[in] path A store path
275+
* @param[in] userdata The data to pass to the callback
276+
* @param[in] callback Called for when the path info is resolved
277+
*/
278+
nix_err nix_store_query_path_info(
279+
nix_c_context * context,
280+
Store * store,
281+
const StorePath * store_path,
282+
void * userdata,
283+
nix_get_string_callback callback);
284+
285+
/**
286+
* @brief Builds the paths, if they are a derivation then they get built.
287+
*
288+
* @note Path and result for the callback only exist for the lifetime of
289+
* the call. Result is a string containing the build result in JSON.
290+
*
291+
* @param[out] context Optional, stores error information
292+
* @param[in] store nix store reference
293+
* @param[in] store_paths Pointer to list of nix store paths
294+
* @param[in] num_store_paths Number of nix store paths
295+
* @param[in] callback The callback to trigger for build results
296+
* @param[in] userdata User data to pass to the callback
297+
*/
298+
nix_err nix_store_build_paths(
299+
nix_c_context * context,
300+
Store * store,
301+
const StorePath ** store_paths,
302+
unsigned int num_store_paths,
303+
void (*callback)(void * userdata, const char * path, const char * result),
304+
void * userdata);
305+
279306
// cffi end
280307
#ifdef __cplusplus
281308
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#ifndef NIX_API_STORE_DERIVATION_H
2+
#define NIX_API_STORE_DERIVATION_H
3+
/**
4+
* @defgroup libstore_derivation Derivation
5+
* @ingroup libstore
6+
* @brief Derivation operations that don't require a Store
7+
* @{
8+
*/
9+
/** @file
10+
* @brief Derivation operations
11+
*/
12+
13+
#include "nix_api_util.h"
14+
15+
#ifdef __cplusplus
16+
extern "C" {
17+
#endif
18+
// cffi start
19+
20+
/** @brief Nix Derivation */
21+
typedef struct nix_derivation nix_derivation;
22+
23+
/**
24+
* @brief Copy a `nix_derivation`
25+
*
26+
* @param[in] d the derivation to copy
27+
* @return a new `nix_derivation`
28+
*/
29+
nix_derivation * nix_derivation_clone(const nix_derivation * d);
30+
31+
/**
32+
* @brief Deallocate a `nix_derivation`
33+
*
34+
* Does not fail.
35+
* @param[in] drv the derivation to free
36+
*/
37+
void nix_derivation_free(nix_derivation * drv);
38+
39+
/**
40+
* @brief Gets the derivation as a JSON string
41+
*
42+
* @param[out] context Optional, stores error information
43+
* @param[in] drv The derivation
44+
* @param[in] callback Called with the JSON string
45+
* @param[in] userdata Arbitrary data passed to the callback
46+
*/
47+
nix_err nix_derivation_to_json(
48+
nix_c_context * context, const nix_derivation * drv, nix_get_string_callback callback, void * userdata);
49+
50+
// cffi end
51+
#ifdef __cplusplus
52+
}
53+
#endif
54+
/**
55+
* @}
56+
*/
57+
#endif // NIX_API_STORE_DERIVATION_H

0 commit comments

Comments
 (0)