forked from lix-project/lix
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.
This commit is contained in:
parent
88b44b1e94
commit
b9fb372075
|
@ -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,23 +408,40 @@ 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);
|
||||
|
||||
} 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);
|
||||
}
|
||||
|
||||
updateLocks(fakeInputs,
|
||||
oldLock->second,
|
||||
newLocks.inputs.find(id)->second,
|
||||
inputPath);
|
||||
|
||||
} else {
|
||||
/* We need to update/create a new lock file
|
||||
entry. So fetch the flake/non-flake. */
|
||||
|
|
|
@ -78,7 +78,12 @@ struct LockFlags
|
|||
allowed. */
|
||||
bool allowMutable = true;
|
||||
|
||||
/* Flake inputs to be overriden. */
|
||||
std::map<InputPath, FlakeRef> inputOverrides;
|
||||
|
||||
/* Flake inputs to be updated. This means that any existing lock
|
||||
for those inputs will be ignored. */
|
||||
std::set<InputPath> inputUpdates;
|
||||
};
|
||||
|
||||
LockedFlake lockFlake(
|
||||
|
|
|
@ -72,6 +72,22 @@ std::optional<LockedInput *> LockedInputs::findInput(const InputPath & path)
|
|||
return (LockedInput *) pos;
|
||||
}
|
||||
|
||||
void LockedInputs::removeInput(const InputPath & path)
|
||||
{
|
||||
assert(!path.empty());
|
||||
|
||||
LockedInputs * pos = this;
|
||||
|
||||
for (size_t n = 0; n < path.size(); n++) {
|
||||
auto i = pos->inputs.find(path[n]);
|
||||
if (i == pos->inputs.end()) return;
|
||||
if (n + 1 == path.size())
|
||||
pos->inputs.erase(i);
|
||||
else
|
||||
pos = &i->second;
|
||||
}
|
||||
}
|
||||
|
||||
nlohmann::json LockFile::toJson() const
|
||||
{
|
||||
auto json = LockedInputs::toJson();
|
||||
|
|
|
@ -27,6 +27,8 @@ struct LockedInputs
|
|||
bool isImmutable() const;
|
||||
|
||||
std::optional<LockedInput *> findInput(const InputPath & path);
|
||||
|
||||
void removeInput(const InputPath & path);
|
||||
};
|
||||
|
||||
/* Lock file information about a flake input. */
|
||||
|
|
|
@ -39,6 +39,14 @@ MixFlakeOptions::MixFlakeOptions()
|
|||
.description("don't use flake registries")
|
||||
.set(&lockFlags.useRegistries, false);
|
||||
|
||||
mkFlag()
|
||||
.longName("update-input")
|
||||
.description("update a specific flake input")
|
||||
.label("input-path")
|
||||
.handler([&](std::vector<std::string> ss) {
|
||||
lockFlags.inputUpdates.insert(flake::parseInputPath(ss[0]));
|
||||
});
|
||||
|
||||
mkFlag()
|
||||
.longName("override-input")
|
||||
.description("override a specific flake input (e.g. 'dwarffs/nixpkgs')")
|
||||
|
|
|
@ -610,3 +610,10 @@ nix flake update $flake3Dir --override-input flake2/flake1 flake1
|
|||
|
||||
nix flake update $flake3Dir --override-input flake2/flake1 flake1/master/$hash1
|
||||
[[ $(jq .inputs.flake2.inputs.flake1.url $flake3Dir/flake.lock) =~ flake1.*rev=$hash1 ]]
|
||||
|
||||
# Test --update-input.
|
||||
nix flake update $flake3Dir
|
||||
[[ $(jq .inputs.flake2.inputs.flake1.url $flake3Dir/flake.lock) =~ flake1.*rev=$hash1 ]]
|
||||
|
||||
nix flake update $flake3Dir --update-input flake2/flake1
|
||||
[[ $(jq .inputs.flake2.inputs.flake1.url $flake3Dir/flake.lock) =~ flake1.*rev=$hash2 ]]
|
||||
|
|
Loading…
Reference in a new issue