1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-14 22:42:41 +01:00

Merge remote-tracking branch 'origin/2.29-maintenance' into detsys-main

This commit is contained in:
Eelco Dolstra 2025-05-16 12:48:44 +02:00
commit c20642ac7b
354 changed files with 6768 additions and 3808 deletions

View file

@ -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?

View file

@ -1,12 +1,18 @@
#include <string>
#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 +28,178 @@ 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, 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 {
eval_state->state.resetFileCache();
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
}

View file

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

View file

@ -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;
};

View file

@ -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
];