From 159b5815b527f466578a2d28fbf832617cc45b88 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Mon, 31 Jan 2022 18:03:24 +0100 Subject: [PATCH 01/17] repl: `--option pure-eval true` actually enables pure eval mode To quote Eelco in #5867: > Unfortunately we can't do > > evalSettings.pureEval.setDefault(false); > > because then we have to do the same in main.cc (where > pureEval is set to true), and that would allow pure-eval > to be disabled globally from nix.conf. Instead, a command should specify that it should be impure by default. Then, `evalSettings.pureEval` will be set to `false;` unless it's overridden by e.g. a CLI flag. In that case it's IMHO OK to be (theoretically) able to override `pure-eval` via `nix.conf` because it doesn't have an effect on commands where `forceImpureByDefault` returns `false` (i.e. everything where pure eval actually matters). Closes #5867 --- src/libcmd/repl.cc | 7 +++++-- src/libutil/args.hh | 2 ++ src/nix/main.cc | 3 +++ tests/repl.sh | 5 +++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 458e824c5..3c89a8ea3 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -1039,6 +1039,11 @@ struct CmdRepl : StoreCommand, MixEvalArgs }); } + bool forceImpureByDefault() override + { + return true; + } + std::string description() override { return "start an interactive environment for evaluating Nix expressions"; @@ -1053,8 +1058,6 @@ struct CmdRepl : StoreCommand, MixEvalArgs void run(ref store) override { - evalSettings.pureEval = false; - auto evalState = make_ref(searchPath, store); auto repl = std::make_unique(evalState); diff --git a/src/libutil/args.hh b/src/libutil/args.hh index fdd036f9a..07c017719 100644 --- a/src/libutil/args.hh +++ b/src/libutil/args.hh @@ -25,6 +25,8 @@ public: /* Return a short one-line description of the command. */ virtual std::string description() { return ""; } + virtual bool forceImpureByDefault() { return false; } + /* Return documentation about this command, in Markdown format. */ virtual std::string doc() { return ""; } diff --git a/src/nix/main.cc b/src/nix/main.cc index dadb54306..f398e3118 100644 --- a/src/nix/main.cc +++ b/src/nix/main.cc @@ -380,6 +380,9 @@ void mainWrapped(int argc, char * * argv) settings.ttlPositiveNarInfoCache = 0; } + if (args.command->second->forceImpureByDefault() && !evalSettings.pureEval.overridden) { + evalSettings.pureEval = false; + } args.command->second->prepare(); args.command->second->run(); } diff --git a/tests/repl.sh b/tests/repl.sh index b6937b9e9..9e6a59f18 100644 --- a/tests/repl.sh +++ b/tests/repl.sh @@ -42,6 +42,11 @@ testRepl () { echo "$replOutput" echo "$replOutput" | grep -qs "while evaluating the file" \ || fail "nix repl --show-trace doesn't show the trace" + + nix repl "${nixArgs[@]}" --option pure-eval true 2>&1 <<< "builtins.currentSystem" \ + | grep "attribute 'currentSystem' missing" + nix repl "${nixArgs[@]}" 2>&1 <<< "builtins.currentSystem" \ + | grep "$(nix-instantiate --eval -E 'builtins.currentSystem')" } # Simple test, try building a drv From 0cd560c95dd981bde84c93379f6af677d31a2d0b Mon Sep 17 00:00:00 2001 From: Jonpez2 Date: Mon, 6 Jun 2022 16:56:42 +0100 Subject: [PATCH 02/17] Add security.csm to ignored-acls The security.csm ACL is, as far as I know, never reasonable to remove, so let's add it to the ignore-list in the vanilla nix image. This makes this image usable on GKE. --- docker.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/docker.nix b/docker.nix index 0cd64856f..a236d61d3 100644 --- a/docker.nix +++ b/docker.nix @@ -125,6 +125,7 @@ let sandbox = "false"; build-users-group = "nixbld"; trusted-public-keys = "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="; + ignored-acls = security.csm; }; nixConfContents = (lib.concatStringsSep "\n" (lib.mapAttrsFlatten (n: v: "${n} = ${v}") nixConf)) + "\n"; From bf2f25e3d83f980b86fba315388372a1cae8f7d6 Mon Sep 17 00:00:00 2001 From: Malte Brandy Date: Mon, 6 Jun 2022 20:55:05 +0200 Subject: [PATCH 03/17] respect print-missing variable in new-style build command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently nix-build prints the "printMissing" information by default, nix build doesn’t. People generally don‘t notice this because the standard log-format of nix build would not display the printMissing output long enough to perceive the information. This addresses https://github.com/NixOS/nix/issues/6561 --- src/libcmd/installables.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 21db2b08b..39a5c1a9f 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -919,6 +919,9 @@ std::vector, BuiltPath>> Installable::bui break; case Realise::Outputs: { + if (settings.printMissing) + printMissing(store, pathsToBuild, lvlInfo); + for (auto & buildResult : store->buildPathsWithResults(pathsToBuild, bMode, evalStore)) { if (!buildResult.success()) buildResult.rethrow(); From a7d25d339d94993fc8731de658f18a06e0e2a07e Mon Sep 17 00:00:00 2001 From: Jonpez2 Date: Wed, 8 Jun 2022 09:32:14 +0100 Subject: [PATCH 04/17] Add security.csm to the default ignore list --- src/libstore/globals.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index feb6899cd..0ee27ecb6 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -802,7 +802,7 @@ public: )"}; Setting ignoredAcls{ - this, {"security.selinux", "system.nfs4_acl"}, "ignored-acls", + this, {"security.selinux", "system.nfs4_acl", "security.csm"}, "ignored-acls", R"( A list of ACLs that should be ignored, normally Nix attempts to remove all ACLs from files and directories in the Nix store, but From 7b968af93005348477ee19c1eb2c35937b39f249 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 8 Jun 2022 17:41:31 +0200 Subject: [PATCH 05/17] Update docker.nix Co-authored-by: Cole Helbling --- docker.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker.nix b/docker.nix index a236d61d3..cbda39073 100644 --- a/docker.nix +++ b/docker.nix @@ -125,7 +125,7 @@ let sandbox = "false"; build-users-group = "nixbld"; trusted-public-keys = "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="; - ignored-acls = security.csm; + ignored-acls = "security.csm"; }; nixConfContents = (lib.concatStringsSep "\n" (lib.mapAttrsFlatten (n: v: "${n} = ${v}") nixConf)) + "\n"; From 931930feb139e6db0d7c01097003f8e45862f68f Mon Sep 17 00:00:00 2001 From: Bernardo Meurer Date: Wed, 8 Jun 2022 13:45:39 -0400 Subject: [PATCH 06/17] fix(libstore/lock): support users that belong to more than 10 groups The manpage for `getgrouplist` says: > If the number of groups of which user is a member is less than or > equal to *ngroups, then the value *ngroups is returned. > > If the user is a member of more than *ngroups groups, then > getgrouplist() returns -1. In this case, the value returned in > *ngroups can be used to resize the buffer passed to a further > call getgrouplist(). In our original code, however, we allocated a list of size `10` and, if `getgrouplist` returned `-1` threw an exception. In practice, this caused the code to fail for any user belonging to more than 10 groups. While unusual for single-user systems, large companies commonly have a huge number of POSIX groups users belong to, causing this issue to crop up and make multi-user Nix unusable in such settings. The fix is relatively simple, when `getgrouplist` fails, it stores the real number of GIDs in `ngroups`, so we must resize our list and retry. Only then, if it errors once more, we can raise an exception. This should be backported to, at least, 2.9.x. --- src/libstore/lock.cc | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/libstore/lock.cc b/src/libstore/lock.cc index f1356fdca..fa718f55d 100644 --- a/src/libstore/lock.cc +++ b/src/libstore/lock.cc @@ -67,13 +67,26 @@ bool UserLock::findFreeUser() { #if __linux__ /* Get the list of supplementary groups of this build user. This is usually either empty or contains a group such as "kvm". */ - supplementaryGIDs.resize(10); - int ngroups = supplementaryGIDs.size(); - int err = getgrouplist(pw->pw_name, pw->pw_gid, - supplementaryGIDs.data(), &ngroups); - if (err == -1) - throw Error("failed to get list of supplementary groups for '%1%'", pw->pw_name); + int ngroups = 32; // arbitrary initial guess + supplementaryGIDs.resize(ngroups); + int err = getgrouplist(pw->pw_name, pw->pw_gid, supplementaryGIDs.data(), + &ngroups); + + // Our initial size of 32 wasn't sufficient, the correct size has + // been stored in ngroups, so we try again. + if (err == -1) { + supplementaryGIDs.resize(ngroups); + err = getgrouplist(pw->pw_name, pw->pw_gid, supplementaryGIDs.data(), + &ngroups); + } + + // If it failed once more, then something must be broken. + if (err == -1) + throw Error("failed to get list of supplementary groups for '%1%'", + pw->pw_name); + + // Finally, trim back the GID list to its real size supplementaryGIDs.resize(ngroups); #endif From 7868405d58f39877a267a3f243775dd0fe92e22d Mon Sep 17 00:00:00 2001 From: Sidharth Kshatriya Date: Thu, 9 Jun 2022 19:56:36 +0530 Subject: [PATCH 07/17] nix-env: A small std::move() optimization Avoids doing a O(n) copy of Strings i.e. std::list --- src/nix-env/nix-env.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index c412bb814..a69d3700d 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -1485,7 +1485,7 @@ static int main_nix_env(int argc, char * * argv) if (globals.profile == "") globals.profile = getDefaultProfile(); - op(globals, opFlags, opArgs); + op(globals, std::move(opFlags), std::move(opArgs)); globals.state->printStats(); From bd3a17d00cb92e114a1dc54fa3e0bac5f3261a39 Mon Sep 17 00:00:00 2001 From: Artturin Date: Thu, 9 Jun 2022 23:15:26 +0300 Subject: [PATCH 08/17] install-multi-user: check if selinux is enabled and if it is then abort --- scripts/install-multi-user.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/scripts/install-multi-user.sh b/scripts/install-multi-user.sh index b79a9c23a..9a18280ef 100644 --- a/scripts/install-multi-user.sh +++ b/scripts/install-multi-user.sh @@ -638,6 +638,17 @@ place_channel_configuration() { fi } +check_selinux() { + if command -v getenforce > /dev/null 2>&1; then + if ! [ "$(getenforce)" = "Disabled" ]; then + failure < Date: Fri, 10 Jun 2022 09:17:28 +0100 Subject: [PATCH 09/17] Update docker.nix Co-authored-by: Eelco Dolstra --- docker.nix | 1 - 1 file changed, 1 deletion(-) diff --git a/docker.nix b/docker.nix index cbda39073..0cd64856f 100644 --- a/docker.nix +++ b/docker.nix @@ -125,7 +125,6 @@ let sandbox = "false"; build-users-group = "nixbld"; trusted-public-keys = "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="; - ignored-acls = "security.csm"; }; nixConfContents = (lib.concatStringsSep "\n" (lib.mapAttrsFlatten (n: v: "${n} = ${v}") nixConf)) + "\n"; From 460117a2380c94b4e1ee514eb61e303ee283cf2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophane=20Hufschmitt?= Date: Fri, 10 Jun 2022 12:09:09 +0200 Subject: [PATCH 10/17] Correctly get the nix version in the docker job `defaultPackage` doesn't exist anymore, so we can't use it. Instead just use the new CLI which should be more robust to these changes Fix #6640 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aae5b93e0..fc6531ea5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -88,7 +88,7 @@ jobs: fetch-depth: 0 - uses: cachix/install-nix-action@v17 - run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV - - run: echo NIX_VERSION="$(nix-instantiate --eval -E '(import ./default.nix).defaultPackage.${builtins.currentSystem}.version' | tr -d \")" >> $GITHUB_ENV + - run: echo NIX_VERSION="$(nix --experimental-features 'nix-command flakes' eval .\#default.version | tr -d \")" >> $GITHUB_ENV - uses: cachix/cachix-action@v10 if: needs.check_cachix.outputs.secret == 'true' with: From da8f8668ca0efaad5a4134c55bf801448cec3cd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Na=C3=AFm=20Favier?= Date: Fri, 10 Jun 2022 12:57:13 +0200 Subject: [PATCH 11/17] libfetchers/git: add missing `--git-dir` flags --- src/libfetchers/git.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libfetchers/git.cc b/src/libfetchers/git.cc index 9cbd39247..35fdf807a 100644 --- a/src/libfetchers/git.cc +++ b/src/libfetchers/git.cc @@ -85,8 +85,9 @@ std::optional readHead(const Path & path) bool storeCachedHead(const std::string& actualUrl, const std::string& headRef) { Path cacheDir = getCachePath(actualUrl); + auto gitDir = "."; try { - runProgram("git", true, { "-C", cacheDir, "symbolic-ref", "--", "HEAD", headRef }); + runProgram("git", true, { "-C", cacheDir, "--git-dir", gitDir, "symbolic-ref", "--", "HEAD", headRef }); } catch (ExecError &e) { if (!WIFEXITED(e.status)) throw; return false; @@ -182,7 +183,7 @@ WorkdirInfo getWorkdirInfo(const Input & input, const Path & workdir) if (hasHead) { // Using git diff is preferrable over lower-level operations here, // because its conceptually simpler and we only need the exit code anyways. - auto gitDiffOpts = Strings({ "-C", workdir, "diff", "HEAD", "--quiet"}); + auto gitDiffOpts = Strings({ "-C", workdir, "--git-dir", gitDir, "diff", "HEAD", "--quiet"}); if (!submodules) { // Changes in submodules should only make the tree dirty // when those submodules will be copied as well. @@ -203,6 +204,7 @@ WorkdirInfo getWorkdirInfo(const Input & input, const Path & workdir) std::pair fetchFromWorkdir(ref store, Input & input, const Path & workdir, const WorkdirInfo & workdirInfo) { const bool submodules = maybeGetBoolAttr(input.attrs, "submodules").value_or(false); + auto gitDir = ".git"; if (!fetchSettings.allowDirty) throw Error("Git tree '%s' is dirty", workdir); @@ -210,7 +212,7 @@ std::pair fetchFromWorkdir(ref store, Input & input, co if (fetchSettings.warnDirty) warn("Git tree '%s' is dirty", workdir); - auto gitOpts = Strings({ "-C", workdir, "ls-files", "-z" }); + auto gitOpts = Strings({ "-C", workdir, "--git-dir", gitDir, "ls-files", "-z" }); if (submodules) gitOpts.emplace_back("--recurse-submodules"); @@ -240,7 +242,7 @@ std::pair fetchFromWorkdir(ref store, Input & input, co // modified dirty file? input.attrs.insert_or_assign( "lastModified", - workdirInfo.hasHead ? std::stoull(runProgram("git", true, { "-C", actualPath, "log", "-1", "--format=%ct", "--no-show-signature", "HEAD" })) : 0); + workdirInfo.hasHead ? std::stoull(runProgram("git", true, { "-C", actualPath, "--git-dir", gitDir, "log", "-1", "--format=%ct", "--no-show-signature", "HEAD" })) : 0); return {std::move(storePath), input}; } From 65d09fce2216b3270499ccd8de122e197552cce6 Mon Sep 17 00:00:00 2001 From: Yuriy Taraday Date: Fri, 10 Jun 2022 19:00:19 +0400 Subject: [PATCH 12/17] Mention that -f implies --impure for eval in docs Right now this is not mentioned anywhere and it is unexpected. --- src/libcmd/installables.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 21db2b08b..3cf25e2bc 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -146,7 +146,8 @@ SourceExprCommand::SourceExprCommand(bool supportReadOnlyMode) .shortName = 'f', .description = "Interpret installables as attribute paths relative to the Nix expression stored in *file*. " - "If *file* is the character -, then a Nix expression will be read from standard input.", + "If *file* is the character -, then a Nix expression will be read from standard input. " + "Implies `--impure`.", .category = installablesCategory, .labels = {"file"}, .handler = {&file}, From 754cd53faf12a9e900c7ef6cefa4a798fccea573 Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Fri, 10 Jun 2022 10:49:38 -0700 Subject: [PATCH 13/17] Add missing rethrows in conditional exception handlers Signed-off-by: Anders Kaseorg --- src/libstore/gc.cc | 2 ++ src/libstore/local-binary-cache-store.cc | 1 + src/nix-collect-garbage/nix-collect-garbage.cc | 1 + 3 files changed, 4 insertions(+) diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index f65fb1b2e..d58ed78b1 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -135,6 +135,7 @@ void LocalStore::addTempRoot(const StorePath & path) state->fdRootsSocket.close(); goto restart; } + throw; } } @@ -153,6 +154,7 @@ void LocalStore::addTempRoot(const StorePath & path) state->fdRootsSocket.close(); goto restart; } + throw; } catch (EndOfFile & e) { debug("GC socket disconnected"); state->fdRootsSocket.close(); diff --git a/src/libstore/local-binary-cache-store.cc b/src/libstore/local-binary-cache-store.cc index a3c3e4806..ba4416f6d 100644 --- a/src/libstore/local-binary-cache-store.cc +++ b/src/libstore/local-binary-cache-store.cc @@ -69,6 +69,7 @@ protected: } catch (SysError & e) { if (e.errNo == ENOENT) throw NoSuchBinaryCacheFile("file '%s' does not exist in binary cache", path); + throw; } } diff --git a/src/nix-collect-garbage/nix-collect-garbage.cc b/src/nix-collect-garbage/nix-collect-garbage.cc index af6f1c88c..e413faffe 100644 --- a/src/nix-collect-garbage/nix-collect-garbage.cc +++ b/src/nix-collect-garbage/nix-collect-garbage.cc @@ -37,6 +37,7 @@ void removeOldGenerations(std::string dir) link = readLink(path); } catch (SysError & e) { if (e.errNo == ENOENT) continue; + throw; } if (link.find("link") != std::string::npos) { printInfo(format("removing old generations of profile %1%") % path); From 502d7d9092ccf792a27088f31571dbace96f1962 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Na=C3=AFm=20Favier?= Date: Sat, 11 Jun 2022 15:13:58 +0200 Subject: [PATCH 14/17] nix-build: stop logger when appropriate Reverts b944b588fa280b0555b8269c0f6d097352f8716f in `nix-build.cc`. --- src/nix-build/nix-build.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc index 426f23905..519855ea3 100644 --- a/src/nix-build/nix-build.cc +++ b/src/nix-build/nix-build.cc @@ -543,6 +543,8 @@ static void main_nix_build(int argc, char * * argv) restoreProcessContext(); + logger->stop(); + execvp(shell->c_str(), argPtrs.data()); throw SysError("executing shell '%s'", *shell); @@ -601,6 +603,8 @@ static void main_nix_build(int argc, char * * argv) outPaths.push_back(outputPath); } + logger->stop(); + for (auto & path : outPaths) std::cout << store->printStorePath(path) << '\n'; } From 9f6b4639c2060aa6d7f7336222dad4ea350ccdf8 Mon Sep 17 00:00:00 2001 From: Gabriel Fontes Date: Sat, 11 Jun 2022 16:52:20 -0300 Subject: [PATCH 15/17] fix sourcehut brach/tag resolving regression nixos/nix#6290 introduced a regex pattern to account for tags when resolving sourcehut refs. nixos/nix#4638 reafactored the code, accidentally treating the pattern as a regular string, causing all non-HEAD ref resolving to break. This fixes the regression and adds more test cases to avoid future breakage. --- src/libfetchers/github.cc | 9 +++++---- tests/sourcehut-flakes.nix | 13 ++++++++++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/libfetchers/github.cc b/src/libfetchers/github.cc index 0631fb6e8..a491d82a6 100644 --- a/src/libfetchers/github.cc +++ b/src/libfetchers/github.cc @@ -381,7 +381,7 @@ struct SourceHutInputScheme : GitArchiveInputScheme Headers headers = makeHeadersWithAuthTokens(host); - std::string ref_uri; + std::string refUri; if (ref == "HEAD") { auto file = store->toRealPath( downloadFile(store, fmt("%s/HEAD", base_url), "source", false, headers).storePath); @@ -393,10 +393,11 @@ struct SourceHutInputScheme : GitArchiveInputScheme if (!remoteLine) { throw BadURL("in '%d', couldn't resolve HEAD ref '%d'", input.to_string(), ref); } - ref_uri = remoteLine->target; + refUri = remoteLine->target; } else { - ref_uri = fmt("refs/(heads|tags)/%s", ref); + refUri = fmt("refs/(heads|tags)/%s", ref); } + std::regex refRegex(refUri); auto file = store->toRealPath( downloadFile(store, fmt("%s/info/refs", base_url), "source", false, headers).storePath); @@ -406,7 +407,7 @@ struct SourceHutInputScheme : GitArchiveInputScheme std::optional id; while(!id && getline(is, line)) { auto parsedLine = git::parseLsRemoteLine(line); - if (parsedLine && parsedLine->reference == ref_uri) + if (parsedLine && parsedLine->reference && std::regex_match(*parsedLine->reference, refRegex)) id = parsedLine->target; } diff --git a/tests/sourcehut-flakes.nix b/tests/sourcehut-flakes.nix index aadab9bb5..daa259dd6 100644 --- a/tests/sourcehut-flakes.nix +++ b/tests/sourcehut-flakes.nix @@ -59,7 +59,7 @@ let echo 'ref: refs/heads/master' > $out/HEAD mkdir -p $out/info - echo -e '${nixpkgs.rev}\trefs/heads/master' > $out/info/refs + echo -e '${nixpkgs.rev}\trefs/heads/master\n${nixpkgs.rev}\trefs/tags/foo-bar' > $out/info/refs ''; in @@ -132,6 +132,17 @@ makeTest ( client.succeed("curl -v https://git.sr.ht/ >&2") client.succeed("nix registry list | grep nixpkgs") + # Test that it resolves HEAD + rev = client.succeed("nix flake info sourcehut:~NixOS/nixpkgs --json | jq -r .revision") + assert rev.strip() == "${nixpkgs.rev}", "revision mismatch" + # Test that it resolves branches + rev = client.succeed("nix flake info sourcehut:~NixOS/nixpkgs/master --json | jq -r .revision") + assert rev.strip() == "${nixpkgs.rev}", "revision mismatch" + # Test that it resolves tags + rev = client.succeed("nix flake info sourcehut:~NixOS/nixpkgs/foo-bar --json | jq -r .revision") + assert rev.strip() == "${nixpkgs.rev}", "revision mismatch" + + # Registry and pinning test rev = client.succeed("nix flake info nixpkgs --json | jq -r .revision") assert rev.strip() == "${nixpkgs.rev}", "revision mismatch" From d82a3dc70d5a5c68815327a8922c8db0d0c95cdb Mon Sep 17 00:00:00 2001 From: Alexander Bantyev Date: Mon, 13 Jun 2022 20:49:16 +0400 Subject: [PATCH 16/17] flake.cc: Make non-flake overrides sticky Overrides for inputs with flake=false were non-sticky, since they changed the `original` in `flake.lock`. This fixes it, by using the same locked original for both flake and non-flake inputs. --- src/libexpr/flake/flake.cc | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc index 35c841897..920726b73 100644 --- a/src/libexpr/flake/flake.cc +++ b/src/libexpr/flake/flake.cc @@ -513,6 +513,15 @@ LockedFlake lockFlake( if (!lockFlags.allowMutable && !input.ref->input.isLocked()) throw Error("cannot update flake input '%s' in pure mode", inputPathS); + /* Note: in case of an --override-input, we use + the *original* ref (input2.ref) for the + "original" field, rather than the + override. This ensures that the override isn't + nuked the next time we update the lock + file. That is, overrides are sticky unless you + use --no-write-lock-file. */ + auto ref = input2.ref ? *input2.ref : *input.ref; + if (input.isFlake) { Path localPath = parentPath; FlakeRef localRef = *input.ref; @@ -524,15 +533,7 @@ LockedFlake lockFlake( auto inputFlake = getFlake(state, localRef, useRegistries, flakeCache, inputPath); - /* Note: in case of an --override-input, we use - the *original* ref (input2.ref) for the - "original" field, rather than the - override. This ensures that the override isn't - nuked the next time we update the lock - file. That is, overrides are sticky unless you - use --no-write-lock-file. */ - auto childNode = std::make_shared( - inputFlake.lockedRef, input2.ref ? *input2.ref : *input.ref); + auto childNode = std::make_shared(inputFlake.lockedRef, ref); node->inputs.insert_or_assign(id, childNode); @@ -560,7 +561,7 @@ LockedFlake lockFlake( auto [sourceInfo, resolvedRef, lockedRef] = fetchOrSubstituteTree( state, *input.ref, useRegistries, flakeCache); node->inputs.insert_or_assign(id, - std::make_shared(lockedRef, *input.ref, false)); + std::make_shared(lockedRef, ref, false)); } } From fd7f795750ad97466c0fb9733ac3cc2a0909b84d Mon Sep 17 00:00:00 2001 From: Hugo Osvaldo Barrera Date: Fri, 3 Jun 2022 23:19:12 +0200 Subject: [PATCH 17/17] Add disambiguation to man page This should help future lost newcomers like myself understand where to find the docs for both of these commands and how they differ. --- doc/manual/src/command-ref/nix-build.md | 6 ++++++ doc/manual/src/command-ref/nix-shell.md | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/doc/manual/src/command-ref/nix-build.md b/doc/manual/src/command-ref/nix-build.md index aacb32a25..49c6f3f55 100644 --- a/doc/manual/src/command-ref/nix-build.md +++ b/doc/manual/src/command-ref/nix-build.md @@ -12,6 +12,12 @@ [`--dry-run`] [{`--out-link` | `-o`} *outlink*] +# Disambiguation + +This man page describes the command `nix-build`, which is distinct from `nix +build`. For documentation on the latter, run `nix build --help` or see `man +nix3-build`. + # Description The `nix-build` command builds the derivations described by the Nix diff --git a/doc/manual/src/command-ref/nix-shell.md b/doc/manual/src/command-ref/nix-shell.md index a2b6d8a8e..840bccd25 100644 --- a/doc/manual/src/command-ref/nix-shell.md +++ b/doc/manual/src/command-ref/nix-shell.md @@ -15,6 +15,12 @@ [`--keep` *name*] {{`--packages` | `-p`} {*packages* | *expressions*} … | [*path*]} +# Disambiguation + +This man page describes the command `nix-shell`, which is distinct from `nix +shell`. For documentation on the latter, run `nix shell --help` or see `man +nix3-shell`. + # Description The command `nix-shell` will build the dependencies of the specified