mirror of
https://github.com/NixOS/nix
synced 2025-07-07 18:31:49 +02:00
Merge remote-tracking branch 'upstream/master' into lfs
This commit is contained in:
commit
7756b2286d
207 changed files with 1354 additions and 640 deletions
|
@ -1 +0,0 @@
|
|||
../../build-utils-meson
|
|
@ -14,7 +14,7 @@ project('nix-cmd', 'cpp',
|
|||
|
||||
cxx = meson.get_compiler('cpp')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
subdir('nix-meson-build-support/deps-lists')
|
||||
|
||||
configdata = configuration_data()
|
||||
|
||||
|
@ -28,7 +28,7 @@ deps_public_maybe_subproject = [
|
|||
dependency('nix-flake'),
|
||||
dependency('nix-main'),
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
subdir('nix-meson-build-support/subprojects')
|
||||
|
||||
nlohmann_json = dependency('nlohmann_json', version : '>= 3.9')
|
||||
deps_public += nlohmann_json
|
||||
|
@ -70,7 +70,7 @@ add_project_arguments(
|
|||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/common')
|
||||
subdir('nix-meson-build-support/common')
|
||||
|
||||
sources = files(
|
||||
'built-path.cc',
|
||||
|
@ -125,4 +125,4 @@ install_headers(headers, subdir : 'nix', preserve_path : true)
|
|||
|
||||
libraries_private = []
|
||||
|
||||
subdir('build-utils-meson/export')
|
||||
subdir('nix-meson-build-support/export')
|
||||
|
|
1
src/libcmd/nix-meson-build-support
Symbolic link
1
src/libcmd/nix-meson-build-support
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../nix-meson-build-support
|
|
@ -39,8 +39,8 @@ mkMesonLibrary (finalAttrs: {
|
|||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../nix-meson-build-support
|
||||
./nix-meson-build-support
|
||||
../../.version
|
||||
./.version
|
||||
./meson.build
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../../build-utils-meson
|
|
@ -14,7 +14,7 @@ project('nix-expr-c', 'cpp',
|
|||
|
||||
cxx = meson.get_compiler('cpp')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
subdir('nix-meson-build-support/deps-lists')
|
||||
|
||||
configdata = configuration_data()
|
||||
|
||||
|
@ -27,7 +27,7 @@ deps_public_maybe_subproject = [
|
|||
dependency('nix-util-c'),
|
||||
dependency('nix-store-c'),
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
subdir('nix-meson-build-support/subprojects')
|
||||
|
||||
# TODO rename, because it will conflict with downstream projects
|
||||
configdata.set_quoted('PACKAGE_VERSION', meson.project_version())
|
||||
|
@ -53,7 +53,7 @@ add_project_arguments(
|
|||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/common')
|
||||
subdir('nix-meson-build-support/common')
|
||||
|
||||
sources = files(
|
||||
'nix_api_expr.cc',
|
||||
|
@ -72,8 +72,8 @@ headers = [config_h] + files(
|
|||
# TODO move this header to libexpr, maybe don't use it in tests?
|
||||
headers += files('nix_api_expr_internal.h')
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
subdir('build-utils-meson/windows-version')
|
||||
subdir('nix-meson-build-support/export-all-symbols')
|
||||
subdir('nix-meson-build-support/windows-version')
|
||||
|
||||
this_library = library(
|
||||
'nixexprc',
|
||||
|
@ -89,4 +89,4 @@ install_headers(headers, subdir : 'nix', preserve_path : true)
|
|||
|
||||
libraries_private = []
|
||||
|
||||
subdir('build-utils-meson/export')
|
||||
subdir('nix-meson-build-support/export')
|
||||
|
|
1
src/libexpr-c/nix-meson-build-support
Symbolic link
1
src/libexpr-c/nix-meson-build-support
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../nix-meson-build-support
|
|
@ -20,8 +20,8 @@ mkMesonLibrary (finalAttrs: {
|
|||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../nix-meson-build-support
|
||||
./nix-meson-build-support
|
||||
../../.version
|
||||
./.version
|
||||
./meson.build
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../../build-utils-meson
|
|
@ -14,7 +14,7 @@ project('nix-expr-test-support', 'cpp',
|
|||
|
||||
cxx = meson.get_compiler('cpp')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
subdir('nix-meson-build-support/deps-lists')
|
||||
|
||||
deps_private_maybe_subproject = [
|
||||
]
|
||||
|
@ -26,7 +26,7 @@ deps_public_maybe_subproject = [
|
|||
dependency('nix-expr'),
|
||||
dependency('nix-expr-c'),
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
subdir('nix-meson-build-support/subprojects')
|
||||
|
||||
rapidcheck = dependency('rapidcheck')
|
||||
deps_public += rapidcheck
|
||||
|
@ -40,7 +40,7 @@ add_project_arguments(
|
|||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/common')
|
||||
subdir('nix-meson-build-support/common')
|
||||
|
||||
sources = files(
|
||||
'tests/value/context.cc',
|
||||
|
@ -54,8 +54,8 @@ headers = files(
|
|||
'tests/value/context.hh',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
subdir('build-utils-meson/windows-version')
|
||||
subdir('nix-meson-build-support/export-all-symbols')
|
||||
subdir('nix-meson-build-support/windows-version')
|
||||
|
||||
this_library = library(
|
||||
'nix-expr-test-support',
|
||||
|
@ -73,4 +73,4 @@ install_headers(headers, subdir : 'nix', preserve_path : true)
|
|||
|
||||
libraries_private = []
|
||||
|
||||
subdir('build-utils-meson/export')
|
||||
subdir('nix-meson-build-support/export')
|
||||
|
|
1
src/libexpr-test-support/nix-meson-build-support
Symbolic link
1
src/libexpr-test-support/nix-meson-build-support
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../nix-meson-build-support
|
|
@ -23,8 +23,8 @@ mkMesonLibrary (finalAttrs: {
|
|||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../nix-meson-build-support
|
||||
./nix-meson-build-support
|
||||
../../.version
|
||||
./.version
|
||||
./meson.build
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../../build-utils-meson
|
|
@ -691,15 +691,15 @@ namespace nix {
|
|||
ASSERT_TRACE2("elemAt \"foo\" (-1)",
|
||||
TypeError,
|
||||
HintFmt("expected a list but found %s: %s", "a string", Uncolored(ANSI_MAGENTA "\"foo\"" ANSI_NORMAL)),
|
||||
HintFmt("while evaluating the first argument passed to builtins.elemAt"));
|
||||
HintFmt("while evaluating the first argument passed to 'builtins.elemAt'"));
|
||||
|
||||
ASSERT_TRACE1("elemAt [] (-1)",
|
||||
Error,
|
||||
HintFmt("list index %d is out of bounds", -1));
|
||||
HintFmt("'builtins.elemAt' called with index %d on a list of size %d", -1, 0));
|
||||
|
||||
ASSERT_TRACE1("elemAt [\"foo\"] 3",
|
||||
Error,
|
||||
HintFmt("list index %d is out of bounds", 3));
|
||||
HintFmt("'builtins.elemAt' called with index %d on a list of size %d", 3, 1));
|
||||
|
||||
}
|
||||
|
||||
|
@ -708,11 +708,11 @@ namespace nix {
|
|||
ASSERT_TRACE2("head 1",
|
||||
TypeError,
|
||||
HintFmt("expected a list but found %s: %s", "an integer", Uncolored(ANSI_CYAN "1" ANSI_NORMAL)),
|
||||
HintFmt("while evaluating the first argument passed to builtins.elemAt"));
|
||||
HintFmt("while evaluating the first argument passed to 'builtins.head'"));
|
||||
|
||||
ASSERT_TRACE1("head []",
|
||||
Error,
|
||||
HintFmt("list index %d is out of bounds", 0));
|
||||
HintFmt("'builtins.head' called on an empty list"));
|
||||
|
||||
}
|
||||
|
||||
|
@ -721,11 +721,11 @@ namespace nix {
|
|||
ASSERT_TRACE2("tail 1",
|
||||
TypeError,
|
||||
HintFmt("expected a list but found %s: %s", "an integer", Uncolored(ANSI_CYAN "1" ANSI_NORMAL)),
|
||||
HintFmt("while evaluating the first argument passed to builtins.tail"));
|
||||
HintFmt("while evaluating the first argument passed to 'builtins.tail'"));
|
||||
|
||||
ASSERT_TRACE1("tail []",
|
||||
Error,
|
||||
HintFmt("'tail' called on an empty list"));
|
||||
HintFmt("'builtins.tail' called on an empty list"));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ project('nix-expr-tests', 'cpp',
|
|||
|
||||
cxx = meson.get_compiler('cpp')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
subdir('nix-meson-build-support/deps-lists')
|
||||
|
||||
deps_private_maybe_subproject = [
|
||||
dependency('nix-expr'),
|
||||
|
@ -23,10 +23,10 @@ deps_private_maybe_subproject = [
|
|||
]
|
||||
deps_public_maybe_subproject = [
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
subdir('nix-meson-build-support/subprojects')
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
subdir('build-utils-meson/windows-version')
|
||||
subdir('nix-meson-build-support/export-all-symbols')
|
||||
subdir('nix-meson-build-support/windows-version')
|
||||
|
||||
rapidcheck = dependency('rapidcheck')
|
||||
deps_private += rapidcheck
|
||||
|
@ -49,7 +49,7 @@ add_project_arguments(
|
|||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/common')
|
||||
subdir('nix-meson-build-support/common')
|
||||
|
||||
sources = files(
|
||||
'derived-path.cc',
|
||||
|
|
1
src/libexpr-tests/nix-meson-build-support
Symbolic link
1
src/libexpr-tests/nix-meson-build-support
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../nix-meson-build-support
|
|
@ -27,8 +27,8 @@ mkMesonExecutable (finalAttrs: {
|
|||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../nix-meson-build-support
|
||||
./nix-meson-build-support
|
||||
../../.version
|
||||
./.version
|
||||
./meson.build
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../../build-utils-meson
|
|
@ -347,6 +347,16 @@ void EvalState::allowPath(const StorePath & storePath)
|
|||
rootFS2->allowPrefix(CanonPath(store->toRealPath(storePath)));
|
||||
}
|
||||
|
||||
void EvalState::allowClosure(const StorePath & storePath)
|
||||
{
|
||||
if (!rootFS.dynamic_pointer_cast<AllowListSourceAccessor>()) return;
|
||||
|
||||
StorePathSet closure;
|
||||
store->computeFSClosure(storePath, closure);
|
||||
for (auto & p : closure)
|
||||
allowPath(p);
|
||||
}
|
||||
|
||||
void EvalState::allowAndSetStorePathString(const StorePath & storePath, Value & v)
|
||||
{
|
||||
allowPath(storePath);
|
||||
|
@ -3099,10 +3109,7 @@ std::optional<SourcePath> EvalState::resolveLookupPathPath(const LookupPath::Pat
|
|||
allowPath(path.path.abs());
|
||||
if (store->isInStore(path.path.abs())) {
|
||||
try {
|
||||
StorePathSet closure;
|
||||
store->computeFSClosure(store->toStorePath(path.path.abs()).first, closure);
|
||||
for (auto & p : closure)
|
||||
allowPath(p);
|
||||
allowClosure(store->toStorePath(path.path.abs()).first);
|
||||
} catch (InvalidPath &) { }
|
||||
}
|
||||
}
|
||||
|
@ -3178,5 +3185,14 @@ std::ostream & operator << (std::ostream & str, const ExternalValueBase & v) {
|
|||
return v.print(str);
|
||||
}
|
||||
|
||||
void forceNoNullByte(std::string_view s)
|
||||
{
|
||||
if (s.find('\0') != s.npos) {
|
||||
using namespace std::string_view_literals;
|
||||
auto str = replaceStrings(std::string(s), "\0"sv, "␀"sv);
|
||||
throw Error("input string '%s' cannot be represented as Nix string because it contains null bytes", str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -400,6 +400,11 @@ public:
|
|||
*/
|
||||
void allowPath(const StorePath & storePath);
|
||||
|
||||
/**
|
||||
* Allow access to the closure of a store path.
|
||||
*/
|
||||
void allowClosure(const StorePath & storePath);
|
||||
|
||||
/**
|
||||
* Allow access to a store path and return it as a string.
|
||||
*/
|
||||
|
|
|
@ -50,6 +50,7 @@ class JSONSax : nlohmann::json_sax<json> {
|
|||
public:
|
||||
void key(string_t & name, EvalState & state)
|
||||
{
|
||||
forceNoNullByte(name);
|
||||
attrs.insert_or_assign(state.symbols.create(name), &value(state));
|
||||
}
|
||||
};
|
||||
|
@ -122,6 +123,7 @@ public:
|
|||
|
||||
bool string(string_t & val) override
|
||||
{
|
||||
forceNoNullByte(val);
|
||||
rs->value(state).mkString(val);
|
||||
rs->add();
|
||||
return true;
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
// inluding the generated headers twice leads to errors
|
||||
#ifndef BISON_HEADER
|
||||
# include "lexer-tab.hh"
|
||||
# include "parser-tab.hh"
|
||||
#endif
|
||||
|
||||
namespace nix::lexer::internal {
|
||||
|
||||
void initLoc(YYLTYPE * loc);
|
||||
|
|
|
@ -14,7 +14,7 @@ project('nix-expr', 'cpp',
|
|||
|
||||
cxx = meson.get_compiler('cpp')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
subdir('nix-meson-build-support/deps-lists')
|
||||
|
||||
configdata = configuration_data()
|
||||
|
||||
|
@ -25,7 +25,7 @@ deps_public_maybe_subproject = [
|
|||
dependency('nix-store'),
|
||||
dependency('nix-fetchers'),
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
subdir('nix-meson-build-support/subprojects')
|
||||
|
||||
boost = dependency(
|
||||
'boost',
|
||||
|
@ -77,7 +77,7 @@ add_project_arguments(
|
|||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/common')
|
||||
subdir('nix-meson-build-support/common')
|
||||
|
||||
parser_tab = custom_target(
|
||||
input : 'parser.y',
|
||||
|
@ -121,7 +121,7 @@ lexer_tab = custom_target(
|
|||
install_dir : get_option('includedir') / 'nix',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/generate-header')
|
||||
subdir('nix-meson-build-support/generate-header')
|
||||
|
||||
generated_headers = []
|
||||
foreach header : [
|
||||
|
@ -205,4 +205,4 @@ install_headers(headers, subdir : 'nix', preserve_path : true)
|
|||
|
||||
libraries_private = []
|
||||
|
||||
subdir('build-utils-meson/export')
|
||||
subdir('nix-meson-build-support/export')
|
||||
|
|
1
src/libexpr/nix-meson-build-support
Symbolic link
1
src/libexpr/nix-meson-build-support
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../nix-meson-build-support
|
|
@ -168,7 +168,7 @@ struct ExprVar : Expr
|
|||
the set stored in the environment that is `level` levels up
|
||||
from the current one.*/
|
||||
Level level;
|
||||
Displacement displ;
|
||||
Displacement displ = 0;
|
||||
|
||||
ExprVar(Symbol name) : name(name) { };
|
||||
ExprVar(const PosIdx & pos, Symbol name) : pos(pos), name(name) { };
|
||||
|
@ -242,7 +242,7 @@ struct ExprAttrs : Expr
|
|||
Kind kind;
|
||||
Expr * e;
|
||||
PosIdx pos;
|
||||
Displacement displ; // displacement
|
||||
Displacement displ = 0; // displacement
|
||||
AttrDef(Expr * e, const PosIdx & pos, Kind kind = Kind::Plain)
|
||||
: kind(kind), e(e), pos(pos) { };
|
||||
AttrDef() { };
|
||||
|
|
|
@ -40,8 +40,8 @@ mkMesonLibrary (finalAttrs: {
|
|||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../nix-meson-build-support
|
||||
./nix-meson-build-support
|
||||
../../.version
|
||||
./.version
|
||||
./meson.build
|
||||
|
|
|
@ -119,11 +119,9 @@ StringMap EvalState::realiseContext(const NixStringContext & context, StorePathS
|
|||
if (store != buildStore) copyClosure(*buildStore, *store, outputsToCopyAndAllow);
|
||||
|
||||
if (isIFD) {
|
||||
for (auto & outputPath : outputsToCopyAndAllow) {
|
||||
/* Add the output of this derivations to the allowed
|
||||
paths. */
|
||||
allowPath(outputPath);
|
||||
}
|
||||
/* Allow access to the output closures of this derivation. */
|
||||
for (auto & outputPath : outputsToCopyAndAllow)
|
||||
allowClosure(outputPath);
|
||||
}
|
||||
|
||||
return res;
|
||||
|
@ -1100,7 +1098,7 @@ static RegisterPrimOp primop_warn({
|
|||
.name = "__warn",
|
||||
.args = {"e1", "e2"},
|
||||
.doc = R"(
|
||||
Evaluate *e1*, which must be a string and print iton standard error as a warning.
|
||||
Evaluate *e1*, which must be a string, and print it on standard error as a warning.
|
||||
Then return *e2*.
|
||||
This function is useful for non-critical situations where attention is advisable.
|
||||
|
||||
|
@ -3259,23 +3257,19 @@ static RegisterPrimOp primop_isList({
|
|||
.fun = prim_isList,
|
||||
});
|
||||
|
||||
static void elemAt(EvalState & state, const PosIdx pos, Value & list, int n, Value & v)
|
||||
{
|
||||
state.forceList(list, pos, "while evaluating the first argument passed to builtins.elemAt");
|
||||
if (n < 0 || (unsigned int) n >= list.listSize())
|
||||
state.error<EvalError>(
|
||||
"list index %1% is out of bounds",
|
||||
n
|
||||
).atPos(pos).debugThrow();
|
||||
state.forceValue(*list.listElems()[n], pos);
|
||||
v = *list.listElems()[n];
|
||||
}
|
||||
|
||||
/* Return the n-1'th element of a list. */
|
||||
static void prim_elemAt(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||
{
|
||||
NixInt::Inner elem = state.forceInt(*args[1], pos, "while evaluating the second argument passed to builtins.elemAt").value;
|
||||
elemAt(state, pos, *args[0], elem, v);
|
||||
NixInt::Inner n = state.forceInt(*args[1], pos, "while evaluating the second argument passed to 'builtins.elemAt'").value;
|
||||
state.forceList(*args[0], pos, "while evaluating the first argument passed to 'builtins.elemAt'");
|
||||
if (n < 0 || (unsigned int) n >= args[0]->listSize())
|
||||
state.error<EvalError>(
|
||||
"'builtins.elemAt' called with index %d on a list of size %d",
|
||||
n,
|
||||
args[0]->listSize()
|
||||
).atPos(pos).debugThrow();
|
||||
state.forceValue(*args[0]->listElems()[n], pos);
|
||||
v = *args[0]->listElems()[n];
|
||||
}
|
||||
|
||||
static RegisterPrimOp primop_elemAt({
|
||||
|
@ -3291,7 +3285,13 @@ static RegisterPrimOp primop_elemAt({
|
|||
/* Return the first element of a list. */
|
||||
static void prim_head(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||
{
|
||||
elemAt(state, pos, *args[0], 0, v);
|
||||
state.forceList(*args[0], pos, "while evaluating the first argument passed to 'builtins.head'");
|
||||
if (args[0]->listSize() == 0)
|
||||
state.error<EvalError>(
|
||||
"'builtins.head' called on an empty list"
|
||||
).atPos(pos).debugThrow();
|
||||
state.forceValue(*args[0]->listElems()[0], pos);
|
||||
v = *args[0]->listElems()[0];
|
||||
}
|
||||
|
||||
static RegisterPrimOp primop_head({
|
||||
|
@ -3310,9 +3310,9 @@ static RegisterPrimOp primop_head({
|
|||
don't want to use it! */
|
||||
static void prim_tail(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||
{
|
||||
state.forceList(*args[0], pos, "while evaluating the first argument passed to builtins.tail");
|
||||
state.forceList(*args[0], pos, "while evaluating the first argument passed to 'builtins.tail'");
|
||||
if (args[0]->listSize() == 0)
|
||||
state.error<EvalError>("'tail' called on an empty list").atPos(pos).debugThrow();
|
||||
state.error<EvalError>("'builtins.tail' called on an empty list").atPos(pos).debugThrow();
|
||||
|
||||
auto list = state.buildList(args[0]->listSize() - 1);
|
||||
for (const auto & [n, v] : enumerate(list))
|
||||
|
|
|
@ -28,8 +28,10 @@ static void prim_fromTOML(EvalState & state, const PosIdx pos, Value * * args, V
|
|||
|
||||
auto attrs = state.buildBindings(size);
|
||||
|
||||
for(auto & elem : table)
|
||||
for(auto & elem : table) {
|
||||
forceNoNullByte(elem.first);
|
||||
visit(attrs.alloc(elem.first), elem.second);
|
||||
}
|
||||
|
||||
v.mkAttrs(attrs);
|
||||
}
|
||||
|
@ -54,7 +56,11 @@ static void prim_fromTOML(EvalState & state, const PosIdx pos, Value * * args, V
|
|||
v.mkFloat(toml::get<NixFloat>(t));
|
||||
break;;
|
||||
case toml::value_t::string:
|
||||
v.mkString(toml::get<std::string>(t));
|
||||
{
|
||||
auto s = toml::get<std::string_view>(t);
|
||||
forceNoNullByte(s);
|
||||
v.mkString(s);
|
||||
}
|
||||
break;;
|
||||
case toml::value_t::local_datetime:
|
||||
case toml::value_t::offset_datetime:
|
||||
|
@ -66,7 +72,9 @@ static void prim_fromTOML(EvalState & state, const PosIdx pos, Value * * args, V
|
|||
attrs.alloc("_type").mkString("timestamp");
|
||||
std::ostringstream s;
|
||||
s << t;
|
||||
attrs.alloc("value").mkString(toView(s));
|
||||
auto str = toView(s);
|
||||
forceNoNullByte(str);
|
||||
attrs.alloc("value").mkString(str);
|
||||
v.mkAttrs(attrs);
|
||||
} else {
|
||||
throw std::runtime_error("Dates and times are not supported");
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <limits>
|
||||
#include <stddef.h>
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
|
@ -510,4 +510,6 @@ typedef std::shared_ptr<Value *> RootValue;
|
|||
|
||||
RootValue allocRootValue(Value * v);
|
||||
|
||||
void forceNoNullByte(std::string_view s);
|
||||
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../../build-utils-meson
|
|
@ -14,7 +14,7 @@ project('nix-fetchers-tests', 'cpp',
|
|||
|
||||
cxx = meson.get_compiler('cpp')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
subdir('nix-meson-build-support/deps-lists')
|
||||
|
||||
deps_private_maybe_subproject = [
|
||||
dependency('nix-store-test-support'),
|
||||
|
@ -22,10 +22,10 @@ deps_private_maybe_subproject = [
|
|||
]
|
||||
deps_public_maybe_subproject = [
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
subdir('nix-meson-build-support/subprojects')
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
subdir('build-utils-meson/windows-version')
|
||||
subdir('nix-meson-build-support/export-all-symbols')
|
||||
subdir('nix-meson-build-support/windows-version')
|
||||
|
||||
rapidcheck = dependency('rapidcheck')
|
||||
deps_private += rapidcheck
|
||||
|
@ -42,7 +42,7 @@ add_project_arguments(
|
|||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/common')
|
||||
subdir('nix-meson-build-support/common')
|
||||
|
||||
sources = files(
|
||||
'public-key.cc',
|
||||
|
|
1
src/libfetchers-tests/nix-meson-build-support
Symbolic link
1
src/libfetchers-tests/nix-meson-build-support
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../nix-meson-build-support
|
|
@ -26,8 +26,8 @@ mkMesonExecutable (finalAttrs: {
|
|||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../nix-meson-build-support
|
||||
./nix-meson-build-support
|
||||
../../.version
|
||||
./.version
|
||||
./meson.build
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../../build-utils-meson
|
|
@ -113,7 +113,15 @@ Input Input::fromAttrs(const Settings & settings, Attrs && attrs)
|
|||
|
||||
std::optional<std::string> Input::getFingerprint(ref<Store> store) const
|
||||
{
|
||||
return scheme ? scheme->getFingerprint(store, *this) : std::nullopt;
|
||||
if (!scheme) return std::nullopt;
|
||||
|
||||
if (cachedFingerprint) return *cachedFingerprint;
|
||||
|
||||
auto fingerprint = scheme->getFingerprint(store, *this);
|
||||
|
||||
cachedFingerprint = fingerprint;
|
||||
|
||||
return fingerprint;
|
||||
}
|
||||
|
||||
ParsedURL Input::toURL() const
|
||||
|
@ -307,7 +315,7 @@ std::pair<ref<SourceAccessor>, Input> Input::getAccessorUnchecked(ref<Store> sto
|
|||
|
||||
auto accessor = makeStorePathAccessor(store, storePath);
|
||||
|
||||
accessor->fingerprint = scheme->getFingerprint(store, *this);
|
||||
accessor->fingerprint = getFingerprint(store);
|
||||
|
||||
return {accessor, *this};
|
||||
} catch (Error & e) {
|
||||
|
@ -318,7 +326,7 @@ std::pair<ref<SourceAccessor>, Input> Input::getAccessorUnchecked(ref<Store> sto
|
|||
auto [accessor, result] = scheme->getAccessor(store, *this);
|
||||
|
||||
assert(!accessor->fingerprint);
|
||||
accessor->fingerprint = scheme->getFingerprint(store, result);
|
||||
accessor->fingerprint = result.getFingerprint(store);
|
||||
|
||||
return {accessor, std::move(result)};
|
||||
}
|
||||
|
|
|
@ -46,6 +46,11 @@ struct Input
|
|||
*/
|
||||
std::optional<Path> parent;
|
||||
|
||||
/**
|
||||
* Cached result of getFingerprint().
|
||||
*/
|
||||
mutable std::optional<std::optional<std::string>> cachedFingerprint;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Create an `Input` from a URL.
|
||||
|
@ -104,6 +109,11 @@ public:
|
|||
|
||||
bool operator ==(const Input & other) const noexcept;
|
||||
|
||||
bool operator <(const Input & other) const
|
||||
{
|
||||
return attrs < other.attrs;
|
||||
}
|
||||
|
||||
bool contains(const Input & other) const;
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "signals.hh"
|
||||
#include "users.hh"
|
||||
#include "fs-sink.hh"
|
||||
#include "sync.hh"
|
||||
|
||||
#include <git2/attr.h>
|
||||
#include <git2/blob.h>
|
||||
|
@ -438,7 +439,12 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
|
|||
{
|
||||
if (!(statusFlags & GIT_STATUS_INDEX_DELETED) &&
|
||||
!(statusFlags & GIT_STATUS_WT_DELETED))
|
||||
{
|
||||
info.files.insert(CanonPath(path));
|
||||
if (statusFlags != GIT_STATUS_CURRENT)
|
||||
info.dirtyFiles.insert(CanonPath(path));
|
||||
} else
|
||||
info.deletedFiles.insert(CanonPath(path));
|
||||
if (statusFlags != GIT_STATUS_CURRENT)
|
||||
info.isDirty = true;
|
||||
return 0;
|
||||
|
@ -1311,4 +1317,17 @@ ref<GitRepo> getTarballCache()
|
|||
return GitRepo::openRepo(repoDir, true, true);
|
||||
}
|
||||
|
||||
GitRepo::WorkdirInfo GitRepo::getCachedWorkdirInfo(const std::filesystem::path & path)
|
||||
{
|
||||
static Sync<std::map<std::filesystem::path, WorkdirInfo>> _cache;
|
||||
{
|
||||
auto cache(_cache.lock());
|
||||
auto i = cache->find(path);
|
||||
if (i != cache->end()) return i->second;
|
||||
}
|
||||
auto workdirInfo = GitRepo::openRepo(path)->getWorkdirInfo();
|
||||
_cache.lock()->emplace(path, workdirInfo);
|
||||
return workdirInfo;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -59,12 +59,20 @@ struct GitRepo
|
|||
modified or added, but excluding deleted files. */
|
||||
std::set<CanonPath> files;
|
||||
|
||||
/* All modified or added files. */
|
||||
std::set<CanonPath> dirtyFiles;
|
||||
|
||||
/* The deleted files. */
|
||||
std::set<CanonPath> deletedFiles;
|
||||
|
||||
/* The submodules listed in .gitmodules of this workdir. */
|
||||
std::vector<Submodule> submodules;
|
||||
};
|
||||
|
||||
virtual WorkdirInfo getWorkdirInfo() = 0;
|
||||
|
||||
static WorkdirInfo getCachedWorkdirInfo(const std::filesystem::path & path);
|
||||
|
||||
/* Get the ref that HEAD points to. */
|
||||
virtual std::optional<std::string> getWorkdirRef() = 0;
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "finally.hh"
|
||||
#include "fetch-settings.hh"
|
||||
#include "json-utils.hh"
|
||||
#include "archive.hh"
|
||||
|
||||
#include <regex>
|
||||
#include <string.h>
|
||||
|
@ -438,7 +439,7 @@ struct GitInputScheme : InputScheme
|
|||
// If this is a local directory and no ref or revision is
|
||||
// given, then allow the use of an unclean working tree.
|
||||
if (!input.getRef() && !input.getRev() && repoInfo.isLocal)
|
||||
repoInfo.workdirInfo = GitRepo::openRepo(repoInfo.url)->getWorkdirInfo();
|
||||
repoInfo.workdirInfo = GitRepo::getCachedWorkdirInfo(repoInfo.url);
|
||||
|
||||
return repoInfo;
|
||||
}
|
||||
|
@ -803,12 +804,33 @@ struct GitInputScheme : InputScheme
|
|||
|
||||
std::optional<std::string> getFingerprint(ref<Store> store, const Input & input) const override
|
||||
{
|
||||
if (auto rev = input.getRev())
|
||||
auto makeFingerprint = [&](const Hash & rev)
|
||||
{
|
||||
return rev->gitRev() + (getSubmodulesAttr(input) ? ";s" : "") + (getExportIgnoreAttr(input) ? ";e" : "") + (getLfsAttr(input) ? ";l" : "");
|
||||
}
|
||||
else
|
||||
return rev.gitRev() + (getSubmodulesAttr(input) ? ";s" : "") + (getExportIgnoreAttr(input) ? ";e" : "") + (getLfsAttr(input) ? ";l" : "");
|
||||
};
|
||||
|
||||
if (auto rev = input.getRev())
|
||||
return makeFingerprint(*rev);
|
||||
else {
|
||||
auto repoInfo = getRepoInfo(input);
|
||||
if (repoInfo.isLocal && repoInfo.workdirInfo.headRev && repoInfo.workdirInfo.submodules.empty()) {
|
||||
/* Calculate a fingerprint that takes into account the
|
||||
deleted and modified/added files. */
|
||||
HashSink hashSink{HashAlgorithm::SHA512};
|
||||
for (auto & file : repoInfo.workdirInfo.dirtyFiles) {
|
||||
writeString("modified:", hashSink);
|
||||
writeString(file.abs(), hashSink);
|
||||
dumpPath(repoInfo.url + "/" + file.abs(), hashSink);
|
||||
}
|
||||
for (auto & file : repoInfo.workdirInfo.deletedFiles) {
|
||||
writeString("deleted:", hashSink);
|
||||
writeString(file.abs(), hashSink);
|
||||
}
|
||||
return makeFingerprint(*repoInfo.workdirInfo.headRev)
|
||||
+ ";d=" + hashSink.finish().first.to_string(HashFormat::Base16, false);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
bool isLocked(const Input & input) const override
|
||||
|
|
|
@ -14,7 +14,7 @@ project('nix-fetchers', 'cpp',
|
|||
|
||||
cxx = meson.get_compiler('cpp')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
subdir('nix-meson-build-support/deps-lists')
|
||||
|
||||
configdata = configuration_data()
|
||||
|
||||
|
@ -24,7 +24,7 @@ deps_public_maybe_subproject = [
|
|||
dependency('nix-util'),
|
||||
dependency('nix-store'),
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
subdir('nix-meson-build-support/subprojects')
|
||||
|
||||
nlohmann_json = dependency('nlohmann_json', version : '>= 3.9')
|
||||
deps_public += nlohmann_json
|
||||
|
@ -44,7 +44,7 @@ add_project_arguments(
|
|||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/common')
|
||||
subdir('nix-meson-build-support/common')
|
||||
|
||||
sources = files(
|
||||
'attrs.cc',
|
||||
|
@ -94,4 +94,4 @@ install_headers(headers, subdir : 'nix', preserve_path : true)
|
|||
|
||||
libraries_private = []
|
||||
|
||||
subdir('build-utils-meson/export')
|
||||
subdir('nix-meson-build-support/export')
|
||||
|
|
1
src/libfetchers/nix-meson-build-support
Symbolic link
1
src/libfetchers/nix-meson-build-support
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../nix-meson-build-support
|
|
@ -23,8 +23,8 @@ mkMesonLibrary (finalAttrs: {
|
|||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../nix-meson-build-support
|
||||
./nix-meson-build-support
|
||||
../../.version
|
||||
./.version
|
||||
./meson.build
|
||||
|
|
|
@ -178,7 +178,8 @@ Registries getRegistries(const Settings & settings, ref<Store> store)
|
|||
|
||||
std::pair<Input, Attrs> lookupInRegistries(
|
||||
ref<Store> store,
|
||||
const Input & _input)
|
||||
const Input & _input,
|
||||
const RegistryFilter & filter)
|
||||
{
|
||||
Attrs extraAttrs;
|
||||
int n = 0;
|
||||
|
@ -190,6 +191,7 @@ std::pair<Input, Attrs> lookupInRegistries(
|
|||
if (n > 100) throw Error("cycle detected in flake registry for '%s'", input.to_string());
|
||||
|
||||
for (auto & registry : getRegistries(*input.settings, store)) {
|
||||
if (filter && !filter(registry->type)) continue;
|
||||
// FIXME: O(n)
|
||||
for (auto & entry : registry->entries) {
|
||||
if (entry.exact) {
|
||||
|
|
|
@ -65,8 +65,15 @@ void overrideRegistry(
|
|||
const Input & to,
|
||||
const Attrs & extraAttrs);
|
||||
|
||||
using RegistryFilter = std::function<bool(Registry::RegistryType)>;
|
||||
|
||||
/**
|
||||
* Rewrite a flakeref using the registries. If `filter` is set, only
|
||||
* use the registries for which the filter function returns true.
|
||||
*/
|
||||
std::pair<Input, Attrs> lookupInRegistries(
|
||||
ref<Store> store,
|
||||
const Input & input);
|
||||
const Input & input,
|
||||
const RegistryFilter & filter = {});
|
||||
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../../build-utils-meson/
|
|
@ -14,7 +14,7 @@ project('nix-flake-c', 'cpp',
|
|||
|
||||
cxx = meson.get_compiler('cpp')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
subdir('nix-meson-build-support/deps-lists')
|
||||
|
||||
configdata = configuration_data()
|
||||
|
||||
|
@ -29,7 +29,7 @@ deps_public_maybe_subproject = [
|
|||
dependency('nix-store-c'),
|
||||
dependency('nix-expr-c'),
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
subdir('nix-meson-build-support/subprojects')
|
||||
|
||||
# TODO rename, because it will conflict with downstream projects
|
||||
configdata.set_quoted('PACKAGE_VERSION', meson.project_version())
|
||||
|
@ -58,7 +58,7 @@ add_project_arguments(
|
|||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/common')
|
||||
subdir('nix-meson-build-support/common')
|
||||
|
||||
sources = files(
|
||||
'nix_api_flake.cc',
|
||||
|
@ -73,8 +73,8 @@ headers = [config_h] + files(
|
|||
# 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')
|
||||
subdir('nix-meson-build-support/export-all-symbols')
|
||||
subdir('nix-meson-build-support/windows-version')
|
||||
|
||||
this_library = library(
|
||||
'nixflakec',
|
||||
|
@ -90,4 +90,4 @@ install_headers(headers, subdir : 'nix', preserve_path : true)
|
|||
|
||||
libraries_private = []
|
||||
|
||||
subdir('build-utils-meson/export')
|
||||
subdir('nix-meson-build-support/export')
|
||||
|
|
1
src/libflake-c/nix-meson-build-support
Symbolic link
1
src/libflake-c/nix-meson-build-support
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../nix-meson-build-support
|
|
@ -21,8 +21,8 @@ mkMesonLibrary (finalAttrs: {
|
|||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../nix-meson-build-support
|
||||
./nix-meson-build-support
|
||||
../../.version
|
||||
./.version
|
||||
./meson.build
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../../build-utils-meson
|
|
@ -14,7 +14,7 @@ project('nix-flake-tests', 'cpp',
|
|||
|
||||
cxx = meson.get_compiler('cpp')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
subdir('nix-meson-build-support/deps-lists')
|
||||
|
||||
deps_private_maybe_subproject = [
|
||||
dependency('nix-expr-test-support'),
|
||||
|
@ -23,10 +23,10 @@ deps_private_maybe_subproject = [
|
|||
]
|
||||
deps_public_maybe_subproject = [
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
subdir('nix-meson-build-support/subprojects')
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
subdir('build-utils-meson/windows-version')
|
||||
subdir('nix-meson-build-support/export-all-symbols')
|
||||
subdir('nix-meson-build-support/windows-version')
|
||||
|
||||
rapidcheck = dependency('rapidcheck')
|
||||
deps_private += rapidcheck
|
||||
|
@ -43,7 +43,7 @@ add_project_arguments(
|
|||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/common')
|
||||
subdir('nix-meson-build-support/common')
|
||||
|
||||
sources = files(
|
||||
'flakeref.cc',
|
||||
|
|
1
src/libflake-tests/nix-meson-build-support
Symbolic link
1
src/libflake-tests/nix-meson-build-support
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../nix-meson-build-support
|
|
@ -27,8 +27,8 @@ mkMesonExecutable (finalAttrs: {
|
|||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../nix-meson-build-support
|
||||
./nix-meson-build-support
|
||||
../../.version
|
||||
./.version
|
||||
./meson.build
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../../build-utils-meson
|
|
@ -21,23 +21,23 @@ using namespace flake;
|
|||
|
||||
namespace flake {
|
||||
|
||||
typedef std::pair<StorePath, FlakeRef> FetchedFlake;
|
||||
typedef std::vector<std::pair<FlakeRef, FetchedFlake>> FlakeCache;
|
||||
struct FetchedFlake
|
||||
{
|
||||
FlakeRef lockedRef;
|
||||
StorePath storePath;
|
||||
};
|
||||
|
||||
typedef std::map<FlakeRef, FetchedFlake> FlakeCache;
|
||||
|
||||
static std::optional<FetchedFlake> lookupInFlakeCache(
|
||||
const FlakeCache & flakeCache,
|
||||
const FlakeRef & flakeRef)
|
||||
{
|
||||
// FIXME: inefficient.
|
||||
for (auto & i : flakeCache) {
|
||||
if (flakeRef == i.first) {
|
||||
debug("mapping '%s' to previously seen input '%s' -> '%s",
|
||||
flakeRef, i.first, i.second.second);
|
||||
return i.second;
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
auto i = flakeCache.find(flakeRef);
|
||||
if (i == flakeCache.end()) return std::nullopt;
|
||||
debug("mapping '%s' to previously seen input '%s' -> '%s",
|
||||
flakeRef, i->first, i->second.lockedRef);
|
||||
return i->second;
|
||||
}
|
||||
|
||||
static std::tuple<StorePath, FlakeRef, FlakeRef> fetchOrSubstituteTree(
|
||||
|
@ -51,32 +51,39 @@ static std::tuple<StorePath, FlakeRef, FlakeRef> fetchOrSubstituteTree(
|
|||
|
||||
if (!fetched) {
|
||||
if (originalRef.input.isDirect()) {
|
||||
fetched.emplace(originalRef.fetchTree(state.store));
|
||||
auto [storePath, lockedRef] = originalRef.fetchTree(state.store);
|
||||
fetched.emplace(FetchedFlake{.lockedRef = lockedRef, .storePath = storePath});
|
||||
} else {
|
||||
if (allowLookup) {
|
||||
resolvedRef = originalRef.resolve(state.store);
|
||||
auto fetchedResolved = lookupInFlakeCache(flakeCache, originalRef);
|
||||
if (!fetchedResolved) fetchedResolved.emplace(resolvedRef.fetchTree(state.store));
|
||||
flakeCache.push_back({resolvedRef, *fetchedResolved});
|
||||
fetched.emplace(*fetchedResolved);
|
||||
resolvedRef = originalRef.resolve(
|
||||
state.store,
|
||||
[](fetchers::Registry::RegistryType type) {
|
||||
/* Only use the global registry and CLI flags
|
||||
to resolve indirect flakerefs. */
|
||||
return type == fetchers::Registry::Flag || type == fetchers::Registry::Global;
|
||||
});
|
||||
fetched = lookupInFlakeCache(flakeCache, originalRef);
|
||||
if (!fetched) {
|
||||
auto [storePath, lockedRef] = resolvedRef.fetchTree(state.store);
|
||||
fetched.emplace(FetchedFlake{.lockedRef = lockedRef, .storePath = storePath});
|
||||
}
|
||||
flakeCache.insert_or_assign(resolvedRef, *fetched);
|
||||
}
|
||||
else {
|
||||
throw Error("'%s' is an indirect flake reference, but registry lookups are not allowed", originalRef);
|
||||
}
|
||||
}
|
||||
flakeCache.push_back({originalRef, *fetched});
|
||||
flakeCache.insert_or_assign(originalRef, *fetched);
|
||||
}
|
||||
|
||||
auto [storePath, lockedRef] = *fetched;
|
||||
|
||||
debug("got tree '%s' from '%s'",
|
||||
state.store->printStorePath(storePath), lockedRef);
|
||||
state.store->printStorePath(fetched->storePath), fetched->lockedRef);
|
||||
|
||||
state.allowPath(storePath);
|
||||
state.allowPath(fetched->storePath);
|
||||
|
||||
assert(!originalRef.input.getNarHash() || storePath == originalRef.input.computeStorePath(*state.store));
|
||||
assert(!originalRef.input.getNarHash() || fetched->storePath == originalRef.input.computeStorePath(*state.store));
|
||||
|
||||
return {std::move(storePath), resolvedRef, lockedRef};
|
||||
return {fetched->storePath, resolvedRef, fetched->lockedRef};
|
||||
}
|
||||
|
||||
static void forceTrivialValue(EvalState & state, Value & value, const PosIdx pos)
|
||||
|
@ -672,6 +679,8 @@ LockedFlake lockFlake(
|
|||
if (lockFlags.writeLockFile) {
|
||||
if (sourcePath || lockFlags.outputLockFilePath) {
|
||||
if (auto unlockedInput = newLockFile.isUnlocked()) {
|
||||
if (lockFlags.failOnUnlocked)
|
||||
throw Error("cannot write lock file of flake '%s' because it has an unlocked input ('%s').\n", topRef, *unlockedInput);
|
||||
if (state.fetchSettings.warnDirty)
|
||||
warn("will not write lock file of flake '%s' because it has an unlocked input ('%s')", topRef, *unlockedInput);
|
||||
} else {
|
||||
|
|
|
@ -156,6 +156,11 @@ struct LockFlags
|
|||
*/
|
||||
bool writeLockFile = true;
|
||||
|
||||
/**
|
||||
* Throw an exception when the flake has an unlocked input.
|
||||
*/
|
||||
bool failOnUnlocked = false;
|
||||
|
||||
/**
|
||||
* Whether to use the registries to lookup indirect flake
|
||||
* references like 'nixpkgs'.
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include "url.hh"
|
||||
#include "url-parts.hh"
|
||||
#include "fetchers.hh"
|
||||
#include "registry.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
@ -36,7 +35,9 @@ std::ostream & operator << (std::ostream & str, const FlakeRef & flakeRef)
|
|||
return str;
|
||||
}
|
||||
|
||||
FlakeRef FlakeRef::resolve(ref<Store> store) const
|
||||
FlakeRef FlakeRef::resolve(
|
||||
ref<Store> store,
|
||||
const fetchers::RegistryFilter & filter) const
|
||||
{
|
||||
auto [input2, extraAttrs] = lookupInRegistries(store, input);
|
||||
return FlakeRef(std::move(input2), fetchers::maybeGetStrAttr(extraAttrs, "dir").value_or(subdir));
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "types.hh"
|
||||
#include "fetchers.hh"
|
||||
#include "outputs-spec.hh"
|
||||
#include "registry.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
@ -48,6 +49,11 @@ struct FlakeRef
|
|||
|
||||
bool operator ==(const FlakeRef & other) const = default;
|
||||
|
||||
bool operator <(const FlakeRef & other) const
|
||||
{
|
||||
return std::tie(input, subdir) < std::tie(other.input, other.subdir);
|
||||
}
|
||||
|
||||
FlakeRef(fetchers::Input && input, const Path & subdir)
|
||||
: input(std::move(input)), subdir(subdir)
|
||||
{ }
|
||||
|
@ -57,7 +63,9 @@ struct FlakeRef
|
|||
|
||||
fetchers::Attrs toAttrs() const;
|
||||
|
||||
FlakeRef resolve(ref<Store> store) const;
|
||||
FlakeRef resolve(
|
||||
ref<Store> store,
|
||||
const fetchers::RegistryFilter & filter = {}) const;
|
||||
|
||||
static FlakeRef fromAttrs(
|
||||
const fetchers::Settings & fetchSettings,
|
||||
|
|
|
@ -14,7 +14,7 @@ project('nix-flake', 'cpp',
|
|||
|
||||
cxx = meson.get_compiler('cpp')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
subdir('nix-meson-build-support/deps-lists')
|
||||
|
||||
deps_private_maybe_subproject = [
|
||||
]
|
||||
|
@ -24,7 +24,7 @@ deps_public_maybe_subproject = [
|
|||
dependency('nix-fetchers'),
|
||||
dependency('nix-expr'),
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
subdir('nix-meson-build-support/subprojects')
|
||||
|
||||
nlohmann_json = dependency('nlohmann_json', version : '>= 3.9')
|
||||
deps_public += nlohmann_json
|
||||
|
@ -39,7 +39,7 @@ add_project_arguments(
|
|||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/common')
|
||||
subdir('nix-meson-build-support/common')
|
||||
|
||||
sources = files(
|
||||
'flake/config.cc',
|
||||
|
@ -72,4 +72,4 @@ install_headers(headers, subdir : 'nix', preserve_path : true)
|
|||
|
||||
libraries_private = []
|
||||
|
||||
subdir('build-utils-meson/export')
|
||||
subdir('nix-meson-build-support/export')
|
||||
|
|
1
src/libflake/nix-meson-build-support
Symbolic link
1
src/libflake/nix-meson-build-support
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../nix-meson-build-support
|
|
@ -23,8 +23,8 @@ mkMesonLibrary (finalAttrs: {
|
|||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../nix-meson-build-support
|
||||
./nix-meson-build-support
|
||||
../../.version
|
||||
./.version
|
||||
./meson.build
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../../build-utils-meson
|
|
@ -14,7 +14,7 @@ project('nix-main-c', 'cpp',
|
|||
|
||||
cxx = meson.get_compiler('cpp')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
subdir('nix-meson-build-support/deps-lists')
|
||||
|
||||
configdata = configuration_data()
|
||||
|
||||
|
@ -27,7 +27,7 @@ deps_public_maybe_subproject = [
|
|||
dependency('nix-util-c'),
|
||||
dependency('nix-store-c'),
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
subdir('nix-meson-build-support/subprojects')
|
||||
|
||||
# TODO rename, because it will conflict with downstream projects
|
||||
configdata.set_quoted('PACKAGE_VERSION', meson.project_version())
|
||||
|
@ -53,7 +53,7 @@ add_project_arguments(
|
|||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/common')
|
||||
subdir('nix-meson-build-support/common')
|
||||
|
||||
sources = files(
|
||||
'nix_api_main.cc',
|
||||
|
@ -65,8 +65,8 @@ headers = [config_h] + files(
|
|||
'nix_api_main.h',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
subdir('build-utils-meson/windows-version')
|
||||
subdir('nix-meson-build-support/export-all-symbols')
|
||||
subdir('nix-meson-build-support/windows-version')
|
||||
|
||||
this_library = library(
|
||||
'nixmainc',
|
||||
|
@ -82,4 +82,4 @@ install_headers(headers, subdir : 'nix', preserve_path : true)
|
|||
|
||||
libraries_private = []
|
||||
|
||||
subdir('build-utils-meson/export')
|
||||
subdir('nix-meson-build-support/export')
|
||||
|
|
1
src/libmain-c/nix-meson-build-support
Symbolic link
1
src/libmain-c/nix-meson-build-support
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../nix-meson-build-support
|
|
@ -22,8 +22,8 @@ mkMesonLibrary (finalAttrs: {
|
|||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../nix-meson-build-support
|
||||
./nix-meson-build-support
|
||||
../../.version
|
||||
./.version
|
||||
./meson.build
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../../build-utils-meson
|
|
@ -14,7 +14,7 @@ project('nix-main', 'cpp',
|
|||
|
||||
cxx = meson.get_compiler('cpp')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
subdir('nix-meson-build-support/deps-lists')
|
||||
|
||||
configdata = configuration_data()
|
||||
|
||||
|
@ -24,7 +24,7 @@ deps_public_maybe_subproject = [
|
|||
dependency('nix-util'),
|
||||
dependency('nix-store'),
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
subdir('nix-meson-build-support/subprojects')
|
||||
|
||||
pubsetbuf_test = '''
|
||||
#include <iostream>
|
||||
|
@ -58,7 +58,7 @@ add_project_arguments(
|
|||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/common')
|
||||
subdir('nix-meson-build-support/common')
|
||||
|
||||
sources = files(
|
||||
'common-args.cc',
|
||||
|
@ -96,4 +96,4 @@ install_headers(headers, subdir : 'nix', preserve_path : true)
|
|||
|
||||
libraries_private = []
|
||||
|
||||
subdir('build-utils-meson/export')
|
||||
subdir('nix-meson-build-support/export')
|
||||
|
|
1
src/libmain/nix-meson-build-support
Symbolic link
1
src/libmain/nix-meson-build-support
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../nix-meson-build-support
|
|
@ -22,8 +22,8 @@ mkMesonLibrary (finalAttrs: {
|
|||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../nix-meson-build-support
|
||||
./nix-meson-build-support
|
||||
../../.version
|
||||
./.version
|
||||
./meson.build
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../../build-utils-meson
|
|
@ -14,7 +14,7 @@ project('nix-store-c', 'cpp',
|
|||
|
||||
cxx = meson.get_compiler('cpp')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
subdir('nix-meson-build-support/deps-lists')
|
||||
|
||||
configdata = configuration_data()
|
||||
|
||||
|
@ -25,7 +25,7 @@ deps_private_maybe_subproject = [
|
|||
deps_public_maybe_subproject = [
|
||||
dependency('nix-util-c'),
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
subdir('nix-meson-build-support/subprojects')
|
||||
|
||||
# TODO rename, because it will conflict with downstream projects
|
||||
configdata.set_quoted('PACKAGE_VERSION', meson.project_version())
|
||||
|
@ -49,7 +49,7 @@ add_project_arguments(
|
|||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/common')
|
||||
subdir('nix-meson-build-support/common')
|
||||
|
||||
sources = files(
|
||||
'nix_api_store.cc',
|
||||
|
@ -64,8 +64,8 @@ headers = [config_h] + files(
|
|||
# TODO don't install this once tests don't use it and/or move the header into `libstore`, non-`c`
|
||||
headers += files('nix_api_store_internal.h')
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
subdir('build-utils-meson/windows-version')
|
||||
subdir('nix-meson-build-support/export-all-symbols')
|
||||
subdir('nix-meson-build-support/windows-version')
|
||||
|
||||
this_library = library(
|
||||
'nixstorec',
|
||||
|
@ -81,4 +81,4 @@ install_headers(headers, subdir : 'nix', preserve_path : true)
|
|||
|
||||
libraries_private = []
|
||||
|
||||
subdir('build-utils-meson/export')
|
||||
subdir('nix-meson-build-support/export')
|
||||
|
|
1
src/libstore-c/nix-meson-build-support
Symbolic link
1
src/libstore-c/nix-meson-build-support
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../nix-meson-build-support
|
|
@ -67,6 +67,17 @@ nix_err nix_store_get_uri(nix_c_context * context, Store * store, nix_get_string
|
|||
NIXC_CATCH_ERRS
|
||||
}
|
||||
|
||||
nix_err
|
||||
nix_store_get_storedir(nix_c_context * context, Store * store, nix_get_string_callback callback, void * user_data)
|
||||
{
|
||||
if (context)
|
||||
context->last_err_code = NIX_OK;
|
||||
try {
|
||||
return call_nix_get_string_callback(store->ptr->storeDir, callback, user_data);
|
||||
}
|
||||
NIXC_CATCH_ERRS
|
||||
}
|
||||
|
||||
nix_err
|
||||
nix_store_get_version(nix_c_context * context, Store * store, nix_get_string_callback callback, void * user_data)
|
||||
{
|
||||
|
@ -89,6 +100,18 @@ bool nix_store_is_valid_path(nix_c_context * context, Store * store, StorePath *
|
|||
NIXC_CATCH_ERRS_RES(false);
|
||||
}
|
||||
|
||||
nix_err nix_store_real_path(
|
||||
nix_c_context * context, Store * store, StorePath * path, nix_get_string_callback callback, void * user_data)
|
||||
{
|
||||
if (context)
|
||||
context->last_err_code = NIX_OK;
|
||||
try {
|
||||
auto res = store->ptr->toRealPath(path->path);
|
||||
return call_nix_get_string_callback(res, callback, user_data);
|
||||
}
|
||||
NIXC_CATCH_ERRS
|
||||
}
|
||||
|
||||
StorePath * nix_store_parse_path(nix_c_context * context, Store * store, const char * path)
|
||||
{
|
||||
if (context)
|
||||
|
|
|
@ -48,12 +48,27 @@ nix_err nix_libstore_init_no_load_config(nix_c_context * context);
|
|||
* Store instances may share state and resources behind the scenes.
|
||||
*
|
||||
* @param[out] context Optional, stores error information
|
||||
* @param[in] uri URI of the Nix store, copied. See [*Store URL format* in the Nix Reference
|
||||
*
|
||||
* @param[in] uri @parblock
|
||||
* URI of the Nix store, copied.
|
||||
*
|
||||
* If `NULL`, the store from the settings will be used.
|
||||
* Note that `"auto"` holds a strange middle ground, reading part of the general environment, but not all of it. It
|
||||
* ignores `NIX_REMOTE` and the `store` option. For this reason, `NULL` is most likely the better choice.
|
||||
*
|
||||
* For supported store URLs, see [*Store URL format* in the Nix Reference
|
||||
* Manual](https://nixos.org/manual/nix/stable/store/types/#store-url-format).
|
||||
* @param[in] params optional, null-terminated array of key-value pairs, e.g. {{"endpoint",
|
||||
* "https://s3.local"}}. See [*Store Types* in the Nix Reference
|
||||
* Manual](https://nixos.org/manual/nix/stable/store/types).
|
||||
* @endparblock
|
||||
*
|
||||
* @param[in] params @parblock
|
||||
* optional, null-terminated array of key-value pairs, e.g. {{"endpoint",
|
||||
* "https://s3.local"}}.
|
||||
*
|
||||
* See [*Store Types* in the Nix Reference Manual](https://nixos.org/manual/nix/stable/store/types).
|
||||
* @endparblock
|
||||
*
|
||||
* @return a Store pointer, NULL in case of errors
|
||||
*
|
||||
* @see nix_store_free
|
||||
*/
|
||||
Store * nix_store_open(nix_c_context * context, const char * uri, const char *** params);
|
||||
|
@ -78,7 +93,18 @@ void nix_store_free(Store * store);
|
|||
*/
|
||||
nix_err nix_store_get_uri(nix_c_context * context, Store * store, nix_get_string_callback callback, void * user_data);
|
||||
|
||||
// returns: owned StorePath*
|
||||
/**
|
||||
* @brief get the storeDir of a Nix store, typically `"/nix/store"`
|
||||
* @param[out] context Optional, stores error information
|
||||
* @param[in] store nix store reference
|
||||
* @param[in] callback Called with the URI.
|
||||
* @param[in] user_data optional, arbitrary data, passed to the callback when it's called.
|
||||
* @see nix_get_string_callback
|
||||
* @return error code, NIX_OK on success.
|
||||
*/
|
||||
nix_err
|
||||
nix_store_get_storedir(nix_c_context * context, Store * store, nix_get_string_callback callback, void * user_data);
|
||||
|
||||
/**
|
||||
* @brief Parse a Nix store path into a StorePath
|
||||
*
|
||||
|
@ -123,6 +149,26 @@ void nix_store_path_free(StorePath * p);
|
|||
* @return true or false, error info in context
|
||||
*/
|
||||
bool nix_store_is_valid_path(nix_c_context * context, Store * store, StorePath * path);
|
||||
|
||||
/**
|
||||
* @brief Get the physical location of a store path
|
||||
*
|
||||
* A store may reside at a different location than its `storeDir` suggests.
|
||||
* This situation is called a relocated store.
|
||||
* Relocated stores are used during NixOS installation, as well as in restricted computing environments that don't offer
|
||||
* a writable `/nix/store`.
|
||||
*
|
||||
* Not all types of stores support this operation.
|
||||
*
|
||||
* @param[in] context Optional, stores error information
|
||||
* @param[in] store nix store reference
|
||||
* @param[in] path the path to get the real path from
|
||||
* @param[in] callback called with the real path
|
||||
* @param[in] user_data arbitrary data, passed to the callback when it's called.
|
||||
*/
|
||||
nix_err nix_store_real_path(
|
||||
nix_c_context * context, Store * store, StorePath * path, nix_get_string_callback callback, void * user_data);
|
||||
|
||||
// nix_err nix_store_ensure(Store*, const char*);
|
||||
// nix_err nix_store_build_paths(Store*);
|
||||
/**
|
||||
|
|
|
@ -20,8 +20,8 @@ mkMesonLibrary (finalAttrs: {
|
|||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../nix-meson-build-support
|
||||
./nix-meson-build-support
|
||||
../../.version
|
||||
./.version
|
||||
./meson.build
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../../build-utils-meson
|
|
@ -14,7 +14,7 @@ project('nix-store-test-support', 'cpp',
|
|||
|
||||
cxx = meson.get_compiler('cpp')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
subdir('nix-meson-build-support/deps-lists')
|
||||
|
||||
deps_private_maybe_subproject = [
|
||||
]
|
||||
|
@ -24,7 +24,7 @@ deps_public_maybe_subproject = [
|
|||
dependency('nix-store'),
|
||||
dependency('nix-store-c'),
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
subdir('nix-meson-build-support/subprojects')
|
||||
|
||||
rapidcheck = dependency('rapidcheck')
|
||||
deps_public += rapidcheck
|
||||
|
@ -37,7 +37,7 @@ add_project_arguments(
|
|||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/common')
|
||||
subdir('nix-meson-build-support/common')
|
||||
|
||||
sources = files(
|
||||
'tests/derived-path.cc',
|
||||
|
@ -56,8 +56,8 @@ headers = files(
|
|||
'tests/protocol.hh',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
subdir('build-utils-meson/windows-version')
|
||||
subdir('nix-meson-build-support/export-all-symbols')
|
||||
subdir('nix-meson-build-support/windows-version')
|
||||
|
||||
this_library = library(
|
||||
'nix-store-test-support',
|
||||
|
@ -75,4 +75,4 @@ install_headers(headers, subdir : 'nix', preserve_path : true)
|
|||
|
||||
libraries_private = []
|
||||
|
||||
subdir('build-utils-meson/export')
|
||||
subdir('nix-meson-build-support/export')
|
||||
|
|
1
src/libstore-test-support/nix-meson-build-support
Symbolic link
1
src/libstore-test-support/nix-meson-build-support
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../nix-meson-build-support
|
|
@ -23,8 +23,8 @@ mkMesonLibrary (finalAttrs: {
|
|||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../nix-meson-build-support
|
||||
./nix-meson-build-support
|
||||
../../.version
|
||||
./.version
|
||||
./meson.build
|
||||
|
|
|
@ -19,12 +19,12 @@ public:
|
|||
protected:
|
||||
LibStoreTest()
|
||||
: store(openStore({
|
||||
.variant =
|
||||
StoreReference::Specified{
|
||||
.scheme = "dummy",
|
||||
},
|
||||
.params = {},
|
||||
}))
|
||||
.variant =
|
||||
StoreReference::Specified{
|
||||
.scheme = "dummy",
|
||||
},
|
||||
.params = {},
|
||||
}))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../../build-utils-meson
|
|
@ -14,19 +14,21 @@ project('nix-store-tests', 'cpp',
|
|||
|
||||
cxx = meson.get_compiler('cpp')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
subdir('nix-meson-build-support/deps-lists')
|
||||
|
||||
nix_store = dependency('nix-store')
|
||||
|
||||
deps_private_maybe_subproject = [
|
||||
dependency('nix-store'),
|
||||
nix_store,
|
||||
dependency('nix-store-c'),
|
||||
dependency('nix-store-test-support'),
|
||||
]
|
||||
deps_public_maybe_subproject = [
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
subdir('nix-meson-build-support/subprojects')
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
subdir('build-utils-meson/windows-version')
|
||||
subdir('nix-meson-build-support/export-all-symbols')
|
||||
subdir('nix-meson-build-support/windows-version')
|
||||
|
||||
sqlite = dependency('sqlite3', 'sqlite', version : '>=3.6.19')
|
||||
deps_private += sqlite
|
||||
|
@ -50,7 +52,7 @@ add_project_arguments(
|
|||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/common')
|
||||
subdir('nix-meson-build-support/common')
|
||||
|
||||
sources = files(
|
||||
'common-protocol.cc',
|
||||
|
@ -90,6 +92,7 @@ this_exe = executable(
|
|||
include_directories : include_dirs,
|
||||
# TODO: -lrapidcheck, see ../libutil-support/build.meson
|
||||
link_args: linker_export_flags + ['-lrapidcheck'],
|
||||
cpp_args : [ '-DNIX_STORE_DIR="' + nix_store.get_variable('storedir') + '"' ],
|
||||
# get main from gtest
|
||||
install : true,
|
||||
)
|
||||
|
|
1
src/libstore-tests/nix-meson-build-support
Symbolic link
1
src/libstore-tests/nix-meson-build-support
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../nix-meson-build-support
|
|
@ -24,6 +24,39 @@ TEST_F(nix_api_store_test, nix_store_get_uri)
|
|||
ASSERT_STREQ("local", str.c_str());
|
||||
}
|
||||
|
||||
TEST_F(nix_api_util_context, nix_store_get_storedir_default)
|
||||
{
|
||||
if (nix::getEnv("HOME").value_or("") == "/homeless-shelter") {
|
||||
// skipping test in sandbox because nix_store_open tries to create /nix/var/nix/profiles
|
||||
GTEST_SKIP();
|
||||
}
|
||||
nix_libstore_init(ctx);
|
||||
Store * store = nix_store_open(ctx, nullptr, nullptr);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(store, nullptr);
|
||||
|
||||
std::string str;
|
||||
auto ret = nix_store_get_storedir(ctx, store, OBSERVE_STRING(str));
|
||||
assert_ctx_ok();
|
||||
ASSERT_EQ(NIX_OK, ret);
|
||||
|
||||
// These tests run with a unique storeDir, but not a relocated store
|
||||
ASSERT_STREQ(NIX_STORE_DIR, str.c_str());
|
||||
|
||||
nix_store_free(store);
|
||||
}
|
||||
|
||||
TEST_F(nix_api_store_test, nix_store_get_storedir)
|
||||
{
|
||||
std::string str;
|
||||
auto ret = nix_store_get_storedir(ctx, store, OBSERVE_STRING(str));
|
||||
assert_ctx_ok();
|
||||
ASSERT_EQ(NIX_OK, ret);
|
||||
|
||||
// These tests run with a unique storeDir, but not a relocated store
|
||||
ASSERT_STREQ(nixStoreDir.c_str(), str.c_str());
|
||||
}
|
||||
|
||||
TEST_F(nix_api_store_test, InvalidPathFails)
|
||||
{
|
||||
nix_store_parse_path(ctx, store, "invalid-path");
|
||||
|
@ -86,4 +119,84 @@ TEST_F(nix_api_store_test, nix_store_is_valid_path_not_in_store)
|
|||
ASSERT_EQ(false, nix_store_is_valid_path(ctx, store, path));
|
||||
}
|
||||
|
||||
TEST_F(nix_api_store_test, nix_store_real_path)
|
||||
{
|
||||
StorePath * path = nix_store_parse_path(ctx, store, (nixStoreDir + PATH_SUFFIX).c_str());
|
||||
std::string rp;
|
||||
auto ret = nix_store_real_path(ctx, store, path, OBSERVE_STRING(rp));
|
||||
assert_ctx_ok();
|
||||
ASSERT_EQ(NIX_OK, ret);
|
||||
// Assumption: we're not testing with a relocated store
|
||||
ASSERT_STREQ((nixStoreDir + PATH_SUFFIX).c_str(), rp.c_str());
|
||||
|
||||
nix_store_path_free(path);
|
||||
}
|
||||
|
||||
TEST_F(nix_api_util_context, nix_store_real_path_relocated)
|
||||
{
|
||||
if (nix::getEnv("HOME").value_or("") == "/homeless-shelter") {
|
||||
// Can't open default store from within sandbox
|
||||
GTEST_SKIP();
|
||||
}
|
||||
auto tmp = nix::createTempDir();
|
||||
std::string storeRoot = tmp + "/store";
|
||||
std::string stateDir = tmp + "/state";
|
||||
std::string logDir = tmp + "/log";
|
||||
const char * rootkv[] = {"root", storeRoot.c_str()};
|
||||
const char * statekv[] = {"state", stateDir.c_str()};
|
||||
const char * logkv[] = {"log", logDir.c_str()};
|
||||
// const char * rokv[] = {"read-only", "true"};
|
||||
const char ** kvs[] = {rootkv, statekv, logkv, NULL};
|
||||
|
||||
nix_libstore_init(ctx);
|
||||
assert_ctx_ok();
|
||||
|
||||
Store * store = nix_store_open(ctx, "local", kvs);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(store, nullptr);
|
||||
|
||||
std::string nixStoreDir;
|
||||
auto ret = nix_store_get_storedir(ctx, store, OBSERVE_STRING(nixStoreDir));
|
||||
ASSERT_EQ(NIX_OK, ret);
|
||||
ASSERT_STREQ(NIX_STORE_DIR, nixStoreDir.c_str());
|
||||
|
||||
StorePath * path = nix_store_parse_path(ctx, store, (nixStoreDir + PATH_SUFFIX).c_str());
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(path, nullptr);
|
||||
|
||||
std::string rp;
|
||||
ret = nix_store_real_path(ctx, store, path, OBSERVE_STRING(rp));
|
||||
assert_ctx_ok();
|
||||
ASSERT_EQ(NIX_OK, ret);
|
||||
|
||||
// Assumption: we're not testing with a relocated store
|
||||
ASSERT_STREQ((storeRoot + NIX_STORE_DIR + PATH_SUFFIX).c_str(), rp.c_str());
|
||||
|
||||
nix_store_path_free(path);
|
||||
}
|
||||
|
||||
TEST_F(nix_api_util_context, nix_store_real_path_binary_cache)
|
||||
{
|
||||
if (nix::getEnv("HOME").value_or("") == "/homeless-shelter") {
|
||||
// TODO: override NIX_CACHE_HOME?
|
||||
// skipping test in sandbox because narinfo cache can't be written
|
||||
GTEST_SKIP();
|
||||
}
|
||||
|
||||
Store * store = nix_store_open(ctx, "https://cache.nixos.org", nullptr);
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(store, nullptr);
|
||||
|
||||
std::string path_raw = std::string(NIX_STORE_DIR) + PATH_SUFFIX;
|
||||
StorePath * path = nix_store_parse_path(ctx, store, path_raw.c_str());
|
||||
assert_ctx_ok();
|
||||
ASSERT_NE(path, nullptr);
|
||||
|
||||
std::string rp;
|
||||
auto ret = nix_store_real_path(ctx, store, path, OBSERVE_STRING(rp));
|
||||
assert_ctx_ok();
|
||||
ASSERT_EQ(NIX_OK, ret);
|
||||
ASSERT_STREQ(path_raw.c_str(), rp.c_str());
|
||||
}
|
||||
|
||||
} // namespace nixC
|
||||
|
|
|
@ -28,8 +28,8 @@ mkMesonExecutable (finalAttrs: {
|
|||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../nix-meson-build-support
|
||||
./nix-meson-build-support
|
||||
../../.version
|
||||
./.version
|
||||
./meson.build
|
||||
|
|
|
@ -39,15 +39,13 @@ BinaryCacheStore::BinaryCacheStore(const Params & params)
|
|||
|
||||
void BinaryCacheStore::init()
|
||||
{
|
||||
std::string cacheInfoFile = "nix-cache-info";
|
||||
|
||||
auto cacheInfo = getFile(cacheInfoFile);
|
||||
auto cacheInfo = getNixCacheInfo();
|
||||
if (!cacheInfo) {
|
||||
upsertFile(cacheInfoFile, "StoreDir: " + storeDir + "\n", "text/x-nix-cache-info");
|
||||
} else {
|
||||
for (auto & line : tokenizeString<Strings>(*cacheInfo, "\n")) {
|
||||
size_t colon= line.find(':');
|
||||
if (colon ==std::string::npos) continue;
|
||||
size_t colon = line.find(':');
|
||||
if (colon == std::string::npos) continue;
|
||||
auto name = line.substr(0, colon);
|
||||
auto value = trim(line.substr(colon + 1, std::string::npos));
|
||||
if (name == "StoreDir") {
|
||||
|
@ -63,6 +61,11 @@ void BinaryCacheStore::init()
|
|||
}
|
||||
}
|
||||
|
||||
std::optional<std::string> BinaryCacheStore::getNixCacheInfo()
|
||||
{
|
||||
return getFile(cacheInfoFile);
|
||||
}
|
||||
|
||||
void BinaryCacheStore::upsertFile(const std::string & path,
|
||||
std::string && data,
|
||||
const std::string & mimeType)
|
||||
|
|
|
@ -64,6 +64,8 @@ protected:
|
|||
// The prefix under which realisation infos will be stored
|
||||
const std::string realisationsPrefix = "realisations";
|
||||
|
||||
const std::string cacheInfoFile = "nix-cache-info";
|
||||
|
||||
BinaryCacheStore(const Params & params);
|
||||
|
||||
public:
|
||||
|
@ -84,6 +86,12 @@ public:
|
|||
*/
|
||||
virtual void getFile(const std::string & path, Sink & sink);
|
||||
|
||||
/**
|
||||
* Get the contents of /nix-cache-info. Return std::nullopt if it
|
||||
* doesn't exist.
|
||||
*/
|
||||
virtual std::optional<std::string> getNixCacheInfo();
|
||||
|
||||
/**
|
||||
* Fetch the specified file and call the specified callback with
|
||||
* the result. A subclass may implement this asynchronously.
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../../build-utils-meson
|
|
@ -1161,7 +1161,7 @@ HookReply DerivationGoal::tryBuildHook()
|
|||
throw;
|
||||
}
|
||||
}();
|
||||
if (handleJSONLogMessage(s, worker.act, worker.hook->activities, true))
|
||||
if (handleJSONLogMessage(s, worker.act, worker.hook->activities, "the build hook", true))
|
||||
;
|
||||
else if (s.substr(0, 2) == "# ") {
|
||||
reply = s.substr(2);
|
||||
|
@ -1346,9 +1346,9 @@ void DerivationGoal::handleChildOutput(Descriptor fd, std::string_view data)
|
|||
if (hook && fd == hook->fromHook.readSide.get()) {
|
||||
for (auto c : data)
|
||||
if (c == '\n') {
|
||||
auto json = parseJSONMessage(currentHookLine);
|
||||
auto json = parseJSONMessage(currentHookLine, "the derivation builder");
|
||||
if (json) {
|
||||
auto s = handleJSONLogMessage(*json, worker.act, hook->activities, true);
|
||||
auto s = handleJSONLogMessage(*json, worker.act, hook->activities, "the derivation builder", true);
|
||||
// ensure that logs from a builder using `ssh-ng://` as protocol
|
||||
// are also available to `nix log`.
|
||||
if (s && !isWrittenToLog && logSink) {
|
||||
|
@ -1390,7 +1390,7 @@ void DerivationGoal::handleEOF(Descriptor fd)
|
|||
|
||||
void DerivationGoal::flushLine()
|
||||
{
|
||||
if (handleJSONLogMessage(currentLogLine, *act, builderActivities, false))
|
||||
if (handleJSONLogMessage(currentLogLine, *act, builderActivities, "the derivation builder", false))
|
||||
;
|
||||
|
||||
else {
|
||||
|
|
|
@ -194,6 +194,19 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
std::optional<std::string> getNixCacheInfo() override
|
||||
{
|
||||
try {
|
||||
auto result = getFileTransfer()->download(makeRequest(cacheInfoFile));
|
||||
return result.data;
|
||||
} catch (FileTransferError & e) {
|
||||
if (e.error == FileTransfer::NotFound)
|
||||
return std::nullopt;
|
||||
maybeDisable();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This isn't actually necessary read only. We support "upsert" now, so we
|
||||
* have a notion of authentication via HTTP POST/PUT.
|
||||
|
|
|
@ -15,7 +15,7 @@ project('nix-store', 'cpp',
|
|||
|
||||
cxx = meson.get_compiler('cpp')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
subdir('nix-meson-build-support/deps-lists')
|
||||
|
||||
configdata = configuration_data()
|
||||
|
||||
|
@ -29,7 +29,7 @@ deps_private_maybe_subproject = [
|
|||
deps_public_maybe_subproject = [
|
||||
dependency('nix-util'),
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
subdir('nix-meson-build-support/subprojects')
|
||||
|
||||
run_command('ln', '-s',
|
||||
meson.project_build_root() / '__nothing_link_target',
|
||||
|
@ -81,7 +81,7 @@ if host_machine.system() == 'windows'
|
|||
deps_other += [wsock32]
|
||||
endif
|
||||
|
||||
subdir('build-utils-meson/libatomic')
|
||||
subdir('nix-meson-build-support/libatomic')
|
||||
|
||||
boost = dependency(
|
||||
'boost',
|
||||
|
@ -131,7 +131,7 @@ if aws_s3.found()
|
|||
endif
|
||||
deps_other += aws_s3
|
||||
|
||||
subdir('build-utils-meson/generate-header')
|
||||
subdir('nix-meson-build-support/generate-header')
|
||||
|
||||
generated_headers = []
|
||||
foreach header : [
|
||||
|
@ -179,7 +179,7 @@ add_project_arguments(
|
|||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/common')
|
||||
subdir('nix-meson-build-support/common')
|
||||
|
||||
sources = files(
|
||||
'binary-cache-store.cc',
|
||||
|
@ -416,8 +416,8 @@ foreach name, value : cpp_str_defines
|
|||
]
|
||||
endforeach
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
subdir('build-utils-meson/windows-version')
|
||||
subdir('nix-meson-build-support/export-all-symbols')
|
||||
subdir('nix-meson-build-support/windows-version')
|
||||
|
||||
this_library = library(
|
||||
'nixstore',
|
||||
|
@ -446,4 +446,4 @@ if host_machine.system() != 'darwin'
|
|||
}
|
||||
endif
|
||||
|
||||
subdir('build-utils-meson/export')
|
||||
subdir('nix-meson-build-support/export')
|
||||
|
|
1
src/libstore/nix-meson-build-support
Symbolic link
1
src/libstore/nix-meson-build-support
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../nix-meson-build-support
|
|
@ -32,8 +32,8 @@ mkMesonLibrary (finalAttrs: {
|
|||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../nix-meson-build-support
|
||||
./nix-meson-build-support
|
||||
../../.version
|
||||
./.version
|
||||
./meson.build
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
///@file
|
||||
|
||||
#include <string_view>
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
||||
|
|
|
@ -48,7 +48,11 @@ R && checkAws(std::string_view s, Aws::Utils::Outcome<R, E> && outcome)
|
|||
if (!outcome.IsSuccess())
|
||||
throw S3Error(
|
||||
outcome.GetError().GetErrorType(),
|
||||
s + ": " + outcome.GetError().GetMessage());
|
||||
fmt(
|
||||
"%s: %s (request id: %s)",
|
||||
s,
|
||||
outcome.GetError().GetMessage(),
|
||||
outcome.GetError().GetRequestId()));
|
||||
return outcome.GetResultWithOwnership();
|
||||
}
|
||||
|
||||
|
@ -121,9 +125,10 @@ class RetryStrategy : public Aws::Client::DefaultRetryStrategy
|
|||
checkInterrupt();
|
||||
auto retry = Aws::Client::DefaultRetryStrategy::ShouldRetry(error, attemptedRetries);
|
||||
if (retry)
|
||||
printError("AWS error '%s' (%s), will retry in %d ms",
|
||||
printError("AWS error '%s' (%s; request id: %s), will retry in %d ms",
|
||||
error.GetExceptionName(),
|
||||
error.GetMessage(),
|
||||
error.GetRequestId(),
|
||||
CalculateDelayBeforeNextRetry(error, attemptedRetries));
|
||||
return retry;
|
||||
}
|
||||
|
|
|
@ -41,8 +41,17 @@ void SSHMaster::addCommonSSHOpts(Strings & args)
|
|||
{
|
||||
auto state(state_.lock());
|
||||
|
||||
for (auto & i : tokenizeString<Strings>(getEnv("NIX_SSHOPTS").value_or("")))
|
||||
args.push_back(i);
|
||||
std::string sshOpts = getEnv("NIX_SSHOPTS").value_or("");
|
||||
|
||||
try {
|
||||
std::list<std::string> opts = shellSplitString(sshOpts);
|
||||
for (auto & i : opts)
|
||||
args.push_back(i);
|
||||
} catch (Error & e) {
|
||||
e.addTrace({}, "while splitting NIX_SSHOPTS '%s'", sshOpts);
|
||||
throw;
|
||||
}
|
||||
|
||||
if (!keyFile.empty())
|
||||
args.insert(args.end(), {"-i", keyFile});
|
||||
if (!sshPublicHostKey.empty()) {
|
||||
|
|
|
@ -2,10 +2,12 @@
|
|||
#include "pathlocks.hh"
|
||||
#include "signals.hh"
|
||||
#include "util.hh"
|
||||
#include <errhandlingapi.h>
|
||||
#include <fileapi.h>
|
||||
#include <windows.h>
|
||||
#include "windows-error.hh"
|
||||
|
||||
#ifdef WIN32
|
||||
# include <errhandlingapi.h>
|
||||
# include <fileapi.h>
|
||||
# include <windows.h>
|
||||
# include "windows-error.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
@ -154,3 +156,4 @@ FdLock::FdLock(Descriptor desc, LockType lockType, bool wait, std::string_view w
|
|||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../../build-utils-meson
|
|
@ -14,7 +14,7 @@ project('nix-util-c', 'cpp',
|
|||
|
||||
cxx = meson.get_compiler('cpp')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
subdir('nix-meson-build-support/deps-lists')
|
||||
|
||||
configdata = configuration_data()
|
||||
|
||||
|
@ -23,7 +23,7 @@ deps_private_maybe_subproject = [
|
|||
]
|
||||
deps_public_maybe_subproject = [
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
subdir('nix-meson-build-support/subprojects')
|
||||
|
||||
# TODO rename, because it will conflict with downstream projects
|
||||
configdata.set_quoted('PACKAGE_VERSION', meson.project_version())
|
||||
|
@ -45,7 +45,7 @@ add_project_arguments(
|
|||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/common')
|
||||
subdir('nix-meson-build-support/common')
|
||||
|
||||
sources = files(
|
||||
'nix_api_util.cc',
|
||||
|
@ -60,8 +60,8 @@ headers = [config_h] + files(
|
|||
# TODO don't install this once tests don't use it.
|
||||
headers += files('nix_api_util_internal.h')
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
subdir('build-utils-meson/windows-version')
|
||||
subdir('nix-meson-build-support/export-all-symbols')
|
||||
subdir('nix-meson-build-support/windows-version')
|
||||
|
||||
this_library = library(
|
||||
'nixutilc',
|
||||
|
@ -77,4 +77,4 @@ install_headers(headers, subdir : 'nix', preserve_path : true)
|
|||
|
||||
libraries_private = []
|
||||
|
||||
subdir('build-utils-meson/export')
|
||||
subdir('nix-meson-build-support/export')
|
||||
|
|
1
src/libutil-c/nix-meson-build-support
Symbolic link
1
src/libutil-c/nix-meson-build-support
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../nix-meson-build-support
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue