Add option --commit-lock-file

This commit is contained in:
Eelco Dolstra 2020-02-05 14:48:49 +01:00
parent e2213d77a2
commit 9d7fb62db6
7 changed files with 42 additions and 27 deletions

View file

@ -321,15 +321,15 @@ static std::string diffLockFiles(const LockedInputs & oldLocks, const LockedInpu
while (i != oldFlat.end() || j != newFlat.end()) { while (i != oldFlat.end() || j != newFlat.end()) {
if (j != newFlat.end() && (i == oldFlat.end() || i->first > j->first)) { if (j != newFlat.end() && (i == oldFlat.end() || i->first > j->first)) {
res += fmt(" added '%s': '%s'\n", concatStringsSep("/", j->first), j->second->lockedRef); res += fmt("* Added '%s': '%s'\n", concatStringsSep("/", j->first), j->second->lockedRef);
++j; ++j;
} else if (i != oldFlat.end() && (j == newFlat.end() || i->first < j->first)) { } else if (i != oldFlat.end() && (j == newFlat.end() || i->first < j->first)) {
res += fmt(" removed '%s'\n", concatStringsSep("/", i->first)); res += fmt("* Removed '%s'\n", concatStringsSep("/", i->first));
++i; ++i;
} else { } else {
if (!(i->second->lockedRef == j->second->lockedRef)) { if (!(i->second->lockedRef == j->second->lockedRef)) {
assert(i->second->lockedRef.to_string() != j->second->lockedRef.to_string()); assert(i->second->lockedRef.to_string() != j->second->lockedRef.to_string());
res += fmt(" updated '%s': '%s' -> '%s'\n", res += fmt("* Updated '%s': '%s' -> '%s'\n",
concatStringsSep("/", i->first), concatStringsSep("/", i->first),
i->second->lockedRef, i->second->lockedRef,
j->second->lockedRef); j->second->lockedRef);
@ -558,8 +558,10 @@ LockedFlake lockFlake(
/* Check whether we need to / can write the new lock file. */ /* Check whether we need to / can write the new lock file. */
if (!(newLockFile == oldLockFile)) { if (!(newLockFile == oldLockFile)) {
auto diff = diffLockFiles(oldLockFile, newLockFile);
if (!(oldLockFile == LockFile())) if (!(oldLockFile == LockFile()))
printInfo("inputs of flake '%s' changed:\n%s", topRef, chomp(diffLockFiles(oldLockFile, newLockFile))); printInfo("inputs of flake '%s' changed:\n%s", topRef, chomp(diff));
if (lockFlags.writeLockFile) { if (lockFlags.writeLockFile) {
if (auto sourcePath = topRef.input->getSourcePath()) { if (auto sourcePath = topRef.input->getSourcePath()) {
@ -572,7 +574,9 @@ LockedFlake lockFlake(
auto path = *sourcePath + (topRef.subdir == "" ? "" : "/" + topRef.subdir) + "/flake.lock"; auto path = *sourcePath + (topRef.subdir == "" ? "" : "/" + topRef.subdir) + "/flake.lock";
if (pathExists(path)) bool lockFileExists = pathExists(path);
if (lockFileExists)
warn("updating lock file '%s'", path); warn("updating lock file '%s'", path);
else else
warn("creating lock file '%s'", path); warn("creating lock file '%s'", path);
@ -580,7 +584,10 @@ LockedFlake lockFlake(
newLockFile.write(path); newLockFile.write(path);
topRef.input->markChangedFile( topRef.input->markChangedFile(
(topRef.subdir == "" ? "" : topRef.subdir + "/") + "flake.lock"); (topRef.subdir == "" ? "" : topRef.subdir + "/") + "flake.lock",
lockFlags.commitLockFile
? std::optional<std::string>(fmt("flake.lock: %s\n\nFlake input changes:\n\n%s", lockFileExists ? "Update" : "Add", diff))
: std::nullopt);
/* Rewriting the lockfile changed the top-level /* Rewriting the lockfile changed the top-level
repo, so we should re-read it. FIXME: we could repo, so we should re-read it. FIXME: we could

View file

@ -78,6 +78,9 @@ struct LockFlags
allowed. */ allowed. */
bool allowMutable = true; bool allowMutable = true;
/* Whether to commit changes to flake.lock. */
bool commitLockFile = false;
/* Flake inputs to be overriden. */ /* Flake inputs to be overriden. */
std::map<InputPath, FlakeRef> inputOverrides; std::map<InputPath, FlakeRef> inputOverrides;

View file

@ -62,8 +62,10 @@ 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(
virtual void markChangedFile(std::string_view file) const { assert(false); } std::string_view file,
std::optional<std::string> commitMsg) const
{ assert(false); }
virtual void clone(const Path & destDir) const virtual void clone(const Path & destDir) const
{ {

View file

@ -169,17 +169,17 @@ struct GitInput : Input
return url.path; return url.path;
return {}; return {};
} }
void markChangedFile(std::string_view file, std::optional<std::string> commitMsg) const override
void markChangedFile(std::string_view file) const override
{ {
auto sourcePath = getSourcePath(); auto sourcePath = getSourcePath();
assert(sourcePath); assert(sourcePath);
runProgram("git", true, runProgram("git", true,
{ "-C", *sourcePath, "add", { "-C", *sourcePath, "add", "--force", "--intent-to-add", std::string(file) });
"--force",
"--intent-to-add", if (commitMsg)
std::string(file) runProgram("git", true,
}); { "-C", *sourcePath, "commit", std::string(file), "-m", *commitMsg });
} }
std::pair<bool, std::string> getActualUrl() const std::pair<bool, std::string> getActualUrl() const

View file

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

View file

@ -39,6 +39,11 @@ MixFlakeOptions::MixFlakeOptions()
.description("don't use flake registries") .description("don't use flake registries")
.set(&lockFlags.useRegistries, false); .set(&lockFlags.useRegistries, false);
mkFlag()
.longName("commit-lock-file")
.description("commit changes to the lock file")
.set(&lockFlags.commitLockFile, true);
mkFlag() mkFlag()
.longName("update-input") .longName("update-input")
.description("update a specific flake input") .description("update a specific flake input")

View file

@ -170,10 +170,9 @@ nix build -o $TEST_ROOT/result $flake2Dir#bar --no-update-lock-file 2>&1 | grep
# But it should succeed without that flag. # But it should succeed without that flag.
nix build -o $TEST_ROOT/result $flake2Dir#bar --no-write-lock-file nix build -o $TEST_ROOT/result $flake2Dir#bar --no-write-lock-file
nix build -o $TEST_ROOT/result $flake2Dir#bar --no-update-lock-file 2>&1 | grep 'requires lock file changes' nix build -o $TEST_ROOT/result $flake2Dir#bar --no-update-lock-file 2>&1 | grep 'requires lock file changes'
nix build -o $TEST_ROOT/result $flake2Dir#bar nix build -o $TEST_ROOT/result $flake2Dir#bar --commit-lock-file
[[ -e $flake2Dir/flake.lock ]] [[ -e $flake2Dir/flake.lock ]]
git -C $flake2Dir add flake.lock [[ -z $(git -C $flake2Dir diff master) ]]
git -C $flake2Dir commit flake.lock -m 'Add flake.lock'
# Rerunning the build should not change the lockfile. # Rerunning the build should not change the lockfile.
nix build -o $TEST_ROOT/result $flake2Dir#bar nix build -o $TEST_ROOT/result $flake2Dir#bar
@ -291,11 +290,7 @@ git -C $flake3Dir commit -m 'Add nonFlakeInputs'
# Check whether `nix build` works with a lockfile which is missing a # Check whether `nix build` works with a lockfile which is missing a
# nonFlakeInputs. # nonFlakeInputs.
nix build -o $TEST_ROOT/result $flake3Dir#sth nix build -o $TEST_ROOT/result $flake3Dir#sth --commit-lock-file
git -C $flake3Dir add flake.lock
git -C $flake3Dir commit -m 'Update nonFlakeInputs'
nix build -o $TEST_ROOT/result flake3#fnord nix build -o $TEST_ROOT/result flake3#fnord
[[ $(cat $TEST_ROOT/result) = FNORD ]] [[ $(cat $TEST_ROOT/result) = FNORD ]]