mirror of
https://github.com/NixOS/nix.git
synced 2025-11-08 19:46:02 +01:00
Merge branch 'master' into fix-fetch-to-store-caching
This commit is contained in:
commit
6721ef5feb
33 changed files with 586 additions and 530 deletions
|
|
@ -106,28 +106,6 @@
|
|||
enable = true;
|
||||
excludes = [
|
||||
# We haven't linted these files yet
|
||||
''^tests/functional/dump-db\.sh$''
|
||||
''^tests/functional/dyn-drv/eval-outputOf\.sh$''
|
||||
''^tests/functional/dyn-drv/old-daemon-error-hack\.sh$''
|
||||
''^tests/functional/dyn-drv/recursive-mod-json\.sh$''
|
||||
''^tests/functional/eval-store\.sh$''
|
||||
''^tests/functional/export-graph\.sh$''
|
||||
''^tests/functional/export\.sh$''
|
||||
''^tests/functional/extra-sandbox-profile\.sh$''
|
||||
''^tests/functional/fetchClosure\.sh$''
|
||||
''^tests/functional/fetchGit\.sh$''
|
||||
''^tests/functional/fetchGitRefs\.sh$''
|
||||
''^tests/functional/fetchGitSubmodules\.sh$''
|
||||
''^tests/functional/fetchGitVerification\.sh$''
|
||||
''^tests/functional/fetchMercurial\.sh$''
|
||||
''^tests/functional/fixed\.builder1\.sh$''
|
||||
''^tests/functional/fixed\.builder2\.sh$''
|
||||
''^tests/functional/fixed\.sh$''
|
||||
''^tests/functional/flakes/absolute-paths\.sh$''
|
||||
''^tests/functional/flakes/check\.sh$''
|
||||
''^tests/functional/flakes/config\.sh$''
|
||||
''^tests/functional/flakes/flakes\.sh$''
|
||||
''^tests/functional/flakes/follow-paths\.sh$''
|
||||
''^tests/functional/flakes/prefetch\.sh$''
|
||||
''^tests/functional/flakes/run\.sh$''
|
||||
''^tests/functional/flakes/show\.sh$''
|
||||
|
|
@ -214,10 +192,6 @@
|
|||
''^tests/functional/user-envs\.sh$''
|
||||
''^tests/functional/why-depends\.sh$''
|
||||
|
||||
# Shellcheck doesn't support fish or zsh shell syntax
|
||||
''^misc/fish/completion\.fish$''
|
||||
''^misc/zsh/completion\.zsh$''
|
||||
|
||||
# Content-addressed test files that use recursive-*looking* sourcing
|
||||
# (cd .. && source <self>), causing shellcheck to loop
|
||||
# They're small wrapper scripts with not a lot going on
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
# shellcheck disable=all
|
||||
function _nix_complete
|
||||
# Get the current command up to a cursor.
|
||||
# - Behaves correctly even with pipes and nested in commands like env.
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
# shellcheck disable=all
|
||||
#compdef nix
|
||||
|
||||
function _nix() {
|
||||
|
|
|
|||
|
|
@ -760,7 +760,7 @@ void NixRepl::loadFlake(const std::string & flakeRefS)
|
|||
|
||||
void NixRepl::initEnv()
|
||||
{
|
||||
env = &state->allocEnv(envSize);
|
||||
env = &state->mem.allocEnv(envSize);
|
||||
env->up = &state->baseEnv;
|
||||
displ = 0;
|
||||
staticEnv->vars.clear();
|
||||
|
|
|
|||
|
|
@ -679,7 +679,7 @@ nix_err nix_bindings_builder_insert(nix_c_context * context, BindingsBuilder * b
|
|||
context->last_err_code = NIX_OK;
|
||||
try {
|
||||
auto & v = check_value_not_null(value);
|
||||
nix::Symbol s = bb->builder.state.get().symbols.create(name);
|
||||
nix::Symbol s = bb->builder.symbols.get().create(name);
|
||||
bb->builder.insert(s, &v);
|
||||
}
|
||||
NIXC_CATCH_ERRS
|
||||
|
|
|
|||
|
|
@ -10,27 +10,27 @@ Bindings Bindings::emptyBindings;
|
|||
/* Allocate a new array of attributes for an attribute set with a specific
|
||||
capacity. The space is implicitly reserved after the Bindings
|
||||
structure. */
|
||||
Bindings * EvalState::allocBindings(size_t capacity)
|
||||
Bindings * EvalMemory::allocBindings(size_t capacity)
|
||||
{
|
||||
if (capacity == 0)
|
||||
return &Bindings::emptyBindings;
|
||||
if (capacity > std::numeric_limits<Bindings::size_type>::max())
|
||||
throw Error("attribute set of size %d is too big", capacity);
|
||||
nrAttrsets++;
|
||||
nrAttrsInAttrsets += capacity;
|
||||
stats.nrAttrsets++;
|
||||
stats.nrAttrsInAttrsets += capacity;
|
||||
return new (allocBytes(sizeof(Bindings) + sizeof(Attr) * capacity)) Bindings();
|
||||
}
|
||||
|
||||
Value & BindingsBuilder::alloc(Symbol name, PosIdx pos)
|
||||
{
|
||||
auto value = state.get().allocValue();
|
||||
auto value = mem.get().allocValue();
|
||||
bindings->push_back(Attr(name, value, pos));
|
||||
return *value;
|
||||
}
|
||||
|
||||
Value & BindingsBuilder::alloc(std::string_view name, PosIdx pos)
|
||||
{
|
||||
return alloc(state.get().symbols.create(name), pos);
|
||||
return alloc(symbols.get().create(name), pos);
|
||||
}
|
||||
|
||||
void Bindings::sort()
|
||||
|
|
|
|||
|
|
@ -194,6 +194,15 @@ static Symbol getName(const AttrName & name, EvalState & state, Env & env)
|
|||
|
||||
static constexpr size_t BASE_ENV_SIZE = 128;
|
||||
|
||||
EvalMemory::EvalMemory()
|
||||
#if NIX_USE_BOEHMGC
|
||||
: valueAllocCache(std::allocate_shared<void *>(traceable_allocator<void *>(), nullptr))
|
||||
, env1AllocCache(std::allocate_shared<void *>(traceable_allocator<void *>(), nullptr))
|
||||
#endif
|
||||
{
|
||||
assertGCInitialized();
|
||||
}
|
||||
|
||||
EvalState::EvalState(
|
||||
const LookupPath & lookupPathFromArguments,
|
||||
ref<Store> store,
|
||||
|
|
@ -267,12 +276,10 @@ EvalState::EvalState(
|
|||
, fileEvalCache(make_ref<decltype(fileEvalCache)::element_type>())
|
||||
, regexCache(makeRegexCache())
|
||||
#if NIX_USE_BOEHMGC
|
||||
, valueAllocCache(std::allocate_shared<void *>(traceable_allocator<void *>(), nullptr))
|
||||
, env1AllocCache(std::allocate_shared<void *>(traceable_allocator<void *>(), nullptr))
|
||||
, baseEnvP(std::allocate_shared<Env *>(traceable_allocator<Env *>(), &allocEnv(BASE_ENV_SIZE)))
|
||||
, baseEnvP(std::allocate_shared<Env *>(traceable_allocator<Env *>(), &mem.allocEnv(BASE_ENV_SIZE)))
|
||||
, baseEnv(**baseEnvP)
|
||||
#else
|
||||
, baseEnv(allocEnv(BASE_ENV_SIZE))
|
||||
, baseEnv(mem.allocEnv(BASE_ENV_SIZE))
|
||||
#endif
|
||||
, staticBaseEnv{std::make_shared<StaticEnv>(nullptr, nullptr)}
|
||||
{
|
||||
|
|
@ -281,8 +288,6 @@ EvalState::EvalState(
|
|||
|
||||
countCalls = getEnv("NIX_COUNT_CALLS").value_or("0") != "0";
|
||||
|
||||
assertGCInitialized();
|
||||
|
||||
static_assert(sizeof(Env) <= 16, "environment must be <= 16 bytes");
|
||||
static_assert(sizeof(Counter) == 64, "counters must be 64 bytes");
|
||||
|
||||
|
|
@ -878,11 +883,10 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval)
|
|||
}
|
||||
}
|
||||
|
||||
ListBuilder::ListBuilder(EvalState & state, size_t size)
|
||||
ListBuilder::ListBuilder(size_t size)
|
||||
: size(size)
|
||||
, elems(size <= 2 ? inlineElems : (Value **) allocBytes(size * sizeof(Value *)))
|
||||
{
|
||||
state.nrListElems += size;
|
||||
}
|
||||
|
||||
Value * EvalState::getBool(bool b)
|
||||
|
|
@ -1176,7 +1180,7 @@ void ExprPath::eval(EvalState & state, Env & env, Value & v)
|
|||
|
||||
Env * ExprAttrs::buildInheritFromEnv(EvalState & state, Env & up)
|
||||
{
|
||||
Env & inheritEnv = state.allocEnv(inheritFromExprs->size());
|
||||
Env & inheritEnv = state.mem.allocEnv(inheritFromExprs->size());
|
||||
inheritEnv.up = &up;
|
||||
|
||||
Displacement displ = 0;
|
||||
|
|
@ -1195,7 +1199,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
|||
if (recursive) {
|
||||
/* Create a new environment that contains the attributes in
|
||||
this `rec'. */
|
||||
Env & env2(state.allocEnv(attrs.size()));
|
||||
Env & env2(state.mem.allocEnv(attrs.size()));
|
||||
env2.up = &env;
|
||||
dynamicEnv = &env2;
|
||||
Env * inheritEnv = inheritFromExprs ? buildInheritFromEnv(state, env2) : nullptr;
|
||||
|
|
@ -1287,7 +1291,7 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v)
|
|||
{
|
||||
/* Create a new environment that contains the attributes in this
|
||||
`let'. */
|
||||
Env & env2(state.allocEnv(attrs->attrs.size()));
|
||||
Env & env2(state.mem.allocEnv(attrs->attrs.size()));
|
||||
env2.up = &env;
|
||||
|
||||
Env * inheritEnv = attrs->inheritFromExprs ? attrs->buildInheritFromEnv(state, env2) : nullptr;
|
||||
|
|
@ -1493,7 +1497,7 @@ void EvalState::callFunction(Value & fun, std::span<Value *> args, Value & vRes,
|
|||
ExprLambda & lambda(*vCur.lambda().fun);
|
||||
|
||||
auto size = (!lambda.arg ? 0 : 1) + (lambda.hasFormals() ? lambda.formals->formals.size() : 0);
|
||||
Env & env2(allocEnv(size));
|
||||
Env & env2(mem.allocEnv(size));
|
||||
env2.up = vCur.lambda().env;
|
||||
|
||||
Displacement displ = 0;
|
||||
|
|
@ -1782,7 +1786,7 @@ https://nix.dev/manual/nix/stable/language/syntax.html#functions.)",
|
|||
|
||||
void ExprWith::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
Env & env2(state.allocEnv(1));
|
||||
Env & env2(state.mem.allocEnv(1));
|
||||
env2.up = &env;
|
||||
env2.values[0] = attrs->maybeThunk(state, env);
|
||||
|
||||
|
|
@ -2909,10 +2913,12 @@ void EvalState::printStatistics()
|
|||
std::chrono::microseconds cpuTimeDuration = getCpuUserTime();
|
||||
float cpuTime = std::chrono::duration_cast<std::chrono::duration<float>>(cpuTimeDuration).count();
|
||||
|
||||
uint64_t bEnvs = nrEnvs * sizeof(Env) + nrValuesInEnvs * sizeof(Value *);
|
||||
uint64_t bLists = nrListElems * sizeof(Value *);
|
||||
uint64_t bValues = nrValues * sizeof(Value);
|
||||
uint64_t bAttrsets = nrAttrsets * sizeof(Bindings) + nrAttrsInAttrsets * sizeof(Attr);
|
||||
auto & memstats = mem.getStats();
|
||||
|
||||
uint64_t bEnvs = memstats.nrEnvs * sizeof(Env) + memstats.nrValuesInEnvs * sizeof(Value *);
|
||||
uint64_t bLists = memstats.nrListElems * sizeof(Value *);
|
||||
uint64_t bValues = memstats.nrValues * sizeof(Value);
|
||||
uint64_t bAttrsets = memstats.nrAttrsets * sizeof(Bindings) + memstats.nrAttrsInAttrsets * sizeof(Attr);
|
||||
|
||||
#if NIX_USE_BOEHMGC
|
||||
GC_word heapSize, totalBytes;
|
||||
|
|
@ -2938,18 +2944,18 @@ void EvalState::printStatistics()
|
|||
#endif
|
||||
};
|
||||
topObj["envs"] = {
|
||||
{"number", nrEnvs.load()},
|
||||
{"elements", nrValuesInEnvs.load()},
|
||||
{"number", memstats.nrEnvs.load()},
|
||||
{"elements", memstats.nrValuesInEnvs.load()},
|
||||
{"bytes", bEnvs},
|
||||
};
|
||||
topObj["nrExprs"] = Expr::nrExprs.load();
|
||||
topObj["list"] = {
|
||||
{"elements", nrListElems.load()},
|
||||
{"elements", memstats.nrListElems.load()},
|
||||
{"bytes", bLists},
|
||||
{"concats", nrListConcats.load()},
|
||||
};
|
||||
topObj["values"] = {
|
||||
{"number", nrValues.load()},
|
||||
{"number", memstats.nrValues.load()},
|
||||
{"bytes", bValues},
|
||||
};
|
||||
topObj["symbols"] = {
|
||||
|
|
@ -2957,9 +2963,9 @@ void EvalState::printStatistics()
|
|||
{"bytes", symbols.totalSize()},
|
||||
};
|
||||
topObj["sets"] = {
|
||||
{"number", nrAttrsets.load()},
|
||||
{"number", memstats.nrAttrsets.load()},
|
||||
{"bytes", bAttrsets},
|
||||
{"elements", nrAttrsInAttrsets.load()},
|
||||
{"elements", memstats.nrAttrsInAttrsets.load()},
|
||||
};
|
||||
topObj["sizes"] = {
|
||||
{"Env", sizeof(Env)},
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
namespace nix {
|
||||
|
||||
class EvalState;
|
||||
class EvalMemory;
|
||||
struct Value;
|
||||
|
||||
/**
|
||||
|
|
@ -426,7 +426,7 @@ public:
|
|||
return res;
|
||||
}
|
||||
|
||||
friend class EvalState;
|
||||
friend class EvalMemory;
|
||||
};
|
||||
|
||||
static_assert(std::forward_iterator<Bindings::iterator>);
|
||||
|
|
@ -448,12 +448,13 @@ private:
|
|||
Bindings * bindings;
|
||||
Bindings::size_type capacity_;
|
||||
|
||||
friend class EvalState;
|
||||
friend class EvalMemory;
|
||||
|
||||
BindingsBuilder(EvalState & state, Bindings * bindings, size_type capacity)
|
||||
BindingsBuilder(EvalMemory & mem, SymbolTable & symbols, Bindings * bindings, size_type capacity)
|
||||
: bindings(bindings)
|
||||
, capacity_(capacity)
|
||||
, state(state)
|
||||
, mem(mem)
|
||||
, symbols(symbols)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -471,7 +472,8 @@ private:
|
|||
}
|
||||
|
||||
public:
|
||||
std::reference_wrapper<EvalState> state;
|
||||
std::reference_wrapper<EvalMemory> mem;
|
||||
std::reference_wrapper<SymbolTable> symbols;
|
||||
|
||||
void insert(Symbol name, Value * value, PosIdx pos = noPos)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ inline void * allocBytes(size_t n)
|
|||
}
|
||||
|
||||
[[gnu::always_inline]]
|
||||
Value * EvalState::allocValue()
|
||||
Value * EvalMemory::allocValue()
|
||||
{
|
||||
#if NIX_USE_BOEHMGC
|
||||
/* We use the boehm batch allocator to speed up allocations of Values (of which there are many).
|
||||
|
|
@ -48,15 +48,15 @@ Value * EvalState::allocValue()
|
|||
void * p = allocBytes(sizeof(Value));
|
||||
#endif
|
||||
|
||||
nrValues++;
|
||||
stats.nrValues++;
|
||||
return (Value *) p;
|
||||
}
|
||||
|
||||
[[gnu::always_inline]]
|
||||
Env & EvalState::allocEnv(size_t size)
|
||||
Env & EvalMemory::allocEnv(size_t size)
|
||||
{
|
||||
nrEnvs++;
|
||||
nrValuesInEnvs += size;
|
||||
stats.nrEnvs++;
|
||||
stats.nrValuesInEnvs += size;
|
||||
|
||||
Env * env;
|
||||
|
||||
|
|
|
|||
|
|
@ -303,6 +303,63 @@ struct StaticEvalSymbols
|
|||
}
|
||||
};
|
||||
|
||||
class EvalMemory
|
||||
{
|
||||
#if NIX_USE_BOEHMGC
|
||||
/**
|
||||
* Allocation cache for GC'd Value objects.
|
||||
*/
|
||||
std::shared_ptr<void *> valueAllocCache;
|
||||
|
||||
/**
|
||||
* Allocation cache for size-1 Env objects.
|
||||
*/
|
||||
std::shared_ptr<void *> env1AllocCache;
|
||||
#endif
|
||||
|
||||
public:
|
||||
struct Statistics
|
||||
{
|
||||
Counter nrEnvs;
|
||||
Counter nrValuesInEnvs;
|
||||
Counter nrValues;
|
||||
Counter nrAttrsets;
|
||||
Counter nrAttrsInAttrsets;
|
||||
Counter nrListElems;
|
||||
};
|
||||
|
||||
EvalMemory();
|
||||
|
||||
EvalMemory(const EvalMemory &) = delete;
|
||||
EvalMemory(EvalMemory &&) = delete;
|
||||
EvalMemory & operator=(const EvalMemory &) = delete;
|
||||
EvalMemory & operator=(EvalMemory &&) = delete;
|
||||
|
||||
inline Value * allocValue();
|
||||
inline Env & allocEnv(size_t size);
|
||||
|
||||
Bindings * allocBindings(size_t capacity);
|
||||
|
||||
BindingsBuilder buildBindings(SymbolTable & symbols, size_t capacity)
|
||||
{
|
||||
return BindingsBuilder(*this, symbols, allocBindings(capacity), capacity);
|
||||
}
|
||||
|
||||
ListBuilder buildList(size_t size)
|
||||
{
|
||||
stats.nrListElems += size;
|
||||
return ListBuilder(size);
|
||||
}
|
||||
|
||||
const Statistics & getStats() const &
|
||||
{
|
||||
return stats;
|
||||
}
|
||||
|
||||
private:
|
||||
Statistics stats;
|
||||
};
|
||||
|
||||
class EvalState : public std::enable_shared_from_this<EvalState>
|
||||
{
|
||||
public:
|
||||
|
|
@ -313,6 +370,8 @@ public:
|
|||
SymbolTable symbols;
|
||||
PosTable positions;
|
||||
|
||||
EvalMemory mem;
|
||||
|
||||
/**
|
||||
* If set, force copying files to the Nix store even if they
|
||||
* already exist there.
|
||||
|
|
@ -442,18 +501,6 @@ private:
|
|||
*/
|
||||
std::shared_ptr<RegexCache> regexCache;
|
||||
|
||||
#if NIX_USE_BOEHMGC
|
||||
/**
|
||||
* Allocation cache for GC'd Value objects.
|
||||
*/
|
||||
std::shared_ptr<void *> valueAllocCache;
|
||||
|
||||
/**
|
||||
* Allocation cache for size-1 Env objects.
|
||||
*/
|
||||
std::shared_ptr<void *> env1AllocCache;
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
EvalState(
|
||||
|
|
@ -464,6 +511,15 @@ public:
|
|||
std::shared_ptr<Store> buildStore = nullptr);
|
||||
~EvalState();
|
||||
|
||||
/**
|
||||
* A wrapper around EvalMemory::allocValue() to avoid code churn when it
|
||||
* was introduced.
|
||||
*/
|
||||
inline Value * allocValue()
|
||||
{
|
||||
return mem.allocValue();
|
||||
}
|
||||
|
||||
LookupPath getLookupPath()
|
||||
{
|
||||
return lookupPath;
|
||||
|
|
@ -840,22 +896,14 @@ public:
|
|||
*/
|
||||
void autoCallFunction(const Bindings & args, Value & fun, Value & res);
|
||||
|
||||
/**
|
||||
* Allocation primitives.
|
||||
*/
|
||||
inline Value * allocValue();
|
||||
inline Env & allocEnv(size_t size);
|
||||
|
||||
Bindings * allocBindings(size_t capacity);
|
||||
|
||||
BindingsBuilder buildBindings(size_t capacity)
|
||||
{
|
||||
return BindingsBuilder(*this, allocBindings(capacity), capacity);
|
||||
return mem.buildBindings(symbols, capacity);
|
||||
}
|
||||
|
||||
ListBuilder buildList(size_t size)
|
||||
{
|
||||
return ListBuilder(*this, size);
|
||||
return mem.buildList(size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -972,13 +1020,7 @@ private:
|
|||
*/
|
||||
std::string mkSingleDerivedPathStringRaw(const SingleDerivedPath & p);
|
||||
|
||||
Counter nrEnvs;
|
||||
Counter nrValuesInEnvs;
|
||||
Counter nrValues;
|
||||
Counter nrListElems;
|
||||
Counter nrLookups;
|
||||
Counter nrAttrsets;
|
||||
Counter nrAttrsInAttrsets;
|
||||
Counter nrAvoided;
|
||||
Counter nrOpUpdates;
|
||||
Counter nrOpUpdateValuesCopied;
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ class ListBuilder
|
|||
Value * inlineElems[2] = {nullptr, nullptr};
|
||||
public:
|
||||
Value ** elems;
|
||||
ListBuilder(EvalState & state, size_t size);
|
||||
ListBuilder(size_t size);
|
||||
|
||||
// NOTE: Can be noexcept because we are just copying integral values and
|
||||
// raw pointers.
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ static void scopedImport(EvalState & state, const PosIdx pos, SourcePath & path,
|
|||
{
|
||||
state.forceAttrs(*vScope, pos, "while evaluating the first argument passed to builtins.scopedImport");
|
||||
|
||||
Env * env = &state.allocEnv(vScope->attrs()->size());
|
||||
Env * env = &state.mem.allocEnv(vScope->attrs()->size());
|
||||
env->up = &state.baseEnv;
|
||||
|
||||
auto staticEnv = std::make_shared<StaticEnv>(nullptr, state.staticBaseEnv, vScope->attrs()->size());
|
||||
|
|
@ -3161,7 +3161,7 @@ static void prim_listToAttrs(EvalState & state, const PosIdx pos, Value ** args,
|
|||
// Step 1. Sort the name-value attrsets in place using the memory we allocate for the result
|
||||
auto listView = args[0]->listView();
|
||||
size_t listSize = listView.size();
|
||||
auto & bindings = *state.allocBindings(listSize);
|
||||
auto & bindings = *state.mem.allocBindings(listSize);
|
||||
using ElemPtr = decltype(&bindings[0].value);
|
||||
|
||||
for (const auto & [n, v2] : enumerate(listView)) {
|
||||
|
|
|
|||
|
|
@ -226,8 +226,8 @@ static void showHelp(std::vector<std::string> subcommand, NixArgs & toplevel)
|
|||
|
||||
auto mdName = subcommand.empty() ? "nix" : fmt("nix3-%s", concatStringsSep("-", subcommand));
|
||||
|
||||
evalSettings.restrictEval = false;
|
||||
evalSettings.pureEval = false;
|
||||
evalSettings.restrictEval = true;
|
||||
evalSettings.pureEval = true;
|
||||
EvalState state({}, openStore("dummy://"), fetchSettings, evalSettings);
|
||||
|
||||
auto vGenerateManpage = state.allocValue();
|
||||
|
|
|
|||
|
|
@ -8,19 +8,18 @@ needLocalStore "--dump-db requires a local store"
|
|||
|
||||
clearStore
|
||||
|
||||
path=$(nix-build dependencies.nix -o $TEST_ROOT/result)
|
||||
nix-build dependencies.nix -o "$TEST_ROOT"/result
|
||||
deps="$(nix-store -qR "$TEST_ROOT"/result)"
|
||||
|
||||
deps="$(nix-store -qR $TEST_ROOT/result)"
|
||||
nix-store --dump-db > "$TEST_ROOT"/dump
|
||||
|
||||
nix-store --dump-db > $TEST_ROOT/dump
|
||||
rm -rf "$NIX_STATE_DIR"/db
|
||||
|
||||
rm -rf $NIX_STATE_DIR/db
|
||||
nix-store --load-db < "$TEST_ROOT"/dump
|
||||
|
||||
nix-store --load-db < $TEST_ROOT/dump
|
||||
|
||||
deps2="$(nix-store -qR $TEST_ROOT/result)"
|
||||
deps2="$(nix-store -qR "$TEST_ROOT"/result)"
|
||||
|
||||
[ "$deps" = "$deps2" ];
|
||||
|
||||
nix-store --dump-db > $TEST_ROOT/dump2
|
||||
cmp $TEST_ROOT/dump $TEST_ROOT/dump2
|
||||
nix-store --dump-db > "$TEST_ROOT"/dump2
|
||||
cmp "$TEST_ROOT"/dump "$TEST_ROOT"/dump2
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
# shellcheck shell=bash
|
||||
# Purposely bypassing our usual common for this subgroup
|
||||
source ../common.sh
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
# shellcheck shell=bash
|
||||
source common.sh
|
||||
|
||||
# FIXME
|
||||
|
|
@ -10,18 +11,18 @@ restartDaemon
|
|||
|
||||
clearStore
|
||||
|
||||
rm -f $TEST_ROOT/result
|
||||
rm -f "$TEST_ROOT"/result
|
||||
|
||||
EXTRA_PATH=$(dirname $(type -p nix)):$(dirname $(type -p jq))
|
||||
EXTRA_PATH=$(dirname "$(type -p nix)"):$(dirname "$(type -p jq)")
|
||||
export EXTRA_PATH
|
||||
|
||||
# Will produce a drv
|
||||
metaDrv=$(nix-instantiate ./recursive-mod-json.nix)
|
||||
|
||||
# computed "dynamic" derivation
|
||||
drv=$(nix-store -r $metaDrv)
|
||||
drv=$(nix-store -r "$metaDrv")
|
||||
|
||||
# build that dyn drv
|
||||
res=$(nix-store -r $drv)
|
||||
res=$(nix-store -r "$drv")
|
||||
|
||||
grep 'I am alive!' $res/hello
|
||||
grep 'I am alive!' "$res"/hello
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ TODO_NixOS
|
|||
|
||||
# Using `--eval-store` with the daemon will eventually copy everything
|
||||
# to the build store, invalidating most of the tests here
|
||||
# shellcheck disable=SC1111
|
||||
needLocalStore "“--eval-store” doesn't achieve much with the daemon"
|
||||
|
||||
eval_store=$TEST_ROOT/eval-store
|
||||
|
|
@ -15,7 +16,7 @@ rm -rf "$eval_store"
|
|||
|
||||
nix build -f dependencies.nix --eval-store "$eval_store" -o "$TEST_ROOT/result"
|
||||
[[ -e $TEST_ROOT/result/foobar ]]
|
||||
if [[ ! -n "${NIX_TESTS_CA_BY_DEFAULT:-}" ]]; then
|
||||
if [[ -z "${NIX_TESTS_CA_BY_DEFAULT:-}" ]]; then
|
||||
# Resolved CA derivations are written to store for building
|
||||
#
|
||||
# TODO when we something more systematic
|
||||
|
|
@ -23,35 +24,35 @@ if [[ ! -n "${NIX_TESTS_CA_BY_DEFAULT:-}" ]]; then
|
|||
# between scratch storage for building and the final destination
|
||||
# store, we'll be able to make this unconditional again -- resolved
|
||||
# derivations should only appear in the scratch store.
|
||||
(! ls $NIX_STORE_DIR/*.drv)
|
||||
(! ls "$NIX_STORE_DIR"/*.drv)
|
||||
fi
|
||||
ls $eval_store/nix/store/*.drv
|
||||
ls "$eval_store"/nix/store/*.drv
|
||||
|
||||
clearStore
|
||||
rm -rf "$eval_store"
|
||||
|
||||
nix-instantiate dependencies.nix --eval-store "$eval_store"
|
||||
(! ls $NIX_STORE_DIR/*.drv)
|
||||
ls $eval_store/nix/store/*.drv
|
||||
(! ls "$NIX_STORE_DIR"/*.drv)
|
||||
ls "$eval_store"/nix/store/*.drv
|
||||
|
||||
clearStore
|
||||
rm -rf "$eval_store"
|
||||
|
||||
nix-build dependencies.nix --eval-store "$eval_store" -o "$TEST_ROOT/result"
|
||||
[[ -e $TEST_ROOT/result/foobar ]]
|
||||
if [[ ! -n "${NIX_TESTS_CA_BY_DEFAULT:-}" ]]; then
|
||||
if [[ -z "${NIX_TESTS_CA_BY_DEFAULT:-}" ]]; then
|
||||
# See above
|
||||
(! ls $NIX_STORE_DIR/*.drv)
|
||||
(! ls "$NIX_STORE_DIR"/*.drv)
|
||||
fi
|
||||
ls $eval_store/nix/store/*.drv
|
||||
ls "$eval_store"/nix/store/*.drv
|
||||
|
||||
clearStore
|
||||
rm -rf "$eval_store"
|
||||
|
||||
# Confirm that import-from-derivation builds on the build store
|
||||
[[ $(nix eval --eval-store "$eval_store?require-sigs=false" --impure --raw --file ./ifd.nix) = hi ]]
|
||||
ls $NIX_STORE_DIR/*dependencies-top/foobar
|
||||
(! ls $eval_store/nix/store/*dependencies-top/foobar)
|
||||
ls "$NIX_STORE_DIR"/*dependencies-top/foobar
|
||||
(! ls "$eval_store"/nix/store/*dependencies-top/foobar)
|
||||
|
||||
# Can't write .drv by default
|
||||
(! nix-instantiate dependencies.nix --eval-store "dummy://")
|
||||
|
|
|
|||
|
|
@ -8,27 +8,29 @@ clearStore
|
|||
clearProfiles
|
||||
|
||||
checkRef() {
|
||||
nix-store -q --references $TEST_ROOT/result | grepQuiet "$1"'$' || fail "missing reference $1"
|
||||
nix-store -q --references "$TEST_ROOT"/result | grepQuiet "$1"'$' || fail "missing reference $1"
|
||||
}
|
||||
|
||||
# Test the export of the runtime dependency graph.
|
||||
|
||||
outPath=$(nix-build ./export-graph.nix -A 'foo."bar.runtimeGraph"' -o $TEST_ROOT/result)
|
||||
outPath=$(nix-build ./export-graph.nix -A 'foo."bar.runtimeGraph"' -o "$TEST_ROOT"/result)
|
||||
|
||||
test $(nix-store -q --references $TEST_ROOT/result | wc -l) = 3 || fail "bad nr of references"
|
||||
test "$(nix-store -q --references "$TEST_ROOT"/result | wc -l)" = 3 || fail "bad nr of references"
|
||||
|
||||
checkRef input-2
|
||||
for i in $(cat $outPath); do checkRef $i; done
|
||||
# shellcheck disable=SC2013
|
||||
for i in $(cat "$outPath"); do checkRef "$i"; done
|
||||
|
||||
# Test the export of the build-time dependency graph.
|
||||
|
||||
nix-store --gc # should force rebuild of input-1
|
||||
|
||||
outPath=$(nix-build ./export-graph.nix -A 'foo."bar.buildGraph"' -o $TEST_ROOT/result)
|
||||
outPath=$(nix-build ./export-graph.nix -A 'foo."bar.buildGraph"' -o "$TEST_ROOT"/result)
|
||||
|
||||
checkRef input-1
|
||||
checkRef input-1.drv
|
||||
checkRef input-2
|
||||
checkRef input-2.drv
|
||||
|
||||
for i in $(cat $outPath); do checkRef $i; done
|
||||
# shellcheck disable=SC2013
|
||||
for i in $(cat "$outPath"); do checkRef "$i"; done
|
||||
|
|
|
|||
|
|
@ -8,11 +8,12 @@ clearStore
|
|||
|
||||
outPath=$(nix-build dependencies.nix --no-out-link)
|
||||
|
||||
nix-store --export $outPath > $TEST_ROOT/exp
|
||||
nix-store --export "$outPath" > "$TEST_ROOT"/exp
|
||||
|
||||
nix-store --export $(nix-store -qR $outPath) > $TEST_ROOT/exp_all
|
||||
# shellcheck disable=SC2046
|
||||
nix-store --export $(nix-store -qR "$outPath") > "$TEST_ROOT"/exp_all
|
||||
|
||||
if nix-store --export $outPath >/dev/full ; then
|
||||
if nix-store --export "$outPath" >/dev/full ; then
|
||||
echo "exporting to a bad file descriptor should fail"
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -20,7 +21,7 @@ fi
|
|||
|
||||
clearStore
|
||||
|
||||
if nix-store --import < $TEST_ROOT/exp; then
|
||||
if nix-store --import < "$TEST_ROOT"/exp; then
|
||||
echo "importing a non-closure should fail"
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -28,13 +29,14 @@ fi
|
|||
|
||||
clearStore
|
||||
|
||||
nix-store --import < $TEST_ROOT/exp_all
|
||||
nix-store --import < "$TEST_ROOT"/exp_all
|
||||
|
||||
nix-store --export $(nix-store -qR $outPath) > $TEST_ROOT/exp_all2
|
||||
# shellcheck disable=SC2046
|
||||
nix-store --export $(nix-store -qR "$outPath") > "$TEST_ROOT"/exp_all2
|
||||
|
||||
|
||||
clearStore
|
||||
|
||||
# Regression test: the derivers in exp_all2 are empty, which shouldn't
|
||||
# cause a failure.
|
||||
nix-store --import < $TEST_ROOT/exp_all2
|
||||
nix-store --import < "$TEST_ROOT"/exp_all2
|
||||
|
|
|
|||
|
|
@ -17,14 +17,14 @@ requireDaemonNewerThan "2.16.0pre20230524"
|
|||
|
||||
# Initialize binary cache.
|
||||
nonCaPath=$(nix build --json --file ./dependencies.nix --no-link | jq -r .[].outputs.out)
|
||||
caPath=$(nix store make-content-addressed --json $nonCaPath | jq -r '.rewrites | map(.) | .[]')
|
||||
nix copy --to file://$cacheDir $nonCaPath
|
||||
caPath=$(nix store make-content-addressed --json "$nonCaPath" | jq -r '.rewrites | map(.) | .[]')
|
||||
nix copy --to file://"$cacheDir" "$nonCaPath"
|
||||
|
||||
# Test basic fetchClosure rewriting from non-CA to CA.
|
||||
clearStore
|
||||
|
||||
[ ! -e $nonCaPath ]
|
||||
[ ! -e $caPath ]
|
||||
[ ! -e "$nonCaPath" ]
|
||||
[ ! -e "$caPath" ]
|
||||
|
||||
[[ $(nix eval -v --raw --expr "
|
||||
builtins.fetchClosure {
|
||||
|
|
@ -32,10 +32,10 @@ clearStore
|
|||
fromPath = $nonCaPath;
|
||||
toPath = $caPath;
|
||||
}
|
||||
") = $caPath ]]
|
||||
") = "$caPath" ]]
|
||||
|
||||
[ ! -e $nonCaPath ]
|
||||
[ -e $caPath ]
|
||||
[ ! -e "$nonCaPath" ]
|
||||
[ -e "$caPath" ]
|
||||
|
||||
clearStore
|
||||
|
||||
|
|
@ -55,7 +55,7 @@ if [[ "$NIX_REMOTE" != "daemon" ]]; then
|
|||
# TODO: Should the closure be rejected, despite single user mode?
|
||||
# [ ! -e $nonCaPath ]
|
||||
|
||||
[ ! -e $caPath ]
|
||||
[ ! -e "$caPath" ]
|
||||
|
||||
# We can use non-CA paths when we ask explicitly.
|
||||
[[ $(nix eval --raw --no-require-sigs --expr "
|
||||
|
|
@ -64,15 +64,15 @@ if [[ "$NIX_REMOTE" != "daemon" ]]; then
|
|||
fromPath = $nonCaPath;
|
||||
inputAddressed = true;
|
||||
}
|
||||
") = $nonCaPath ]]
|
||||
") = "$nonCaPath" ]]
|
||||
|
||||
[ -e $nonCaPath ]
|
||||
[ ! -e $caPath ]
|
||||
[ -e "$nonCaPath" ]
|
||||
[ ! -e "$caPath" ]
|
||||
|
||||
|
||||
fi
|
||||
|
||||
[ ! -e $caPath ]
|
||||
[ ! -e "$caPath" ]
|
||||
|
||||
# 'toPath' set to empty string should fail but print the expected path.
|
||||
expectStderr 1 nix eval -v --json --expr "
|
||||
|
|
@ -84,39 +84,41 @@ expectStderr 1 nix eval -v --json --expr "
|
|||
" | grep "error: rewriting.*$nonCaPath.*yielded.*$caPath"
|
||||
|
||||
# If fromPath is CA, then toPath isn't needed.
|
||||
nix copy --to file://$cacheDir $caPath
|
||||
nix copy --to file://"$cacheDir" "$caPath"
|
||||
|
||||
clearStore
|
||||
|
||||
[ ! -e $caPath ]
|
||||
[ ! -e "$caPath" ]
|
||||
|
||||
[[ $(nix eval -v --raw --expr "
|
||||
builtins.fetchClosure {
|
||||
fromStore = \"file://$cacheDir\";
|
||||
fromPath = $caPath;
|
||||
}
|
||||
") = $caPath ]]
|
||||
") = "$caPath" ]]
|
||||
|
||||
[ -e $caPath ]
|
||||
[ -e "$caPath" ]
|
||||
|
||||
# Check that URL query parameters aren't allowed.
|
||||
clearStore
|
||||
narCache=$TEST_ROOT/nar-cache
|
||||
rm -rf $narCache
|
||||
rm -rf "$narCache"
|
||||
(! nix eval -v --raw --expr "
|
||||
builtins.fetchClosure {
|
||||
fromStore = \"file://$cacheDir?local-nar-cache=$narCache\";
|
||||
fromPath = $caPath;
|
||||
}
|
||||
")
|
||||
(! [ -e $narCache ])
|
||||
# shellcheck disable=SC2235
|
||||
(! [ -e "$narCache" ])
|
||||
|
||||
# If toPath is specified but wrong, we check it (only) when the path is missing.
|
||||
clearStore
|
||||
|
||||
badPath=$(echo $caPath | sed -e 's!/store/................................-!/store/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-!')
|
||||
# shellcheck disable=SC2001
|
||||
badPath=$(echo "$caPath" | sed -e 's!/store/................................-!/store/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-!')
|
||||
|
||||
[ ! -e $badPath ]
|
||||
[ ! -e "$badPath" ]
|
||||
|
||||
expectStderr 1 nix eval -v --raw --expr "
|
||||
builtins.fetchClosure {
|
||||
|
|
@ -126,11 +128,11 @@ expectStderr 1 nix eval -v --raw --expr "
|
|||
}
|
||||
" | grep "error: rewriting.*$nonCaPath.*yielded.*$caPath.*while.*$badPath.*was expected"
|
||||
|
||||
[ ! -e $badPath ]
|
||||
[ ! -e "$badPath" ]
|
||||
|
||||
# We only check it when missing, as a performance optimization similar to what we do for fixed output derivations. So if it's already there, we don't check it.
|
||||
# It would be nice for this to fail, but checking it would be too(?) slow.
|
||||
[ -e $caPath ]
|
||||
[ -e "$caPath" ]
|
||||
|
||||
[[ $(nix eval -v --raw --expr "
|
||||
builtins.fetchClosure {
|
||||
|
|
@ -138,7 +140,7 @@ expectStderr 1 nix eval -v --raw --expr "
|
|||
fromPath = $badPath;
|
||||
toPath = $caPath;
|
||||
}
|
||||
") = $caPath ]]
|
||||
") = "$caPath" ]]
|
||||
|
||||
|
||||
# However, if the output address is unexpected, we can report it
|
||||
|
|
|
|||
|
|
@ -12,25 +12,25 @@ repo=$TEST_ROOT/./git
|
|||
|
||||
export _NIX_FORCE_HTTP=1
|
||||
|
||||
rm -rf $repo ${repo}-tmp $TEST_HOME/.cache/nix $TEST_ROOT/worktree $TEST_ROOT/minimal
|
||||
rm -rf "$repo" "${repo}"-tmp "$TEST_HOME"/.cache/nix "$TEST_ROOT"/worktree "$TEST_ROOT"/minimal
|
||||
|
||||
git init $repo
|
||||
git -C $repo config user.email "foobar@example.com"
|
||||
git -C $repo config user.name "Foobar"
|
||||
git init "$repo"
|
||||
git -C "$repo" config user.email "foobar@example.com"
|
||||
git -C "$repo" config user.name "Foobar"
|
||||
|
||||
echo utrecht > $repo/hello
|
||||
touch $repo/.gitignore
|
||||
git -C $repo add hello .gitignore
|
||||
git -C $repo commit -m 'Bla1'
|
||||
rev1=$(git -C $repo rev-parse HEAD)
|
||||
git -C $repo tag -a tag1 -m tag1
|
||||
echo utrecht > "$repo"/hello
|
||||
touch "$repo"/.gitignore
|
||||
git -C "$repo" add hello .gitignore
|
||||
git -C "$repo" commit -m 'Bla1'
|
||||
rev1=$(git -C "$repo" rev-parse HEAD)
|
||||
git -C "$repo" tag -a tag1 -m tag1
|
||||
|
||||
echo world > $repo/hello
|
||||
git -C $repo commit -m 'Bla2' -a
|
||||
git -C $repo worktree add $TEST_ROOT/worktree
|
||||
echo hello >> $TEST_ROOT/worktree/hello
|
||||
rev2=$(git -C $repo rev-parse HEAD)
|
||||
git -C $repo tag -a tag2 -m tag2
|
||||
echo world > "$repo"/hello
|
||||
git -C "$repo" commit -m 'Bla2' -a
|
||||
git -C "$repo" worktree add "$TEST_ROOT"/worktree
|
||||
echo hello >> "$TEST_ROOT"/worktree/hello
|
||||
rev2=$(git -C "$repo" rev-parse HEAD)
|
||||
git -C "$repo" tag -a tag2 -m tag2
|
||||
|
||||
# Check whether fetching in read-only mode works.
|
||||
nix-instantiate --eval -E "builtins.readFile ((builtins.fetchGit file://$TEST_ROOT/worktree) + \"/hello\") == \"utrecht\\n\""
|
||||
|
|
@ -40,52 +40,52 @@ unset _NIX_FORCE_HTTP
|
|||
expectStderr 0 nix eval -vvvv --impure --raw --expr "(builtins.fetchGit file://$TEST_ROOT/worktree).outPath" | grepQuiet "copying '$TEST_ROOT/worktree/' to the store"
|
||||
path0=$(nix eval --impure --raw --expr "(builtins.fetchGit file://$TEST_ROOT/worktree).outPath")
|
||||
path0_=$(nix eval --impure --raw --expr "(builtins.fetchTree { type = \"git\"; url = file://$TEST_ROOT/worktree; }).outPath")
|
||||
[[ $path0 = $path0_ ]]
|
||||
[[ $path0 = "$path0_" ]]
|
||||
path0_=$(nix eval --impure --raw --expr "(builtins.fetchTree git+file://$TEST_ROOT/worktree).outPath")
|
||||
[[ $path0 = $path0_ ]]
|
||||
[[ $path0 = "$path0_" ]]
|
||||
export _NIX_FORCE_HTTP=1
|
||||
[[ $(tail -n 1 $path0/hello) = "hello" ]]
|
||||
[[ $(tail -n 1 "$path0"/hello) = "hello" ]]
|
||||
|
||||
# Nuke the cache
|
||||
rm -rf $TEST_HOME/.cache/nix
|
||||
rm -rf "$TEST_HOME"/.cache/nix
|
||||
|
||||
# Fetch the default branch.
|
||||
path=$(nix eval --impure --raw --expr "(builtins.fetchGit file://$repo).outPath")
|
||||
[[ $(cat $path/hello) = world ]]
|
||||
[[ $(cat "$path"/hello) = world ]]
|
||||
|
||||
# Fetch again. This should be cached.
|
||||
# NOTE: This has to be done before the test case below which tries to pack-refs
|
||||
# the reason being that the lookup on the cache uses the ref-file `/refs/heads/master`
|
||||
# which does not exist after packing.
|
||||
mv $repo ${repo}-tmp
|
||||
mv "$repo" "${repo}"-tmp
|
||||
path2=$(nix eval --impure --raw --expr "(builtins.fetchGit file://$repo).outPath")
|
||||
[[ $path = $path2 ]]
|
||||
[[ $path = "$path2" ]]
|
||||
|
||||
[[ $(nix eval --impure --expr "(builtins.fetchGit file://$repo).revCount") = 2 ]]
|
||||
[[ $(nix eval --impure --raw --expr "(builtins.fetchGit file://$repo).rev") = $rev2 ]]
|
||||
[[ $(nix eval --impure --raw --expr "(builtins.fetchGit file://$repo).shortRev") = ${rev2:0:7} ]]
|
||||
[[ $(nix eval --impure --raw --expr "(builtins.fetchGit file://$repo).rev") = "$rev2" ]]
|
||||
[[ $(nix eval --impure --raw --expr "(builtins.fetchGit file://$repo).shortRev") = "${rev2:0:7}" ]]
|
||||
|
||||
# Fetching with a explicit hash should succeed.
|
||||
path2=$(nix eval --refresh --raw --expr "(builtins.fetchGit { url = file://$repo; rev = \"$rev2\"; }).outPath")
|
||||
[[ $path = $path2 ]]
|
||||
[[ $path = "$path2" ]]
|
||||
|
||||
path2=$(nix eval --refresh --raw --expr "(builtins.fetchGit { url = file://$repo; rev = \"$rev1\"; }).outPath")
|
||||
[[ $(cat $path2/hello) = utrecht ]]
|
||||
[[ $(cat "$path2"/hello) = utrecht ]]
|
||||
|
||||
mv ${repo}-tmp $repo
|
||||
mv "${repo}"-tmp "$repo"
|
||||
|
||||
# Fetch when the cache has packed-refs
|
||||
# Regression test of #8822
|
||||
git -C $TEST_HOME/.cache/nix/gitv3/*/ pack-refs --all
|
||||
git -C "$TEST_HOME"/.cache/nix/gitv3/*/ pack-refs --all
|
||||
path=$(nix eval --impure --raw --expr "(builtins.fetchGit file://$repo).outPath")
|
||||
|
||||
# Fetch a rev from another branch
|
||||
git -C $repo checkout -b devtest
|
||||
echo "different file" >> $TEST_ROOT/git/differentbranch
|
||||
git -C $repo add differentbranch
|
||||
git -C $repo commit -m 'Test2'
|
||||
git -C $repo checkout master
|
||||
devrev=$(git -C $repo rev-parse devtest)
|
||||
git -C "$repo" checkout -b devtest
|
||||
echo "different file" >> "$TEST_ROOT"/git/differentbranch
|
||||
git -C "$repo" add differentbranch
|
||||
git -C "$repo" commit -m 'Test2'
|
||||
git -C "$repo" checkout master
|
||||
devrev=$(git -C "$repo" rev-parse devtest)
|
||||
nix eval --raw --expr "builtins.fetchGit { url = file://$repo; rev = \"$devrev\"; }"
|
||||
|
||||
[[ $(nix eval --raw --expr "builtins.readFile (builtins.fetchGit { url = file://$repo; rev = \"$devrev\"; allRefs = true; } + \"/differentbranch\")") = 'different file' ]]
|
||||
|
|
@ -96,7 +96,7 @@ nix eval --raw --expr "builtins.fetchGit { url = file://$repo; rev = \"$devrev\"
|
|||
|
||||
# Fetch using an explicit revision hash.
|
||||
path2=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$repo; rev = \"$rev2\"; }).outPath")
|
||||
[[ $path = $path2 ]]
|
||||
[[ $path = "$path2" ]]
|
||||
|
||||
# In pure eval mode, fetchGit with a revision should succeed.
|
||||
[[ $(nix eval --raw --expr "builtins.readFile (fetchGit { url = file://$repo; rev = \"$rev2\"; } + \"/hello\")") = world ]]
|
||||
|
|
@ -106,23 +106,23 @@ expectStderr 1 nix eval --expr 'builtins.fetchGit "file:///foo"' | grepQuiet "'f
|
|||
|
||||
# Using a clean working tree should produce the same result.
|
||||
path2=$(nix eval --impure --raw --expr "(builtins.fetchGit $repo).outPath")
|
||||
[[ $path = $path2 ]]
|
||||
[[ $path = "$path2" ]]
|
||||
|
||||
# Using an unclean tree should yield the tracked but uncommitted changes.
|
||||
mkdir $repo/dir1 $repo/dir2
|
||||
echo foo > $repo/dir1/foo
|
||||
echo bar > $repo/bar
|
||||
echo bar > $repo/dir2/bar
|
||||
git -C $repo add dir1/foo
|
||||
git -C $repo rm hello
|
||||
mkdir "$repo"/dir1 "$repo"/dir2
|
||||
echo foo > "$repo"/dir1/foo
|
||||
echo bar > "$repo"/bar
|
||||
echo bar > "$repo"/dir2/bar
|
||||
git -C "$repo" add dir1/foo
|
||||
git -C "$repo" rm hello
|
||||
|
||||
unset _NIX_FORCE_HTTP
|
||||
path2=$(nix eval --impure --raw --expr "(builtins.fetchGit $repo).outPath")
|
||||
[ ! -e $path2/hello ]
|
||||
[ ! -e $path2/bar ]
|
||||
[ ! -e $path2/dir2/bar ]
|
||||
[ ! -e $path2/.git ]
|
||||
[[ $(cat $path2/dir1/foo) = foo ]]
|
||||
[ ! -e "$path2"/hello ]
|
||||
[ ! -e "$path2"/bar ]
|
||||
[ ! -e "$path2"/dir2/bar ]
|
||||
[ ! -e "$path2"/.git ]
|
||||
[[ $(cat "$path2"/dir1/foo) = foo ]]
|
||||
|
||||
[[ $(nix eval --impure --raw --expr "(builtins.fetchGit $repo).rev") = 0000000000000000000000000000000000000000 ]]
|
||||
[[ $(nix eval --impure --raw --expr "(builtins.fetchGit $repo).dirtyRev") = "${rev2}-dirty" ]]
|
||||
|
|
@ -130,16 +130,16 @@ path2=$(nix eval --impure --raw --expr "(builtins.fetchGit $repo).outPath")
|
|||
|
||||
# ... unless we're using an explicit ref or rev.
|
||||
path3=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = $repo; ref = \"master\"; }).outPath")
|
||||
[[ $path = $path3 ]]
|
||||
[[ $path = "$path3" ]]
|
||||
|
||||
path3=$(nix eval --raw --expr "(builtins.fetchGit { url = $repo; rev = \"$rev2\"; }).outPath")
|
||||
[[ $path = $path3 ]]
|
||||
[[ $path = "$path3" ]]
|
||||
|
||||
# Committing should not affect the store path.
|
||||
git -C $repo commit -m 'Bla3' -a
|
||||
git -C "$repo" commit -m 'Bla3' -a
|
||||
|
||||
path4=$(nix eval --impure --refresh --raw --expr "(builtins.fetchGit file://$repo).outPath")
|
||||
[[ $path2 = $path4 ]]
|
||||
[[ $path2 = "$path4" ]]
|
||||
|
||||
[[ $(nix eval --impure --expr "builtins.hasAttr \"rev\" (builtins.fetchGit $repo)") == "true" ]]
|
||||
[[ $(nix eval --impure --expr "builtins.hasAttr \"dirtyRev\" (builtins.fetchGit $repo)") == "false" ]]
|
||||
|
|
@ -148,7 +148,7 @@ path4=$(nix eval --impure --refresh --raw --expr "(builtins.fetchGit file://$rep
|
|||
expect 102 nix eval --raw --expr "(builtins.fetchGit { url = $repo; rev = \"$rev2\"; narHash = \"sha256-B5yIPHhEm0eysJKEsO7nqxprh9vcblFxpJG11gXJus1=\"; }).outPath"
|
||||
|
||||
path5=$(nix eval --raw --expr "(builtins.fetchGit { url = $repo; rev = \"$rev2\"; narHash = \"sha256-Hr8g6AqANb3xqX28eu1XnjK/3ab8Gv6TJSnkb1LezG9=\"; }).outPath")
|
||||
[[ $path = $path5 ]]
|
||||
[[ $path = "$path5" ]]
|
||||
|
||||
# Ensure that NAR hashes are checked.
|
||||
expectStderr 102 nix eval --raw --expr "(builtins.fetchGit { url = $repo; rev = \"$rev2\"; narHash = \"sha256-Hr8g6AqANb4xqX28eu1XnjK/3ab8Gv6TJSnkb1LezG9=\"; }).outPath" | grepQuiet "error: NAR hash mismatch"
|
||||
|
|
@ -157,22 +157,22 @@ expectStderr 102 nix eval --raw --expr "(builtins.fetchGit { url = $repo; rev =
|
|||
expectStderr 0 nix eval --raw --expr "(builtins.fetchGit { url = $repo; ref = \"tag2\"; narHash = \"sha256-Hr8g6AqANb3xqX28eu1XnjK/3ab8Gv6TJSnkb1LezG9=\"; }).outPath" | grepQuiet "warning: Input .* is unlocked"
|
||||
|
||||
# tarball-ttl should be ignored if we specify a rev
|
||||
echo delft > $repo/hello
|
||||
git -C $repo add hello
|
||||
git -C $repo commit -m 'Bla4'
|
||||
rev3=$(git -C $repo rev-parse HEAD)
|
||||
echo delft > "$repo"/hello
|
||||
git -C "$repo" add hello
|
||||
git -C "$repo" commit -m 'Bla4'
|
||||
rev3=$(git -C "$repo" rev-parse HEAD)
|
||||
nix eval --tarball-ttl 3600 --expr "builtins.fetchGit { url = $repo; rev = \"$rev3\"; }" >/dev/null
|
||||
|
||||
# Update 'path' to reflect latest master
|
||||
path=$(nix eval --impure --raw --expr "(builtins.fetchGit file://$repo).outPath")
|
||||
|
||||
# Check behavior when non-master branch is used
|
||||
git -C $repo checkout $rev2 -b dev
|
||||
echo dev > $repo/hello
|
||||
git -C "$repo" checkout "$rev2" -b dev
|
||||
echo dev > "$repo"/hello
|
||||
|
||||
# File URI uses dirty tree unless specified otherwise
|
||||
path2=$(nix eval --impure --raw --expr "(builtins.fetchGit file://$repo).outPath")
|
||||
[ $(cat $path2/hello) = dev ]
|
||||
[ "$(cat "$path2"/hello)" = dev ]
|
||||
|
||||
# Using local path with branch other than 'master' should work when clean or dirty
|
||||
path3=$(nix eval --impure --raw --expr "(builtins.fetchGit $repo).outPath")
|
||||
|
|
@ -181,53 +181,53 @@ path3=$(nix eval --impure --raw --expr "(builtins.fetchGit $repo).outPath")
|
|||
[[ $(nix eval --impure --raw --expr "(builtins.fetchGit $repo).shortRev") = 0000000 ]]
|
||||
# Making a dirty tree clean again and fetching it should
|
||||
# record correct revision information. See: #4140
|
||||
echo world > $repo/hello
|
||||
[[ $(nix eval --impure --raw --expr "(builtins.fetchGit $repo).rev") = $rev2 ]]
|
||||
echo world > "$repo"/hello
|
||||
[[ $(nix eval --impure --raw --expr "(builtins.fetchGit $repo).rev") = "$rev2" ]]
|
||||
|
||||
# Committing shouldn't change store path, or switch to using 'master'
|
||||
echo dev > $repo/hello
|
||||
git -C $repo commit -m 'Bla5' -a
|
||||
echo dev > "$repo"/hello
|
||||
git -C "$repo" commit -m 'Bla5' -a
|
||||
path4=$(nix eval --impure --raw --expr "(builtins.fetchGit $repo).outPath")
|
||||
[[ $(cat $path4/hello) = dev ]]
|
||||
[[ $path3 = $path4 ]]
|
||||
[[ $(cat "$path4"/hello) = dev ]]
|
||||
[[ $path3 = "$path4" ]]
|
||||
|
||||
# Using remote path with branch other than 'master' should fetch the HEAD revision.
|
||||
# (--tarball-ttl 0 to prevent using the cached repo above)
|
||||
export _NIX_FORCE_HTTP=1
|
||||
path4=$(nix eval --tarball-ttl 0 --impure --raw --expr "(builtins.fetchGit $repo).outPath")
|
||||
[[ $(cat $path4/hello) = dev ]]
|
||||
[[ $path3 = $path4 ]]
|
||||
[[ $(cat "$path4"/hello) = dev ]]
|
||||
[[ $path3 = "$path4" ]]
|
||||
unset _NIX_FORCE_HTTP
|
||||
|
||||
# Confirm same as 'dev' branch
|
||||
path5=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = $repo; ref = \"dev\"; }).outPath")
|
||||
[[ $path3 = $path5 ]]
|
||||
[[ $path3 = "$path5" ]]
|
||||
|
||||
|
||||
# Nuke the cache
|
||||
rm -rf $TEST_HOME/.cache/nix
|
||||
rm -rf "$TEST_HOME"/.cache/nix
|
||||
|
||||
# Try again. This should work.
|
||||
path5=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = $repo; ref = \"dev\"; }).outPath")
|
||||
[[ $path3 = $path5 ]]
|
||||
[[ $path3 = "$path5" ]]
|
||||
|
||||
# Fetching from a repo with only a specific revision and no branches should
|
||||
# not fall back to copying files and record correct revision information. See: #5302
|
||||
mkdir $TEST_ROOT/minimal
|
||||
git -C $TEST_ROOT/minimal init
|
||||
git -C $TEST_ROOT/minimal fetch $repo $rev2
|
||||
git -C $TEST_ROOT/minimal checkout $rev2
|
||||
[[ $(nix eval --impure --raw --expr "(builtins.fetchGit { url = $TEST_ROOT/minimal; }).rev") = $rev2 ]]
|
||||
mkdir "$TEST_ROOT"/minimal
|
||||
git -C "$TEST_ROOT"/minimal init
|
||||
git -C "$TEST_ROOT"/minimal fetch "$repo" "$rev2"
|
||||
git -C "$TEST_ROOT"/minimal checkout "$rev2"
|
||||
[[ $(nix eval --impure --raw --expr "(builtins.fetchGit { url = $TEST_ROOT/minimal; }).rev") = "$rev2" ]]
|
||||
|
||||
# Explicit ref = "HEAD" should work, and produce the same outPath as without ref
|
||||
path7=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$repo\"; ref = \"HEAD\"; }).outPath")
|
||||
path8=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$repo\"; }).outPath")
|
||||
[[ $path7 = $path8 ]]
|
||||
[[ $path7 = "$path8" ]]
|
||||
|
||||
# ref = "HEAD" should fetch the HEAD revision
|
||||
rev4=$(git -C $repo rev-parse HEAD)
|
||||
rev4=$(git -C "$repo" rev-parse HEAD)
|
||||
rev4_nix=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$repo\"; ref = \"HEAD\"; }).rev")
|
||||
[[ $rev4 = $rev4_nix ]]
|
||||
[[ $rev4 = "$rev4_nix" ]]
|
||||
|
||||
# The name argument should be handled
|
||||
path9=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$repo\"; ref = \"HEAD\"; name = \"foo\"; }).outPath")
|
||||
|
|
@ -236,33 +236,36 @@ path9=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$rep
|
|||
# Specifying a ref without a rev shouldn't pick a cached rev for a different ref
|
||||
export _NIX_FORCE_HTTP=1
|
||||
rev_tag1_nix=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$repo\"; ref = \"refs/tags/tag1\"; }).rev")
|
||||
rev_tag1=$(git -C $repo rev-parse refs/tags/tag1^{commit})
|
||||
[[ $rev_tag1_nix = $rev_tag1 ]]
|
||||
# shellcheck disable=SC1083
|
||||
rev_tag1=$(git -C "$repo" rev-parse refs/tags/tag1^{commit})
|
||||
[[ $rev_tag1_nix = "$rev_tag1" ]]
|
||||
rev_tag2_nix=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$repo\"; ref = \"refs/tags/tag2\"; }).rev")
|
||||
rev_tag2=$(git -C $repo rev-parse refs/tags/tag2^{commit})
|
||||
[[ $rev_tag2_nix = $rev_tag2 ]]
|
||||
# shellcheck disable=SC1083
|
||||
rev_tag2=$(git -C "$repo" rev-parse refs/tags/tag2^{commit})
|
||||
[[ $rev_tag2_nix = "$rev_tag2" ]]
|
||||
unset _NIX_FORCE_HTTP
|
||||
|
||||
# Ensure .gitattributes is respected
|
||||
touch $repo/not-exported-file
|
||||
touch $repo/exported-wonky
|
||||
echo "/not-exported-file export-ignore" >> $repo/.gitattributes
|
||||
echo "/exported-wonky export-ignore=wonk" >> $repo/.gitattributes
|
||||
git -C $repo add not-exported-file exported-wonky .gitattributes
|
||||
git -C $repo commit -m 'Bla6'
|
||||
rev5=$(git -C $repo rev-parse HEAD)
|
||||
touch "$repo"/not-exported-file
|
||||
touch "$repo"/exported-wonky
|
||||
echo "/not-exported-file export-ignore" >> "$repo"/.gitattributes
|
||||
echo "/exported-wonky export-ignore=wonk" >> "$repo"/.gitattributes
|
||||
git -C "$repo" add not-exported-file exported-wonky .gitattributes
|
||||
git -C "$repo" commit -m 'Bla6'
|
||||
rev5=$(git -C "$repo" rev-parse HEAD)
|
||||
path12=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$repo; rev = \"$rev5\"; }).outPath")
|
||||
[[ ! -e $path12/not-exported-file ]]
|
||||
[[ -e $path12/exported-wonky ]]
|
||||
|
||||
# should fail if there is no repo
|
||||
rm -rf $repo/.git
|
||||
rm -rf $TEST_HOME/.cache/nix
|
||||
rm -rf "$repo"/.git
|
||||
rm -rf "$TEST_HOME"/.cache/nix
|
||||
(! nix eval --impure --raw --expr "(builtins.fetchGit \"file://$repo\").outPath")
|
||||
|
||||
# should succeed for a repo without commits
|
||||
git init $repo
|
||||
git -C $repo add hello # need to add at least one file to cause the root of the repo to be visible
|
||||
git init "$repo"
|
||||
git -C "$repo" add hello # need to add at least one file to cause the root of the repo to be visible
|
||||
# shellcheck disable=SC2034
|
||||
path10=$(nix eval --impure --raw --expr "(builtins.fetchGit \"file://$repo\").outPath")
|
||||
|
||||
# should succeed for a path with a space
|
||||
|
|
@ -277,6 +280,7 @@ touch "$repo/.gitignore"
|
|||
git -C "$repo" add hello .gitignore
|
||||
git -C "$repo" commit -m 'Bla1'
|
||||
cd "$repo"
|
||||
# shellcheck disable=SC2034
|
||||
path11=$(nix eval --impure --raw --expr "(builtins.fetchGit ./.).outPath")
|
||||
|
||||
# Test a workdir with no commits.
|
||||
|
|
|
|||
|
|
@ -38,16 +38,16 @@ path=$(nix eval --raw --impure --expr "(builtins.fetchGit { url = $repo; ref = \
|
|||
# 10. They cannot contain a \.
|
||||
|
||||
valid_ref() {
|
||||
{ set +x; printf >&2 '\n>>>>>>>>>> valid_ref %s\b <<<<<<<<<<\n' $(printf %s "$1" | sed -n -e l); set -x; }
|
||||
{ set +x; printf >&2 '\n>>>>>>>>>> valid_ref %s\b <<<<<<<<<<\n' "$(printf %s "$1" | sed -n -e l)"; set -x; }
|
||||
git check-ref-format --branch "$1" >/dev/null
|
||||
git -C "$repo" branch "$1" master >/dev/null
|
||||
path1=$(nix eval --raw --impure --expr "(builtins.fetchGit { url = $repo; ref = ''$1''; }).outPath")
|
||||
[[ $path1 = $path ]]
|
||||
[[ $path1 = "$path" ]]
|
||||
git -C "$repo" branch -D "$1" >/dev/null
|
||||
}
|
||||
|
||||
invalid_ref() {
|
||||
{ set +x; printf >&2 '\n>>>>>>>>>> invalid_ref %s\b <<<<<<<<<<\n' $(printf %s "$1" | sed -n -e l); set -x; }
|
||||
{ set +x; printf >&2 '\n>>>>>>>>>> invalid_ref %s\b <<<<<<<<<<\n' "$(printf %s "$1" | sed -n -e l)"; set -x; }
|
||||
# special case for a sole @:
|
||||
# --branch @ will try to interpret @ as a branch reference and not fail. Thus we need --allow-onelevel
|
||||
if [ "$1" = "@" ]; then
|
||||
|
|
@ -68,6 +68,7 @@ valid_ref 'heads/foo@bar'
|
|||
valid_ref "$(printf 'heads/fu\303\237')"
|
||||
valid_ref 'foo-bar-baz'
|
||||
valid_ref 'branch#'
|
||||
# shellcheck disable=SC2016
|
||||
valid_ref '$1'
|
||||
valid_ref 'foo.locke'
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ clearStoreIfPossible
|
|||
rootRepo=$TEST_ROOT/gitSubmodulesRoot
|
||||
subRepo=$TEST_ROOT/gitSubmodulesSub
|
||||
|
||||
rm -rf ${rootRepo} ${subRepo} $TEST_HOME/.cache/nix
|
||||
rm -rf "${rootRepo}" "${subRepo}" "$TEST_HOME"/.cache/nix
|
||||
|
||||
# Submodules can't be fetched locally by default, which can cause
|
||||
# information leakage vulnerabilities, but for these tests our
|
||||
|
|
@ -23,35 +23,35 @@ export XDG_CONFIG_HOME=$TEST_HOME/.config
|
|||
git config --global protocol.file.allow always
|
||||
|
||||
initGitRepo() {
|
||||
git init $1
|
||||
git -C $1 config user.email "foobar@example.com"
|
||||
git -C $1 config user.name "Foobar"
|
||||
git init "$1"
|
||||
git -C "$1" config user.email "foobar@example.com"
|
||||
git -C "$1" config user.name "Foobar"
|
||||
}
|
||||
|
||||
addGitContent() {
|
||||
echo "lorem ipsum" > $1/content
|
||||
git -C $1 add content
|
||||
git -C $1 commit -m "Initial commit"
|
||||
echo "lorem ipsum" > "$1"/content
|
||||
git -C "$1" add content
|
||||
git -C "$1" commit -m "Initial commit"
|
||||
}
|
||||
|
||||
initGitRepo $subRepo
|
||||
addGitContent $subRepo
|
||||
initGitRepo "$subRepo"
|
||||
addGitContent "$subRepo"
|
||||
|
||||
initGitRepo $rootRepo
|
||||
initGitRepo "$rootRepo"
|
||||
|
||||
git -C $rootRepo submodule init
|
||||
git -C $rootRepo submodule add $subRepo sub
|
||||
git -C $rootRepo add sub
|
||||
git -C $rootRepo commit -m "Add submodule"
|
||||
git -C "$rootRepo" submodule init
|
||||
git -C "$rootRepo" submodule add "$subRepo" sub
|
||||
git -C "$rootRepo" add sub
|
||||
git -C "$rootRepo" commit -m "Add submodule"
|
||||
|
||||
rev=$(git -C $rootRepo rev-parse HEAD)
|
||||
rev=$(git -C "$rootRepo" rev-parse HEAD)
|
||||
|
||||
r1=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; }).outPath")
|
||||
r2=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; submodules = false; }).outPath")
|
||||
r3=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; submodules = true; }).outPath")
|
||||
|
||||
[[ $r1 == $r2 ]]
|
||||
[[ $r2 != $r3 ]]
|
||||
[[ $r1 == "$r2" ]]
|
||||
[[ $r2 != "$r3" ]]
|
||||
|
||||
r4=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; ref = \"master\"; rev = \"$rev\"; }).outPath")
|
||||
r5=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; ref = \"master\"; rev = \"$rev\"; submodules = false; }).outPath")
|
||||
|
|
@ -59,11 +59,11 @@ r6=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; ref = \
|
|||
r7=$(nix eval --raw --expr "(builtins.fetchGit { url = $rootRepo; ref = \"master\"; rev = \"$rev\"; submodules = true; }).outPath")
|
||||
r8=$(nix eval --raw --expr "(builtins.fetchGit { url = $rootRepo; rev = \"$rev\"; submodules = true; }).outPath")
|
||||
|
||||
[[ $r1 == $r4 ]]
|
||||
[[ $r4 == $r5 ]]
|
||||
[[ $r3 == $r6 ]]
|
||||
[[ $r6 == $r7 ]]
|
||||
[[ $r7 == $r8 ]]
|
||||
[[ $r1 == "$r4" ]]
|
||||
[[ $r4 == "$r5" ]]
|
||||
[[ $r3 == "$r6" ]]
|
||||
[[ $r6 == "$r7" ]]
|
||||
[[ $r7 == "$r8" ]]
|
||||
|
||||
have_submodules=$(nix eval --expr "(builtins.fetchGit { url = $rootRepo; rev = \"$rev\"; }).submodules")
|
||||
[[ $have_submodules == false ]]
|
||||
|
|
@ -80,13 +80,13 @@ pathWithSubmodulesAgain=$(nix eval --raw --expr "(builtins.fetchGit { url = file
|
|||
pathWithSubmodulesAgainWithRef=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; ref = \"master\"; rev = \"$rev\"; submodules = true; }).outPath")
|
||||
|
||||
# The resulting store path cannot be the same.
|
||||
[[ $pathWithoutSubmodules != $pathWithSubmodules ]]
|
||||
[[ $pathWithoutSubmodules != "$pathWithSubmodules" ]]
|
||||
|
||||
# Checking out the same repo with submodules returns in the same store path.
|
||||
[[ $pathWithSubmodules == $pathWithSubmodulesAgain ]]
|
||||
[[ $pathWithSubmodules == "$pathWithSubmodulesAgain" ]]
|
||||
|
||||
# Checking out the same repo with submodules returns in the same store path.
|
||||
[[ $pathWithSubmodulesAgain == $pathWithSubmodulesAgainWithRef ]]
|
||||
[[ $pathWithSubmodulesAgain == "$pathWithSubmodulesAgainWithRef" ]]
|
||||
|
||||
# The submodules flag is actually honored.
|
||||
[[ ! -e $pathWithoutSubmodules/sub/content ]]
|
||||
|
|
@ -98,14 +98,14 @@ pathWithSubmodulesAgainWithRef=$(nix eval --raw --expr "(builtins.fetchGit { url
|
|||
test "$(find "$pathWithSubmodules" -name .git)" = ""
|
||||
|
||||
# Git repos without submodules can be fetched with submodules = true.
|
||||
subRev=$(git -C $subRepo rev-parse HEAD)
|
||||
subRev=$(git -C "$subRepo" rev-parse HEAD)
|
||||
noSubmoduleRepoBaseline=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$subRepo; rev = \"$subRev\"; }).outPath")
|
||||
noSubmoduleRepo=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$subRepo; rev = \"$subRev\"; submodules = true; }).outPath")
|
||||
|
||||
[[ $noSubmoduleRepoBaseline == $noSubmoduleRepo ]]
|
||||
[[ $noSubmoduleRepoBaseline == "$noSubmoduleRepo" ]]
|
||||
|
||||
# Test .gitmodules with entries that refer to non-existent objects or objects that are not submodules.
|
||||
cat >> $rootRepo/.gitmodules <<EOF
|
||||
cat >> "$rootRepo"/.gitmodules <<EOF
|
||||
[submodule "missing"]
|
||||
path = missing
|
||||
url = https://example.org/missing.git
|
||||
|
|
@ -114,11 +114,11 @@ cat >> $rootRepo/.gitmodules <<EOF
|
|||
path = file
|
||||
url = https://example.org/file.git
|
||||
EOF
|
||||
echo foo > $rootRepo/file
|
||||
git -C $rootRepo add file
|
||||
git -C $rootRepo commit -a -m "Add bad submodules"
|
||||
echo foo > "$rootRepo"/file
|
||||
git -C "$rootRepo" add file
|
||||
git -C "$rootRepo" commit -a -m "Add bad submodules"
|
||||
|
||||
rev=$(git -C $rootRepo rev-parse HEAD)
|
||||
rev=$(git -C "$rootRepo" rev-parse HEAD)
|
||||
|
||||
r=$(nix eval --raw --expr "builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; submodules = true; }")
|
||||
|
||||
|
|
@ -126,44 +126,44 @@ r=$(nix eval --raw --expr "builtins.fetchGit { url = file://$rootRepo; rev = \"$
|
|||
[[ ! -e $r/missing ]]
|
||||
|
||||
# Test relative submodule URLs.
|
||||
rm $TEST_HOME/.cache/nix/fetcher-cache*
|
||||
rm -rf $rootRepo/.git $rootRepo/.gitmodules $rootRepo/sub
|
||||
initGitRepo $rootRepo
|
||||
git -C $rootRepo submodule add ../gitSubmodulesSub sub
|
||||
git -C $rootRepo commit -m "Add submodule"
|
||||
rev2=$(git -C $rootRepo rev-parse HEAD)
|
||||
rm "$TEST_HOME"/.cache/nix/fetcher-cache*
|
||||
rm -rf "$rootRepo"/.git "$rootRepo"/.gitmodules "$rootRepo"/sub
|
||||
initGitRepo "$rootRepo"
|
||||
git -C "$rootRepo" submodule add ../gitSubmodulesSub sub
|
||||
git -C "$rootRepo" commit -m "Add submodule"
|
||||
rev2=$(git -C "$rootRepo" rev-parse HEAD)
|
||||
pathWithRelative=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev2\"; submodules = true; }).outPath")
|
||||
diff -r -x .gitmodules $pathWithSubmodules $pathWithRelative
|
||||
diff -r -x .gitmodules "$pathWithSubmodules" "$pathWithRelative"
|
||||
|
||||
# Test clones that have an upstream with relative submodule URLs.
|
||||
rm $TEST_HOME/.cache/nix/fetcher-cache*
|
||||
rm "$TEST_HOME"/.cache/nix/fetcher-cache*
|
||||
cloneRepo=$TEST_ROOT/a/b/gitSubmodulesClone # NB /a/b to make the relative path not work relative to $cloneRepo
|
||||
git clone $rootRepo $cloneRepo
|
||||
git clone "$rootRepo" "$cloneRepo"
|
||||
pathIndirect=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$cloneRepo; rev = \"$rev2\"; submodules = true; }).outPath")
|
||||
[[ $pathIndirect = $pathWithRelative ]]
|
||||
[[ $pathIndirect = "$pathWithRelative" ]]
|
||||
|
||||
# Test submodule export-ignore interaction
|
||||
git -C $rootRepo/sub config user.email "foobar@example.com"
|
||||
git -C $rootRepo/sub config user.name "Foobar"
|
||||
git -C "$rootRepo"/sub config user.email "foobar@example.com"
|
||||
git -C "$rootRepo"/sub config user.name "Foobar"
|
||||
|
||||
echo "/exclude-from-root export-ignore" >> $rootRepo/.gitattributes
|
||||
echo "/exclude-from-root export-ignore" >> "$rootRepo"/.gitattributes
|
||||
# TBD possible semantics for submodules + exportIgnore
|
||||
# echo "/sub/exclude-deep export-ignore" >> $rootRepo/.gitattributes
|
||||
echo nope > $rootRepo/exclude-from-root
|
||||
git -C $rootRepo add .gitattributes exclude-from-root
|
||||
git -C $rootRepo commit -m "Add export-ignore"
|
||||
echo nope > "$rootRepo"/exclude-from-root
|
||||
git -C "$rootRepo" add .gitattributes exclude-from-root
|
||||
git -C "$rootRepo" commit -m "Add export-ignore"
|
||||
|
||||
echo "/exclude-from-sub export-ignore" >> $rootRepo/sub/.gitattributes
|
||||
echo nope > $rootRepo/sub/exclude-from-sub
|
||||
echo "/exclude-from-sub export-ignore" >> "$rootRepo"/sub/.gitattributes
|
||||
echo nope > "$rootRepo"/sub/exclude-from-sub
|
||||
# TBD possible semantics for submodules + exportIgnore
|
||||
# echo aye > $rootRepo/sub/exclude-from-root
|
||||
git -C $rootRepo/sub add .gitattributes exclude-from-sub
|
||||
git -C $rootRepo/sub commit -m "Add export-ignore (sub)"
|
||||
git -C "$rootRepo"/sub add .gitattributes exclude-from-sub
|
||||
git -C "$rootRepo"/sub commit -m "Add export-ignore (sub)"
|
||||
|
||||
git -C $rootRepo add sub
|
||||
git -C $rootRepo commit -m "Update submodule"
|
||||
git -C "$rootRepo" add sub
|
||||
git -C "$rootRepo" commit -m "Update submodule"
|
||||
|
||||
git -C $rootRepo status
|
||||
git -C "$rootRepo" status
|
||||
|
||||
# # TBD: not supported yet, because semantics are undecided and current implementation leaks rules from the root to submodules
|
||||
# # exportIgnore can be used with submodules
|
||||
|
|
@ -199,39 +199,40 @@ test_submodule_nested() {
|
|||
local repoB=$TEST_ROOT/submodule_nested/b
|
||||
local repoC=$TEST_ROOT/submodule_nested/c
|
||||
|
||||
rm -rf $repoA $repoB $repoC $TEST_HOME/.cache/nix
|
||||
rm -rf "$repoA" "$repoB" "$repoC" "$TEST_HOME"/.cache/nix
|
||||
|
||||
initGitRepo $repoC
|
||||
touch $repoC/inside-c
|
||||
git -C $repoC add inside-c
|
||||
addGitContent $repoC
|
||||
initGitRepo "$repoC"
|
||||
touch "$repoC"/inside-c
|
||||
git -C "$repoC" add inside-c
|
||||
addGitContent "$repoC"
|
||||
|
||||
initGitRepo $repoB
|
||||
git -C $repoB submodule add $repoC c
|
||||
git -C $repoB add c
|
||||
addGitContent $repoB
|
||||
initGitRepo "$repoB"
|
||||
git -C "$repoB" submodule add "$repoC" c
|
||||
git -C "$repoB" add c
|
||||
addGitContent "$repoB"
|
||||
|
||||
initGitRepo $repoA
|
||||
git -C $repoA submodule add $repoB b
|
||||
git -C $repoA add b
|
||||
addGitContent $repoA
|
||||
initGitRepo "$repoA"
|
||||
git -C "$repoA" submodule add "$repoB" b
|
||||
git -C "$repoA" add b
|
||||
addGitContent "$repoA"
|
||||
|
||||
|
||||
# Check non-worktree fetch
|
||||
local rev=$(git -C $repoA rev-parse HEAD)
|
||||
local rev
|
||||
rev=$(git -C "$repoA" rev-parse HEAD)
|
||||
out=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$repoA\"; rev = \"$rev\"; submodules = true; }).outPath")
|
||||
test -e $out/b/c/inside-c
|
||||
test -e $out/content
|
||||
test -e $out/b/content
|
||||
test -e $out/b/c/content
|
||||
test -e "$out"/b/c/inside-c
|
||||
test -e "$out"/content
|
||||
test -e "$out"/b/content
|
||||
test -e "$out"/b/c/content
|
||||
local nonWorktree=$out
|
||||
|
||||
# Check worktree based fetch
|
||||
# TODO: make it work without git submodule update
|
||||
git -C $repoA submodule update --init --recursive
|
||||
git -C "$repoA" submodule update --init --recursive
|
||||
out=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$repoA\"; submodules = true; }).outPath")
|
||||
find $out
|
||||
[[ $out == $nonWorktree ]] || { find $out; false; }
|
||||
find "$out"
|
||||
[[ $out == "$nonWorktree" ]] || { find "$out"; false; }
|
||||
|
||||
}
|
||||
test_submodule_nested
|
||||
|
|
|
|||
|
|
@ -21,29 +21,29 @@ ssh-keygen -f "$keysDir/testkey2" -t rsa -P "" -C "test key 2"
|
|||
key2File="$keysDir/testkey2.pub"
|
||||
publicKey2=$(awk '{print $2}' "$key2File")
|
||||
|
||||
git init $repo
|
||||
git -C $repo config user.email "foobar@example.com"
|
||||
git -C $repo config user.name "Foobar"
|
||||
git -C $repo config gpg.format ssh
|
||||
git init "$repo"
|
||||
git -C "$repo" config user.email "foobar@example.com"
|
||||
git -C "$repo" config user.name "Foobar"
|
||||
git -C "$repo" config gpg.format ssh
|
||||
|
||||
echo 'hello' > $repo/text
|
||||
git -C $repo add text
|
||||
git -C $repo -c "user.signingkey=$key1File" commit -S -m 'initial commit'
|
||||
echo 'hello' > "$repo"/text
|
||||
git -C "$repo" add text
|
||||
git -C "$repo" -c "user.signingkey=$key1File" commit -S -m 'initial commit'
|
||||
|
||||
out=$(nix eval --impure --raw --expr "builtins.fetchGit { url = \"file://$repo\"; keytype = \"ssh-rsa\"; publicKey = \"$publicKey2\"; }" 2>&1) || status=$?
|
||||
[[ $status == 1 ]]
|
||||
[[ $out =~ 'No principal matched.' ]]
|
||||
[[ $out == *'No principal matched.'* ]]
|
||||
[[ $(nix eval --impure --raw --expr "builtins.readFile (builtins.fetchGit { url = \"file://$repo\"; publicKey = \"$publicKey1\"; } + \"/text\")") = 'hello' ]]
|
||||
|
||||
echo 'hello world' > $repo/text
|
||||
echo 'hello world' > "$repo"/text
|
||||
|
||||
# Verification on a dirty repo should fail.
|
||||
out=$(nix eval --impure --raw --expr "builtins.fetchGit { url = \"file://$repo\"; keytype = \"ssh-rsa\"; publicKey = \"$publicKey2\"; }" 2>&1) || status=$?
|
||||
[[ $status == 1 ]]
|
||||
[[ $out =~ 'dirty' ]]
|
||||
|
||||
git -C $repo add text
|
||||
git -C $repo -c "user.signingkey=$key2File" commit -S -m 'second commit'
|
||||
git -C "$repo" add text
|
||||
git -C "$repo" -c "user.signingkey=$key2File" commit -S -m 'second commit'
|
||||
|
||||
[[ $(nix eval --impure --raw --expr "builtins.readFile (builtins.fetchGit { url = \"file://$repo\"; publicKeys = [{key = \"$publicKey1\";} {type = \"ssh-rsa\"; key = \"$publicKey2\";}]; } + \"/text\")") = 'hello world' ]]
|
||||
|
||||
|
|
@ -80,5 +80,6 @@ cat > "$flakeDir/flake.nix" <<EOF
|
|||
}
|
||||
EOF
|
||||
out=$(nix build "$flakeDir#test" 2>&1) || status=$?
|
||||
|
||||
[[ $status == 1 ]]
|
||||
[[ $out =~ 'No principal matched.' ]]
|
||||
[[ $out == *'No principal matched.'* ]]
|
||||
|
|
|
|||
|
|
@ -12,34 +12,35 @@ clearStore
|
|||
# See https://github.com/NixOS/nix/issues/6195
|
||||
repo=$TEST_ROOT/./hg
|
||||
|
||||
rm -rf $repo ${repo}-tmp $TEST_HOME/.cache/nix
|
||||
rm -rf "$repo" "${repo}"-tmp "$TEST_HOME"/.cache/nix
|
||||
|
||||
hg init $repo
|
||||
echo '[ui]' >> $repo/.hg/hgrc
|
||||
echo 'username = Foobar <foobar@example.org>' >> $repo/.hg/hgrc
|
||||
hg init "$repo"
|
||||
{
|
||||
echo '[ui]'
|
||||
echo 'username = Foobar <foobar@example.org>'
|
||||
# Set ui.tweakdefaults to ensure HGPLAIN is being set.
|
||||
echo 'tweakdefaults = True'
|
||||
} >> "$repo"/.hg/hgrc
|
||||
|
||||
# Set ui.tweakdefaults to ensure HGPLAIN is being set.
|
||||
echo 'tweakdefaults = True' >> $repo/.hg/hgrc
|
||||
echo utrecht > "$repo"/hello
|
||||
touch "$repo"/.hgignore
|
||||
hg add --cwd "$repo" hello .hgignore
|
||||
hg commit --cwd "$repo" -m 'Bla1'
|
||||
rev1=$(hg log --cwd "$repo" -r tip --template '{node}')
|
||||
|
||||
echo utrecht > $repo/hello
|
||||
touch $repo/.hgignore
|
||||
hg add --cwd $repo hello .hgignore
|
||||
hg commit --cwd $repo -m 'Bla1'
|
||||
rev1=$(hg log --cwd $repo -r tip --template '{node}')
|
||||
|
||||
echo world > $repo/hello
|
||||
hg commit --cwd $repo -m 'Bla2'
|
||||
rev2=$(hg log --cwd $repo -r tip --template '{node}')
|
||||
echo world > "$repo"/hello
|
||||
hg commit --cwd "$repo" -m 'Bla2'
|
||||
rev2=$(hg log --cwd "$repo" -r tip --template '{node}')
|
||||
|
||||
# Fetch an unclean branch.
|
||||
echo unclean > $repo/hello
|
||||
echo unclean > "$repo"/hello
|
||||
path=$(nix eval --impure --raw --expr "(builtins.fetchMercurial file://$repo).outPath")
|
||||
[[ $(cat $path/hello) = unclean ]]
|
||||
hg revert --cwd $repo --all
|
||||
[[ $(cat "$path"/hello) = unclean ]]
|
||||
hg revert --cwd "$repo" --all
|
||||
|
||||
# Fetch the default branch.
|
||||
path=$(nix eval --impure --raw --expr "(builtins.fetchMercurial file://$repo).outPath")
|
||||
[[ $(cat $path/hello) = world ]]
|
||||
[[ $(cat "$path"/hello) = world ]]
|
||||
|
||||
# In pure eval mode, fetchGit without a revision should fail.
|
||||
[[ $(nix eval --impure --raw --expr "(builtins.readFile (fetchMercurial file://$repo + \"/hello\"))") = world ]]
|
||||
|
|
@ -47,64 +48,64 @@ path=$(nix eval --impure --raw --expr "(builtins.fetchMercurial file://$repo).ou
|
|||
|
||||
# Fetch using an explicit revision hash.
|
||||
path2=$(nix eval --impure --raw --expr "(builtins.fetchMercurial { url = file://$repo; rev = \"$rev2\"; }).outPath")
|
||||
[[ $path = $path2 ]]
|
||||
[[ $path = "$path2" ]]
|
||||
|
||||
# In pure eval mode, fetchGit with a revision should succeed.
|
||||
[[ $(nix eval --raw --expr "builtins.readFile (fetchMercurial { url = file://$repo; rev = \"$rev2\"; } + \"/hello\")") = world ]]
|
||||
|
||||
# Fetch again. This should be cached.
|
||||
mv $repo ${repo}-tmp
|
||||
mv "$repo" "${repo}"-tmp
|
||||
path2=$(nix eval --impure --raw --expr "(builtins.fetchMercurial file://$repo).outPath")
|
||||
[[ $path = $path2 ]]
|
||||
[[ $path = "$path2" ]]
|
||||
|
||||
[[ $(nix eval --impure --raw --expr "(builtins.fetchMercurial file://$repo).branch") = default ]]
|
||||
[[ $(nix eval --impure --expr "(builtins.fetchMercurial file://$repo).revCount") = 1 ]]
|
||||
[[ $(nix eval --impure --raw --expr "(builtins.fetchMercurial file://$repo).rev") = $rev2 ]]
|
||||
[[ $(nix eval --impure --raw --expr "(builtins.fetchMercurial file://$repo).rev") = "$rev2" ]]
|
||||
|
||||
# But with TTL 0, it should fail.
|
||||
(! nix eval --impure --refresh --expr "builtins.fetchMercurial file://$repo")
|
||||
|
||||
# Fetching with a explicit hash should succeed.
|
||||
path2=$(nix eval --refresh --raw --expr "(builtins.fetchMercurial { url = file://$repo; rev = \"$rev2\"; }).outPath")
|
||||
[[ $path = $path2 ]]
|
||||
[[ $path = "$path2" ]]
|
||||
|
||||
path2=$(nix eval --refresh --raw --expr "(builtins.fetchMercurial { url = file://$repo; rev = \"$rev1\"; }).outPath")
|
||||
[[ $(cat $path2/hello) = utrecht ]]
|
||||
[[ $(cat "$path2"/hello) = utrecht ]]
|
||||
|
||||
mv ${repo}-tmp $repo
|
||||
mv "${repo}"-tmp "$repo"
|
||||
|
||||
# Using a clean working tree should produce the same result.
|
||||
path2=$(nix eval --impure --raw --expr "(builtins.fetchMercurial $repo).outPath")
|
||||
[[ $path = $path2 ]]
|
||||
[[ $path = "$path2" ]]
|
||||
|
||||
# Using an unclean tree should yield the tracked but uncommitted changes.
|
||||
mkdir $repo/dir1 $repo/dir2
|
||||
echo foo > $repo/dir1/foo
|
||||
echo bar > $repo/bar
|
||||
echo bar > $repo/dir2/bar
|
||||
hg add --cwd $repo dir1/foo
|
||||
hg rm --cwd $repo hello
|
||||
mkdir "$repo"/dir1 "$repo"/dir2
|
||||
echo foo > "$repo"/dir1/foo
|
||||
echo bar > "$repo"/bar
|
||||
echo bar > "$repo"/dir2/bar
|
||||
hg add --cwd "$repo" dir1/foo
|
||||
hg rm --cwd "$repo" hello
|
||||
|
||||
path2=$(nix eval --impure --raw --expr "(builtins.fetchMercurial $repo).outPath")
|
||||
[ ! -e $path2/hello ]
|
||||
[ ! -e $path2/bar ]
|
||||
[ ! -e $path2/dir2/bar ]
|
||||
[ ! -e $path2/.hg ]
|
||||
[[ $(cat $path2/dir1/foo) = foo ]]
|
||||
[ ! -e "$path2"/hello ]
|
||||
[ ! -e "$path2"/bar ]
|
||||
[ ! -e "$path2"/dir2/bar ]
|
||||
[ ! -e "$path2"/.hg ]
|
||||
[[ $(cat "$path2"/dir1/foo) = foo ]]
|
||||
|
||||
[[ $(nix eval --impure --raw --expr "(builtins.fetchMercurial $repo).rev") = 0000000000000000000000000000000000000000 ]]
|
||||
|
||||
# ... unless we're using an explicit ref.
|
||||
path3=$(nix eval --impure --raw --expr "(builtins.fetchMercurial { url = $repo; rev = \"default\"; }).outPath")
|
||||
[[ $path = $path3 ]]
|
||||
[[ $path = "$path3" ]]
|
||||
|
||||
# Committing should not affect the store path.
|
||||
hg commit --cwd $repo -m 'Bla3'
|
||||
hg commit --cwd "$repo" -m 'Bla3'
|
||||
|
||||
path4=$(nix eval --impure --refresh --raw --expr "(builtins.fetchMercurial file://$repo).outPath")
|
||||
[[ $path2 = $path4 ]]
|
||||
[[ $path2 = "$path4" ]]
|
||||
|
||||
echo paris > $repo/hello
|
||||
echo paris > "$repo"/hello
|
||||
|
||||
# Passing a `name` argument should be reflected in the output path
|
||||
path5=$(nix eval -vvvvv --impure --refresh --raw --expr "(builtins.fetchMercurial { url = \"file://$repo\"; name = \"foo\"; } ).outPath")
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
# shellcheck shell=bash
|
||||
if test "$IMPURE_VAR1" != "foo"; then exit 1; fi
|
||||
if test "$IMPURE_VAR2" != "bar"; then exit 1; fi
|
||||
echo "Hello World!" > $out
|
||||
# shellcheck disable=SC2154
|
||||
echo "Hello World!" > "$out"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
echo dummy: $dummy
|
||||
# shellcheck shell=bash
|
||||
# shellcheck disable=SC2154
|
||||
echo dummy: "$dummy"
|
||||
if test -n "$dummy"; then sleep 2; fi
|
||||
mkdir $out
|
||||
mkdir $out/bla
|
||||
echo "Hello World!" > $out/foo
|
||||
ln -s foo $out/bar
|
||||
# shellcheck disable=SC2154
|
||||
mkdir "$out"
|
||||
mkdir "$out"/bla
|
||||
echo "Hello World!" > "$out"/foo
|
||||
ln -s foo "$out"/bar
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ TODO_NixOS
|
|||
|
||||
clearStore
|
||||
|
||||
path=$(nix-store -q $(nix-instantiate fixed.nix -A good.0))
|
||||
path=$(nix-store -q "$(nix-instantiate fixed.nix -A good.0)")
|
||||
|
||||
echo 'testing bad...'
|
||||
nix-build fixed.nix -A bad --no-out-link && fail "should fail"
|
||||
|
|
@ -14,7 +14,7 @@ nix-build fixed.nix -A bad --no-out-link && fail "should fail"
|
|||
# Building with the bad hash should produce the "good" output path as
|
||||
# a side-effect.
|
||||
[[ -e $path ]]
|
||||
nix path-info --json $path | grep fixed:md5:2qk15sxzzjlnpjk9brn7j8ppcd
|
||||
nix path-info --json "$path" | grep fixed:md5:2qk15sxzzjlnpjk9brn7j8ppcd
|
||||
|
||||
echo 'testing good...'
|
||||
nix-build fixed.nix -A good --no-out-link
|
||||
|
|
@ -37,7 +37,7 @@ fi
|
|||
|
||||
# While we're at it, check attribute selection a bit more.
|
||||
echo 'testing attribute selection...'
|
||||
test $(nix-instantiate fixed.nix -A good.1 | wc -l) = 1
|
||||
test "$(nix-instantiate fixed.nix -A good.1 | wc -l)" = 1
|
||||
|
||||
# Test parallel builds of derivations that produce the same output.
|
||||
# Only one should run at the same time.
|
||||
|
|
@ -51,16 +51,16 @@ echo 'testing sameAsAdd...'
|
|||
out=$(nix-build fixed.nix -A sameAsAdd --no-out-link)
|
||||
|
||||
# This is what fixed.builder2 produces...
|
||||
rm -rf $TEST_ROOT/fixed
|
||||
mkdir $TEST_ROOT/fixed
|
||||
mkdir $TEST_ROOT/fixed/bla
|
||||
echo "Hello World!" > $TEST_ROOT/fixed/foo
|
||||
ln -s foo $TEST_ROOT/fixed/bar
|
||||
rm -rf "$TEST_ROOT"/fixed
|
||||
mkdir "$TEST_ROOT"/fixed
|
||||
mkdir "$TEST_ROOT"/fixed/bla
|
||||
echo "Hello World!" > "$TEST_ROOT"/fixed/foo
|
||||
ln -s foo "$TEST_ROOT"/fixed/bar
|
||||
|
||||
out2=$(nix-store --add $TEST_ROOT/fixed)
|
||||
out2=$(nix-store --add "$TEST_ROOT"/fixed)
|
||||
[ "$out" = "$out2" ]
|
||||
|
||||
out3=$(nix-store --add-fixed --recursive sha256 $TEST_ROOT/fixed)
|
||||
out3=$(nix-store --add-fixed --recursive sha256 "$TEST_ROOT"/fixed)
|
||||
[ "$out" = "$out3" ]
|
||||
|
||||
out4=$(nix-store --print-fixed-path --recursive sha256 "1ixr6yd3297ciyp9im522dfxpqbkhcw0pylkb2aab915278fqaik" fixed)
|
||||
|
|
|
|||
|
|
@ -7,13 +7,13 @@ requireGit
|
|||
flake1Dir=$TEST_ROOT/flake1
|
||||
flake2Dir=$TEST_ROOT/flake2
|
||||
|
||||
createGitRepo $flake1Dir
|
||||
cat > $flake1Dir/flake.nix <<EOF
|
||||
createGitRepo "$flake1Dir"
|
||||
cat > "$flake1Dir"/flake.nix <<EOF
|
||||
{
|
||||
outputs = { self }: { x = builtins.readFile $(pwd)/absolute-paths.sh; };
|
||||
}
|
||||
EOF
|
||||
git -C $flake1Dir add flake.nix
|
||||
git -C $flake1Dir commit -m Initial
|
||||
git -C "$flake1Dir" add flake.nix
|
||||
git -C "$flake1Dir" commit -m Initial
|
||||
|
||||
nix eval --impure --json $flake1Dir#x
|
||||
nix eval --impure --json "$flake1Dir"#x
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
source common.sh
|
||||
|
||||
flakeDir=$TEST_ROOT/flake3
|
||||
mkdir -p $flakeDir
|
||||
mkdir -p "$flakeDir"
|
||||
|
||||
cat > $flakeDir/flake.nix <<EOF
|
||||
cat > "$flakeDir"/flake.nix <<EOF
|
||||
{
|
||||
outputs = { self }: {
|
||||
overlay = final: prev: {
|
||||
|
|
@ -14,9 +14,9 @@ cat > $flakeDir/flake.nix <<EOF
|
|||
}
|
||||
EOF
|
||||
|
||||
nix flake check $flakeDir
|
||||
nix flake check "$flakeDir"
|
||||
|
||||
cat > $flakeDir/flake.nix <<EOF
|
||||
cat > "$flakeDir"/flake.nix <<EOF
|
||||
{
|
||||
outputs = { self }: {
|
||||
overlay = finalll: prev: {
|
||||
|
|
@ -25,9 +25,9 @@ cat > $flakeDir/flake.nix <<EOF
|
|||
}
|
||||
EOF
|
||||
|
||||
(! nix flake check $flakeDir)
|
||||
(! nix flake check "$flakeDir")
|
||||
|
||||
cat > $flakeDir/flake.nix <<EOF
|
||||
cat > "$flakeDir"/flake.nix <<EOF
|
||||
{
|
||||
outputs = { self, ... }: {
|
||||
overlays.x86_64-linux.foo = final: prev: {
|
||||
|
|
@ -36,10 +36,11 @@ cat > $flakeDir/flake.nix <<EOF
|
|||
}
|
||||
EOF
|
||||
|
||||
checkRes=$(nix flake check $flakeDir 2>&1 && fail "nix flake check --all-systems should have failed" || true)
|
||||
# shellcheck disable=SC2015
|
||||
checkRes=$(nix flake check "$flakeDir" 2>&1 && fail "nix flake check --all-systems should have failed" || true)
|
||||
echo "$checkRes" | grepQuiet "error: overlay is not a function, but a set instead"
|
||||
|
||||
cat > $flakeDir/flake.nix <<EOF
|
||||
cat > "$flakeDir"/flake.nix <<EOF
|
||||
{
|
||||
outputs = { self }: {
|
||||
nixosModules.foo = {
|
||||
|
|
@ -50,9 +51,9 @@ cat > $flakeDir/flake.nix <<EOF
|
|||
}
|
||||
EOF
|
||||
|
||||
nix flake check $flakeDir
|
||||
nix flake check "$flakeDir"
|
||||
|
||||
cat > $flakeDir/flake.nix <<EOF
|
||||
cat > "$flakeDir"/flake.nix <<EOF
|
||||
{
|
||||
outputs = { self }: {
|
||||
nixosModules.foo = assert false; {
|
||||
|
|
@ -63,9 +64,9 @@ cat > $flakeDir/flake.nix <<EOF
|
|||
}
|
||||
EOF
|
||||
|
||||
(! nix flake check $flakeDir)
|
||||
(! nix flake check "$flakeDir")
|
||||
|
||||
cat > $flakeDir/flake.nix <<EOF
|
||||
cat > "$flakeDir"/flake.nix <<EOF
|
||||
{
|
||||
outputs = { self }: {
|
||||
nixosModule = { config, pkgs, ... }: {
|
||||
|
|
@ -75,9 +76,9 @@ cat > $flakeDir/flake.nix <<EOF
|
|||
}
|
||||
EOF
|
||||
|
||||
nix flake check $flakeDir
|
||||
nix flake check "$flakeDir"
|
||||
|
||||
cat > $flakeDir/flake.nix <<EOF
|
||||
cat > "$flakeDir"/flake.nix <<EOF
|
||||
{
|
||||
outputs = { self }: {
|
||||
packages.system-1.default = "foo";
|
||||
|
|
@ -86,13 +87,14 @@ cat > $flakeDir/flake.nix <<EOF
|
|||
}
|
||||
EOF
|
||||
|
||||
nix flake check $flakeDir
|
||||
nix flake check "$flakeDir"
|
||||
|
||||
checkRes=$(nix flake check --all-systems --keep-going $flakeDir 2>&1 && fail "nix flake check --all-systems should have failed" || true)
|
||||
# shellcheck disable=SC2015
|
||||
checkRes=$(nix flake check --all-systems --keep-going "$flakeDir" 2>&1 && fail "nix flake check --all-systems should have failed" || true)
|
||||
echo "$checkRes" | grepQuiet "packages.system-1.default"
|
||||
echo "$checkRes" | grepQuiet "packages.system-2.default"
|
||||
|
||||
cat > $flakeDir/flake.nix <<EOF
|
||||
cat > "$flakeDir"/flake.nix <<EOF
|
||||
{
|
||||
outputs = { self }: {
|
||||
apps.system-1.default = {
|
||||
|
|
@ -108,9 +110,9 @@ cat > $flakeDir/flake.nix <<EOF
|
|||
}
|
||||
EOF
|
||||
|
||||
nix flake check --all-systems $flakeDir
|
||||
nix flake check --all-systems "$flakeDir"
|
||||
|
||||
cat > $flakeDir/flake.nix <<EOF
|
||||
cat > "$flakeDir"/flake.nix <<EOF
|
||||
{
|
||||
outputs = { self }: {
|
||||
apps.system-1.default = {
|
||||
|
|
@ -122,10 +124,11 @@ cat > $flakeDir/flake.nix <<EOF
|
|||
}
|
||||
EOF
|
||||
|
||||
checkRes=$(nix flake check --all-systems $flakeDir 2>&1 && fail "nix flake check --all-systems should have failed" || true)
|
||||
# shellcheck disable=SC2015
|
||||
checkRes=$(nix flake check --all-systems "$flakeDir" 2>&1 && fail "nix flake check --all-systems should have failed" || true)
|
||||
echo "$checkRes" | grepQuiet "unknown-attr"
|
||||
|
||||
cat > $flakeDir/flake.nix <<EOF
|
||||
cat > "$flakeDir"/flake.nix <<EOF
|
||||
{
|
||||
outputs = { self }: {
|
||||
formatter.system-1 = "foo";
|
||||
|
|
@ -133,11 +136,12 @@ cat > $flakeDir/flake.nix <<EOF
|
|||
}
|
||||
EOF
|
||||
|
||||
checkRes=$(nix flake check --all-systems $flakeDir 2>&1 && fail "nix flake check --all-systems should have failed" || true)
|
||||
# shellcheck disable=SC2015
|
||||
checkRes=$(nix flake check --all-systems "$flakeDir" 2>&1 && fail "nix flake check --all-systems should have failed" || true)
|
||||
echo "$checkRes" | grepQuiet "formatter.system-1"
|
||||
|
||||
# Test whether `nix flake check` builds checks.
|
||||
cat > $flakeDir/flake.nix <<EOF
|
||||
cat > "$flakeDir"/flake.nix <<EOF
|
||||
{
|
||||
outputs = { self }: {
|
||||
checks.$system.foo = with import ./config.nix; mkDerivation {
|
||||
|
|
@ -152,7 +156,7 @@ cp "${config_nix}" "$flakeDir/"
|
|||
|
||||
expectStderr 0 nix flake check "$flakeDir" | grepQuiet 'running 1 flake check'
|
||||
|
||||
cat > $flakeDir/flake.nix <<EOF
|
||||
cat > "$flakeDir"/flake.nix <<EOF
|
||||
{
|
||||
outputs = { self }: {
|
||||
checks.$system.foo = with import ./config.nix; mkDerivation {
|
||||
|
|
@ -164,14 +168,14 @@ cat > $flakeDir/flake.nix <<EOF
|
|||
EOF
|
||||
|
||||
# FIXME: error code 100 doesn't get propagated from the daemon.
|
||||
if !isTestOnNixOS && $NIX_REMOTE != daemon; then
|
||||
if ! isTestOnNixOS && $NIX_REMOTE != daemon; then
|
||||
expectStderr 100 nix flake check "$flakeDir" | grepQuiet 'builder failed with exit code 1'
|
||||
fi
|
||||
|
||||
# Ensure non-substitutable (read: usually failed) checks are actually run
|
||||
# https://github.com/NixOS/nix/pull/13574
|
||||
cp "$config_nix" $flakeDir/
|
||||
cat > $flakeDir/flake.nix <<EOF
|
||||
cp "$config_nix" "$flakeDir"/
|
||||
cat > "$flakeDir"/flake.nix <<EOF
|
||||
{
|
||||
outputs = { self }: with import ./config.nix; {
|
||||
checks.${system}.expectedToFail = derivation {
|
||||
|
|
@ -185,5 +189,6 @@ EOF
|
|||
|
||||
# NOTE: Regex pattern is used for compatibility with older daemon versions
|
||||
# We also can't expect a specific status code. Earlier daemons return 1, but as of 2.31, we return 100
|
||||
checkRes=$(nix flake check $flakeDir 2>&1 && fail "nix flake check should have failed" || true)
|
||||
# shellcheck disable=SC2015
|
||||
checkRes=$(nix flake check "$flakeDir" 2>&1 && fail "nix flake check should have failed" || true)
|
||||
echo "$checkRes" | grepQuiet -E "builder( for .*)? failed with exit code 1"
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
source common.sh
|
||||
|
||||
cp ../simple.nix ../simple.builder.sh "${config_nix}" $TEST_HOME
|
||||
cp ../simple.nix ../simple.builder.sh "${config_nix}" "$TEST_HOME"
|
||||
|
||||
cd $TEST_HOME
|
||||
cd "$TEST_HOME"
|
||||
|
||||
rm -f post-hook-ran
|
||||
cat <<EOF > echoing-post-hook.sh
|
||||
|
|
@ -37,6 +37,7 @@ if type -p script >/dev/null && script -q -c true /dev/null; then
|
|||
else
|
||||
echo "script is not available or not GNU-like, so we skip testing with an added tty"
|
||||
fi
|
||||
# shellcheck disable=SC2235
|
||||
(! [[ -f post-hook-ran ]])
|
||||
TODO_NixOS
|
||||
clearStore
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ TODO_NixOS
|
|||
requireGit
|
||||
|
||||
clearStore
|
||||
rm -rf $TEST_HOME/.cache $TEST_HOME/.config
|
||||
rm -rf "$TEST_HOME"/.cache "$TEST_HOME"/.config
|
||||
|
||||
createFlake1
|
||||
createFlake2
|
||||
|
|
@ -59,7 +59,7 @@ nix flake metadata flake1
|
|||
nix flake metadata flake1 | grepQuiet 'Locked URL:.*flake1.*'
|
||||
|
||||
# Test 'nix flake metadata' on a chroot store.
|
||||
nix flake metadata --store $TEST_ROOT/chroot-store flake1
|
||||
nix flake metadata --store "$TEST_ROOT"/chroot-store flake1
|
||||
|
||||
# Test 'nix flake metadata' on a local flake.
|
||||
(cd "$flake1Dir" && nix flake metadata) | grepQuiet 'URL:.*flake1.*'
|
||||
|
|
@ -75,17 +75,18 @@ hash1=$(echo "$json" | jq -r .revision)
|
|||
[[ -n $(echo "$json" | jq -r .fingerprint) ]]
|
||||
|
||||
echo foo > "$flake1Dir/foo"
|
||||
git -C "$flake1Dir" add $flake1Dir/foo
|
||||
git -C "$flake1Dir" add "$flake1Dir"/foo
|
||||
[[ $(nix flake metadata flake1 --json --refresh | jq -r .dirtyRevision) == "$hash1-dirty" ]]
|
||||
[[ "$(nix flake metadata flake1 --json | jq -r .fingerprint)" != null ]]
|
||||
|
||||
echo -n '# foo' >> "$flake1Dir/flake.nix"
|
||||
flake1OriginalCommit=$(git -C "$flake1Dir" rev-parse HEAD)
|
||||
git -C "$flake1Dir" commit -a -m 'Foo'
|
||||
# shellcheck disable=SC2034
|
||||
flake1NewCommit=$(git -C "$flake1Dir" rev-parse HEAD)
|
||||
hash2=$(nix flake metadata flake1 --json --refresh | jq -r .revision)
|
||||
[[ $(nix flake metadata flake1 --json --refresh | jq -r .dirtyRevision) == "null" ]]
|
||||
[[ $hash1 != $hash2 ]]
|
||||
[[ $hash1 != "$hash2" ]]
|
||||
|
||||
# Test 'nix build' on a flake.
|
||||
nix build -o "$TEST_ROOT/result" flake1#foo
|
||||
|
|
@ -204,8 +205,8 @@ git -C "$flake3Dir" add flake.nix
|
|||
git -C "$flake3Dir" commit -m 'Update flake.nix'
|
||||
|
||||
# Check whether `nix build` works with an incomplete lockfile
|
||||
nix build -o $TEST_ROOT/result "$flake3Dir#sth sth"
|
||||
nix build -o $TEST_ROOT/result "$flake3Dir#sth%20sth"
|
||||
nix build -o "$TEST_ROOT"/result "$flake3Dir#sth sth"
|
||||
nix build -o "$TEST_ROOT"/result "$flake3Dir#sth%20sth"
|
||||
|
||||
# Check whether it saved the lockfile
|
||||
[[ -n $(git -C "$flake3Dir" diff master) ]]
|
||||
|
|
@ -249,7 +250,7 @@ nix flake lock "$flake3Dir"
|
|||
[[ -z $(git -C "$flake3Dir" diff master || echo failed) ]]
|
||||
|
||||
nix flake update --flake "$flake3Dir" --override-flake flake2 nixpkgs
|
||||
[[ ! -z $(git -C "$flake3Dir" diff master || echo failed) ]]
|
||||
[[ -n $(git -C "$flake3Dir" diff master || echo failed) ]]
|
||||
|
||||
# Testing the nix CLI
|
||||
nix registry add flake1 flake3
|
||||
|
|
@ -262,7 +263,7 @@ nix registry remove flake1
|
|||
[[ $(nix registry list | wc -l) == 4 ]]
|
||||
|
||||
# Test 'nix registry list' with a disabled global registry.
|
||||
nix registry add user-flake1 git+file://$flake1Dir
|
||||
nix registry add user-flake1 git+file://"$flake1Dir"
|
||||
nix registry add user-flake2 "git+file://$percentEncodedFlake2Dir"
|
||||
[[ $(nix --flake-registry "" registry list | wc -l) == 2 ]]
|
||||
nix --flake-registry "" registry list | grepQuietInverse '^global' # nothing in global registry
|
||||
|
|
@ -273,9 +274,9 @@ nix registry remove user-flake2
|
|||
[[ $(nix registry list | wc -l) == 4 ]]
|
||||
|
||||
# Test 'nix flake clone'.
|
||||
rm -rf $TEST_ROOT/flake1-v2
|
||||
nix flake clone flake1 --dest $TEST_ROOT/flake1-v2
|
||||
[ -e $TEST_ROOT/flake1-v2/flake.nix ]
|
||||
rm -rf "$TEST_ROOT"/flake1-v2
|
||||
nix flake clone flake1 --dest "$TEST_ROOT"/flake1-v2
|
||||
[ -e "$TEST_ROOT"/flake1-v2/flake.nix ]
|
||||
|
||||
# Test 'follows' inputs.
|
||||
cat > "$flake3Dir/flake.nix" <<EOF
|
||||
|
|
@ -319,9 +320,9 @@ nix flake lock "$flake3Dir"
|
|||
[[ $(jq -c .nodes.root.inputs.bar "$flake3Dir/flake.lock") = '["flake2"]' ]]
|
||||
|
||||
# Test overriding inputs of inputs.
|
||||
writeTrivialFlake $flake7Dir
|
||||
git -C $flake7Dir add flake.nix
|
||||
git -C $flake7Dir commit -m 'Initial'
|
||||
writeTrivialFlake "$flake7Dir"
|
||||
git -C "$flake7Dir" add flake.nix
|
||||
git -C "$flake7Dir" commit -m 'Initial'
|
||||
|
||||
cat > "$flake3Dir/flake.nix" <<EOF
|
||||
{
|
||||
|
|
@ -349,54 +350,55 @@ cat > "$flake3Dir/flake.nix" <<EOF
|
|||
EOF
|
||||
|
||||
nix flake update --flake "$flake3Dir"
|
||||
# shellcheck disable=SC2076
|
||||
[[ $(jq -c .nodes.flake2.inputs.flake1 "$flake3Dir/flake.lock") =~ '["foo"]' ]]
|
||||
[[ $(jq .nodes.foo.locked.url "$flake3Dir/flake.lock") =~ flake7 ]]
|
||||
|
||||
# Test git+file with bare repo.
|
||||
rm -rf $flakeGitBare
|
||||
git clone --bare $flake1Dir $flakeGitBare
|
||||
nix build -o $TEST_ROOT/result git+file://$flakeGitBare
|
||||
rm -rf "$flakeGitBare"
|
||||
git clone --bare "$flake1Dir" "$flakeGitBare"
|
||||
nix build -o "$TEST_ROOT"/result git+file://"$flakeGitBare"
|
||||
|
||||
# Test path flakes.
|
||||
mkdir -p $flake5Dir
|
||||
writeDependentFlake $flake5Dir
|
||||
nix flake lock path://$flake5Dir
|
||||
mkdir -p "$flake5Dir"
|
||||
writeDependentFlake "$flake5Dir"
|
||||
nix flake lock path://"$flake5Dir"
|
||||
|
||||
# Test tarball flakes.
|
||||
tar cfz $TEST_ROOT/flake.tar.gz -C $TEST_ROOT flake5
|
||||
tar cfz "$TEST_ROOT"/flake.tar.gz -C "$TEST_ROOT" flake5
|
||||
|
||||
nix build -o $TEST_ROOT/result file://$TEST_ROOT/flake.tar.gz
|
||||
nix build -o "$TEST_ROOT"/result file://"$TEST_ROOT"/flake.tar.gz
|
||||
|
||||
# Building with a tarball URL containing a SRI hash should also work.
|
||||
url=$(nix flake metadata --json file://$TEST_ROOT/flake.tar.gz | jq -r .url)
|
||||
url=$(nix flake metadata --json file://"$TEST_ROOT"/flake.tar.gz | jq -r .url)
|
||||
[[ $url =~ sha256- ]]
|
||||
|
||||
nix build -o $TEST_ROOT/result $url
|
||||
nix build -o "$TEST_ROOT"/result "$url"
|
||||
|
||||
# Building with an incorrect SRI hash should fail.
|
||||
expectStderr 102 nix build -o $TEST_ROOT/result "file://$TEST_ROOT/flake.tar.gz?narHash=sha256-qQ2Zz4DNHViCUrp6gTS7EE4+RMqFQtUfWF2UNUtJKS0=" | grep 'NAR hash mismatch'
|
||||
expectStderr 102 nix build -o "$TEST_ROOT"/result "file://$TEST_ROOT/flake.tar.gz?narHash=sha256-qQ2Zz4DNHViCUrp6gTS7EE4+RMqFQtUfWF2UNUtJKS0=" | grep 'NAR hash mismatch'
|
||||
|
||||
# Test --override-input.
|
||||
git -C "$flake3Dir" reset --hard
|
||||
nix flake lock "$flake3Dir" --override-input flake2/flake1 file://$TEST_ROOT/flake.tar.gz -vvvvv
|
||||
nix flake lock "$flake3Dir" --override-input flake2/flake1 file://"$TEST_ROOT"/flake.tar.gz -vvvvv
|
||||
[[ $(jq .nodes.flake1_2.locked.url "$flake3Dir/flake.lock") =~ flake.tar.gz ]]
|
||||
|
||||
nix flake lock "$flake3Dir" --override-input flake2/flake1 flake1
|
||||
[[ $(jq -r .nodes.flake1_2.locked.rev "$flake3Dir/flake.lock") =~ $hash2 ]]
|
||||
|
||||
nix flake lock "$flake3Dir" --override-input flake2/flake1 flake1/master/$hash1
|
||||
nix flake lock "$flake3Dir" --override-input flake2/flake1 flake1/master/"$hash1"
|
||||
[[ $(jq -r .nodes.flake1_2.locked.rev "$flake3Dir/flake.lock") =~ $hash1 ]]
|
||||
|
||||
# Test --update-input.
|
||||
nix flake lock "$flake3Dir"
|
||||
[[ $(jq -r .nodes.flake1_2.locked.rev "$flake3Dir/flake.lock") = $hash1 ]]
|
||||
[[ $(jq -r .nodes.flake1_2.locked.rev "$flake3Dir/flake.lock") = "$hash1" ]]
|
||||
|
||||
nix flake update flake2/flake1 --flake "$flake3Dir"
|
||||
[[ $(jq -r .nodes.flake1_2.locked.rev "$flake3Dir/flake.lock") =~ $hash2 ]]
|
||||
|
||||
# Test updating multiple inputs.
|
||||
nix flake lock "$flake3Dir" --override-input flake1 flake1/master/$hash1
|
||||
nix flake lock "$flake3Dir" --override-input flake2/flake1 flake1/master/$hash1
|
||||
nix flake lock "$flake3Dir" --override-input flake1 flake1/master/"$hash1"
|
||||
nix flake lock "$flake3Dir" --override-input flake2/flake1 flake1/master/"$hash1"
|
||||
[[ $(jq -r .nodes.flake1.locked.rev "$flake3Dir/flake.lock") =~ $hash1 ]]
|
||||
[[ $(jq -r .nodes.flake1_2.locked.rev "$flake3Dir/flake.lock") =~ $hash1 ]]
|
||||
|
||||
|
|
@ -409,13 +411,13 @@ nix flake metadata "$flake3Dir" --json | jq .
|
|||
nix flake metadata "$flake3Dir" --json --eval-store "dummy://?read-only=false" | jq .
|
||||
|
||||
# Test flake in store does not evaluate.
|
||||
rm -rf $badFlakeDir
|
||||
mkdir $badFlakeDir
|
||||
echo INVALID > $badFlakeDir/flake.nix
|
||||
nix store delete $(nix store add-path $badFlakeDir)
|
||||
rm -rf "$badFlakeDir"
|
||||
mkdir "$badFlakeDir"
|
||||
echo INVALID > "$badFlakeDir"/flake.nix
|
||||
nix store delete "$(nix store add-path "$badFlakeDir")"
|
||||
|
||||
[[ $(nix path-info $(nix store add-path $flake1Dir)) =~ flake1 ]]
|
||||
[[ $(nix path-info path:$(nix store add-path $flake1Dir)) =~ simple ]]
|
||||
[[ $(nix path-info "$(nix store add-path "$flake1Dir")") =~ flake1 ]]
|
||||
[[ $(nix path-info path:"$(nix store add-path "$flake1Dir")") =~ simple ]]
|
||||
|
||||
# Test fetching flakerefs in the legacy CLI.
|
||||
[[ $(nix-instantiate --eval flake:flake3 -A x) = 123 ]]
|
||||
|
|
@ -424,15 +426,15 @@ nix store delete $(nix store add-path $badFlakeDir)
|
|||
[[ $(NIX_PATH=flake3=flake:flake3 nix-instantiate --eval '<flake3>' -A x) = 123 ]]
|
||||
|
||||
# Test alternate lockfile paths.
|
||||
nix flake lock "$flake2Dir" --output-lock-file $TEST_ROOT/flake2.lock
|
||||
cmp "$flake2Dir/flake.lock" $TEST_ROOT/flake2.lock >/dev/null # lockfiles should be identical, since we're referencing flake2's original one
|
||||
nix flake lock "$flake2Dir" --output-lock-file "$TEST_ROOT"/flake2.lock
|
||||
cmp "$flake2Dir/flake.lock" "$TEST_ROOT"/flake2.lock >/dev/null # lockfiles should be identical, since we're referencing flake2's original one
|
||||
|
||||
nix flake lock "$flake2Dir" --output-lock-file $TEST_ROOT/flake2-overridden.lock --override-input flake1 git+file://$flake1Dir?rev=$flake1OriginalCommit
|
||||
expectStderr 1 cmp "$flake2Dir/flake.lock" $TEST_ROOT/flake2-overridden.lock
|
||||
nix flake metadata "$flake2Dir" --reference-lock-file $TEST_ROOT/flake2-overridden.lock | grepQuiet $flake1OriginalCommit
|
||||
nix flake lock "$flake2Dir" --output-lock-file "$TEST_ROOT"/flake2-overridden.lock --override-input flake1 git+file://"$flake1Dir"?rev="$flake1OriginalCommit"
|
||||
expectStderr 1 cmp "$flake2Dir/flake.lock" "$TEST_ROOT"/flake2-overridden.lock
|
||||
nix flake metadata "$flake2Dir" --reference-lock-file "$TEST_ROOT"/flake2-overridden.lock | grepQuiet "$flake1OriginalCommit"
|
||||
|
||||
# reference-lock-file can only be used if allow-dirty is set.
|
||||
expectStderr 1 nix flake metadata "$flake2Dir" --no-allow-dirty --reference-lock-file $TEST_ROOT/flake2-overridden.lock
|
||||
expectStderr 1 nix flake metadata "$flake2Dir" --no-allow-dirty --reference-lock-file "$TEST_ROOT"/flake2-overridden.lock
|
||||
|
||||
# After changing an input (flake2 from newFlake2Rev to prevFlake2Rev), we should have the transitive inputs locked by revision $prevFlake2Rev of flake2.
|
||||
prevFlake1Rev=$(nix flake metadata --json "$flake1Dir" | jq -r .revision)
|
||||
|
|
@ -459,7 +461,7 @@ git -C "$flake3Dir" commit flake.nix -m 'bla'
|
|||
|
||||
rm "$flake3Dir/flake.lock"
|
||||
nix flake lock "$flake3Dir"
|
||||
[[ "$(nix flake metadata --json "$flake3Dir" | jq -r .locks.nodes.flake1.locked.rev)" = $newFlake1Rev ]]
|
||||
[[ "$(nix flake metadata --json "$flake3Dir" | jq -r .locks.nodes.flake1.locked.rev)" = "$newFlake1Rev" ]]
|
||||
|
||||
cat > "$flake3Dir/flake.nix" <<EOF
|
||||
{
|
||||
|
|
@ -470,7 +472,7 @@ cat > "$flake3Dir/flake.nix" <<EOF
|
|||
}
|
||||
EOF
|
||||
|
||||
[[ "$(nix flake metadata --json "$flake3Dir" | jq -r .locks.nodes.flake1.locked.rev)" = $prevFlake1Rev ]]
|
||||
[[ "$(nix flake metadata --json "$flake3Dir" | jq -r .locks.nodes.flake1.locked.rev)" = "$prevFlake1Rev" ]]
|
||||
|
||||
baseDir=$TEST_ROOT/$RANDOM
|
||||
subdirFlakeDir1=$baseDir/foo1
|
||||
|
|
|
|||
|
|
@ -11,13 +11,13 @@ flakeFollowsD=$TEST_ROOT/follows/flakeA/flakeD
|
|||
flakeFollowsE=$TEST_ROOT/follows/flakeA/flakeE
|
||||
|
||||
# Test following path flakerefs.
|
||||
createGitRepo $flakeFollowsA
|
||||
mkdir -p $flakeFollowsB
|
||||
mkdir -p $flakeFollowsC
|
||||
mkdir -p $flakeFollowsD
|
||||
mkdir -p $flakeFollowsE
|
||||
createGitRepo "$flakeFollowsA"
|
||||
mkdir -p "$flakeFollowsB"
|
||||
mkdir -p "$flakeFollowsC"
|
||||
mkdir -p "$flakeFollowsD"
|
||||
mkdir -p "$flakeFollowsE"
|
||||
|
||||
cat > $flakeFollowsA/flake.nix <<EOF
|
||||
cat > "$flakeFollowsA"/flake.nix <<EOF
|
||||
{
|
||||
description = "Flake A";
|
||||
inputs = {
|
||||
|
|
@ -32,7 +32,7 @@ cat > $flakeFollowsA/flake.nix <<EOF
|
|||
}
|
||||
EOF
|
||||
|
||||
cat > $flakeFollowsB/flake.nix <<EOF
|
||||
cat > "$flakeFollowsB"/flake.nix <<EOF
|
||||
{
|
||||
description = "Flake B";
|
||||
inputs = {
|
||||
|
|
@ -47,7 +47,7 @@ cat > $flakeFollowsB/flake.nix <<EOF
|
|||
}
|
||||
EOF
|
||||
|
||||
cat > $flakeFollowsC/flake.nix <<EOF
|
||||
cat > "$flakeFollowsC"/flake.nix <<EOF
|
||||
{
|
||||
description = "Flake C";
|
||||
inputs = {
|
||||
|
|
@ -58,7 +58,7 @@ cat > $flakeFollowsC/flake.nix <<EOF
|
|||
}
|
||||
EOF
|
||||
|
||||
cat > $flakeFollowsD/flake.nix <<EOF
|
||||
cat > "$flakeFollowsD"/flake.nix <<EOF
|
||||
{
|
||||
description = "Flake D";
|
||||
inputs = {};
|
||||
|
|
@ -66,7 +66,7 @@ cat > $flakeFollowsD/flake.nix <<EOF
|
|||
}
|
||||
EOF
|
||||
|
||||
cat > $flakeFollowsE/flake.nix <<EOF
|
||||
cat > "$flakeFollowsE"/flake.nix <<EOF
|
||||
{
|
||||
description = "Flake E";
|
||||
inputs = {};
|
||||
|
|
@ -74,32 +74,32 @@ cat > $flakeFollowsE/flake.nix <<EOF
|
|||
}
|
||||
EOF
|
||||
|
||||
git -C $flakeFollowsA add flake.nix flakeB/flake.nix \
|
||||
git -C "$flakeFollowsA" add flake.nix flakeB/flake.nix \
|
||||
flakeB/flakeC/flake.nix flakeD/flake.nix flakeE/flake.nix
|
||||
|
||||
nix flake metadata $flakeFollowsA
|
||||
nix flake metadata "$flakeFollowsA"
|
||||
|
||||
nix flake update --flake $flakeFollowsA
|
||||
nix flake update --flake "$flakeFollowsA"
|
||||
|
||||
nix flake lock $flakeFollowsA
|
||||
nix flake lock "$flakeFollowsA"
|
||||
|
||||
oldLock="$(cat "$flakeFollowsA/flake.lock")"
|
||||
|
||||
# Ensure that locking twice doesn't change anything
|
||||
|
||||
nix flake lock $flakeFollowsA
|
||||
nix flake lock "$flakeFollowsA"
|
||||
|
||||
newLock="$(cat "$flakeFollowsA/flake.lock")"
|
||||
|
||||
diff <(echo "$newLock") <(echo "$oldLock")
|
||||
|
||||
[[ $(jq -c .nodes.B.inputs.C $flakeFollowsA/flake.lock) = '"C"' ]]
|
||||
[[ $(jq -c .nodes.B.inputs.foobar $flakeFollowsA/flake.lock) = '["foobar"]' ]]
|
||||
[[ $(jq -c .nodes.C.inputs.foobar $flakeFollowsA/flake.lock) = '["B","foobar"]' ]]
|
||||
[[ $(jq -c .nodes.B.inputs.C "$flakeFollowsA"/flake.lock) = '"C"' ]]
|
||||
[[ $(jq -c .nodes.B.inputs.foobar "$flakeFollowsA"/flake.lock) = '["foobar"]' ]]
|
||||
[[ $(jq -c .nodes.C.inputs.foobar "$flakeFollowsA"/flake.lock) = '["B","foobar"]' ]]
|
||||
|
||||
# Ensure removing follows from flake.nix removes them from the lockfile
|
||||
|
||||
cat > $flakeFollowsA/flake.nix <<EOF
|
||||
cat > "$flakeFollowsA"/flake.nix <<EOF
|
||||
{
|
||||
description = "Flake A";
|
||||
inputs = {
|
||||
|
|
@ -112,13 +112,13 @@ cat > $flakeFollowsA/flake.nix <<EOF
|
|||
}
|
||||
EOF
|
||||
|
||||
nix flake lock $flakeFollowsA
|
||||
nix flake lock "$flakeFollowsA"
|
||||
|
||||
[[ $(jq -c .nodes.B.inputs.foobar $flakeFollowsA/flake.lock) = '"foobar"' ]]
|
||||
jq -r -c '.nodes | keys | .[]' $flakeFollowsA/flake.lock | grep "^foobar$"
|
||||
[[ $(jq -c .nodes.B.inputs.foobar "$flakeFollowsA"/flake.lock) = '"foobar"' ]]
|
||||
jq -r -c '.nodes | keys | .[]' "$flakeFollowsA"/flake.lock | grep "^foobar$"
|
||||
|
||||
# Check that path: inputs cannot escape from their root.
|
||||
cat > $flakeFollowsA/flake.nix <<EOF
|
||||
cat > "$flakeFollowsA"/flake.nix <<EOF
|
||||
{
|
||||
description = "Flake A";
|
||||
inputs = {
|
||||
|
|
@ -128,13 +128,13 @@ cat > $flakeFollowsA/flake.nix <<EOF
|
|||
}
|
||||
EOF
|
||||
|
||||
git -C $flakeFollowsA add flake.nix
|
||||
git -C "$flakeFollowsA" add flake.nix
|
||||
|
||||
expect 1 nix flake lock $flakeFollowsA 2>&1 | grep '/flakeB.*is forbidden in pure evaluation mode'
|
||||
expect 1 nix flake lock --impure $flakeFollowsA 2>&1 | grep "'flakeB' is too short to be a valid store path"
|
||||
expect 1 nix flake lock "$flakeFollowsA" 2>&1 | grep '/flakeB.*is forbidden in pure evaluation mode'
|
||||
expect 1 nix flake lock --impure "$flakeFollowsA" 2>&1 | grep "'flakeB' is too short to be a valid store path"
|
||||
|
||||
# Test relative non-flake inputs.
|
||||
cat > $flakeFollowsA/flake.nix <<EOF
|
||||
cat > "$flakeFollowsA"/flake.nix <<EOF
|
||||
{
|
||||
description = "Flake A";
|
||||
inputs = {
|
||||
|
|
@ -145,16 +145,16 @@ cat > $flakeFollowsA/flake.nix <<EOF
|
|||
}
|
||||
EOF
|
||||
|
||||
echo 123 > $flakeFollowsA/foo.nix
|
||||
echo 123 > "$flakeFollowsA"/foo.nix
|
||||
|
||||
git -C $flakeFollowsA add flake.nix foo.nix
|
||||
git -C "$flakeFollowsA" add flake.nix foo.nix
|
||||
|
||||
nix flake lock $flakeFollowsA
|
||||
nix flake lock "$flakeFollowsA"
|
||||
|
||||
[[ $(nix eval --json $flakeFollowsA#e) = 123 ]]
|
||||
[[ $(nix eval --json "$flakeFollowsA"#e) = 123 ]]
|
||||
|
||||
# Non-existant follows should print a warning.
|
||||
cat >$flakeFollowsA/flake.nix <<EOF
|
||||
cat >"$flakeFollowsA"/flake.nix <<EOF
|
||||
{
|
||||
description = "Flake A";
|
||||
inputs.B = {
|
||||
|
|
@ -167,7 +167,7 @@ cat >$flakeFollowsA/flake.nix <<EOF
|
|||
}
|
||||
EOF
|
||||
|
||||
git -C $flakeFollowsA add flake.nix
|
||||
git -C "$flakeFollowsA" add flake.nix
|
||||
|
||||
nix flake lock "$flakeFollowsA" 2>&1 | grep "warning: input 'B' has an override for a non-existent input 'invalid'"
|
||||
nix flake lock "$flakeFollowsA" 2>&1 | grep "warning: input 'B' has an override for a non-existent input 'invalid2'"
|
||||
|
|
@ -269,7 +269,7 @@ flakeFollowCycle="$TEST_ROOT/follows/followCycle"
|
|||
# Test following path flakerefs.
|
||||
mkdir -p "$flakeFollowCycle"
|
||||
|
||||
cat > $flakeFollowCycle/flake.nix <<EOF
|
||||
cat > "$flakeFollowCycle"/flake.nix <<EOF
|
||||
{
|
||||
description = "Flake A";
|
||||
inputs = {
|
||||
|
|
@ -281,8 +281,9 @@ cat > $flakeFollowCycle/flake.nix <<EOF
|
|||
}
|
||||
EOF
|
||||
|
||||
# shellcheck disable=SC2015
|
||||
checkRes=$(nix flake lock "$flakeFollowCycle" 2>&1 && fail "nix flake lock should have failed." || true)
|
||||
echo $checkRes | grep -F "error: follow cycle detected: [baz -> foo -> bar -> baz]"
|
||||
echo "$checkRes" | grep -F "error: follow cycle detected: [baz -> foo -> bar -> baz]"
|
||||
|
||||
|
||||
# Test transitive input url locking
|
||||
|
|
@ -362,22 +363,22 @@ echo "$json" | jq .locks.nodes.C.original
|
|||
|
||||
# Test deep overrides, e.g. `inputs.B.inputs.C.inputs.D.follows = ...`.
|
||||
|
||||
cat <<EOF > $flakeFollowsD/flake.nix
|
||||
cat <<EOF > "$flakeFollowsD"/flake.nix
|
||||
{ outputs = _: {}; }
|
||||
EOF
|
||||
cat <<EOF > $flakeFollowsC/flake.nix
|
||||
cat <<EOF > "$flakeFollowsC"/flake.nix
|
||||
{
|
||||
inputs.D.url = "path:nosuchflake";
|
||||
outputs = _: {};
|
||||
}
|
||||
EOF
|
||||
cat <<EOF > $flakeFollowsB/flake.nix
|
||||
cat <<EOF > "$flakeFollowsB"/flake.nix
|
||||
{
|
||||
inputs.C.url = "path:$flakeFollowsC";
|
||||
outputs = _: {};
|
||||
}
|
||||
EOF
|
||||
cat <<EOF > $flakeFollowsA/flake.nix
|
||||
cat <<EOF > "$flakeFollowsA"/flake.nix
|
||||
{
|
||||
inputs.B.url = "path:$flakeFollowsB";
|
||||
inputs.D.url = "path:$flakeFollowsD";
|
||||
|
|
@ -386,26 +387,26 @@ cat <<EOF > $flakeFollowsA/flake.nix
|
|||
}
|
||||
EOF
|
||||
|
||||
nix flake lock $flakeFollowsA
|
||||
nix flake lock "$flakeFollowsA"
|
||||
|
||||
[[ $(jq -c .nodes.C.inputs.D $flakeFollowsA/flake.lock) = '["D"]' ]]
|
||||
[[ $(jq -c .nodes.C.inputs.D "$flakeFollowsA"/flake.lock) = '["D"]' ]]
|
||||
|
||||
# Test overlapping flake follows: B has D follow C/D, while A has B/C follow C
|
||||
|
||||
cat <<EOF > $flakeFollowsC/flake.nix
|
||||
cat <<EOF > "$flakeFollowsC"/flake.nix
|
||||
{
|
||||
inputs.D.url = "path:$flakeFollowsD";
|
||||
outputs = _: {};
|
||||
}
|
||||
EOF
|
||||
cat <<EOF > $flakeFollowsB/flake.nix
|
||||
cat <<EOF > "$flakeFollowsB"/flake.nix
|
||||
{
|
||||
inputs.C.url = "path:nosuchflake";
|
||||
inputs.D.follows = "C/D";
|
||||
outputs = _: {};
|
||||
}
|
||||
EOF
|
||||
cat <<EOF > $flakeFollowsA/flake.nix
|
||||
cat <<EOF > "$flakeFollowsA"/flake.nix
|
||||
{
|
||||
inputs.B.url = "path:$flakeFollowsB";
|
||||
inputs.C.url = "path:$flakeFollowsC";
|
||||
|
|
@ -415,12 +416,12 @@ cat <<EOF > $flakeFollowsA/flake.nix
|
|||
EOF
|
||||
|
||||
# bug was not triggered without recreating the lockfile
|
||||
nix flake lock $flakeFollowsA --recreate-lock-file
|
||||
nix flake lock "$flakeFollowsA" --recreate-lock-file
|
||||
|
||||
[[ $(jq -c .nodes.B.inputs.D $flakeFollowsA/flake.lock) = '["B","C","D"]' ]]
|
||||
[[ $(jq -c .nodes.B.inputs.D "$flakeFollowsA"/flake.lock) = '["B","C","D"]' ]]
|
||||
|
||||
# Check that you can't have both a flakeref and a follows attribute on an input.
|
||||
cat <<EOF > $flakeFollowsB/flake.nix
|
||||
cat <<EOF > "$flakeFollowsB"/flake.nix
|
||||
{
|
||||
inputs.C.url = "path:nosuchflake";
|
||||
inputs.D.url = "path:nosuchflake";
|
||||
|
|
@ -429,4 +430,4 @@ cat <<EOF > $flakeFollowsB/flake.nix
|
|||
}
|
||||
EOF
|
||||
|
||||
expectStderr 1 nix flake lock $flakeFollowsA --recreate-lock-file | grepQuiet "flake input has both a flake reference and a follows attribute"
|
||||
expectStderr 1 nix flake lock "$flakeFollowsA" --recreate-lock-file | grepQuiet "flake input has both a flake reference and a follows attribute"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue