Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: NixOS/nix
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: d132d057a85a
Choose a base ref
...
head repository: NixOS/nix
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: d4fe9daed6f4
Choose a head ref
  • 2 commits
  • 4 files changed
  • 1 contributor

Commits on Jun 21, 2019

  1. Don't update the global registry when building a locked flake

    It's unnecessary and slows things down (e.g. when you're on a Thalys
    with super-crappy Internet).
    edolstra committed Jun 21, 2019

    Verified

    This commit was signed with the committer’s verified signature.
    elevenfive Matthew Zavislak
    Copy the full SHA
    aa28461 View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    d4fe9da View commit details
Showing with 48 additions and 31 deletions.
  1. +29 −19 src/libexpr/flake/flake.cc
  2. +8 −1 src/libexpr/flake/flake.hh
  3. +4 −3 src/nix/flake.cc
  4. +7 −8 tests/flakes.sh
48 changes: 29 additions & 19 deletions src/libexpr/flake/flake.cc
Original file line number Diff line number Diff line change
@@ -89,9 +89,6 @@ FlakeRef updateFlakeRef(EvalState & state, const FlakeRef & newRef, const Regist
static FlakeRef lookupFlake(EvalState & state, const FlakeRef & flakeRef, const Registries & registries,
std::vector<FlakeRef> pastSearches)
{
if (registries.empty() && !flakeRef.isDirect())
throw Error("indirect flake reference '%s' is not allowed", flakeRef);

for (std::shared_ptr<FlakeRegistry> registry : registries) {
auto i = registry->entries.find(flakeRef);
if (i != registry->entries.end()) {
@@ -115,14 +112,24 @@ static FlakeRef lookupFlake(EvalState & state, const FlakeRef & flakeRef, const
return flakeRef;
}

// Lookups happen here too
static SourceInfo fetchFlake(EvalState & state, const FlakeRef & flakeRef, bool impureIsAllowed = false)
FlakeRef maybeLookupFlake(
EvalState & state,
const FlakeRef & flakeRef,
bool allowLookup)
{
FlakeRef resolvedRef = lookupFlake(state, flakeRef,
impureIsAllowed ? state.getFlakeRegistries() : std::vector<std::shared_ptr<FlakeRegistry>>());
if (!flakeRef.isDirect()) {
if (allowLookup)
return lookupFlake(state, flakeRef, state.getFlakeRegistries());
else
throw Error("'%s' is an indirect flake reference, but registry lookups are not allowed", flakeRef);
} else
return flakeRef;
}

if (evalSettings.pureEval && !impureIsAllowed && !resolvedRef.isImmutable())
throw Error("requested to fetch mutable flake '%s' in pure mode", resolvedRef);

static SourceInfo fetchFlake(EvalState & state, const FlakeRef & resolvedRef)
{
assert(resolvedRef.isDirect());

auto doGit = [&](const GitInfo & gitInfo) {
FlakeRef ref(resolvedRef.baseRef());
@@ -188,10 +195,9 @@ static SourceInfo fetchFlake(EvalState & state, const FlakeRef & flakeRef, bool
else abort();
}

// This will return the flake which corresponds to a given FlakeRef. The lookupFlake is done within `fetchFlake`, which is used here.
Flake getFlake(EvalState & state, const FlakeRef & flakeRef, bool impureIsAllowed = false)
Flake getFlake(EvalState & state, const FlakeRef & flakeRef)
{
SourceInfo sourceInfo = fetchFlake(state, flakeRef, impureIsAllowed);
SourceInfo sourceInfo = fetchFlake(state, flakeRef);
debug("got flake source '%s' with flakeref %s", sourceInfo.storePath, sourceInfo.resolvedRef.to_string());

FlakeRef resolvedRef = sourceInfo.resolvedRef;
@@ -276,10 +282,9 @@ Flake getFlake(EvalState & state, const FlakeRef & flakeRef, bool impureIsAllowe
return flake;
}

// Get the `NonFlake` corresponding to a `FlakeRef`.
NonFlake getNonFlake(EvalState & state, const FlakeRef & flakeRef, bool impureIsAllowed = false)
NonFlake getNonFlake(EvalState & state, const FlakeRef & flakeRef)
{
auto sourceInfo = fetchFlake(state, flakeRef, impureIsAllowed);
auto sourceInfo = fetchFlake(state, flakeRef);
debug("got non-flake source '%s' with flakeref %s", sourceInfo.storePath, sourceInfo.resolvedRef.to_string());

FlakeRef resolvedRef = sourceInfo.resolvedRef;
@@ -345,7 +350,7 @@ static std::pair<Flake, FlakeInput> updateLocks(
} else {
if (handleLockFile == AllPure || handleLockFile == TopRefUsesRegistries)
throw Error("cannot update non-flake dependency '%s' in pure mode", id);
auto nonFlake = getNonFlake(state, ref, allowedToUseRegistries(handleLockFile, false));
auto nonFlake = getNonFlake(state, maybeLookupFlake(state, ref, allowedToUseRegistries(handleLockFile, false)));
newEntry.nonFlakeInputs.insert_or_assign(id,
NonFlakeInput(
nonFlake.sourceInfo.resolvedRef,
@@ -362,7 +367,7 @@ static std::pair<Flake, FlakeInput> updateLocks(
throw Error("cannot update flake dependency '%s' in pure mode", inputRef);
newEntry.flakeInputs.insert_or_assign(inputRef,
updateLocks(state,
getFlake(state, inputRef, allowedToUseRegistries(handleLockFile, false)),
getFlake(state, maybeLookupFlake(state, inputRef, allowedToUseRegistries(handleLockFile, false))),
handleLockFile, {}, false).second);
}
}
@@ -374,7 +379,7 @@ static std::pair<Flake, FlakeInput> updateLocks(
and optionally write it to file, it the flake is writable. */
ResolvedFlake resolveFlake(EvalState & state, const FlakeRef & topRef, HandleLockFile handleLockFile)
{
auto flake = getFlake(state, topRef, allowedToUseRegistries(handleLockFile, true));
auto flake = getFlake(state, maybeLookupFlake(state, topRef, allowedToUseRegistries(handleLockFile, true)));

LockFile oldLockFile;

@@ -439,7 +444,10 @@ static void emitSourceInfoAttrs(EvalState & state, const SourceInfo & sourceInfo
static void prim_callFlake(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
auto lazyFlake = (FlakeInput *) args[0]->attrs;
auto flake = getFlake(state, lazyFlake->ref, false);

assert(lazyFlake->ref.isImmutable());

auto flake = getFlake(state, lazyFlake->ref);

if (flake.sourceInfo.narHash != lazyFlake->narHash)
throw Error("the content hash of flake '%s' doesn't match the hash recorded in the referring lockfile", flake.sourceInfo.resolvedRef);
@@ -451,6 +459,8 @@ static void prim_callNonFlake(EvalState & state, const Pos & pos, Value * * args
{
auto lazyNonFlake = (NonFlakeInput *) args[0]->attrs;

assert(lazyNonFlake->ref.isImmutable());

auto nonFlake = getNonFlake(state, lazyNonFlake->ref);

if (nonFlake.sourceInfo.narHash != lazyNonFlake->narHash)
9 changes: 8 additions & 1 deletion src/libexpr/flake/flake.hh
Original file line number Diff line number Diff line change
@@ -81,7 +81,14 @@ struct NonFlake
: originalRef(origRef), sourceInfo(sourceInfo) {};
};

Flake getFlake(EvalState &, const FlakeRef &, bool impureIsAllowed);
Flake getFlake(EvalState &, const FlakeRef &);

/* If 'allowLookup' is true, then resolve 'flakeRef' using the
registries. */
FlakeRef maybeLookupFlake(
EvalState & state,
const FlakeRef & flakeRef,
bool allowLookup);

/* Fingerprint of a locked flake; used as a cache key. */
typedef Hash Fingerprint;
7 changes: 4 additions & 3 deletions src/nix/flake.cc
Original file line number Diff line number Diff line change
@@ -38,7 +38,8 @@ class FlakeCommand : virtual Args, public EvalCommand, public MixFlakeOptions
Flake getFlake()
{
auto evalState = getEvalState();
return flake::getFlake(*evalState, getFlakeRef(), useRegistries);
return flake::getFlake(*evalState,
maybeLookupFlake(*evalState, getFlakeRef(), useRegistries));
}

ResolvedFlake resolveFlake()
@@ -425,13 +426,13 @@ struct CmdFlakePin : virtual Args, EvalCommand
FlakeRegistry userRegistry = *readRegistry(userRegistryPath);
auto it = userRegistry.entries.find(FlakeRef(alias));
if (it != userRegistry.entries.end()) {
it->second = getFlake(*evalState, it->second, true).sourceInfo.resolvedRef;
it->second = getFlake(*evalState, maybeLookupFlake(*evalState, it->second, true)).sourceInfo.resolvedRef;
writeRegistry(userRegistry, userRegistryPath);
} else {
std::shared_ptr<FlakeRegistry> globalReg = evalState->getGlobalFlakeRegistry();
it = globalReg->entries.find(FlakeRef(alias));
if (it != globalReg->entries.end()) {
auto newRef = getFlake(*evalState, it->second, true).sourceInfo.resolvedRef;
auto newRef = getFlake(*evalState, maybeLookupFlake(*evalState, it->second, true)).sourceInfo.resolvedRef;
userRegistry.entries.insert_or_assign(alias, newRef);
writeRegistry(userRegistry, userRegistryPath);
} else
15 changes: 7 additions & 8 deletions tests/flakes.sh
Original file line number Diff line number Diff line change
@@ -107,9 +107,6 @@ cat > $registry <<EOF
"flake3": {
"uri": "file://$flake3Dir"
},
"file://$flake4Dir": {
"uri": "file://$flake3Dir"
},
"flake4": {
"uri": "flake3"
},
@@ -122,7 +119,7 @@ cat > $registry <<EOF
EOF

# Test 'nix flake list'.
(( $(nix flake list --flake-registry $registry | wc -l) == 6 ))
(( $(nix flake list --flake-registry $registry | wc -l) == 5 ))

# Test 'nix flake info'.
nix flake info --flake-registry $registry flake1 | grep -q 'ID: *flake1'
@@ -168,6 +165,9 @@ git -C $flake2Dir commit flake.lock -m 'Add flake.lock'
nix build -o $TEST_ROOT/result --flake-registry $registry $flake2Dir:bar
[[ -z $(git -C $flake2Dir diff master) ]]

# Building with a lockfile should not require a fetch of the registry.
nix build -o $TEST_ROOT/result --flake-registry file:///no-registry.json $flake2Dir:bar --tarball-ttl 0

# Updating the flake should not change the lockfile.
nix flake update --flake-registry $registry $flake2Dir
[[ -z $(git -C $flake2Dir diff master) ]]
@@ -297,7 +297,6 @@ nix build -o $TEST_ROOT/result --flake-registry $registry flake3:xyzzy flake3:fn

# Test doing multiple `lookupFlake`s
nix build -o $TEST_ROOT/result --flake-registry $registry flake4:xyzzy
nix build -o $TEST_ROOT/result --flake-registry $registry file://$flake4Dir:xyzzy

# Make branch "removeXyzzy" where flake3 doesn't have xyzzy anymore
git -C $flake3Dir checkout -b removeXyzzy
@@ -344,11 +343,11 @@ nix build -o $TEST_ROOT/result --flake-registry $registry flake4/removeXyzzy:sth

# Testing the nix CLI
nix flake add --flake-registry $registry flake1 flake3
(( $(nix flake list --flake-registry $registry | wc -l) == 7 ))
(( $(nix flake list --flake-registry $registry | wc -l) == 6 ))
nix flake pin --flake-registry $registry flake1
(( $(nix flake list --flake-registry $registry | wc -l) == 7 ))
nix flake remove --flake-registry $registry flake1
(( $(nix flake list --flake-registry $registry | wc -l) == 6 ))
nix flake remove --flake-registry $registry flake1
(( $(nix flake list --flake-registry $registry | wc -l) == 5 ))

(cd $flake7Dir && nix flake init)
nix flake --flake-registry $registry check $flake3Dir