mirror of
https://github.com/NixOS/nix
synced 2025-07-07 10:11:47 +02:00
Merge pull request #11940 from NixOS/c-api-libflake
C API: Add libflake-c
This commit is contained in:
commit
46b0f7755f
23 changed files with 522 additions and 25 deletions
|
@ -40,6 +40,7 @@ GENERATE_LATEX = NO
|
|||
INPUT = \
|
||||
@src@/src/libutil-c \
|
||||
@src@/src/libexpr-c \
|
||||
@src@/src/libflake-c \
|
||||
@src@/src/libstore-c \
|
||||
@src@/src/external-api-docs/README.md
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ mkMesonDerivation (finalAttrs: {
|
|||
# Source is not compiled, but still must be available for Doxygen
|
||||
# to gather comments.
|
||||
(cpp ../libexpr-c)
|
||||
(cpp ../libflake-c)
|
||||
(cpp ../libstore-c)
|
||||
(cpp ../libutil-c)
|
||||
];
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "eval-gc.hh"
|
||||
#include "globals.hh"
|
||||
#include "eval-settings.hh"
|
||||
#include "ref.hh"
|
||||
|
||||
#include "nix_api_expr.h"
|
||||
#include "nix_api_expr_internal.h"
|
||||
|
@ -18,6 +19,29 @@
|
|||
# include <mutex>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Allocate and initialize using self-reference
|
||||
*
|
||||
* This allows a brace initializer to reference the object being constructed.
|
||||
*
|
||||
* @warning Use with care, as the pointer points to an object that is not fully constructed yet.
|
||||
*
|
||||
* @tparam T Type to allocate
|
||||
* @tparam F A function type for `init`, taking a T* and returning the initializer for T
|
||||
* @param init Function that takes a T* and returns the initializer for T
|
||||
* @return Pointer to allocated and initialized object
|
||||
*/
|
||||
template <typename T, typename F>
|
||||
static T * unsafe_new_with_self(F && init)
|
||||
{
|
||||
// Allocate
|
||||
void * p = ::operator new(
|
||||
sizeof(T),
|
||||
static_cast<std::align_val_t>(alignof(T)));
|
||||
// Initialize with placement new
|
||||
return new (p) T(init(static_cast<T *>(p)));
|
||||
}
|
||||
|
||||
nix_err nix_libexpr_init(nix_c_context * context)
|
||||
{
|
||||
if (context)
|
||||
|
@ -93,7 +117,42 @@ nix_err nix_value_force_deep(nix_c_context * context, EvalState * state, nix_val
|
|||
NIXC_CATCH_ERRS
|
||||
}
|
||||
|
||||
EvalState * nix_state_create(nix_c_context * context, const char ** lookupPath_c, Store * store)
|
||||
nix_eval_state_builder * nix_eval_state_builder_new(nix_c_context * context, Store * store)
|
||||
{
|
||||
if (context)
|
||||
context->last_err_code = NIX_OK;
|
||||
try {
|
||||
return unsafe_new_with_self<nix_eval_state_builder>([&](auto * self) {
|
||||
return nix_eval_state_builder{
|
||||
.store = nix::ref<nix::Store>(store->ptr),
|
||||
.settings = nix::EvalSettings{/* &bool */ self->readOnlyMode},
|
||||
.fetchSettings = nix::fetchers::Settings{},
|
||||
.readOnlyMode = true,
|
||||
};
|
||||
});
|
||||
}
|
||||
NIXC_CATCH_ERRS_NULL
|
||||
}
|
||||
|
||||
void nix_eval_state_builder_free(nix_eval_state_builder * builder)
|
||||
{
|
||||
delete builder;
|
||||
}
|
||||
|
||||
nix_err nix_eval_state_builder_load(nix_c_context * context, nix_eval_state_builder * builder)
|
||||
{
|
||||
if (context)
|
||||
context->last_err_code = NIX_OK;
|
||||
try {
|
||||
// TODO: load in one go?
|
||||
builder->settings.readOnlyMode = nix::settings.readOnlyMode;
|
||||
loadConfFile(builder->settings);
|
||||
loadConfFile(builder->fetchSettings);
|
||||
}
|
||||
NIXC_CATCH_ERRS
|
||||
}
|
||||
|
||||
nix_err nix_eval_state_builder_set_lookup_path(nix_c_context * context, nix_eval_state_builder * builder, const char ** lookupPath_c)
|
||||
{
|
||||
if (context)
|
||||
context->last_err_code = NIX_OK;
|
||||
|
@ -102,28 +161,47 @@ EvalState * nix_state_create(nix_c_context * context, const char ** lookupPath_c
|
|||
if (lookupPath_c != nullptr)
|
||||
for (size_t i = 0; lookupPath_c[i] != nullptr; i++)
|
||||
lookupPath.push_back(lookupPath_c[i]);
|
||||
builder->lookupPath = nix::LookupPath::parse(lookupPath);
|
||||
}
|
||||
NIXC_CATCH_ERRS
|
||||
}
|
||||
|
||||
void * p = ::operator new(
|
||||
sizeof(EvalState),
|
||||
static_cast<std::align_val_t>(alignof(EvalState)));
|
||||
auto * p2 = static_cast<EvalState *>(p);
|
||||
new (p) EvalState {
|
||||
.fetchSettings = nix::fetchers::Settings{},
|
||||
.settings = nix::EvalSettings{
|
||||
nix::settings.readOnlyMode,
|
||||
},
|
||||
.state = nix::EvalState(
|
||||
nix::LookupPath::parse(lookupPath),
|
||||
store->ptr,
|
||||
p2->fetchSettings,
|
||||
p2->settings),
|
||||
};
|
||||
loadConfFile(p2->settings);
|
||||
return p2;
|
||||
EvalState * nix_eval_state_build(nix_c_context * context, nix_eval_state_builder * builder)
|
||||
{
|
||||
if (context)
|
||||
context->last_err_code = NIX_OK;
|
||||
try {
|
||||
return unsafe_new_with_self<EvalState>([&](auto * self) {
|
||||
return EvalState{
|
||||
.fetchSettings = std::move(builder->fetchSettings),
|
||||
.settings = std::move(builder->settings),
|
||||
.state = nix::EvalState(
|
||||
builder->lookupPath,
|
||||
builder->store,
|
||||
self->fetchSettings,
|
||||
self->settings),
|
||||
};
|
||||
});
|
||||
}
|
||||
NIXC_CATCH_ERRS_NULL
|
||||
}
|
||||
|
||||
EvalState * nix_state_create(nix_c_context * context, const char ** lookupPath_c, Store * store)
|
||||
{
|
||||
auto builder = nix_eval_state_builder_new(context, store);
|
||||
if (builder == nullptr)
|
||||
return nullptr;
|
||||
|
||||
if (nix_eval_state_builder_load(context, builder) != NIX_OK)
|
||||
return nullptr;
|
||||
|
||||
if (nix_eval_state_builder_set_lookup_path(context, builder, lookupPath_c)
|
||||
!= NIX_OK)
|
||||
return nullptr;
|
||||
|
||||
return nix_eval_state_build(context, builder);
|
||||
}
|
||||
|
||||
void nix_state_free(EvalState * state)
|
||||
{
|
||||
delete state;
|
||||
|
|
|
@ -30,6 +30,11 @@ extern "C" {
|
|||
// cffi start
|
||||
|
||||
// Type definitions
|
||||
/**
|
||||
* @brief Builder for EvalState
|
||||
*/
|
||||
typedef struct nix_eval_state_builder nix_eval_state_builder;
|
||||
|
||||
/**
|
||||
* @brief Represents a state of the Nix language evaluator.
|
||||
*
|
||||
|
@ -174,12 +179,70 @@ nix_err nix_value_force(nix_c_context * context, EvalState * state, nix_value *
|
|||
nix_err nix_value_force_deep(nix_c_context * context, EvalState * state, nix_value * value);
|
||||
|
||||
/**
|
||||
* @brief Create a new Nix language evaluator state.
|
||||
* @brief Create a new nix_eval_state_builder
|
||||
*
|
||||
* The settings are initialized to their default value.
|
||||
* Values can be sourced elsewhere with nix_eval_state_builder_load.
|
||||
*
|
||||
* @param[out] context Optional, stores error information
|
||||
* @param[in] store The Nix store to use.
|
||||
* @return A new nix_eval_state_builder or NULL on failure.
|
||||
*/
|
||||
nix_eval_state_builder * nix_eval_state_builder_new(nix_c_context * context, Store * store);
|
||||
|
||||
/**
|
||||
* @brief Read settings from the ambient environment
|
||||
*
|
||||
* Settings are sourced from environment variables and configuration files,
|
||||
* as documented in the Nix manual.
|
||||
*
|
||||
* @param[out] context Optional, stores error information
|
||||
* @param[out] builder The builder to modify.
|
||||
* @return NIX_OK if successful, an error code otherwise.
|
||||
*/
|
||||
nix_err nix_eval_state_builder_load(nix_c_context * context, nix_eval_state_builder * builder);
|
||||
|
||||
/**
|
||||
* @brief Set the lookup path for `<...>` expressions
|
||||
*
|
||||
* @param[in] context Optional, stores error information
|
||||
* @param[in] builder The builder to modify.
|
||||
* @param[in] lookupPath Null-terminated array of strings corresponding to entries in NIX_PATH.
|
||||
*/
|
||||
nix_err nix_eval_state_builder_set_lookup_path(
|
||||
nix_c_context * context, nix_eval_state_builder * builder, const char ** lookupPath);
|
||||
|
||||
/**
|
||||
* @brief Create a new Nix language evaluator state
|
||||
*
|
||||
* Remember to nix_eval_state_builder_free after building the state.
|
||||
*
|
||||
* @param[out] context Optional, stores error information
|
||||
* @param[in] builder The builder to use and free
|
||||
* @return A new Nix state or NULL on failure.
|
||||
* @see nix_eval_state_builder_new, nix_eval_state_builder_free
|
||||
*/
|
||||
EvalState * nix_eval_state_build(nix_c_context * context, nix_eval_state_builder * builder);
|
||||
|
||||
/**
|
||||
* @brief Free a nix_eval_state_builder
|
||||
*
|
||||
* Does not fail.
|
||||
*
|
||||
* @param[in] builder The builder to free.
|
||||
*/
|
||||
void nix_eval_state_builder_free(nix_eval_state_builder * builder);
|
||||
|
||||
/**
|
||||
* @brief Create a new Nix language evaluator state
|
||||
*
|
||||
* For more control, use nix_eval_state_builder
|
||||
*
|
||||
* @param[out] context Optional, stores error information
|
||||
* @param[in] lookupPath Null-terminated array of strings corresponding to entries in NIX_PATH.
|
||||
* @param[in] store The Nix store to use.
|
||||
* @return A new Nix state or NULL on failure.
|
||||
* @see nix_state_builder_new
|
||||
*/
|
||||
EvalState * nix_state_create(nix_c_context * context, const char ** lookupPath, Store * store);
|
||||
|
||||
|
|
|
@ -6,6 +6,17 @@
|
|||
#include "eval-settings.hh"
|
||||
#include "attr-set.hh"
|
||||
#include "nix_api_value.h"
|
||||
#include "search-path.hh"
|
||||
|
||||
struct nix_eval_state_builder
|
||||
{
|
||||
nix::ref<nix::Store> store;
|
||||
nix::EvalSettings settings;
|
||||
nix::fetchers::Settings fetchSettings;
|
||||
nix::LookupPath lookupPath;
|
||||
// TODO: make an EvalSettings setting own this instead?
|
||||
bool readOnlyMode;
|
||||
};
|
||||
|
||||
struct EvalState
|
||||
{
|
||||
|
|
|
@ -213,7 +213,7 @@ nix_get_string(nix_c_context * context, const nix_value * value, nix_get_string_
|
|||
/** @brief Get path as string
|
||||
* @param[out] context Optional, stores error information
|
||||
* @param[in] value Nix value to inspect
|
||||
* @return string
|
||||
* @return string, if the type is NIX_TYPE_PATH
|
||||
* @return NULL in case of error.
|
||||
*/
|
||||
const char * nix_get_path_string(nix_c_context * context, const nix_value * value);
|
||||
|
|
|
@ -7,12 +7,49 @@
|
|||
|
||||
#include "tests/nix_api_expr.hh"
|
||||
#include "tests/string_callback.hh"
|
||||
#include "file-system.hh"
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace nixC {
|
||||
|
||||
TEST_F(nix_api_store_test, nix_eval_state_lookup_path)
|
||||
{
|
||||
auto tmpDir = nix::createTempDir();
|
||||
auto delTmpDir = std::make_unique<nix::AutoDelete>(tmpDir, true);
|
||||
auto nixpkgs = tmpDir + "/pkgs";
|
||||
auto nixos = tmpDir + "/cfg";
|
||||
std::filesystem::create_directories(nixpkgs);
|
||||
std::filesystem::create_directories(nixos);
|
||||
|
||||
std::string nixpkgsEntry = "nixpkgs=" + nixpkgs;
|
||||
std::string nixosEntry = "nixos-config=" + nixos;
|
||||
const char * lookupPath[] = {nixpkgsEntry.c_str(), nixosEntry.c_str(), nullptr};
|
||||
|
||||
auto builder = nix_eval_state_builder_new(ctx, store);
|
||||
assert_ctx_ok();
|
||||
|
||||
ASSERT_EQ(NIX_OK, nix_eval_state_builder_set_lookup_path(ctx, builder, lookupPath));
|
||||
assert_ctx_ok();
|
||||
|
||||
auto state = nix_eval_state_build(ctx, builder);
|
||||
assert_ctx_ok();
|
||||
|
||||
nix_eval_state_builder_free(builder);
|
||||
|
||||
Value * value = nix_alloc_value(ctx, state);
|
||||
nix_expr_eval_from_string(ctx, state, "builtins.seq <nixos-config> <nixpkgs>", ".", value);
|
||||
assert_ctx_ok();
|
||||
|
||||
ASSERT_EQ(nix_get_type(ctx, value), NIX_TYPE_PATH);
|
||||
assert_ctx_ok();
|
||||
|
||||
auto pathStr = nix_get_path_string(ctx, value);
|
||||
assert_ctx_ok();
|
||||
ASSERT_EQ(0, strcmp(pathStr, nixpkgs.c_str()));
|
||||
}
|
||||
|
||||
TEST_F(nix_api_expr_test, nix_expr_eval_from_string)
|
||||
{
|
||||
nix_expr_eval_from_string(nullptr, state, "builtins.nixVersion", ".", value);
|
||||
|
|
1
src/libflake-c/.version
Symbolic link
1
src/libflake-c/.version
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../.version
|
1
src/libflake-c/build-utils-meson
Symbolic link
1
src/libflake-c/build-utils-meson
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../build-utils-meson/
|
93
src/libflake-c/meson.build
Normal file
93
src/libflake-c/meson.build
Normal file
|
@ -0,0 +1,93 @@
|
|||
project('nix-flake-c', 'cpp',
|
||||
version : files('.version'),
|
||||
default_options : [
|
||||
'cpp_std=c++2a',
|
||||
# TODO(Qyriad): increase the warning level
|
||||
'warning_level=1',
|
||||
'debug=true',
|
||||
'optimization=2',
|
||||
'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('build-utils-meson/deps-lists')
|
||||
|
||||
configdata = configuration_data()
|
||||
|
||||
deps_private_maybe_subproject = [
|
||||
dependency('nix-util'),
|
||||
dependency('nix-store'),
|
||||
dependency('nix-expr'),
|
||||
dependency('nix-flake'),
|
||||
]
|
||||
deps_public_maybe_subproject = [
|
||||
dependency('nix-util-c'),
|
||||
dependency('nix-store-c'),
|
||||
dependency('nix-expr-c'),
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
|
||||
# TODO rename, because it will conflict with downstream projects
|
||||
configdata.set_quoted('PACKAGE_VERSION', meson.project_version())
|
||||
|
||||
config_h = configure_file(
|
||||
configuration : configdata,
|
||||
output : 'config-flake.h',
|
||||
)
|
||||
|
||||
add_project_arguments(
|
||||
# TODO(Qyriad): Yes this is how the autoconf+Make system did it.
|
||||
# It would be nice for our headers to be idempotent instead.
|
||||
|
||||
# From C++ libraries, only for internals
|
||||
'-include', 'config-util.hh',
|
||||
'-include', 'config-store.hh',
|
||||
'-include', 'config-expr.hh',
|
||||
# not generated (yet?)
|
||||
# '-include', 'config-flake.hh',
|
||||
|
||||
# From C libraries, for our public, installed headers too
|
||||
'-include', 'config-util.h',
|
||||
'-include', 'config-store.h',
|
||||
'-include', 'config-expr.h',
|
||||
'-include', 'config-flake.h',
|
||||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/common')
|
||||
|
||||
sources = files(
|
||||
'nix_api_flake.cc',
|
||||
)
|
||||
|
||||
include_dirs = [include_directories('.')]
|
||||
|
||||
headers = [config_h] + files(
|
||||
'nix_api_flake.h',
|
||||
)
|
||||
|
||||
# TODO move this header to libexpr, maybe don't use it in tests?
|
||||
headers += files('nix_api_flake.h')
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
subdir('build-utils-meson/windows-version')
|
||||
|
||||
this_library = library(
|
||||
'nixflakec',
|
||||
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, subdir : 'nix', preserve_path : true)
|
||||
|
||||
libraries_private = []
|
||||
|
||||
subdir('build-utils-meson/export')
|
32
src/libflake-c/nix_api_flake.cc
Normal file
32
src/libflake-c/nix_api_flake.cc
Normal file
|
@ -0,0 +1,32 @@
|
|||
#include "nix_api_flake.h"
|
||||
#include "nix_api_flake_internal.hh"
|
||||
#include "nix_api_util_internal.h"
|
||||
|
||||
#include "flake/flake.hh"
|
||||
|
||||
nix_flake_settings * nix_flake_settings_new(nix_c_context * context)
|
||||
{
|
||||
try {
|
||||
auto settings = nix::make_ref<nix::flake::Settings>();
|
||||
return new nix_flake_settings{settings};
|
||||
}
|
||||
NIXC_CATCH_ERRS_NULL
|
||||
}
|
||||
|
||||
void nix_flake_settings_free(nix_flake_settings * settings)
|
||||
{
|
||||
delete settings;
|
||||
}
|
||||
|
||||
nix_err nix_flake_init_global(nix_c_context * context, nix_flake_settings * settings)
|
||||
{
|
||||
static std::shared_ptr<nix::flake::Settings> registeredSettings;
|
||||
try {
|
||||
if (registeredSettings)
|
||||
throw nix::Error("nix_flake_init_global already initialized");
|
||||
|
||||
registeredSettings = settings->settings;
|
||||
nix::flake::initLib(*registeredSettings);
|
||||
}
|
||||
NIXC_CATCH_ERRS
|
||||
}
|
46
src/libflake-c/nix_api_flake.h
Normal file
46
src/libflake-c/nix_api_flake.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
#ifndef NIX_API_FLAKE_H
|
||||
#define NIX_API_FLAKE_H
|
||||
/** @defgroup libflake libflake
|
||||
* @brief Bindings to the Nix Flakes library
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
/** @file
|
||||
* @brief Main entry for the libflake C bindings
|
||||
*/
|
||||
|
||||
#include "nix_api_store.h"
|
||||
#include "nix_api_util.h"
|
||||
#include "nix_api_expr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
// cffi start
|
||||
|
||||
typedef struct nix_flake_settings nix_flake_settings;
|
||||
|
||||
// Function prototypes
|
||||
/**
|
||||
* Create a nix_flake_settings initialized with default values.
|
||||
* @param[out] context Optional, stores error information
|
||||
* @return A new nix_flake_settings or NULL on failure.
|
||||
* @see nix_flake_settings_free
|
||||
*/
|
||||
nix_flake_settings * nix_flake_settings_new(nix_c_context * context);
|
||||
|
||||
/**
|
||||
* @brief Release the resources associated with a nix_flake_settings.
|
||||
*/
|
||||
void nix_flake_settings_free(nix_flake_settings * settings);
|
||||
|
||||
/**
|
||||
* @brief Register Flakes support process-wide.
|
||||
*/
|
||||
nix_err nix_flake_init_global(nix_c_context * context, nix_flake_settings * settings);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
9
src/libflake-c/nix_api_flake_internal.hh
Normal file
9
src/libflake-c/nix_api_flake_internal.hh
Normal file
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "ref.hh"
|
||||
#include "flake/settings.hh"
|
||||
|
||||
struct nix_flake_settings
|
||||
{
|
||||
nix::ref<nix::flake::Settings> settings;
|
||||
};
|
60
src/libflake-c/package.nix
Normal file
60
src/libflake-c/package.nix
Normal file
|
@ -0,0 +1,60 @@
|
|||
{ lib
|
||||
, stdenv
|
||||
, mkMesonLibrary
|
||||
|
||||
, nix-store-c
|
||||
, nix-expr-c
|
||||
, nix-flake
|
||||
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) fileset;
|
||||
in
|
||||
|
||||
mkMesonLibrary (finalAttrs: {
|
||||
pname = "nix-flake-c";
|
||||
inherit version;
|
||||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../.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-expr-c
|
||||
nix-store-c
|
||||
nix-flake
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
||||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
};
|
||||
|
||||
})
|
|
@ -19,6 +19,7 @@ subdir('build-utils-meson/deps-lists')
|
|||
deps_private_maybe_subproject = [
|
||||
dependency('nix-expr-test-support'),
|
||||
dependency('nix-flake'),
|
||||
dependency('nix-flake-c'),
|
||||
]
|
||||
deps_public_maybe_subproject = [
|
||||
]
|
||||
|
@ -46,6 +47,7 @@ subdir('build-utils-meson/common')
|
|||
|
||||
sources = files(
|
||||
'flakeref.cc',
|
||||
'nix_api_flake.cc',
|
||||
'url-name.cc',
|
||||
)
|
||||
|
||||
|
@ -68,6 +70,7 @@ test(
|
|||
this_exe,
|
||||
env : {
|
||||
'_NIX_TEST_UNIT_DATA': meson.current_source_dir() / 'data',
|
||||
'NIX_CONFIG': 'extra-experimental-features = flakes',
|
||||
},
|
||||
protocol : 'gtest',
|
||||
)
|
||||
|
|
51
src/libflake-tests/nix_api_flake.cc
Normal file
51
src/libflake-tests/nix_api_flake.cc
Normal file
|
@ -0,0 +1,51 @@
|
|||
#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"
|
||||
|
||||
#include "tests/nix_api_expr.hh"
|
||||
#include "tests/string_callback.hh"
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace nixC {
|
||||
|
||||
TEST_F(nix_api_store_test, nix_api_init_global_getFlake_exists)
|
||||
{
|
||||
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);
|
||||
|
||||
nix_flake_init_global(ctx, settings);
|
||||
assert_ctx_ok();
|
||||
|
||||
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 value = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(nullptr, value);
|
||||
|
||||
nix_err err = nix_expr_eval_from_string(ctx, state, "builtins.getFlake", ".", value);
|
||||
assert_ctx_ok();
|
||||
ASSERT_EQ(NIX_OK, err);
|
||||
ASSERT_EQ(NIX_TYPE_FUNCTION, nix_get_type(ctx, value));
|
||||
}
|
||||
|
||||
} // namespace nixC
|
|
@ -4,6 +4,7 @@
|
|||
, mkMesonExecutable
|
||||
|
||||
, nix-flake
|
||||
, nix-flake-c
|
||||
, nix-expr-test-support
|
||||
|
||||
, rapidcheck
|
||||
|
@ -38,6 +39,7 @@ mkMesonExecutable (finalAttrs: {
|
|||
|
||||
buildInputs = [
|
||||
nix-flake
|
||||
nix-flake-c
|
||||
nix-expr-test-support
|
||||
rapidcheck
|
||||
gtest
|
||||
|
@ -67,6 +69,7 @@ mkMesonExecutable (finalAttrs: {
|
|||
mkdir -p "$HOME"
|
||||
'' + ''
|
||||
export _NIX_TEST_UNIT_DATA=${resolvePath ./data}
|
||||
export NIX_CONFIG="extra-experimental-features = flakes"
|
||||
${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage}
|
||||
touch $out
|
||||
'');
|
||||
|
|
|
@ -40,7 +40,7 @@ void checkGTestWith(Testable && testable, MakeTestParams makeTestParams)
|
|||
} else {
|
||||
std::ostringstream ss;
|
||||
printResultMessage(result, ss);
|
||||
FAIL() << ss.str() << std::endl;
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,14 +26,13 @@ protected:
|
|||
|
||||
inline void assert_ctx_ok()
|
||||
{
|
||||
|
||||
if (nix_err_code(ctx) == NIX_OK) {
|
||||
return;
|
||||
}
|
||||
unsigned int n;
|
||||
const char * p = nix_err_msg(nullptr, ctx, &n);
|
||||
std::string msg(p, n);
|
||||
FAIL() << "nix_err_code(ctx) != NIX_OK, message: " << msg;
|
||||
throw std::runtime_error(std::string("nix_err_code(ctx) != NIX_OK, message: ") + msg);
|
||||
}
|
||||
|
||||
inline void assert_ctx_err()
|
||||
|
@ -41,7 +40,7 @@ protected:
|
|||
if (nix_err_code(ctx) != NIX_OK) {
|
||||
return;
|
||||
}
|
||||
FAIL() << "Got NIX_OK, but expected an error!";
|
||||
throw std::runtime_error("Got NIX_OK, but expected an error!");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue