From 9d7fb62db6e8ee6da7f8dbc5f5509271dc12f2ba Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 5 Feb 2020 14:48:49 +0100 Subject: [PATCH] Add option --commit-lock-file --- src/libexpr/flake/flake.cc | 19 +++++++++++++------ src/libexpr/flake/flake.hh | 3 +++ src/libstore/fetchers/fetchers.hh | 6 ++++-- src/libstore/fetchers/git.cc | 14 +++++++------- src/libstore/fetchers/mercurial.cc | 11 +++++++---- src/nix/installables.cc | 5 +++++ tests/flakes.sh | 11 +++-------- 7 files changed, 42 insertions(+), 27 deletions(-) diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc index a0f41e6b9..5f64b76d9 100644 --- a/src/libexpr/flake/flake.cc +++ b/src/libexpr/flake/flake.cc @@ -321,15 +321,15 @@ static std::string diffLockFiles(const LockedInputs & oldLocks, const LockedInpu while (i != oldFlat.end() || j != newFlat.end()) { 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; } 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; } else { if (!(i->second->lockedRef == j->second->lockedRef)) { 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), i->second->lockedRef, j->second->lockedRef); @@ -558,8 +558,10 @@ LockedFlake lockFlake( /* Check whether we need to / can write the new lock file. */ if (!(newLockFile == oldLockFile)) { + auto diff = diffLockFiles(oldLockFile, newLockFile); + 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 (auto sourcePath = topRef.input->getSourcePath()) { @@ -572,7 +574,9 @@ LockedFlake lockFlake( auto path = *sourcePath + (topRef.subdir == "" ? "" : "/" + topRef.subdir) + "/flake.lock"; - if (pathExists(path)) + bool lockFileExists = pathExists(path); + + if (lockFileExists) warn("updating lock file '%s'", path); else warn("creating lock file '%s'", path); @@ -580,7 +584,10 @@ LockedFlake lockFlake( newLockFile.write(path); topRef.input->markChangedFile( - (topRef.subdir == "" ? "" : topRef.subdir + "/") + "flake.lock"); + (topRef.subdir == "" ? "" : topRef.subdir + "/") + "flake.lock", + lockFlags.commitLockFile + ? std::optional(fmt("flake.lock: %s\n\nFlake input changes:\n\n%s", lockFileExists ? "Update" : "Add", diff)) + : std::nullopt); /* Rewriting the lockfile changed the top-level repo, so we should re-read it. FIXME: we could diff --git a/src/libexpr/flake/flake.hh b/src/libexpr/flake/flake.hh index 4eb36236c..7c71f3383 100644 --- a/src/libexpr/flake/flake.hh +++ b/src/libexpr/flake/flake.hh @@ -78,6 +78,9 @@ struct LockFlags allowed. */ bool allowMutable = true; + /* Whether to commit changes to flake.lock. */ + bool commitLockFile = false; + /* Flake inputs to be overriden. */ std::map inputOverrides; diff --git a/src/libstore/fetchers/fetchers.hh b/src/libstore/fetchers/fetchers.hh index 64628d1bb..9fafbffb6 100644 --- a/src/libstore/fetchers/fetchers.hh +++ b/src/libstore/fetchers/fetchers.hh @@ -62,8 +62,10 @@ struct Input : std::enable_shared_from_this virtual std::optional getSourcePath() const { return {}; } - // FIXME: should merge with getSourcePath(). - virtual void markChangedFile(std::string_view file) const { assert(false); } + virtual void markChangedFile( + std::string_view file, + std::optional commitMsg) const + { assert(false); } virtual void clone(const Path & destDir) const { diff --git a/src/libstore/fetchers/git.cc b/src/libstore/fetchers/git.cc index 35a5c18b5..134d44ecd 100644 --- a/src/libstore/fetchers/git.cc +++ b/src/libstore/fetchers/git.cc @@ -169,17 +169,17 @@ struct GitInput : Input return url.path; return {}; } - - void markChangedFile(std::string_view file) const override + void markChangedFile(std::string_view file, std::optional commitMsg) const override { auto sourcePath = getSourcePath(); assert(sourcePath); + runProgram("git", true, - { "-C", *sourcePath, "add", - "--force", - "--intent-to-add", - std::string(file) - }); + { "-C", *sourcePath, "add", "--force", "--intent-to-add", std::string(file) }); + + if (commitMsg) + runProgram("git", true, + { "-C", *sourcePath, "commit", std::string(file), "-m", *commitMsg }); } std::pair getActualUrl() const diff --git a/src/libstore/fetchers/mercurial.cc b/src/libstore/fetchers/mercurial.cc index 0825f6b23..6ab0add1d 100644 --- a/src/libstore/fetchers/mercurial.cc +++ b/src/libstore/fetchers/mercurial.cc @@ -84,15 +84,18 @@ struct MercurialInput : Input return {}; } - void markChangedFile(std::string_view file) const override + void markChangedFile(std::string_view file, std::optional commitMsg) const override { auto sourcePath = getSourcePath(); assert(sourcePath); + // FIXME: shut up if file is already tracked. runProgram("hg", true, - { "add", - *sourcePath + "/" + std::string(file) - }); + { "add", *sourcePath + "/" + std::string(file) }); + + if (commitMsg) + runProgram("hg", true, + { "commit", *sourcePath + "/" + std::string(file), "-m", *commitMsg }); } std::pair getActualUrl() const diff --git a/src/nix/installables.cc b/src/nix/installables.cc index 545b5e839..752a1466f 100644 --- a/src/nix/installables.cc +++ b/src/nix/installables.cc @@ -39,6 +39,11 @@ MixFlakeOptions::MixFlakeOptions() .description("don't use flake registries") .set(&lockFlags.useRegistries, false); + mkFlag() + .longName("commit-lock-file") + .description("commit changes to the lock file") + .set(&lockFlags.commitLockFile, true); + mkFlag() .longName("update-input") .description("update a specific flake input") diff --git a/tests/flakes.sh b/tests/flakes.sh index 63e7f8e87..434f5cb7a 100644 --- a/tests/flakes.sh +++ b/tests/flakes.sh @@ -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. 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 +nix build -o $TEST_ROOT/result $flake2Dir#bar --commit-lock-file [[ -e $flake2Dir/flake.lock ]] -git -C $flake2Dir add flake.lock -git -C $flake2Dir commit flake.lock -m 'Add flake.lock' +[[ -z $(git -C $flake2Dir diff master) ]] # Rerunning the build should not change the lockfile. 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 # nonFlakeInputs. -nix build -o $TEST_ROOT/result $flake3Dir#sth - -git -C $flake3Dir add flake.lock - -git -C $flake3Dir commit -m 'Update nonFlakeInputs' +nix build -o $TEST_ROOT/result $flake3Dir#sth --commit-lock-file nix build -o $TEST_ROOT/result flake3#fnord [[ $(cat $TEST_ROOT/result) = FNORD ]]