Automatically do git/hg add on flake.lock

This commit is contained in:
Eelco Dolstra 2020-02-02 16:32:46 +01:00
parent f83acbbfe3
commit d5334c466b
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
5 changed files with 47 additions and 23 deletions

View file

@ -579,22 +579,23 @@ LockedFlake lockFlake(
newLockFile.write(path); newLockFile.write(path);
// Rewriting the lockfile changed the top-level topRef.input->markChangedFile(
// repo, so we should re-read it. (topRef.subdir == "" ? "" : topRef.subdir + "/") + "flake.lock");
/* Rewriting the lockfile changed the top-level
repo, so we should re-read it. FIXME: we could
also just clear the 'rev' field... */
auto prevLockedRef = flake.lockedRef;
FlakeCache dummyCache; FlakeCache dummyCache;
flake = getFlake(state, topRef, {}, lockFlags.useRegistries, dummyCache); flake = getFlake(state, topRef, {}, lockFlags.useRegistries, dummyCache);
if (flake.lockedRef.input->isImmutable()) /* Make sure that we picked up the change,
i.e. the tree should usually be dirty
now. Corner case: we could have reverted from a
dirty to a clean tree! */
if (flake.lockedRef.input == prevLockedRef.input
&& !flake.lockedRef.input->isImmutable())
throw Error("'%s' did not change after I updated its 'flake.lock' file; is 'flake.lock' under version control?", flake.originalRef); throw Error("'%s' did not change after I updated its 'flake.lock' file; is 'flake.lock' under version control?", flake.originalRef);
#if 0
// Hack: Make sure that flake.lock is visible to Git, so it ends up in the Nix store.
runProgram("git", true,
{ "-C", *sourcePath, "add",
"--force",
"--intent-to-add",
(topRef.subdir == "" ? "" : topRef.subdir + "/") + "flake.lock" });
#endif
} }
} else } else
throw Error("cannot write modified lock file of flake '%s' (use '--no-write-lock-file' to ignore)", topRef); throw Error("cannot write modified lock file of flake '%s' (use '--no-write-lock-file' to ignore)", topRef);

View file

@ -62,6 +62,9 @@ struct Input : std::enable_shared_from_this<Input>
virtual std::optional<Path> getSourcePath() const { return {}; } virtual std::optional<Path> getSourcePath() const { return {}; }
// FIXME: should merge with getSourcePath().
virtual void markChangedFile(std::string_view file) const { assert(false); }
virtual void clone(const Path & destDir) const virtual void clone(const Path & destDir) const
{ {
throw Error("do not know how to clone input '%s'", to_string()); throw Error("do not know how to clone input '%s'", to_string());

View file

@ -165,6 +165,18 @@ struct GitInput : Input
return {}; return {};
} }
void markChangedFile(std::string_view file) const override
{
auto sourcePath = getSourcePath();
assert(sourcePath);
runProgram("git", true,
{ "-C", *sourcePath, "add",
"--force",
"--intent-to-add",
std::string(file)
});
}
std::pair<bool, std::string> getActualUrl() const std::pair<bool, std::string> getActualUrl() const
{ {
// Don't clone file:// URIs (but otherwise treat them the // Don't clone file:// URIs (but otherwise treat them the

View file

@ -84,6 +84,17 @@ struct MercurialInput : Input
return {}; return {};
} }
void markChangedFile(std::string_view file) const override
{
auto sourcePath = getSourcePath();
assert(sourcePath);
// FIXME: shut up if file is already tracked.
runProgram("hg", true,
{ "add",
*sourcePath + "/" + std::string(file)
});
}
std::pair<bool, std::string> getActualUrl() const std::pair<bool, std::string> getActualUrl() const
{ {
bool isLocal = url.scheme == "file"; bool isLocal = url.scheme == "file";

View file

@ -5,6 +5,11 @@ if [[ -z $(type -p git) ]]; then
exit 99 exit 99
fi fi
if [[ -z $(type -p hg) ]]; then
echo "Mercurial not installed; skipping flake tests"
exit 99
fi
clearStore clearStore
rm -rf $TEST_HOME/.cache $TEST_HOME/.config rm -rf $TEST_HOME/.cache $TEST_HOME/.config
@ -372,7 +377,7 @@ nix flake remove flake1
(cd $flake7Dir && nix flake init) (cd $flake7Dir && nix flake init)
git -C $flake7Dir add flake.nix git -C $flake7Dir add flake.nix
nix flake check $flake7Dir nix flake check $flake7Dir
git -C $flake7Dir commit -m 'Initial' git -C $flake7Dir commit -a -m 'Initial'
# Test 'nix flake clone'. # Test 'nix flake clone'.
rm -rf $TEST_ROOT/flake1-v2 rm -rf $TEST_ROOT/flake1-v2
@ -545,11 +550,6 @@ nix flake update $flake3Dir --recreate-lock-file
[[ $(jq .inputs.flake2.inputs.flake1.locked.url $flake3Dir/flake.lock) =~ flake7 ]] [[ $(jq .inputs.flake2.inputs.flake1.locked.url $flake3Dir/flake.lock) =~ flake7 ]]
# Test Mercurial flakes. # Test Mercurial flakes.
if [[ -z $(type -p hg) ]]; then
echo "Git not installed; skipping Mercurial flake tests"
exit 99
fi
rm -rf $flake5Dir rm -rf $flake5Dir
hg init $flake5Dir hg init $flake5Dir
@ -571,12 +571,9 @@ hg commit --config ui.username=foobar@example.org $flake5Dir -m 'Initial commit'
nix build -o $TEST_ROOT/result hg+file://$flake5Dir nix build -o $TEST_ROOT/result hg+file://$flake5Dir
[[ -e $TEST_ROOT/result/hello ]] [[ -e $TEST_ROOT/result/hello ]]
nix flake info --json hg+file://$flake5Dir | jq -e -r .revision (! nix flake info --json hg+file://$flake5Dir | jq -e -r .revision)
# This will fail because flake.lock is not tracked by Mercurial. nix eval hg+file://$flake5Dir#expr
(! nix eval hg+file://$flake5Dir#expr)
hg add $flake5Dir/flake.lock
nix eval hg+file://$flake5Dir#expr nix eval hg+file://$flake5Dir#expr