mirror of
https://github.com/NixOS/nix.git
synced 2025-04-16 14:19:21 +00:00
Merge pull request #12877 from roberth/c-api-libflake-override-input
C API: Flake loading, input overriding
This commit is contained in:
commit
e76bbe413e
@ -355,6 +355,7 @@
|
||||
"nix-store-tests" = { };
|
||||
|
||||
"nix-fetchers" = { };
|
||||
"nix-fetchers-c" = { };
|
||||
"nix-fetchers-tests" = { };
|
||||
|
||||
"nix-expr" = { };
|
||||
@ -363,6 +364,7 @@
|
||||
"nix-expr-tests" = { };
|
||||
|
||||
"nix-flake" = { };
|
||||
"nix-flake-c" = { };
|
||||
"nix-flake-tests" = { };
|
||||
|
||||
"nix-main" = { };
|
||||
|
@ -33,6 +33,7 @@ endif
|
||||
# External C wrapper libraries
|
||||
subproject('libutil-c')
|
||||
subproject('libstore-c')
|
||||
subproject('libfetchers-c')
|
||||
subproject('libexpr-c')
|
||||
subproject('libflake-c')
|
||||
subproject('libmain-c')
|
||||
|
@ -333,6 +333,7 @@ in
|
||||
nix-store-tests = callPackage ../src/libstore-tests/package.nix { };
|
||||
|
||||
nix-fetchers = callPackage ../src/libfetchers/package.nix { };
|
||||
nix-fetchers-c = callPackage ../src/libfetchers-c/package.nix { };
|
||||
nix-fetchers-tests = callPackage ../src/libfetchers-tests/package.nix { };
|
||||
|
||||
nix-expr = callPackage ../src/libexpr/package.nix { };
|
||||
|
@ -15,6 +15,7 @@
|
||||
nix-store-tests,
|
||||
|
||||
nix-fetchers,
|
||||
nix-fetchers-c,
|
||||
nix-fetchers-tests,
|
||||
|
||||
nix-expr,
|
||||
@ -54,6 +55,7 @@ let
|
||||
nix-store
|
||||
nix-store-c
|
||||
nix-fetchers
|
||||
nix-fetchers-c
|
||||
nix-expr
|
||||
nix-expr-c
|
||||
nix-flake
|
||||
@ -230,6 +232,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
"nix-expr"
|
||||
"nix-expr-c"
|
||||
"nix-fetchers"
|
||||
"nix-fetchers-c"
|
||||
"nix-flake"
|
||||
"nix-flake-c"
|
||||
"nix-main"
|
||||
|
@ -48,6 +48,7 @@ let
|
||||
"nix-store-test-support"
|
||||
"nix-store-tests"
|
||||
"nix-fetchers"
|
||||
"nix-fetchers-c"
|
||||
"nix-fetchers-tests"
|
||||
"nix-expr"
|
||||
"nix-expr-c"
|
||||
|
@ -37,13 +37,11 @@ include_dirs = [include_directories('.')]
|
||||
|
||||
headers = files(
|
||||
'nix_api_expr.h',
|
||||
'nix_api_expr_internal.h',
|
||||
'nix_api_external.h',
|
||||
'nix_api_value.h',
|
||||
)
|
||||
|
||||
# TODO move this header to libexpr, maybe don't use it in tests?
|
||||
headers += files('nix_api_expr_internal.h')
|
||||
|
||||
subdir('nix-meson-build-support/export-all-symbols')
|
||||
subdir('nix-meson-build-support/windows-version')
|
||||
|
||||
|
@ -286,6 +286,11 @@ nix_err nix_gc_incref(nix_c_context * context, const void * object);
|
||||
/**
|
||||
* @brief Decrement the garbage collector reference counter for the given object
|
||||
*
|
||||
* We also provide typed `nix_*_decref` functions, which are
|
||||
* - safer to use
|
||||
* - easier to integrate when deriving bindings
|
||||
* - allow more flexibility
|
||||
*
|
||||
* @param[out] context Optional, stores error information
|
||||
* @param[in] object The object to stop referencing
|
||||
*/
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
namespace nix {
|
||||
using json = nlohmann::json;
|
||||
// TODO: rename. It doesn't print.
|
||||
json printValueAsJSON(EvalState & state, bool strict,
|
||||
Value & v, const PosIdx pos, NixStringContext & context, bool copyToStore)
|
||||
{
|
||||
|
1
src/libfetchers-c/.version
Symbolic link
1
src/libfetchers-c/.version
Symbolic link
@ -0,0 +1 @@
|
||||
../../.version
|
65
src/libfetchers-c/meson.build
Normal file
65
src/libfetchers-c/meson.build
Normal file
@ -0,0 +1,65 @@
|
||||
project('nix-fetchers-c', 'cpp',
|
||||
version : files('.version'),
|
||||
default_options : [
|
||||
'cpp_std=c++2a',
|
||||
# TODO(Qyriad): increase the warning level
|
||||
'warning_level=1',
|
||||
'errorlogs=true', # Please print logs for tests that fail
|
||||
],
|
||||
meson_version : '>= 1.1',
|
||||
license : 'LGPL-2.1-or-later',
|
||||
)
|
||||
|
||||
cxx = meson.get_compiler('cpp')
|
||||
|
||||
subdir('nix-meson-build-support/deps-lists')
|
||||
|
||||
deps_private_maybe_subproject = [
|
||||
dependency('nix-util'),
|
||||
dependency('nix-store'),
|
||||
dependency('nix-fetchers'),
|
||||
]
|
||||
deps_public_maybe_subproject = [
|
||||
dependency('nix-util-c'),
|
||||
dependency('nix-store-c'),
|
||||
]
|
||||
subdir('nix-meson-build-support/subprojects')
|
||||
|
||||
add_project_arguments(
|
||||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('nix-meson-build-support/common')
|
||||
|
||||
sources = files(
|
||||
'nix_api_fetchers.cc',
|
||||
)
|
||||
|
||||
include_dirs = [include_directories('.')]
|
||||
|
||||
headers = files(
|
||||
'nix_api_fetchers.h',
|
||||
'nix_api_fetchers_internal.hh',
|
||||
)
|
||||
|
||||
# TODO move this header to libexpr, maybe don't use it in tests?
|
||||
headers += files('nix_api_fetchers.h')
|
||||
|
||||
subdir('nix-meson-build-support/export-all-symbols')
|
||||
subdir('nix-meson-build-support/windows-version')
|
||||
|
||||
this_library = library(
|
||||
'nixfetchersc',
|
||||
sources,
|
||||
dependencies : deps_public + deps_private + deps_other,
|
||||
include_directories : include_dirs,
|
||||
link_args: linker_export_flags,
|
||||
prelink : true, # For C++ static initializers
|
||||
install : true,
|
||||
)
|
||||
|
||||
install_headers(headers, preserve_path : true)
|
||||
|
||||
libraries_private = []
|
||||
|
||||
subdir('nix-meson-build-support/export')
|
1
src/libfetchers-c/nix-meson-build-support
Symbolic link
1
src/libfetchers-c/nix-meson-build-support
Symbolic link
@ -0,0 +1 @@
|
||||
../../nix-meson-build-support
|
19
src/libfetchers-c/nix_api_fetchers.cc
Normal file
19
src/libfetchers-c/nix_api_fetchers.cc
Normal file
@ -0,0 +1,19 @@
|
||||
#include "nix_api_fetchers.h"
|
||||
#include "nix_api_fetchers_internal.hh"
|
||||
#include "nix_api_util_internal.h"
|
||||
|
||||
nix_fetchers_settings * nix_fetchers_settings_new(nix_c_context * context)
|
||||
{
|
||||
try {
|
||||
auto fetchersSettings = nix::make_ref<nix::fetchers::Settings>(nix::fetchers::Settings{});
|
||||
return new nix_fetchers_settings{
|
||||
.settings = fetchersSettings,
|
||||
};
|
||||
}
|
||||
NIXC_CATCH_ERRS_NULL
|
||||
}
|
||||
|
||||
void nix_fetchers_settings_free(nix_fetchers_settings * settings)
|
||||
{
|
||||
delete settings;
|
||||
}
|
32
src/libfetchers-c/nix_api_fetchers.h
Normal file
32
src/libfetchers-c/nix_api_fetchers.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef NIX_API_FETCHERS_H
|
||||
#define NIX_API_FETCHERS_H
|
||||
/** @defgroup libfetchers libfetchers
|
||||
* @brief Bindings to the Nix fetchers library
|
||||
* @{
|
||||
*/
|
||||
/** @file
|
||||
* @brief Main entry for the libfetchers C bindings
|
||||
*/
|
||||
|
||||
#include "nix_api_util.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
// cffi start
|
||||
|
||||
// Type definitions
|
||||
/**
|
||||
* @brief Shared settings object
|
||||
*/
|
||||
typedef struct nix_fetchers_settings nix_fetchers_settings;
|
||||
|
||||
nix_fetchers_settings * nix_fetchers_settings_new(nix_c_context * context);
|
||||
|
||||
void nix_fetchers_settings_free(nix_fetchers_settings * settings);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // NIX_API_FETCHERS_H
|
12
src/libfetchers-c/nix_api_fetchers_internal.hh
Normal file
12
src/libfetchers-c/nix_api_fetchers_internal.hh
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include "nix/fetchers/fetch-settings.hh"
|
||||
#include "nix/util/ref.hh"
|
||||
|
||||
/**
|
||||
* A shared reference to `nix::fetchers::Settings`
|
||||
* @see nix::fetchers::Settings
|
||||
*/
|
||||
struct nix_fetchers_settings
|
||||
{
|
||||
nix::ref<nix::fetchers::Settings> settings;
|
||||
};
|
50
src/libfetchers-c/package.nix
Normal file
50
src/libfetchers-c/package.nix
Normal file
@ -0,0 +1,50 @@
|
||||
{
|
||||
lib,
|
||||
mkMesonLibrary,
|
||||
|
||||
nix-store-c,
|
||||
nix-expr-c,
|
||||
nix-util-c,
|
||||
nix-fetchers,
|
||||
|
||||
# Configuration Options
|
||||
|
||||
version,
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) fileset;
|
||||
in
|
||||
|
||||
mkMesonLibrary (finalAttrs: {
|
||||
pname = "nix-fetchers-c";
|
||||
inherit version;
|
||||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../nix-meson-build-support
|
||||
./nix-meson-build-support
|
||||
../../.version
|
||||
./.version
|
||||
./meson.build
|
||||
# ./meson.options
|
||||
(fileset.fileFilter (file: file.hasExt "cc") ./.)
|
||||
(fileset.fileFilter (file: file.hasExt "hh") ./.)
|
||||
(fileset.fileFilter (file: file.hasExt "h") ./.)
|
||||
];
|
||||
|
||||
propagatedBuildInputs = [
|
||||
nix-util-c
|
||||
nix-expr-c
|
||||
nix-store-c
|
||||
nix-fetchers
|
||||
];
|
||||
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
};
|
||||
|
||||
})
|
@ -17,6 +17,7 @@ subdir('nix-meson-build-support/deps-lists')
|
||||
deps_private_maybe_subproject = [
|
||||
dependency('nix-store-test-support'),
|
||||
dependency('nix-fetchers'),
|
||||
dependency('nix-fetchers-c'),
|
||||
]
|
||||
deps_public_maybe_subproject = [
|
||||
]
|
||||
@ -39,6 +40,7 @@ subdir('nix-meson-build-support/common')
|
||||
sources = files(
|
||||
'access-tokens.cc',
|
||||
'git-utils.cc',
|
||||
'nix_api_fetchers.cc',
|
||||
'public-key.cc',
|
||||
)
|
||||
|
||||
|
18
src/libfetchers-tests/nix_api_fetchers.cc
Normal file
18
src/libfetchers-tests/nix_api_fetchers.cc
Normal file
@ -0,0 +1,18 @@
|
||||
#include "gmock/gmock.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "nix_api_fetchers.h"
|
||||
#include "nix/store/tests/nix_api_store.hh"
|
||||
|
||||
namespace nixC {
|
||||
|
||||
TEST_F(nix_api_store_test, nix_api_fetchers_new_free)
|
||||
{
|
||||
nix_fetchers_settings * settings = nix_fetchers_settings_new(ctx);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, settings);
|
||||
|
||||
nix_fetchers_settings_free(settings);
|
||||
}
|
||||
|
||||
} // namespace nixC
|
@ -5,6 +5,7 @@
|
||||
mkMesonExecutable,
|
||||
|
||||
nix-fetchers,
|
||||
nix-fetchers-c,
|
||||
nix-store-test-support,
|
||||
|
||||
libgit2,
|
||||
@ -40,6 +41,7 @@ mkMesonExecutable (finalAttrs: {
|
||||
|
||||
buildInputs = [
|
||||
nix-fetchers
|
||||
nix-fetchers-c
|
||||
nix-store-test-support
|
||||
rapidcheck
|
||||
gtest
|
||||
|
@ -17,12 +17,14 @@ subdir('nix-meson-build-support/deps-lists')
|
||||
deps_private_maybe_subproject = [
|
||||
dependency('nix-util'),
|
||||
dependency('nix-store'),
|
||||
dependency('nix-fetchers'),
|
||||
dependency('nix-expr'),
|
||||
dependency('nix-flake'),
|
||||
]
|
||||
deps_public_maybe_subproject = [
|
||||
dependency('nix-util-c'),
|
||||
dependency('nix-store-c'),
|
||||
dependency('nix-fetchers-c'),
|
||||
dependency('nix-expr-c'),
|
||||
]
|
||||
subdir('nix-meson-build-support/subprojects')
|
||||
@ -37,6 +39,7 @@ include_dirs = [include_directories('.')]
|
||||
|
||||
headers = files(
|
||||
'nix_api_flake.h',
|
||||
'nix_api_flake_internal.hh',
|
||||
)
|
||||
|
||||
# TODO move this header to libexpr, maybe don't use it in tests?
|
||||
|
@ -1,12 +1,16 @@
|
||||
#include "nix_api_flake.h"
|
||||
#include "nix_api_flake_internal.hh"
|
||||
#include "nix_api_util.h"
|
||||
#include "nix_api_util_internal.h"
|
||||
#include "nix_api_expr_internal.h"
|
||||
#include "nix_api_fetchers_internal.hh"
|
||||
#include "nix_api_fetchers.h"
|
||||
|
||||
#include "nix/flake/flake.hh"
|
||||
|
||||
nix_flake_settings * nix_flake_settings_new(nix_c_context * context)
|
||||
{
|
||||
nix_clear_err(context);
|
||||
try {
|
||||
auto settings = nix::make_ref<nix::flake::Settings>();
|
||||
return new nix_flake_settings{settings};
|
||||
@ -22,8 +26,177 @@ void nix_flake_settings_free(nix_flake_settings * settings)
|
||||
nix_err nix_flake_settings_add_to_eval_state_builder(
|
||||
nix_c_context * context, nix_flake_settings * settings, nix_eval_state_builder * builder)
|
||||
{
|
||||
nix_clear_err(context);
|
||||
try {
|
||||
settings->settings->configureEvalSettings(builder->settings);
|
||||
}
|
||||
NIXC_CATCH_ERRS
|
||||
}
|
||||
|
||||
nix_flake_reference_parse_flags *
|
||||
nix_flake_reference_parse_flags_new(nix_c_context * context, nix_flake_settings * settings)
|
||||
{
|
||||
nix_clear_err(context);
|
||||
try {
|
||||
return new nix_flake_reference_parse_flags{
|
||||
.baseDirectory = std::nullopt,
|
||||
};
|
||||
}
|
||||
NIXC_CATCH_ERRS_NULL
|
||||
}
|
||||
|
||||
void nix_flake_reference_parse_flags_free(nix_flake_reference_parse_flags * flags)
|
||||
{
|
||||
delete flags;
|
||||
}
|
||||
|
||||
nix_err nix_flake_reference_parse_flags_set_base_directory(
|
||||
nix_c_context * context,
|
||||
nix_flake_reference_parse_flags * flags,
|
||||
const char * baseDirectory,
|
||||
size_t baseDirectoryLen)
|
||||
{
|
||||
nix_clear_err(context);
|
||||
try {
|
||||
flags->baseDirectory.emplace(nix::Path{std::string(baseDirectory, baseDirectoryLen)});
|
||||
return NIX_OK;
|
||||
}
|
||||
NIXC_CATCH_ERRS
|
||||
}
|
||||
|
||||
nix_err nix_flake_reference_and_fragment_from_string(
|
||||
nix_c_context * context,
|
||||
nix_fetchers_settings * fetchSettings,
|
||||
nix_flake_settings * flakeSettings,
|
||||
nix_flake_reference_parse_flags * parseFlags,
|
||||
const char * strData,
|
||||
size_t strSize,
|
||||
nix_flake_reference ** flakeReferenceOut,
|
||||
nix_get_string_callback fragmentCallback,
|
||||
void * fragmentCallbackUserData)
|
||||
{
|
||||
nix_clear_err(context);
|
||||
*flakeReferenceOut = nullptr;
|
||||
try {
|
||||
std::string str(strData, 0, strSize);
|
||||
|
||||
auto [flakeRef, fragment] =
|
||||
nix::parseFlakeRefWithFragment(*fetchSettings->settings, str, parseFlags->baseDirectory, true);
|
||||
*flakeReferenceOut = new nix_flake_reference{nix::make_ref<nix::FlakeRef>(flakeRef)};
|
||||
return call_nix_get_string_callback(fragment, fragmentCallback, fragmentCallbackUserData);
|
||||
}
|
||||
NIXC_CATCH_ERRS
|
||||
}
|
||||
|
||||
void nix_flake_reference_free(nix_flake_reference * flakeReference)
|
||||
{
|
||||
delete flakeReference;
|
||||
}
|
||||
|
||||
nix_flake_lock_flags * nix_flake_lock_flags_new(nix_c_context * context, nix_flake_settings * settings)
|
||||
{
|
||||
nix_clear_err(context);
|
||||
try {
|
||||
auto lockSettings = nix::make_ref<nix::flake::LockFlags>(nix::flake::LockFlags{
|
||||
.recreateLockFile = false,
|
||||
.updateLockFile = true, // == `nix_flake_lock_flags_set_mode_write_as_needed`
|
||||
.writeLockFile = true, // == `nix_flake_lock_flags_set_mode_write_as_needed`
|
||||
.failOnUnlocked = false, // == `nix_flake_lock_flags_set_mode_write_as_needed`
|
||||
.useRegistries = false,
|
||||
.allowUnlocked = false, // == `nix_flake_lock_flags_set_mode_write_as_needed`
|
||||
.commitLockFile = false,
|
||||
|
||||
});
|
||||
return new nix_flake_lock_flags{lockSettings};
|
||||
}
|
||||
NIXC_CATCH_ERRS_NULL
|
||||
}
|
||||
|
||||
void nix_flake_lock_flags_free(nix_flake_lock_flags * flags)
|
||||
{
|
||||
delete flags;
|
||||
}
|
||||
|
||||
nix_err nix_flake_lock_flags_set_mode_virtual(nix_c_context * context, nix_flake_lock_flags * flags)
|
||||
{
|
||||
nix_clear_err(context);
|
||||
try {
|
||||
flags->lockFlags->updateLockFile = true;
|
||||
flags->lockFlags->writeLockFile = false;
|
||||
flags->lockFlags->failOnUnlocked = false;
|
||||
flags->lockFlags->allowUnlocked = true;
|
||||
}
|
||||
NIXC_CATCH_ERRS
|
||||
}
|
||||
|
||||
nix_err nix_flake_lock_flags_set_mode_write_as_needed(nix_c_context * context, nix_flake_lock_flags * flags)
|
||||
{
|
||||
nix_clear_err(context);
|
||||
try {
|
||||
flags->lockFlags->updateLockFile = true;
|
||||
flags->lockFlags->writeLockFile = true;
|
||||
flags->lockFlags->failOnUnlocked = false;
|
||||
flags->lockFlags->allowUnlocked = true;
|
||||
}
|
||||
NIXC_CATCH_ERRS
|
||||
}
|
||||
|
||||
nix_err nix_flake_lock_flags_set_mode_check(nix_c_context * context, nix_flake_lock_flags * flags)
|
||||
{
|
||||
nix_clear_err(context);
|
||||
try {
|
||||
flags->lockFlags->updateLockFile = false;
|
||||
flags->lockFlags->writeLockFile = false;
|
||||
flags->lockFlags->failOnUnlocked = true;
|
||||
flags->lockFlags->allowUnlocked = false;
|
||||
}
|
||||
NIXC_CATCH_ERRS
|
||||
}
|
||||
|
||||
nix_err nix_flake_lock_flags_add_input_override(
|
||||
nix_c_context * context, nix_flake_lock_flags * flags, const char * inputPath, nix_flake_reference * flakeRef)
|
||||
{
|
||||
nix_clear_err(context);
|
||||
try {
|
||||
auto path = nix::flake::parseInputAttrPath(inputPath);
|
||||
flags->lockFlags->inputOverrides.emplace(path, *flakeRef->flakeRef);
|
||||
if (flags->lockFlags->writeLockFile) {
|
||||
return nix_flake_lock_flags_set_mode_virtual(context, flags);
|
||||
}
|
||||
}
|
||||
NIXC_CATCH_ERRS
|
||||
}
|
||||
|
||||
nix_locked_flake * nix_flake_lock(
|
||||
nix_c_context * context,
|
||||
nix_fetchers_settings * fetchSettings,
|
||||
nix_flake_settings * flakeSettings,
|
||||
EvalState * eval_state,
|
||||
nix_flake_lock_flags * flags,
|
||||
nix_flake_reference * flakeReference)
|
||||
{
|
||||
nix_clear_err(context);
|
||||
try {
|
||||
auto lockedFlake = nix::make_ref<nix::flake::LockedFlake>(nix::flake::lockFlake(
|
||||
*flakeSettings->settings, eval_state->state, *flakeReference->flakeRef, *flags->lockFlags));
|
||||
return new nix_locked_flake{lockedFlake};
|
||||
}
|
||||
NIXC_CATCH_ERRS_NULL
|
||||
}
|
||||
|
||||
void nix_locked_flake_free(nix_locked_flake * lockedFlake)
|
||||
{
|
||||
delete lockedFlake;
|
||||
}
|
||||
|
||||
nix_value * nix_locked_flake_get_output_attrs(
|
||||
nix_c_context * context, nix_flake_settings * settings, EvalState * evalState, nix_locked_flake * lockedFlake)
|
||||
{
|
||||
nix_clear_err(context);
|
||||
try {
|
||||
auto v = nix_alloc_value(context, evalState);
|
||||
nix::flake::callFlake(evalState->state, *lockedFlake->lockedFlake, v->value);
|
||||
return v;
|
||||
}
|
||||
NIXC_CATCH_ERRS_NULL
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
* @brief Main entry for the libflake C bindings
|
||||
*/
|
||||
|
||||
#include "nix_api_fetchers.h"
|
||||
#include "nix_api_store.h"
|
||||
#include "nix_api_util.h"
|
||||
#include "nix_api_expr.h"
|
||||
@ -18,8 +19,46 @@ extern "C" {
|
||||
#endif
|
||||
// cffi start
|
||||
|
||||
/**
|
||||
* @brief A settings object for configuring the behavior of the nix-flake-c library.
|
||||
* @see nix_flake_settings_new
|
||||
* @see nix_flake_settings_free
|
||||
*/
|
||||
typedef struct nix_flake_settings nix_flake_settings;
|
||||
|
||||
/**
|
||||
* @brief Context and paramaters for parsing a flake reference
|
||||
* @see nix_flake_reference_parse_flags_free
|
||||
* @see nix_flake_reference_parse_string
|
||||
*/
|
||||
typedef struct nix_flake_reference_parse_flags nix_flake_reference_parse_flags;
|
||||
|
||||
/**
|
||||
* @brief A reference to a flake
|
||||
*
|
||||
* A flake reference specifies how to fetch a flake.
|
||||
*
|
||||
* @see nix_flake_reference_from_string
|
||||
* @see nix_flake_reference_free
|
||||
*/
|
||||
typedef struct nix_flake_reference nix_flake_reference;
|
||||
|
||||
/**
|
||||
* @brief Parameters for locking a flake
|
||||
* @see nix_flake_lock_flags_new
|
||||
* @see nix_flake_lock_flags_free
|
||||
* @see nix_flake_lock
|
||||
*/
|
||||
typedef struct nix_flake_lock_flags nix_flake_lock_flags;
|
||||
|
||||
/**
|
||||
* @brief A flake with a suitable lock (file or otherwise)
|
||||
* @see nix_flake_lock
|
||||
* @see nix_locked_flake_free
|
||||
* @see nix_locked_flake_get_output_attrs
|
||||
*/
|
||||
typedef struct nix_locked_flake nix_locked_flake;
|
||||
|
||||
// Function prototypes
|
||||
/**
|
||||
* Create a nix_flake_settings initialized with default values.
|
||||
@ -38,6 +77,8 @@ void nix_flake_settings_free(nix_flake_settings * settings);
|
||||
* @brief Initialize a `nix_flake_settings` to contain `builtins.getFlake` and
|
||||
* potentially more.
|
||||
*
|
||||
* @warning This does not put the eval state in pure mode!
|
||||
*
|
||||
* @param[out] context Optional, stores error information
|
||||
* @param[in] settings The settings to use for e.g. `builtins.getFlake`
|
||||
* @param[in] builder The builder to modify
|
||||
@ -45,6 +86,158 @@ void nix_flake_settings_free(nix_flake_settings * settings);
|
||||
nix_err nix_flake_settings_add_to_eval_state_builder(
|
||||
nix_c_context * context, nix_flake_settings * settings, nix_eval_state_builder * builder);
|
||||
|
||||
/**
|
||||
* @brief A new `nix_flake_reference_parse_flags` with defaults
|
||||
*/
|
||||
nix_flake_reference_parse_flags *
|
||||
nix_flake_reference_parse_flags_new(nix_c_context * context, nix_flake_settings * settings);
|
||||
|
||||
/**
|
||||
* @brief Deallocate and release the resources associated with a `nix_flake_reference_parse_flags`.
|
||||
* Does not fail.
|
||||
* @param[in] flags the `nix_flake_reference_parse_flags *` to free
|
||||
*/
|
||||
void nix_flake_reference_parse_flags_free(nix_flake_reference_parse_flags * flags);
|
||||
|
||||
/**
|
||||
* @brief Provide a base directory for parsing relative flake references
|
||||
* @param[out] context Optional, stores error information
|
||||
* @param[in] flags The flags to modify
|
||||
* @param[in] baseDirectory The base directory to add
|
||||
* @param[in] baseDirectoryLen The length of baseDirectory
|
||||
* @return NIX_OK on success, NIX_ERR on failure
|
||||
*/
|
||||
nix_err nix_flake_reference_parse_flags_set_base_directory(
|
||||
nix_c_context * context,
|
||||
nix_flake_reference_parse_flags * flags,
|
||||
const char * baseDirectory,
|
||||
size_t baseDirectoryLen);
|
||||
|
||||
/**
|
||||
* @brief A new `nix_flake_lock_flags` with defaults
|
||||
* @param[in] settings Flake settings that may affect the defaults
|
||||
*/
|
||||
nix_flake_lock_flags * nix_flake_lock_flags_new(nix_c_context * context, nix_flake_settings * settings);
|
||||
|
||||
/**
|
||||
* @brief Deallocate and release the resources associated with a `nix_flake_lock_flags`.
|
||||
* Does not fail.
|
||||
* @param[in] settings the `nix_flake_lock_flags *` to free
|
||||
*/
|
||||
void nix_flake_lock_flags_free(nix_flake_lock_flags * settings);
|
||||
|
||||
/**
|
||||
* @brief Put the lock flags in a mode that checks whether the lock is up to date.
|
||||
* @param[out] context Optional, stores error information
|
||||
* @param[in] flags The flags to modify
|
||||
* @return NIX_OK on success, NIX_ERR on failure
|
||||
*
|
||||
* This causes `nix_flake_lock` to fail if the lock needs to be updated.
|
||||
*/
|
||||
nix_err nix_flake_lock_flags_set_mode_check(nix_c_context * context, nix_flake_lock_flags * flags);
|
||||
|
||||
/**
|
||||
* @brief Put the lock flags in a mode that updates the lock file in memory, if needed.
|
||||
* @param[out] context Optional, stores error information
|
||||
* @param[in] flags The flags to modify
|
||||
* @param[in] update Whether to allow updates
|
||||
*
|
||||
* This will cause `nix_flake_lock` to update the lock file in memory, if needed.
|
||||
*/
|
||||
nix_err nix_flake_lock_flags_set_mode_virtual(nix_c_context * context, nix_flake_lock_flags * flags);
|
||||
|
||||
/**
|
||||
* @brief Put the lock flags in a mode that updates the lock file on disk, if needed.
|
||||
* @param[out] context Optional, stores error information
|
||||
* @param[in] flags The flags to modify
|
||||
* @param[in] update Whether to allow updates
|
||||
*
|
||||
* This will cause `nix_flake_lock` to update the lock file on disk, if needed.
|
||||
*/
|
||||
nix_err nix_flake_lock_flags_set_mode_write_as_needed(nix_c_context * context, nix_flake_lock_flags * flags);
|
||||
|
||||
/**
|
||||
* @brief Add input overrides to the lock flags
|
||||
* @param[out] context Optional, stores error information
|
||||
* @param[in] flags The flags to modify
|
||||
* @param[in] inputPath The input path to override
|
||||
* @param[in] flakeRef The flake reference to use as the override
|
||||
*
|
||||
* This switches the `flags` to `nix_flake_lock_flags_set_mode_virtual` if not in mode
|
||||
* `nix_flake_lock_flags_set_mode_check`.
|
||||
*/
|
||||
nix_err nix_flake_lock_flags_add_input_override(
|
||||
nix_c_context * context, nix_flake_lock_flags * flags, const char * inputPath, nix_flake_reference * flakeRef);
|
||||
|
||||
/**
|
||||
* @brief Lock a flake, if not already locked.
|
||||
* @param[out] context Optional, stores error information
|
||||
* @param[in] settings The flake (and fetch) settings to use
|
||||
* @param[in] flags The locking flags to use
|
||||
* @param[in] flake The flake to lock
|
||||
*/
|
||||
nix_locked_flake * nix_flake_lock(
|
||||
nix_c_context * context,
|
||||
nix_fetchers_settings * fetchSettings,
|
||||
nix_flake_settings * settings,
|
||||
EvalState * eval_state,
|
||||
nix_flake_lock_flags * flags,
|
||||
nix_flake_reference * flake);
|
||||
|
||||
/**
|
||||
* @brief Deallocate and release the resources associated with a `nix_locked_flake`.
|
||||
* Does not fail.
|
||||
* @param[in] locked_flake the `nix_locked_flake *` to free
|
||||
*/
|
||||
void nix_locked_flake_free(nix_locked_flake * locked_flake);
|
||||
|
||||
/**
|
||||
* @brief Parse a URL-like string into a `nix_flake_reference`.
|
||||
*
|
||||
* @param[out] context **context** – Optional, stores error information
|
||||
* @param[in] fetchSettings **context** – The fetch settings to use
|
||||
* @param[in] flakeSettings **context** – The flake settings to use
|
||||
* @param[in] parseFlags **context** – Specific context and parameters such as base directory
|
||||
*
|
||||
* @param[in] str **input** – The URI-like string to parse
|
||||
* @param[in] strLen **input** – The length of `str`
|
||||
*
|
||||
* @param[out] flakeReferenceOut **result** – The resulting flake reference
|
||||
* @param[in] fragmentCallback **result** – A callback to call with the fragment part of the URL
|
||||
* @param[in] fragmentCallbackUserData **result** – User data to pass to the fragment callback
|
||||
*
|
||||
* @return NIX_OK on success, NIX_ERR on failure
|
||||
*/
|
||||
nix_err nix_flake_reference_and_fragment_from_string(
|
||||
nix_c_context * context,
|
||||
nix_fetchers_settings * fetchSettings,
|
||||
nix_flake_settings * flakeSettings,
|
||||
nix_flake_reference_parse_flags * parseFlags,
|
||||
const char * str,
|
||||
size_t strLen,
|
||||
nix_flake_reference ** flakeReferenceOut,
|
||||
nix_get_string_callback fragmentCallback,
|
||||
void * fragmentCallbackUserData);
|
||||
|
||||
/**
|
||||
* @brief Deallocate and release the resources associated with a `nix_flake_reference`.
|
||||
*
|
||||
* Does not fail.
|
||||
*
|
||||
* @param[in] store the `nix_flake_reference *` to free
|
||||
*/
|
||||
void nix_flake_reference_free(nix_flake_reference * store);
|
||||
|
||||
/**
|
||||
* @brief Get the output attributes of a flake.
|
||||
* @param[out] context Optional, stores error information
|
||||
* @param[in] settings The settings to use
|
||||
* @param[in] locked_flake the flake to get the output attributes from
|
||||
* @return A new nix_value or NULL on failure. Release the `nix_value` with `nix_value_decref`.
|
||||
*/
|
||||
nix_value * nix_locked_flake_get_output_attrs(
|
||||
nix_c_context * context, nix_flake_settings * settings, EvalState * evalState, nix_locked_flake * lockedFlake);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
@ -1,9 +1,32 @@
|
||||
#pragma once
|
||||
#include <optional>
|
||||
|
||||
#include "nix/util/ref.hh"
|
||||
#include "nix/flake/flake.hh"
|
||||
#include "nix/flake/flakeref.hh"
|
||||
#include "nix/flake/settings.hh"
|
||||
|
||||
struct nix_flake_settings
|
||||
{
|
||||
nix::ref<nix::flake::Settings> settings;
|
||||
};
|
||||
|
||||
struct nix_flake_reference_parse_flags
|
||||
{
|
||||
std::optional<nix::Path> baseDirectory;
|
||||
};
|
||||
|
||||
struct nix_flake_reference
|
||||
{
|
||||
nix::ref<nix::FlakeRef> flakeRef;
|
||||
};
|
||||
|
||||
struct nix_flake_lock_flags
|
||||
{
|
||||
nix::ref<nix::flake::LockFlags> lockFlags;
|
||||
};
|
||||
|
||||
struct nix_locked_flake
|
||||
{
|
||||
nix::ref<nix::flake::LockedFlake> lockedFlake;
|
||||
};
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
nix-store-c,
|
||||
nix-expr-c,
|
||||
nix-fetchers-c,
|
||||
nix-flake,
|
||||
|
||||
# Configuration Options
|
||||
@ -35,6 +36,7 @@ mkMesonLibrary (finalAttrs: {
|
||||
propagatedBuildInputs = [
|
||||
nix-expr-c
|
||||
nix-store-c
|
||||
nix-fetchers-c
|
||||
nix-flake
|
||||
];
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include "nix/util/file-system.hh"
|
||||
#include "nix_api_store.h"
|
||||
#include "nix_api_store_internal.h"
|
||||
#include "nix_api_util.h"
|
||||
#include "nix_api_util_internal.h"
|
||||
#include "nix_api_expr.h"
|
||||
#include "nix_api_value.h"
|
||||
#include "nix_api_flake.h"
|
||||
@ -14,7 +13,7 @@
|
||||
|
||||
namespace nixC {
|
||||
|
||||
TEST_F(nix_api_store_test, nix_api_init_global_getFlake_exists)
|
||||
TEST_F(nix_api_store_test, nix_api_init_getFlake_exists)
|
||||
{
|
||||
nix_libstore_init(ctx);
|
||||
assert_ctx_ok();
|
||||
@ -51,4 +50,334 @@ TEST_F(nix_api_store_test, nix_api_init_global_getFlake_exists)
|
||||
ASSERT_EQ(NIX_TYPE_FUNCTION, nix_get_type(ctx, value));
|
||||
}
|
||||
|
||||
TEST_F(nix_api_store_test, nix_api_flake_reference_not_absolute_no_basedir_fail)
|
||||
{
|
||||
nix_libstore_init(ctx);
|
||||
assert_ctx_ok();
|
||||
nix_libexpr_init(ctx);
|
||||
assert_ctx_ok();
|
||||
|
||||
auto settings = nix_flake_settings_new(ctx);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, settings);
|
||||
|
||||
auto fetchSettings = nix_fetchers_settings_new(ctx);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, fetchSettings);
|
||||
|
||||
auto parseFlags = nix_flake_reference_parse_flags_new(ctx, settings);
|
||||
|
||||
std::string str(".#legacyPackages.aarch127-unknown...orion");
|
||||
std::string fragment;
|
||||
nix_flake_reference * flakeReference = nullptr;
|
||||
auto r = nix_flake_reference_and_fragment_from_string(
|
||||
ctx, fetchSettings, settings, parseFlags, str.data(), str.size(), &flakeReference, OBSERVE_STRING(fragment));
|
||||
|
||||
ASSERT_NE(NIX_OK, r);
|
||||
ASSERT_EQ(nullptr, flakeReference);
|
||||
|
||||
nix_flake_reference_parse_flags_free(parseFlags);
|
||||
}
|
||||
|
||||
TEST_F(nix_api_store_test, nix_api_load_flake)
|
||||
{
|
||||
auto tmpDir = nix::createTempDir();
|
||||
nix::AutoDelete delTmpDir(tmpDir, true);
|
||||
|
||||
nix::writeFile(tmpDir + "/flake.nix", R"(
|
||||
{
|
||||
outputs = { ... }: {
|
||||
hello = "potato";
|
||||
};
|
||||
}
|
||||
)");
|
||||
|
||||
nix_libstore_init(ctx);
|
||||
assert_ctx_ok();
|
||||
nix_libexpr_init(ctx);
|
||||
assert_ctx_ok();
|
||||
|
||||
auto fetchSettings = nix_fetchers_settings_new(ctx);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, fetchSettings);
|
||||
|
||||
auto settings = nix_flake_settings_new(ctx);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, settings);
|
||||
|
||||
nix_eval_state_builder * builder = nix_eval_state_builder_new(ctx, store);
|
||||
ASSERT_NE(nullptr, builder);
|
||||
assert_ctx_ok();
|
||||
|
||||
auto state = nix_eval_state_build(ctx, builder);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, state);
|
||||
|
||||
nix_eval_state_builder_free(builder);
|
||||
|
||||
auto parseFlags = nix_flake_reference_parse_flags_new(ctx, settings);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, parseFlags);
|
||||
|
||||
auto r0 = nix_flake_reference_parse_flags_set_base_directory(ctx, parseFlags, tmpDir.c_str(), tmpDir.size());
|
||||
assert_ctx_ok();
|
||||
ASSERT_EQ(NIX_OK, r0);
|
||||
|
||||
std::string fragment;
|
||||
const std::string ref = ".#legacyPackages.aarch127-unknown...orion";
|
||||
nix_flake_reference * flakeReference = nullptr;
|
||||
auto r = nix_flake_reference_and_fragment_from_string(
|
||||
ctx, fetchSettings, settings, parseFlags, ref.data(), ref.size(), &flakeReference, OBSERVE_STRING(fragment));
|
||||
assert_ctx_ok();
|
||||
ASSERT_EQ(NIX_OK, r);
|
||||
ASSERT_NE(nullptr, flakeReference);
|
||||
ASSERT_EQ(fragment, "legacyPackages.aarch127-unknown...orion");
|
||||
|
||||
nix_flake_reference_parse_flags_free(parseFlags);
|
||||
|
||||
auto lockFlags = nix_flake_lock_flags_new(ctx, settings);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, lockFlags);
|
||||
|
||||
auto lockedFlake = nix_flake_lock(ctx, fetchSettings, settings, state, lockFlags, flakeReference);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, lockedFlake);
|
||||
|
||||
nix_flake_lock_flags_free(lockFlags);
|
||||
|
||||
auto value = nix_locked_flake_get_output_attrs(ctx, settings, state, lockedFlake);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, value);
|
||||
|
||||
auto helloAttr = nix_get_attr_byname(ctx, value, state, "hello");
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, helloAttr);
|
||||
|
||||
std::string helloStr;
|
||||
nix_get_string(ctx, helloAttr, OBSERVE_STRING(helloStr));
|
||||
assert_ctx_ok();
|
||||
ASSERT_EQ("potato", helloStr);
|
||||
|
||||
nix_value_decref(ctx, value);
|
||||
nix_locked_flake_free(lockedFlake);
|
||||
nix_flake_reference_free(flakeReference);
|
||||
nix_state_free(state);
|
||||
nix_flake_settings_free(settings);
|
||||
}
|
||||
|
||||
TEST_F(nix_api_store_test, nix_api_load_flake_with_flags)
|
||||
{
|
||||
nix_libstore_init(ctx);
|
||||
assert_ctx_ok();
|
||||
nix_libexpr_init(ctx);
|
||||
assert_ctx_ok();
|
||||
|
||||
auto tmpDir = nix::createTempDir();
|
||||
nix::AutoDelete delTmpDir(tmpDir, true);
|
||||
|
||||
nix::createDirs(tmpDir + "/b");
|
||||
nix::writeFile(tmpDir + "/b/flake.nix", R"(
|
||||
{
|
||||
outputs = { ... }: {
|
||||
hello = "BOB";
|
||||
};
|
||||
}
|
||||
)");
|
||||
|
||||
nix::createDirs(tmpDir + "/a");
|
||||
nix::writeFile(tmpDir + "/a/flake.nix", R"(
|
||||
{
|
||||
inputs.b.url = ")" + tmpDir + R"(/b";
|
||||
outputs = { b, ... }: {
|
||||
hello = b.hello;
|
||||
};
|
||||
}
|
||||
)");
|
||||
|
||||
nix::createDirs(tmpDir + "/c");
|
||||
nix::writeFile(tmpDir + "/c/flake.nix", R"(
|
||||
{
|
||||
outputs = { ... }: {
|
||||
hello = "Claire";
|
||||
};
|
||||
}
|
||||
)");
|
||||
|
||||
nix_libstore_init(ctx);
|
||||
assert_ctx_ok();
|
||||
|
||||
auto fetchSettings = nix_fetchers_settings_new(ctx);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, fetchSettings);
|
||||
|
||||
auto settings = nix_flake_settings_new(ctx);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, settings);
|
||||
|
||||
nix_eval_state_builder * builder = nix_eval_state_builder_new(ctx, store);
|
||||
ASSERT_NE(nullptr, builder);
|
||||
assert_ctx_ok();
|
||||
|
||||
auto state = nix_eval_state_build(ctx, builder);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, state);
|
||||
|
||||
nix_eval_state_builder_free(builder);
|
||||
|
||||
auto parseFlags = nix_flake_reference_parse_flags_new(ctx, settings);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, parseFlags);
|
||||
|
||||
auto r0 = nix_flake_reference_parse_flags_set_base_directory(ctx, parseFlags, tmpDir.c_str(), tmpDir.size());
|
||||
assert_ctx_ok();
|
||||
ASSERT_EQ(NIX_OK, r0);
|
||||
|
||||
std::string fragment;
|
||||
const std::string ref = "./a";
|
||||
nix_flake_reference * flakeReference = nullptr;
|
||||
auto r = nix_flake_reference_and_fragment_from_string(
|
||||
ctx, fetchSettings, settings, parseFlags, ref.data(), ref.size(), &flakeReference, OBSERVE_STRING(fragment));
|
||||
assert_ctx_ok();
|
||||
ASSERT_EQ(NIX_OK, r);
|
||||
ASSERT_NE(nullptr, flakeReference);
|
||||
ASSERT_EQ(fragment, "");
|
||||
|
||||
// Step 1: Do not update, fails
|
||||
|
||||
auto lockFlags = nix_flake_lock_flags_new(ctx, settings);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, lockFlags);
|
||||
|
||||
nix_flake_lock_flags_set_mode_check(ctx, lockFlags);
|
||||
assert_ctx_ok();
|
||||
|
||||
// Step 2: Update but do not write, succeeds
|
||||
|
||||
auto lockedFlake = nix_flake_lock(ctx, fetchSettings, settings, state, lockFlags, flakeReference);
|
||||
assert_ctx_err();
|
||||
ASSERT_EQ(nullptr, lockedFlake);
|
||||
|
||||
nix_flake_lock_flags_set_mode_virtual(ctx, lockFlags);
|
||||
assert_ctx_ok();
|
||||
|
||||
lockedFlake = nix_flake_lock(ctx, fetchSettings, settings, state, lockFlags, flakeReference);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, lockedFlake);
|
||||
|
||||
// Get the output attrs
|
||||
auto value = nix_locked_flake_get_output_attrs(ctx, settings, state, lockedFlake);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, value);
|
||||
|
||||
auto helloAttr = nix_get_attr_byname(ctx, value, state, "hello");
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, helloAttr);
|
||||
|
||||
std::string helloStr;
|
||||
nix_get_string(ctx, helloAttr, OBSERVE_STRING(helloStr));
|
||||
assert_ctx_ok();
|
||||
ASSERT_EQ("BOB", helloStr);
|
||||
|
||||
nix_value_decref(ctx, value);
|
||||
nix_locked_flake_free(lockedFlake);
|
||||
|
||||
// Step 3: Lock was not written, so Step 1 would fail again
|
||||
|
||||
nix_flake_lock_flags_set_mode_check(ctx, lockFlags);
|
||||
|
||||
lockedFlake = nix_flake_lock(ctx, fetchSettings, settings, state, lockFlags, flakeReference);
|
||||
assert_ctx_err();
|
||||
ASSERT_EQ(nullptr, lockedFlake);
|
||||
|
||||
// Step 4: Update and write, succeeds
|
||||
|
||||
nix_flake_lock_flags_set_mode_write_as_needed(ctx, lockFlags);
|
||||
assert_ctx_ok();
|
||||
|
||||
lockedFlake = nix_flake_lock(ctx, fetchSettings, settings, state, lockFlags, flakeReference);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, lockedFlake);
|
||||
|
||||
// Get the output attrs
|
||||
value = nix_locked_flake_get_output_attrs(ctx, settings, state, lockedFlake);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, value);
|
||||
|
||||
helloAttr = nix_get_attr_byname(ctx, value, state, "hello");
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, helloAttr);
|
||||
|
||||
helloStr.clear();
|
||||
nix_get_string(ctx, helloAttr, OBSERVE_STRING(helloStr));
|
||||
assert_ctx_ok();
|
||||
ASSERT_EQ("BOB", helloStr);
|
||||
|
||||
nix_value_decref(ctx, value);
|
||||
nix_locked_flake_free(lockedFlake);
|
||||
|
||||
// Step 5: Lock was written, so Step 1 would succeed
|
||||
|
||||
nix_flake_lock_flags_set_mode_check(ctx, lockFlags);
|
||||
assert_ctx_ok();
|
||||
|
||||
lockedFlake = nix_flake_lock(ctx, fetchSettings, settings, state, lockFlags, flakeReference);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, lockedFlake);
|
||||
|
||||
// Get the output attrs
|
||||
value = nix_locked_flake_get_output_attrs(ctx, settings, state, lockedFlake);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, value);
|
||||
|
||||
helloAttr = nix_get_attr_byname(ctx, value, state, "hello");
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, helloAttr);
|
||||
|
||||
helloStr.clear();
|
||||
nix_get_string(ctx, helloAttr, OBSERVE_STRING(helloStr));
|
||||
assert_ctx_ok();
|
||||
ASSERT_EQ("BOB", helloStr);
|
||||
|
||||
nix_value_decref(ctx, value);
|
||||
nix_locked_flake_free(lockedFlake);
|
||||
|
||||
// Step 6: Lock with override, do not write
|
||||
|
||||
nix_flake_lock_flags_set_mode_write_as_needed(ctx, lockFlags);
|
||||
assert_ctx_ok();
|
||||
|
||||
nix_flake_reference * overrideFlakeReference = nullptr;
|
||||
nix_flake_reference_and_fragment_from_string(
|
||||
ctx, fetchSettings, settings, parseFlags, "./c", 3, &overrideFlakeReference, OBSERVE_STRING(fragment));
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, overrideFlakeReference);
|
||||
|
||||
nix_flake_lock_flags_add_input_override(ctx, lockFlags, "b", overrideFlakeReference);
|
||||
assert_ctx_ok();
|
||||
|
||||
lockedFlake = nix_flake_lock(ctx, fetchSettings, settings, state, lockFlags, flakeReference);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, lockedFlake);
|
||||
|
||||
// Get the output attrs
|
||||
value = nix_locked_flake_get_output_attrs(ctx, settings, state, lockedFlake);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, value);
|
||||
|
||||
helloAttr = nix_get_attr_byname(ctx, value, state, "hello");
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, helloAttr);
|
||||
|
||||
helloStr.clear();
|
||||
nix_get_string(ctx, helloAttr, OBSERVE_STRING(helloStr));
|
||||
assert_ctx_ok();
|
||||
ASSERT_EQ("Claire", helloStr);
|
||||
|
||||
nix_flake_reference_parse_flags_free(parseFlags);
|
||||
nix_flake_lock_flags_free(lockFlags);
|
||||
nix_flake_reference_free(flakeReference);
|
||||
nix_state_free(state);
|
||||
nix_flake_settings_free(settings);
|
||||
}
|
||||
|
||||
} // namespace nixC
|
||||
|
@ -63,7 +63,7 @@ struct ConfigFile
|
||||
};
|
||||
|
||||
/**
|
||||
* The contents of a flake.nix file.
|
||||
* A flake in context
|
||||
*/
|
||||
struct Flake
|
||||
{
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "nix_api_util.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <string_view>
|
||||
|
||||
namespace nixC {
|
||||
|
||||
@ -24,7 +25,12 @@ protected:
|
||||
|
||||
nix_c_context * ctx;
|
||||
|
||||
inline void assert_ctx_ok()
|
||||
inline std::string loc(const char * file, int line)
|
||||
{
|
||||
return std::string(file) + ":" + std::to_string(line);
|
||||
}
|
||||
|
||||
inline void assert_ctx_ok(const char * file, int line)
|
||||
{
|
||||
if (nix_err_code(ctx) == NIX_OK) {
|
||||
return;
|
||||
@ -32,16 +38,18 @@ protected:
|
||||
unsigned int n;
|
||||
const char * p = nix_err_msg(nullptr, ctx, &n);
|
||||
std::string msg(p, n);
|
||||
throw std::runtime_error(std::string("nix_err_code(ctx) != NIX_OK, message: ") + msg);
|
||||
throw std::runtime_error(loc(file, line) + ": nix_err_code(ctx) != NIX_OK, message: " + msg);
|
||||
}
|
||||
#define assert_ctx_ok() assert_ctx_ok(__FILE__, __LINE__)
|
||||
|
||||
inline void assert_ctx_err()
|
||||
inline void assert_ctx_err(const char * file, int line)
|
||||
{
|
||||
if (nix_err_code(ctx) != NIX_OK) {
|
||||
return;
|
||||
}
|
||||
throw std::runtime_error("Got NIX_OK, but expected an error!");
|
||||
throw std::runtime_error(loc(file, line) + ": Got NIX_OK, but expected an error!");
|
||||
}
|
||||
#define assert_ctx_err() assert_ctx_err(__FILE__, __LINE__)
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user