diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2020-01-29 23:12:58 +0100 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2020-01-29 23:14:27 +0100 |
commit | b9fb3720750a24d8b2fbe6b1491696d6a51dcff3 (patch) | |
tree | 27bef94799d20261c9b49e43bbcd1907a107fde9 /src/libexpr/flake/flake.cc | |
parent | 88b44b1e94735710853bdabb6904073bc77f2ccb (diff) |
Add --update-input flag to update a specific flake input
Typical usage:
$ nix flake update ~/Misc/eelco-configurations/hagbard --update-input nixpkgs
to update the 'nixpkgs' input of a flake while leaving every other
input unchanged.
The argument is an input path, so you can do e.g. '--update-input
dwarffs/nixpkgs' to update an input of an input.
Fixes #2928.
Diffstat (limited to 'src/libexpr/flake/flake.cc')
-rw-r--r-- | src/libexpr/flake/flake.cc | 53 |
1 files changed, 38 insertions, 15 deletions
diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc index c752eeedc..a8f05efb6 100644 --- a/src/libexpr/flake/flake.cc +++ b/src/libexpr/flake/flake.cc @@ -394,7 +394,13 @@ LockedFlake lockFlake( continue; } - auto oldLock = oldLocks.inputs.find(id); + /* Do we have an entry in the existing lock file? And + we don't have a --update-input flag for this + input? */ + auto oldLock = + lockFlags.inputUpdates.count(inputPath) + ? oldLocks.inputs.end() + : oldLocks.inputs.find(id); if (oldLock != oldLocks.inputs.end() && oldLock->second.originalRef == input.ref && !hasOverride) { /* Copy the input from the old lock file if its @@ -402,22 +408,39 @@ LockedFlake lockFlake( from a higher level flake. */ newLocks.inputs.insert_or_assign(id, oldLock->second); - /* However there may be new overrides on the - inputs of this flake, so we need to check those - (without fetching this flake - we need to be - lazy). */ - FlakeInputs fakeInputs; + /* If we have an --update-input flag for an input + of this input, then we must fetch the flake to + to update it. */ + auto lb = lockFlags.inputUpdates.lower_bound(inputPath); - for (auto & i : oldLock->second.inputs) { - fakeInputs.emplace(i.first, FlakeInput { - .ref = i.second.originalRef - }); - } + auto hasChildUpdate = + lb != lockFlags.inputUpdates.end() + && lb->size() > inputPath.size() + && std::equal(inputPath.begin(), inputPath.end(), lb->begin()); + + if (hasChildUpdate) { + auto inputFlake = getFlake(state, oldLock->second.ref, false, flakeCache); + + updateLocks(inputFlake.inputs, + (const LockedInputs &) oldLock->second, + newLocks.inputs.find(id)->second, + inputPath); - updateLocks(fakeInputs, - oldLock->second, - newLocks.inputs.find(id)->second, - inputPath); + } else { + /* No need to fetch this flake, we can be + lazy. However there may be new overrides on + the inputs of this flake, so we need to + check those. */ + FlakeInputs fakeInputs; + + for (auto & i : oldLock->second.inputs) + fakeInputs.emplace(i.first, FlakeInput { .ref = i.second.originalRef }); + + updateLocks(fakeInputs, + oldLock->second, + newLocks.inputs.find(id)->second, + inputPath); + } } else { /* We need to update/create a new lock file |