From 1eac5a6bd0352ff2366e1feedd01abbd83d59546 Mon Sep 17 00:00:00 2001 From: Rok Garbas Date: Wed, 26 Jan 2022 09:22:51 +0100 Subject: [PATCH 001/251] Script to push docker image for releases --- maintainers/push-docker.sh | 69 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100755 maintainers/push-docker.sh diff --git a/maintainers/push-docker.sh b/maintainers/push-docker.sh new file mode 100755 index 000000000..a705f0738 --- /dev/null +++ b/maintainers/push-docker.sh @@ -0,0 +1,69 @@ +#/usr/bin/env bash + +# TODO: parse from .version +MAINTENANCE_VERSION="2.6" +VERSION="$MAINTENANCE_VERSION.0" + +# Should be override `latest` tag, default true +PUSH_AS_LATEST=1 + +PLATFORMS="x86_64-linux aarch64-linux" + +# ensure we are logged to docker hub +docker login + +DOCKER_MANIFEST="" +DOCKER_MANIFEST_LATEST="" + +for PLATFORM in $PLATFORMS; +do + echo "=> Loading docker image for $PLATFORM platform ..." + + DOCKER_IMAGE_TMP_FILE="$PWD/image-$PLATFORM.tar.gz" + if [ ! -f "$DOCKER_IMAGE_TMP_FILE" ]; then + curl -L https://hydra.nixos.org/job/nix/maintenance-$MAINTENANCE_VERSION/dockerImage.$PLATFORM/latest/download/1 > $DOCKER_IMAGE_TMP_FILE + fi + docker load -i $DOCKER_IMAGE_TMP_FILE + + if [ "$PLATFORM" = "x86_64-linux" ]; then DOCKER_PLATFORM="amd64" + elif [ "$PLATFORM" = "aarch64-linux" ]; then DOCKER_PLATFORM="arm64" + else + echo "EROROR: No docker platform found for $PLATFORM platform" + exit 1 + fi + + echo "=> Tagging docker image of version $VERSION for $PLATFORM platform ..." + + docker tag nix:$VERSION nixos/nix:$VERSION-$DOCKER_PLATFORM + if [ $PUSH_AS_LATEST -eq 1 ]; then + echo "=> Tagging docker image of version latest for $PLATFORM platform ..." + docker tag nix:$VERSION nixos/nix:latest + fi + + echo "=> Pushing docker image of version $VERSION for $PLATFORM platform ..." + + docker push nixos/nix:$VERSION-$DOCKER_PLATFORM + if [ $PUSH_AS_LATEST -eq 1 ]; then + echo "=> Pushing docker image of version latest for $PLATFORM platform ..." + docker push nixos/nix:latest + fi + + DOCKER_MANIFEST="$DOCKER_MANIFEST --amend nixos/nix:$VERSION-$DOCKER_PLATFORM" + DOCKER_MANIFEST_LATEST="$DOCKER_MANIFEST_LATEST --amend nixos/nix:latest-$DOCKER_PLATFORM" + + echo +done + +echo "=> Creating $VERSION multi platform docker manifest for the following platforms: $PLATFORMS ..." +docker manifest create nixos/nix:$VERSION $DOCKER_MANIFEST +if [ $PUSH_AS_LATEST -eq 1 ]; then + echo "=> Creating latest multi platform docker manifest for the following platforms: $PLATFORMS ..." + docker manifest create nixos/nix:latest $DOCKER_MANIFEST_LATEST +fi + +echo "=> Pushing $VERSION multi platform docker manifest ..." +docker manifest push nixos/nix:$VERSION +if [ $PUSH_AS_LATEST -eq 1 ]; then + echo "=> Pushing latest multi platform docker manifest ..." + docker manifest push nixos/nix:latest +fi From 4fc3c4da7ba81a69c17063950933b45b39646949 Mon Sep 17 00:00:00 2001 From: Rok Garbas Date: Wed, 26 Jan 2022 10:01:58 +0100 Subject: [PATCH 002/251] typo --- maintainers/push-docker.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maintainers/push-docker.sh b/maintainers/push-docker.sh index a705f0738..fe8fe174e 100755 --- a/maintainers/push-docker.sh +++ b/maintainers/push-docker.sh @@ -37,7 +37,7 @@ do docker tag nix:$VERSION nixos/nix:$VERSION-$DOCKER_PLATFORM if [ $PUSH_AS_LATEST -eq 1 ]; then echo "=> Tagging docker image of version latest for $PLATFORM platform ..." - docker tag nix:$VERSION nixos/nix:latest + docker tag nix:$VERSION nixos/nix:latest-$DOCKER_PLATFORM fi echo "=> Pushing docker image of version $VERSION for $PLATFORM platform ..." @@ -45,7 +45,7 @@ do docker push nixos/nix:$VERSION-$DOCKER_PLATFORM if [ $PUSH_AS_LATEST -eq 1 ]; then echo "=> Pushing docker image of version latest for $PLATFORM platform ..." - docker push nixos/nix:latest + docker push nixos/nix:latest-$DOCKER_PLATFORM fi DOCKER_MANIFEST="$DOCKER_MANIFEST --amend nixos/nix:$VERSION-$DOCKER_PLATFORM" From 50a9c48db4dddd6ba4c81dae74aa60f8ff10bfe5 Mon Sep 17 00:00:00 2001 From: Rok Garbas Date: Wed, 26 Jan 2022 10:05:33 +0100 Subject: [PATCH 003/251] fail early --- maintainers/push-docker.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/maintainers/push-docker.sh b/maintainers/push-docker.sh index fe8fe174e..f9c5a6b18 100755 --- a/maintainers/push-docker.sh +++ b/maintainers/push-docker.sh @@ -17,6 +17,13 @@ DOCKER_MANIFEST_LATEST="" for PLATFORM in $PLATFORMS; do + if [ "$PLATFORM" = "x86_64-linux" ]; then DOCKER_PLATFORM="amd64" + elif [ "$PLATFORM" = "aarch64-linux" ]; then DOCKER_PLATFORM="arm64" + else + echo "EROROR: No docker platform found for $PLATFORM platform" + exit 1 + fi + echo "=> Loading docker image for $PLATFORM platform ..." DOCKER_IMAGE_TMP_FILE="$PWD/image-$PLATFORM.tar.gz" @@ -25,13 +32,6 @@ do fi docker load -i $DOCKER_IMAGE_TMP_FILE - if [ "$PLATFORM" = "x86_64-linux" ]; then DOCKER_PLATFORM="amd64" - elif [ "$PLATFORM" = "aarch64-linux" ]; then DOCKER_PLATFORM="arm64" - else - echo "EROROR: No docker platform found for $PLATFORM platform" - exit 1 - fi - echo "=> Tagging docker image of version $VERSION for $PLATFORM platform ..." docker tag nix:$VERSION nixos/nix:$VERSION-$DOCKER_PLATFORM From f222fba4dca69919d28468467e6e5c4c859cfc13 Mon Sep 17 00:00:00 2001 From: Matthew Bauer Date: Thu, 3 Feb 2022 20:51:47 -0600 Subject: [PATCH 004/251] Allow missing flake.nix for --override-input target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At this point, we don’t know if the input is a flake or not. So, we should allow the user to override the input with a directory without a flake.nix. Ideally, we could figure whether the input was originally a flake or not, but that would require instantiating the whole flake. So just allow it to be missing here, and rely on checks later on to verify the input for us. --- src/libcmd/installables.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 38a177f80..5e8b62e1a 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -97,7 +97,7 @@ MixFlakeOptions::MixFlakeOptions() lockFlags.writeLockFile = false; lockFlags.inputOverrides.insert_or_assign( flake::parseInputPath(inputPath), - parseFlakeRef(flakeRef, absPath("."))); + parseFlakeRef(flakeRef, absPath("."), true)); }} }); From 1daf1babf956cab98857db92de8829a1e7f2ae3e Mon Sep 17 00:00:00 2001 From: pennae Date: Fri, 4 Feb 2022 07:36:56 +0100 Subject: [PATCH 005/251] fix nix repl not overriding existing bindings in :a previously :a would override old bindings of a name with new values if the added set contained names that were already bound. in nix 2.6 this doesn't happen any more, which is potentially confusing. fixes #6041 --- src/libexpr/nixexpr.hh | 12 ++++++++---- tests/repl.sh | 23 +++++++++++++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh index 4e923ac89..6f6acb074 100644 --- a/src/libexpr/nixexpr.hh +++ b/src/libexpr/nixexpr.hh @@ -367,15 +367,19 @@ struct StaticEnv void sort() { - std::sort(vars.begin(), vars.end(), + std::stable_sort(vars.begin(), vars.end(), [](const Vars::value_type & a, const Vars::value_type & b) { return a.first < b.first; }); } void deduplicate() { - const auto last = std::unique(vars.begin(), vars.end(), - [] (const Vars::value_type & a, const Vars::value_type & b) { return a.first == b.first; }); - vars.erase(last, vars.end()); + auto it = vars.begin(), jt = it, end = vars.end(); + while (jt != end) { + *it = *jt++; + while (jt != end && it->first == jt->first) *it = *jt++; + it++; + } + vars.erase(it, end); } Vars::const_iterator find(const Symbol & name) const diff --git a/tests/repl.sh b/tests/repl.sh index 0e23a98db..6505f1741 100644 --- a/tests/repl.sh +++ b/tests/repl.sh @@ -40,3 +40,26 @@ testRepl () { testRepl # Same thing (kind-of), but with a remote store. testRepl --store "$TEST_ROOT/store?real=$NIX_STORE_DIR" + +testReplResponse () { + local response="$(nix repl <<< "$1")" + echo "$response" | grep -qs "$2" \ + || fail "repl command set: + +$1 + +does not respond with: + +$2 + +but with: + +$response" +} + +# :a uses the newest version of a symbol +testReplResponse ' +:a { a = "1"; } +:a { a = "2"; } +"result: ${a}" +' "result: 2" From 9d840758a8d195e52e8b7d08cd9c15f6b8259724 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Fri, 4 Feb 2022 22:43:16 +0100 Subject: [PATCH 006/251] completions: pipe stderr to /dev/null This fixes weird issues where e.g. nix build -L .# deletes the current line from the prompt. --- misc/bash/completion.sh | 2 +- misc/zsh/completion.zsh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/bash/completion.sh b/misc/bash/completion.sh index 8fc224792..045053dee 100644 --- a/misc/bash/completion.sh +++ b/misc/bash/completion.sh @@ -15,7 +15,7 @@ function _complete_nix { else COMPREPLY+=("$completion") fi - done < <(NIX_GET_COMPLETIONS=$cword "${words[@]/#\~/$HOME}") + done < <(NIX_GET_COMPLETIONS=$cword "${words[@]/#\~/$HOME}" 2>/dev/null) __ltrim_colon_completions "$cur" } diff --git a/misc/zsh/completion.zsh b/misc/zsh/completion.zsh index a902e37dc..e702c721e 100644 --- a/misc/zsh/completion.zsh +++ b/misc/zsh/completion.zsh @@ -4,7 +4,7 @@ function _nix() { local ifs_bk="$IFS" local input=("${(Q)words[@]}") IFS=$'\n' - local res=($(NIX_GET_COMPLETIONS=$((CURRENT - 1)) "$input[@]")) + local res=($(NIX_GET_COMPLETIONS=$((CURRENT - 1)) "$input[@]" 2>/dev/null)) IFS="$ifs_bk" local tpe="${${res[1]}%%> *}" local -a suggestions From 45eeb2fd6ade832d045884b9a18decb4cddaceb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20J=C3=A4ckel?= Date: Sat, 5 Feb 2022 17:56:51 +0100 Subject: [PATCH 007/251] nix-shell: set BASH variable to correct shell --- src/nix-build/nix-build.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc index ae4746955..aeabdcdd4 100755 --- a/src/nix-build/nix-build.cc +++ b/src/nix-build/nix-build.cc @@ -500,6 +500,7 @@ static void main_nix_build(int argc, char * * argv) "%3%" "PATH=%4%:\"$PATH\"; " "SHELL=%5%; " + "BASH=%5%; " "set +e; " R"s([ -n "$PS1" -a -z "$NIX_SHELL_PRESERVE_PROMPT" ] && PS1='\n\[\033[1;32m\][nix-shell:\w]\$\[\033[0m\] '; )s" "if [ \"$(type -t runHook)\" = function ]; then runHook shellHook; fi; " From c3b942e0fc4777f9033f614b6b1f462c0f8c473e Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Sun, 6 Feb 2022 13:25:56 +0100 Subject: [PATCH 008/251] Don't hold interruptCallbacks lock during interrupt handling This changes the representation of the interrupt callback list to be safe to use during interrupt handling. Holding a lock while executing arbitrary functions is something to avoid in general, because of the risk of deadlock. Such a deadlock occurs in https://github.com/NixOS/nix/issues/3294 where ~CurlDownloader tries to deregister its interrupt callback. This happens during what seems to be a triggerInterrupt() by the daemon connection's MonitorFdHup thread. This bit I can not confirm based on the stack trace though; it's based on reading the code, so no absolute certainty, but a smoking gun nonetheless. --- src/libutil/util.cc | 55 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/src/libutil/util.cc b/src/libutil/util.cc index cd359cfee..03cbd7765 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -1561,7 +1561,22 @@ std::pair getWindowSize() } -static Sync>> _interruptCallbacks; +/* We keep track of interrupt callbacks using integer tokens, so we can iterate + safely without having to lock the data structure while executing arbitrary + functions. + */ +struct InterruptCallbacks { + typedef int64_t Token; + + /* We use unique tokens so that we can't accidentally delete the wrong + handler because of an erroneous double delete. */ + Token nextToken = 0; + + /* Used as a list, see InterruptCallbacks comment. */ + std::map> callbacks; +}; + +static Sync _interruptCallbacks; static void signalHandlerThread(sigset_t set) { @@ -1583,14 +1598,29 @@ void triggerInterrupt() _isInterrupted = true; { - auto interruptCallbacks(_interruptCallbacks.lock()); - for (auto & callback : *interruptCallbacks) { - try { - callback(); - } catch (...) { - ignoreException(); + InterruptCallbacks::Token i = 0; + std::function callback; + do { + { + auto interruptCallbacks(_interruptCallbacks.lock()); + auto lb = interruptCallbacks->callbacks.lower_bound(i); + if (lb != interruptCallbacks->callbacks.end()) { + callback = lb->second; + i = lb->first + 1; + } else { + callback = nullptr; + } + } + + if (callback) { + try { + callback(); + } catch (...) { + ignoreException(); + } } } + while (callback); } } @@ -1694,21 +1724,22 @@ void restoreProcessContext(bool restoreMounts) /* RAII helper to automatically deregister a callback. */ struct InterruptCallbackImpl : InterruptCallback { - std::list>::iterator it; + InterruptCallbacks::Token token; ~InterruptCallbackImpl() override { - _interruptCallbacks.lock()->erase(it); + auto interruptCallbacks(_interruptCallbacks.lock()); + interruptCallbacks->callbacks.erase(token); } }; std::unique_ptr createInterruptCallback(std::function callback) { auto interruptCallbacks(_interruptCallbacks.lock()); - interruptCallbacks->push_back(callback); + auto token = interruptCallbacks->nextToken++; + interruptCallbacks->callbacks.emplace(token, callback); auto res = std::make_unique(); - res->it = interruptCallbacks->end(); - res->it--; + res->token = token; return std::unique_ptr(res.release()); } From c23501a3b24d84376086179756fefd399c2a7cbb Mon Sep 17 00:00:00 2001 From: "lincoln auster [they/them]" Date: Sun, 6 Feb 2022 16:28:21 -0700 Subject: [PATCH 009/251] repl/load-flake: throw error if path isn't specified --- src/nix/repl.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/nix/repl.cc b/src/nix/repl.cc index e9bebff17..97ca39145 100644 --- a/src/nix/repl.cc +++ b/src/nix/repl.cc @@ -623,6 +623,9 @@ void NixRepl::loadFile(const Path & path) void NixRepl::loadFlake(const std::string & flakeRefS) { + if (flakeRefS.empty()) + throw Error("cannot use `:load-flake` without a path specified. (Use . for the current working directory.)"); + auto flakeRef = parseFlakeRef(flakeRefS, absPath("."), true); if (evalSettings.pureEval && !flakeRef.input.isImmutable()) throw Error("cannot use ':load-flake' on mutable flake reference '%s' (use --impure to override)", flakeRefS); From 97e02c23bde0515540c63081824f85ff1cebd86f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 7 Feb 2022 10:48:57 +0100 Subject: [PATCH 010/251] Fix 'basic_string::_M_construct null not valid' in interrupted download Fixes #5985. --- src/libstore/filetransfer.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstore/filetransfer.cc b/src/libstore/filetransfer.cc index 6b62311cf..76fed11db 100644 --- a/src/libstore/filetransfer.cc +++ b/src/libstore/filetransfer.cc @@ -128,7 +128,7 @@ struct curlFileTransfer : public FileTransfer if (requestHeaders) curl_slist_free_all(requestHeaders); try { if (!done) - fail(FileTransferError(Interrupted, nullptr, "download of '%s' was interrupted", request.uri)); + fail(FileTransferError(Interrupted, {}, "download of '%s' was interrupted", request.uri)); } catch (...) { ignoreException(); } @@ -704,7 +704,7 @@ struct curlFileTransfer : public FileTransfer auto s3Res = s3Helper.getObject(bucketName, key); FileTransferResult res; if (!s3Res.data) - throw FileTransferError(NotFound, nullptr, "S3 object '%s' does not exist", request.uri); + throw FileTransferError(NotFound, {}, "S3 object '%s' does not exist", request.uri); res.data = std::move(*s3Res.data); callback(std::move(res)); #else From b1abfcd0c247df7dc269ba8cb6b1e23d287c20ad Mon Sep 17 00:00:00 2001 From: lincoln auster Date: Mon, 7 Feb 2022 08:35:50 -0700 Subject: [PATCH 011/251] fix markup Co-authored-by: Eelco Dolstra --- src/nix/repl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nix/repl.cc b/src/nix/repl.cc index 97ca39145..2c39fac91 100644 --- a/src/nix/repl.cc +++ b/src/nix/repl.cc @@ -624,7 +624,7 @@ void NixRepl::loadFile(const Path & path) void NixRepl::loadFlake(const std::string & flakeRefS) { if (flakeRefS.empty()) - throw Error("cannot use `:load-flake` without a path specified. (Use . for the current working directory.)"); + throw Error("cannot use ':load-flake' without a path specified. (Use '.' for the current working directory.)"); auto flakeRef = parseFlakeRef(flakeRefS, absPath("."), true); if (evalSettings.pureEval && !flakeRef.input.isImmutable()) From 3ec02deb20b52bd2c23fbf3c98026898857a4def Mon Sep 17 00:00:00 2001 From: Sergei Trofimovich Date: Mon, 7 Feb 2022 16:14:57 +0000 Subject: [PATCH 012/251] Make sure no exceptions leave ignoreException() I noticed that occasional Ctrl-C leaves *.lock files around. `nix-daemon`'s journal logs contained crashes like: nix-daemon[30416]: terminate called after throwing an instance of 'nix::SysError' nix-daemon[30416]: what(): error: writing to file: Broken pipe And core dump backtraces pointed at `teriminate()` call from destructors: ... _Unwind_Resume () nix::ignoreException() () nix::LocalDerivationGoal::~LocalDerivationGoal() ... void ignoreException() { try { throw; } catch (std::exception & e) { printError("error (ignored): %1%", e.what()); } } The crashes happen when client side closes early and printError() throws an IO error. The change wraps `ignoreException()` into blanket `try { ... } catch (...) {}`. Closes: https://github.com/NixOS/nix/issues/6046 --- src/libutil/util.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/libutil/util.cc b/src/libutil/util.cc index cd359cfee..8b317f6a8 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -1358,11 +1358,15 @@ std::string shellEscape(const std::string_view s) void ignoreException() { + /* Make sure no exceptions leave this function. + printError() also throws when remote is closed. */ try { - throw; - } catch (std::exception & e) { - printError("error (ignored): %1%", e.what()); - } + try { + throw; + } catch (std::exception & e) { + printError("error (ignored): %1%", e.what()); + } + } catch (...) { } } bool shouldANSI() From 579dcbabd55d5c565ee9769efb6d4377f3022284 Mon Sep 17 00:00:00 2001 From: Sergei Trofimovich Date: Mon, 7 Feb 2022 23:35:34 +0000 Subject: [PATCH 013/251] mk: prefert inplace library paths to system ones (take 2) It's a second attempt to merge the change. Previous attempt was reverted in b976b34a5b05ba303904cc7b8e0a2579bdb52807. Since then underlying failure exposed by original change was fixed by https://github.com/NixOS/nix/pull/5354. Below goes description of original change: The link failure happens on a system with stable nix-2.3.15 installed in /usr/lib64 (it's libutil.so API differs from master): ``` LANG=C make V=1 g++ -o /home/slyfox/dev/git/nix/src/libstore/libnixstore.so \ -shared -L/usr/lib64 -Wl,--no-copy-dt-needed-entries \ src/libstore/binary-cache-store.o ... src/libstore/uds-remote-store.o \ -lsqlite3 -lcurl -lsodium -pthread -ldl -lseccomp -Wl,-z,defs -Wl,-soname=libnixstore.so -Wl,-rpath,/home/slyfox/dev/git/nix/src/libutil -Lsrc/libutil -lnixutil ld: src/libstore/binary-cache-store.o: in function `nix::BinaryCacheStore::BinaryCacheStore( std::map, ... nix/src/libstore/binary-cache-store.cc:30: undefined reference to `nix::readFile( std::__cxx11::basic_string, std::allocator > const&)' ... ... ``` This happens due to `-L/usr/lib64 -Lsrc/libutil` search path ordering. The change turns it into `-Lsrc/libutil -L/usr/lib64`. Closes: https://github.com/NixOS/nix/issues/3087 --- mk/libraries.mk | 4 ++-- mk/programs.mk | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mk/libraries.mk b/mk/libraries.mk index ffd7b5610..2a86565c9 100644 --- a/mk/libraries.mk +++ b/mk/libraries.mk @@ -91,7 +91,7 @@ define build-library $(1)_PATH := $$(_d)/$$($(1)_NAME).$(SO_EXT) $$($(1)_PATH): $$($(1)_OBJS) $$(_libs) | $$(_d)/ - $$(trace-ld) $(CXX) -o $$(abspath $$@) -shared $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$($(1)_LDFLAGS_PROPAGATED) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE)) $$($(1)_LDFLAGS_UNINSTALLED) + $$(trace-ld) $(CXX) -o $$(abspath $$@) -shared $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE)) $$($(1)_LDFLAGS_UNINSTALLED) $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$($(1)_LDFLAGS_PROPAGATED) ifndef HOST_DARWIN $(1)_LDFLAGS_USE += -Wl,-rpath,$$(abspath $$(_d)) @@ -105,7 +105,7 @@ define build-library $$(eval $$(call create-dir, $$($(1)_INSTALL_DIR))) $$($(1)_INSTALL_PATH): $$($(1)_OBJS) $$(_libs_final) | $(DESTDIR)$$($(1)_INSTALL_DIR)/ - $$(trace-ld) $(CXX) -o $$@ -shared $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$($(1)_LDFLAGS_PROPAGATED) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE_INSTALLED)) + $$(trace-ld) $(CXX) -o $$@ -shared $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE_INSTALLED)) $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$($(1)_LDFLAGS_PROPAGATED) $(1)_LDFLAGS_USE_INSTALLED += -L$$(DESTDIR)$$($(1)_INSTALL_DIR) -l$$(patsubst lib%,%,$$(strip $$($(1)_NAME))) ifndef HOST_DARWIN diff --git a/mk/programs.mk b/mk/programs.mk index d0cf5baf0..70b09f0dd 100644 --- a/mk/programs.mk +++ b/mk/programs.mk @@ -32,7 +32,7 @@ define build-program $$(eval $$(call create-dir, $$(_d))) $$($(1)_PATH): $$($(1)_OBJS) $$(_libs) | $$(_d)/ - $$(trace-ld) $(CXX) -o $$@ $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE)) + $$(trace-ld) $(CXX) -o $$@ $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE)) $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $(1)_INSTALL_DIR ?= $$(bindir) @@ -49,7 +49,7 @@ define build-program _libs_final := $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_INSTALL_PATH)) $(DESTDIR)$$($(1)_INSTALL_PATH): $$($(1)_OBJS) $$(_libs_final) | $(DESTDIR)$$($(1)_INSTALL_DIR)/ - $$(trace-ld) $(CXX) -o $$@ $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE_INSTALLED)) + $$(trace-ld) $(CXX) -o $$@ $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE_INSTALLED)) $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) else From 28b9bd784ca8c7234693b7bca1ab393ed56f52d3 Mon Sep 17 00:00:00 2001 From: Sergei Trofimovich Date: Wed, 9 Feb 2022 13:00:53 +0000 Subject: [PATCH 014/251] Revert "mk: prefert inplace library paths to system ones (take 2)" --- mk/libraries.mk | 4 ++-- mk/programs.mk | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mk/libraries.mk b/mk/libraries.mk index 2a86565c9..ffd7b5610 100644 --- a/mk/libraries.mk +++ b/mk/libraries.mk @@ -91,7 +91,7 @@ define build-library $(1)_PATH := $$(_d)/$$($(1)_NAME).$(SO_EXT) $$($(1)_PATH): $$($(1)_OBJS) $$(_libs) | $$(_d)/ - $$(trace-ld) $(CXX) -o $$(abspath $$@) -shared $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE)) $$($(1)_LDFLAGS_UNINSTALLED) $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$($(1)_LDFLAGS_PROPAGATED) + $$(trace-ld) $(CXX) -o $$(abspath $$@) -shared $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$($(1)_LDFLAGS_PROPAGATED) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE)) $$($(1)_LDFLAGS_UNINSTALLED) ifndef HOST_DARWIN $(1)_LDFLAGS_USE += -Wl,-rpath,$$(abspath $$(_d)) @@ -105,7 +105,7 @@ define build-library $$(eval $$(call create-dir, $$($(1)_INSTALL_DIR))) $$($(1)_INSTALL_PATH): $$($(1)_OBJS) $$(_libs_final) | $(DESTDIR)$$($(1)_INSTALL_DIR)/ - $$(trace-ld) $(CXX) -o $$@ -shared $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE_INSTALLED)) $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$($(1)_LDFLAGS_PROPAGATED) + $$(trace-ld) $(CXX) -o $$@ -shared $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$($(1)_LDFLAGS_PROPAGATED) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE_INSTALLED)) $(1)_LDFLAGS_USE_INSTALLED += -L$$(DESTDIR)$$($(1)_INSTALL_DIR) -l$$(patsubst lib%,%,$$(strip $$($(1)_NAME))) ifndef HOST_DARWIN diff --git a/mk/programs.mk b/mk/programs.mk index 70b09f0dd..d0cf5baf0 100644 --- a/mk/programs.mk +++ b/mk/programs.mk @@ -32,7 +32,7 @@ define build-program $$(eval $$(call create-dir, $$(_d))) $$($(1)_PATH): $$($(1)_OBJS) $$(_libs) | $$(_d)/ - $$(trace-ld) $(CXX) -o $$@ $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE)) $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) + $$(trace-ld) $(CXX) -o $$@ $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE)) $(1)_INSTALL_DIR ?= $$(bindir) @@ -49,7 +49,7 @@ define build-program _libs_final := $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_INSTALL_PATH)) $(DESTDIR)$$($(1)_INSTALL_PATH): $$($(1)_OBJS) $$(_libs_final) | $(DESTDIR)$$($(1)_INSTALL_DIR)/ - $$(trace-ld) $(CXX) -o $$@ $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE_INSTALLED)) $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) + $$(trace-ld) $(CXX) -o $$@ $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE_INSTALLED)) else From b8d57e28839587832109f6607eb28819559fc30c Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 10 Feb 2022 11:10:29 +0100 Subject: [PATCH 015/251] check-hydra-status.sh: Improve error behaviour --- scripts/check-hydra-status.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/check-hydra-status.sh b/scripts/check-hydra-status.sh index c1d2d7c40..7efe9cf97 100644 --- a/scripts/check-hydra-status.sh +++ b/scripts/check-hydra-status.sh @@ -19,9 +19,9 @@ for buildId in $BUILDS_FOR_LATEST_EVAL; do buildStatus=$(echo "$buildInfo" | \ jq -r '.buildstatus') - if [[ "$buildStatus" -ne 0 ]]; then + if [[ $buildStatus != 0 ]]; then someBuildFailed=1 - echo "Job “$(echo "$buildInfo" | jq -r '.job')” failed on hydra" + echo "Job “$(echo "$buildInfo" | jq -r '.job')” failed on hydra: $buildInfo" fi done From 5b586575ac5ecb013be56135ecbcb091c8ad419d Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Thu, 10 Feb 2022 14:12:06 +0100 Subject: [PATCH 016/251] nix/why-depends: fix output when not using `--precise` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Nix 2.6 the output of `nix why-depends --all` seems to be somewhat off: $ nix why-depends /nix/store/kn47hayxab8gc01jhr98dwyywbx561aq-nixos-system-roflmayr-21.11.20220207.6c202a9.drv /nix/store/srn5jbs1q30jpybdmxqrwskyny659qgc-nix-2.6.drv --derivation --extra-experimental-features nix-command --all /nix/store/kn47hayxab8gc01jhr98dwyywbx561aq-nixos-system-roflmayr-21.11.20220207.6c202a9.drv └───/nix/store/g8bpgfjhh5vxrdq0w6r6s64f9kkm9z6c-etc.drv │ └───/nix/store/hm0jmhp8shbf3cl846a685nv4f5cp3fy-nspawn-inst.drv | [...] └───/nix/store/2d6q3ygiim9ijl5d4h0qqx6vnjgxywyr-system-units.drv └───/nix/store/dil014y1b8qyjhhhf5fpaah5fzdf0bzs-unit-systemd-nspawn-hydra.service.drv └───/nix/store/a9r72wwx8qrxyp7hjydyg0gsrwnn26zb-activate.drv └───/nix/store/99hlc7i4gl77wq087lbhag4hkf3kvssj-nixos-system-hydra-21.11pre-git.drv Please note that `[...]-system-units.drv` is supposed to be a direct child of `[...]-etc.drv`. The reason for that is that each new level printed by `printNode` is four spaces off in comparison to `nix why-depends --precise` because the recursive `printNode()` only prints the path and not the `tree*`-chars in the case of `--precise` and in this format the path is four spaces further indented, i.e. on a newline, but on the same level as the path's children, i.e. /nix/store/kn47hayxab8gc01jhr98dwyywbx561aq-nixos-system-roflmayr-21.11.20220207.6c202a9.drv └───/: …1-p8.drv",["out"]),("/nix/store/g8bpgfjhh5vxrdq0w6r6s64f9kkm9z6c-etc.drv",["out"]),("/nix/store/… → /nix/store/g8bpgfjhh5vxrdq0w6r6s64f9kkm9z6c-etc.drv As you can see `[...]-etc.drv` is a direct child of the root, but four spaces indented. This logic was directly applied to the code-path with `precise=false` which resulted in `tree*` being printed four spaces too deep. In case of no `--precise`, `hits[hash]` is empty and the path itself should be printed rather than hits using the same logic as for `hits[hash]`. With this fix, the output looks correct now: /nix/store/kn47hayxab8gc01jhr98dwyywbx561aq-nixos-system-roflmayr-21.11.20220207.6c202a9.drv └───/nix/store/g8bpgfjhh5vxrdq0w6r6s64f9kkm9z6c-etc.drv ├───/nix/store/hm0jmhp8shbf3cl846a685nv4f5cp3fy-nspawn-inst.drv | [...] └───/nix/store/2d6q3ygiim9ijl5d4h0qqx6vnjgxywyr-system-units.drv └───/nix/store/dil014y1b8qyjhhhf5fpaah5fzdf0bzs-unit-systemd-nspawn-hydra.service.drv └───/nix/store/a9r72wwx8qrxyp7hjydyg0gsrwnn26zb-activate.drv └───/nix/store/99hlc7i4gl77wq087lbhag4hkf3kvssj-nixos-system-hydra-21.11pre-git.drv --- src/nix/why-depends.cc | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/nix/why-depends.cc b/src/nix/why-depends.cc index 657df30d7..bc8cfb1c5 100644 --- a/src/nix/why-depends.cc +++ b/src/nix/why-depends.cc @@ -171,12 +171,6 @@ struct CmdWhyDepends : SourceExprCommand node.visited ? "\e[38;5;244m" : "", firstPad != "" ? "→ " : "", pathS); - } else { - logger->cout("%s%s%s%s" ANSI_NORMAL, - firstPad, - node.visited ? "\e[38;5;244m" : "", - firstPad != "" ? treeLast : "", - pathS); } if (node.path == dependencyPath && !all @@ -184,7 +178,7 @@ struct CmdWhyDepends : SourceExprCommand throw BailOut(); if (node.visited) return; - node.visited = true; + if (precise) node.visited = true; /* Sort the references by distance to `dependency` to ensure that the shortest path is printed first. */ @@ -267,6 +261,16 @@ struct CmdWhyDepends : SourceExprCommand if (!all) break; } + if (!precise) { + auto pathS = store->printStorePath(ref.second->path); + logger->cout("%s%s%s%s" ANSI_NORMAL, + firstPad, + ref.second->visited ? "\e[38;5;244m" : "", + last ? treeLast : treeConn, + pathS); + node.visited = true; + } + printNode(*ref.second, tailPad + (last ? treeNull : treeLine), tailPad + (last ? treeNull : treeLine)); @@ -275,6 +279,9 @@ struct CmdWhyDepends : SourceExprCommand RunPager pager; try { + if (!precise) { + logger->cout("%s", store->printStorePath(graph.at(packagePath).path)); + } printNode(graph.at(packagePath), "", ""); } catch (BailOut & ) { } } From 5b809f9e0e0fe84304c2ae0f5f7b2d4db02565ad Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 10 Feb 2022 21:15:07 +0100 Subject: [PATCH 017/251] check-hydra-status.sh: Ignore unfinished builds --- scripts/check-hydra-status.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/scripts/check-hydra-status.sh b/scripts/check-hydra-status.sh index 7efe9cf97..5e2f03429 100644 --- a/scripts/check-hydra-status.sh +++ b/scripts/check-hydra-status.sh @@ -16,8 +16,13 @@ someBuildFailed=0 for buildId in $BUILDS_FOR_LATEST_EVAL; do buildInfo=$(curl -sS -H 'Accept: application/json' "https://hydra.nixos.org/build/$buildId") - buildStatus=$(echo "$buildInfo" | \ - jq -r '.buildstatus') + finished=$(echo "$buildInfo" | jq -r '.finished') + + if [[ $finished = 0 ]]; then + continue + fi + + buildStatus=$(echo "$buildInfo" | jq -r '.buildstatus') if [[ $buildStatus != 0 ]]; then someBuildFailed=1 From d2f9a081b81ae0c4ef194fc66b94a31fb8ed6d73 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 11 Feb 2022 14:45:46 +0100 Subject: [PATCH 018/251] flake.nix: Fix indent --- flake.nix | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/flake.nix b/flake.nix index 5b1e13a16..ae9305144 100644 --- a/flake.nix +++ b/flake.nix @@ -648,11 +648,10 @@ installCheckFlags = "sysconfdir=$(out)/etc"; }; }) crossSystems)) // (builtins.listToAttrs (map (stdenvName: - nixpkgsFor.${system}.lib.nameValuePair - "nix-${stdenvName}" - nixpkgsFor.${system}."${stdenvName}Packages".nix - ) stdenvs)) - ); + nixpkgsFor.${system}.lib.nameValuePair + "nix-${stdenvName}" + nixpkgsFor.${system}."${stdenvName}Packages".nix + ) stdenvs))); defaultPackage = forAllSystems (system: self.packages.${system}.nix); From cdc90c2776ee5542fd4d4e1aaa06d1d826daecb0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 11 Feb 2022 15:50:12 +0100 Subject: [PATCH 019/251] parseInstallables(): Don't try the flake attr path prefixes when no fragment is specified Fixes #5880. --- src/libcmd/installables.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 5e8b62e1a..9f138b420 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -709,7 +709,7 @@ std::vector> SourceExprCommand::parseInstallables( getEvalState(), std::move(flakeRef), fragment == "" ? getDefaultFlakeAttrPaths() : Strings{fragment}, - getDefaultFlakeAttrPathPrefixes(), + fragment == "" ? Strings{} : getDefaultFlakeAttrPathPrefixes(), lockFlags)); continue; } catch (...) { From 270fb5f192c91977efd45e52ceac7f6002bc1422 Mon Sep 17 00:00:00 2001 From: Tom Bereknyei Date: Fri, 11 Feb 2022 10:23:19 -0500 Subject: [PATCH 020/251] profile: add verbosity warn if there are no matches and give notice of removing packages as they are found --- src/nix/profile.cc | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/nix/profile.cc b/src/nix/profile.cc index 9b7c999af..b9279414d 100644 --- a/src/nix/profile.cc +++ b/src/nix/profile.cc @@ -295,7 +295,11 @@ public: expectArgs("elements", &_matchers); } - typedef std::variant Matcher; + struct RegexPattern { + std::string pattern; + std::regex reg; + }; + typedef std::variant Matcher; std::vector getMatchers(ref store) { @@ -307,7 +311,7 @@ public: else if (store->isStorePath(s)) res.push_back(s); else - res.push_back(std::regex(s, std::regex::extended | std::regex::icase)); + res.push_back(RegexPattern{s,std::regex(s, std::regex::extended | std::regex::icase)}); } return res; @@ -320,9 +324,9 @@ public: if (*n == pos) return true; } else if (auto path = std::get_if(&matcher)) { if (element.storePaths.count(store.parseStorePath(*path))) return true; - } else if (auto regex = std::get_if(&matcher)) { + } else if (auto regex = std::get_if(&matcher)) { if (element.source - && std::regex_match(element.source->attrPath, *regex)) + && std::regex_match(element.source->attrPath, regex->reg)) return true; } } @@ -355,16 +359,30 @@ struct CmdProfileRemove : virtual EvalCommand, MixDefaultProfile, MixProfileElem for (size_t i = 0; i < oldManifest.elements.size(); ++i) { auto & element(oldManifest.elements[i]); - if (!matches(*store, element, i, matchers)) + if (!matches(*store, element, i, matchers)) { newManifest.elements.push_back(std::move(element)); + } else { + notice("removing '%s'", element.describe()); + } } - // FIXME: warn about unused matchers? - + auto removedCount = oldManifest.elements.size() - newManifest.elements.size(); printInfo("removed %d packages, kept %d packages", - oldManifest.elements.size() - newManifest.elements.size(), + removedCount, newManifest.elements.size()); + if (removedCount == 0) { + for (auto matcher: matchers) { + if (const size_t* index = std::get_if(&matcher)){ + warn("'%d' is not a valid index in profile", *index); + } else if (const Path* path = std::get_if(&matcher)){ + warn("'%s' does not match any paths in profile", *path); + } else if (const RegexPattern* regex = std::get_if(&matcher)){ + warn("'%s' does not match any packages in profile", regex->pattern); + } + } + warn ("Try `nix profile list` to see the current profile."); + } updateProfile(newManifest.build(store)); } }; From c437e1326d900e2563c5859489f3be2cb557a3d3 Mon Sep 17 00:00:00 2001 From: Sebastian Ullrich Date: Sat, 12 Feb 2022 16:28:36 +0100 Subject: [PATCH 021/251] Fix using sandbox without user namespaces --- src/libstore/build/local-derivation-goal.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc index 0d0afea2d..b76ad702b 100644 --- a/src/libstore/build/local-derivation-goal.cc +++ b/src/libstore/build/local-derivation-goal.cc @@ -912,9 +912,12 @@ void LocalDerivationGoal::startBuilder() sandboxMountNamespace = open(fmt("/proc/%d/ns/mnt", (pid_t) pid).c_str(), O_RDONLY); if (sandboxMountNamespace.get() == -1) throw SysError("getting sandbox mount namespace"); - sandboxUserNamespace = open(fmt("/proc/%d/ns/user", (pid_t) pid).c_str(), O_RDONLY); - if (sandboxUserNamespace.get() == -1) - throw SysError("getting sandbox user namespace"); + + if (usingUserNamespace) { + sandboxUserNamespace = open(fmt("/proc/%d/ns/user", (pid_t) pid).c_str(), O_RDONLY); + if (sandboxUserNamespace.get() == -1) + throw SysError("getting sandbox user namespace"); + } /* Signal the builder that we've updated its user namespace. */ writeFull(userNamespaceSync.writeSide.get(), "1"); From 023e45977745ffd6c16eec299a00affd65176669 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 14 Feb 2022 20:39:44 +0100 Subject: [PATCH 022/251] InstallableFlake: Default attr paths cleanup This removes some duplicated logic, and fixes "nix bundle" parsing its installable twice. --- src/libcmd/installables.cc | 16 ++++++++++------ src/libcmd/installables.hh | 5 +++-- src/nix/bundle.cc | 19 +++++++------------ src/nix/develop.cc | 3 ++- src/nix/flake.cc | 15 +++++++++------ src/nix/profile.cc | 1 + 6 files changed, 32 insertions(+), 27 deletions(-) diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 9f138b420..644954977 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -545,13 +545,14 @@ InstallableFlake::InstallableFlake( SourceExprCommand * cmd, ref state, FlakeRef && flakeRef, - Strings && attrPaths, - Strings && prefixes, + std::string_view fragment, + Strings attrPaths, + Strings prefixes, const flake::LockFlags & lockFlags) : InstallableValue(state), flakeRef(flakeRef), - attrPaths(attrPaths), - prefixes(prefixes), + attrPaths(fragment == "" ? attrPaths : Strings{(std::string) fragment}), + prefixes(fragment == "" ? Strings{} : prefixes), lockFlags(lockFlags) { if (cmd && cmd->getAutoArgs(*state)->size()) @@ -566,6 +567,8 @@ std::tuple InstallableF auto root = cache->getRoot(); for (auto & attrPath : getActualAttrPaths()) { + debug("trying flake output attribute '%s'", attrPath); + auto attr = root->findAlongAttrPath( parseAttrPath(*state, attrPath), true @@ -708,8 +711,9 @@ std::vector> SourceExprCommand::parseInstallables( this, getEvalState(), std::move(flakeRef), - fragment == "" ? getDefaultFlakeAttrPaths() : Strings{fragment}, - fragment == "" ? Strings{} : getDefaultFlakeAttrPathPrefixes(), + fragment, + getDefaultFlakeAttrPaths(), + getDefaultFlakeAttrPathPrefixes(), lockFlags)); continue; } catch (...) { diff --git a/src/libcmd/installables.hh b/src/libcmd/installables.hh index ced6b3f10..3d2563e4b 100644 --- a/src/libcmd/installables.hh +++ b/src/libcmd/installables.hh @@ -102,8 +102,9 @@ struct InstallableFlake : InstallableValue SourceExprCommand * cmd, ref state, FlakeRef && flakeRef, - Strings && attrPaths, - Strings && prefixes, + std::string_view fragment, + Strings attrPaths, + Strings prefixes, const flake::LockFlags & lockFlags); std::string what() const override { return flakeRef.to_string() + "#" + *attrPaths.begin(); } diff --git a/src/nix/bundle.cc b/src/nix/bundle.cc index 113ceca33..c13018328 100644 --- a/src/nix/bundle.cc +++ b/src/nix/bundle.cc @@ -74,21 +74,16 @@ struct CmdBundle : InstallableCommand { auto evalState = getEvalState(); - auto [progFlakeRef, progName] = parseFlakeRefWithFragment(installable->what(), absPath(".")); - const flake::LockFlags lockFlagsProg{ .writeLockFile = false }; - auto programInstallable = InstallableFlake(this, - evalState, std::move(progFlakeRef), - Strings{progName == "" ? "defaultApp" : progName}, - Strings(this->getDefaultFlakeAttrPathPrefixes()), - lockFlagsProg); - auto val = programInstallable.toValue(*evalState).first; + auto val = installable->toValue(*evalState).first; auto [bundlerFlakeRef, bundlerName] = parseFlakeRefWithFragment(bundler, absPath(".")); const flake::LockFlags lockFlags{ .writeLockFile = false }; - auto bundler = InstallableFlake(this, - evalState, std::move(bundlerFlakeRef), - Strings{bundlerName == "" ? "defaultBundler." + settings.thisSystem.get() : settings.thisSystem.get() + "." + bundlerName, bundlerName}, - Strings({"","bundlers."}), lockFlags); + InstallableFlake bundler{this, + evalState, std::move(bundlerFlakeRef), bundlerName, + {"defaultBundler." + settings.thisSystem.get()}, + {"bundlers." + settings.thisSystem.get() + "."}, + lockFlags + }; auto vRes = evalState->allocValue(); evalState->callFunction(*bundler.toValue(*evalState).first, *val, *vRes, noPos); diff --git a/src/nix/develop.cc b/src/nix/develop.cc index 42e13436a..f88f5909c 100644 --- a/src/nix/develop.cc +++ b/src/nix/develop.cc @@ -498,7 +498,8 @@ struct CmdDevelop : Common, MixEnvironment this, state, installable->nixpkgsFlakeRef(), - Strings{"bashInteractive"}, + "bashInteractive", + Strings{}, Strings{"legacyPackages." + settings.thisSystem.get() + "."}, nixpkgsLockFlags); diff --git a/src/nix/flake.cc b/src/nix/flake.cc index 4bc79820c..3effce2c1 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -649,12 +649,14 @@ struct CmdFlakeCheck : FlakeCommand } }; +static Strings defaultTemplateAttrPathsPrefixes{"templates."}; +static Strings defaultTemplateAttrPaths = {"defaultTemplate"}; + struct CmdFlakeInitCommon : virtual Args, EvalCommand { std::string templateUrl = "templates"; Path destDir; - const Strings attrsPathPrefixes{"templates."}; const LockFlags lockFlags{ .writeLockFile = false }; CmdFlakeInitCommon() @@ -669,8 +671,8 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand completeFlakeRefWithFragment( getEvalState(), lockFlags, - attrsPathPrefixes, - {"defaultTemplate"}, + defaultTemplateAttrPathsPrefixes, + defaultTemplateAttrPaths, prefix); }} }); @@ -685,9 +687,10 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand auto [templateFlakeRef, templateName] = parseFlakeRefWithFragment(templateUrl, absPath(".")); auto installable = InstallableFlake(nullptr, - evalState, std::move(templateFlakeRef), - Strings{templateName == "" ? "defaultTemplate" : templateName}, - Strings(attrsPathPrefixes), lockFlags); + evalState, std::move(templateFlakeRef), templateName, + defaultTemplateAttrPaths, + defaultTemplateAttrPathsPrefixes, + lockFlags); auto [cursor, attrPath] = installable.getCursor(*evalState); diff --git a/src/nix/profile.cc b/src/nix/profile.cc index b9279414d..55b5ff736 100644 --- a/src/nix/profile.cc +++ b/src/nix/profile.cc @@ -423,6 +423,7 @@ struct CmdProfileUpgrade : virtual SourceExprCommand, MixDefaultProfile, MixProf this, getEvalState(), FlakeRef(element.source->originalRef), + "", {element.source->attrPath}, {}, lockFlags); From 72e8f94081290784e2d115cfbf09375b53d8cbe9 Mon Sep 17 00:00:00 2001 From: Gabriel Fontes Date: Wed, 6 Oct 2021 13:32:46 -0300 Subject: [PATCH 023/251] add sourcehut input scheme --- src/libfetchers/github.cc | 91 ++++++++++++++++++++++++++++++++++++++- src/nix/flake.md | 32 ++++++++++++++ 2 files changed, 122 insertions(+), 1 deletion(-) diff --git a/src/libfetchers/github.cc b/src/libfetchers/github.cc index 1c539b80e..e101aa3d6 100644 --- a/src/libfetchers/github.cc +++ b/src/libfetchers/github.cc @@ -8,6 +8,7 @@ #include #include +#include namespace nix::fetchers { @@ -17,7 +18,7 @@ struct DownloadUrl Headers headers; }; -// A github or gitlab host +// A github, gitlab, or sourcehut host const static std::string hostRegexS = "[a-zA-Z0-9.]*"; // FIXME: check std::regex hostRegex(hostRegexS, std::regex::ECMAScript); @@ -348,7 +349,95 @@ struct GitLabInputScheme : GitArchiveInputScheme } }; +struct SourceHutInputScheme : GitArchiveInputScheme +{ + std::string type() override { return "sourcehut"; } + + std::optional> accessHeaderFromToken(const std::string & token) const override + { + // SourceHut supports both PAT and OAuth2. See + // https://man.sr.ht/meta.sr.ht/oauth.md + return std::pair("Authorization", fmt("Bearer %s", token)); + // Note: This currently serves no purpose, as this kind of authorization + // does not allow for downloading tarballs on sourcehut private repos. + // Once it is implemented, however, should work as expected. + } + + Hash getRevFromRef(nix::ref store, const Input & input) const override + { + // TODO: In the future, when the sourcehut graphql API is implemented for mercurial + // and with anonymous access, this method should use it instead. + + auto ref = *input.getRef(); + + auto host = maybeGetStrAttr(input.attrs, "host").value_or("git.sr.ht"); + auto base_url = fmt("https://%s/%s/%s", + host, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo")); + + Headers headers = makeHeadersWithAuthTokens(host); + + std::string ref_uri; + if (ref == "HEAD") { + auto file = store->toRealPath( + downloadFile(store, fmt("%s/HEAD", base_url), "source", false, headers).storePath); + std::ifstream is(file); + std::string line; + getline(is, line); + + auto ref_index = line.find("ref: "); + if (ref_index == std::string::npos) { + throw BadURL("in '%d', couldn't resolve HEAD ref '%d'", input.to_string(), ref); + } + + ref_uri = line.substr(ref_index+5, line.length()-1); + } else + ref_uri = fmt("refs/heads/%s", ref); + + auto file = store->toRealPath( + downloadFile(store, fmt("%s/info/refs", base_url), "source", false, headers).storePath); + std::ifstream is(file); + + std::string line; + std::string id; + while(getline(is, line)) { + auto index = line.find(ref_uri); + if (index != std::string::npos) { + id = line.substr(0, index-1); + break; + } + } + + if(id.empty()) + throw BadURL("in '%d', couldn't find ref '%d'", input.to_string(), ref); + + auto rev = Hash::parseAny(id, htSHA1); + debug("HEAD revision for '%s' is %s", fmt("%s/%s", base_url, ref), rev.gitRev()); + return rev; + } + + DownloadUrl getDownloadUrl(const Input & input) const override + { + auto host = maybeGetStrAttr(input.attrs, "host").value_or("git.sr.ht"); + auto url = fmt("https://%s/%s/%s/archive/%s.tar.gz", + host, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo"), + input.getRev()->to_string(Base16, false)); + + Headers headers = makeHeadersWithAuthTokens(host); + return DownloadUrl { url, headers }; + } + + void clone(const Input & input, const Path & destDir) override + { + auto host = maybeGetStrAttr(input.attrs, "host").value_or("git.sr.ht"); + Input::fromURL(fmt("git+https://%s/%s/%s", + host, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo"))) + .applyOverrides(input.getRef(), input.getRev()) + .clone(destDir); + } +}; + static auto rGitHubInputScheme = OnStartup([] { registerInputScheme(std::make_unique()); }); static auto rGitLabInputScheme = OnStartup([] { registerInputScheme(std::make_unique()); }); +static auto rSourceHutInputScheme = OnStartup([] { registerInputScheme(std::make_unique()); }); } diff --git a/src/nix/flake.md b/src/nix/flake.md index accddd436..f539a7c28 100644 --- a/src/nix/flake.md +++ b/src/nix/flake.md @@ -209,6 +209,38 @@ Currently the `type` attribute can be one of the following: * `github:edolstra/dwarffs/unstable` * `github:edolstra/dwarffs/d3f2baba8f425779026c6ec04021b2e927f61e31` +* `sourcehut`: Similar to `github`, is a more efficient way to fetch + SourceHut repositories. The following attributes are required: + + * `owner`: The owner of the repository (including leading `~`). + + * `repo`: The name of the repository. + + Like `github`, these are downloaded as tarball archives. + + The URL syntax for `sourcehut` flakes is: + + `sourcehut:/(/)?(\?)?` + + `` works the same as `github`. Either a branch or tag name + (`ref`), or a commit hash (`rev`) can be specified. + + Since SourceHut allows for self-hosting, you can specify `host` as + a parameter, to point to any instances other than `git.sr.ht`. + + Currently, `ref` name resolution only works for Git repositories. + You can refer to Mercurial repositories by simply changing `host` to + `hg.sr.ht` (or any other Mercurial instance). With the caveat + that you must explicitly specify a commit hash (`rev`). + + Some examples: + + * `sourcehut:~misterio/nix-colors` + * `sourcehut:~misterio/nix-colors/main` + * `sourcehut:~misterio/nix-colors?host=git.example.org` + * `sourcehut:~misterio/nix-colors/182b4b8709b8ffe4e9774a4c5d6877bf6bb9a21c` + * `sourcehut:~misterio/nix-colors/21c1a380a6915d890d408e9f22203436a35bb2de?host=hg.sr.ht` + * `indirect`: Indirections through the flake registry. These have the form From f3a2940e70dea2c35dcae3fca019e94bf8758b4d Mon Sep 17 00:00:00 2001 From: Taeer Bar-Yam Date: Tue, 15 Feb 2022 11:50:14 -0500 Subject: [PATCH 024/251] add descriptive output when creating templates this includes a `welcomeText` attribute which can be set in the template, as well as outputing which files were created. --- src/nix/flake-init.md | 8 ++++++++ src/nix/flake.cc | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/src/nix/flake-init.md b/src/nix/flake-init.md index 890038016..c8bcee375 100644 --- a/src/nix/flake-init.md +++ b/src/nix/flake-init.md @@ -37,6 +37,10 @@ A flake can declare templates through its `templates` and * `path`: The path of the directory to be copied. +* `welcomeText`: A block of text to display when a user initializes a new flake + based on this template. + + Here is an example: ``` @@ -45,6 +49,10 @@ outputs = { self }: { templates.rust = { path = ./rust; description = "A simple Rust/Cargo project"; + welcomeText = '' + You've created a simple Rust/Cargo template. + Visit https://www.rust-lang.org/ for more info. + ''; }; templates.defaultTemplate = self.templates.rust; diff --git a/src/nix/flake.cc b/src/nix/flake.cc index 4bc79820c..f5d34c10f 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -728,6 +728,7 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand else throw Error("file '%s' has unsupported type", from2); files.push_back(to2); + notice("wrote: %s", to2); } }; @@ -738,6 +739,11 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand for (auto & s : files) args.push_back(s); runProgram("git", true, args); } + auto welcomeText = cursor->maybeGetAttr("welcomeText"); + if (welcomeText) { + notice("\n----------\n"); + notice(welcomeText->getString()); + } } }; From d82cf4a016aa0ee136ff62635e909607de78e02a Mon Sep 17 00:00:00 2001 From: Rahul Butani Date: Tue, 15 Feb 2022 15:44:05 -0600 Subject: [PATCH 025/251] manual: fix formatting for options with "machine-specific" defaults --- doc/manual/generate-options.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/manual/generate-options.nix b/doc/manual/generate-options.nix index 9a77f4d36..84d90beb6 100644 --- a/doc/manual/generate-options.nix +++ b/doc/manual/generate-options.nix @@ -20,7 +20,7 @@ concatStrings (map # JSON, but that converts to "{ }" here. (if isAttrs option.value then "`\"\"`" else "`" + toString option.value + "`")) + "\n\n" - else " **Default:** *machine-specific*") + else " **Default:** *machine-specific*\n") + (if option.aliases != [] then " **Deprecated alias:** " + (concatStringsSep ", " (map (s: "`${s}`") option.aliases)) + "\n\n" else "") From 2d6d9a28ebb17b1ba1fe0dc4d56b6aa311f94d39 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 15 Feb 2022 15:08:06 +0100 Subject: [PATCH 026/251] addToStoreFromDump(): Take std::string_view --- src/libstore/binary-cache-store.cc | 2 +- src/libstore/binary-cache-store.hh | 4 ++-- src/libstore/build/local-derivation-goal.cc | 2 +- src/libstore/local-store.cc | 2 +- src/libstore/local-store.hh | 2 +- src/libstore/remote-store.cc | 4 ++-- src/libstore/remote-store.hh | 4 ++-- src/libstore/store-api.hh | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc index 6e4458f7a..b3fd991a1 100644 --- a/src/libstore/binary-cache-store.cc +++ b/src/libstore/binary-cache-store.cc @@ -307,7 +307,7 @@ void BinaryCacheStore::addToStore(const ValidPathInfo & info, Source & narSource }}); } -StorePath BinaryCacheStore::addToStoreFromDump(Source & dump, const string & name, +StorePath BinaryCacheStore::addToStoreFromDump(Source & dump, std::string_view name, FileIngestionMethod method, HashType hashAlgo, RepairFlag repair, const StorePathSet & references) { if (method != FileIngestionMethod::Recursive || hashAlgo != htSHA256) diff --git a/src/libstore/binary-cache-store.hh b/src/libstore/binary-cache-store.hh index 7599230d9..5b5d064f3 100644 --- a/src/libstore/binary-cache-store.hh +++ b/src/libstore/binary-cache-store.hh @@ -98,8 +98,8 @@ public: void addToStore(const ValidPathInfo & info, Source & narSource, RepairFlag repair, CheckSigsFlag checkSigs) override; - StorePath addToStoreFromDump(Source & dump, const string & name, - FileIngestionMethod method, HashType hashAlgo, RepairFlag repair, const StorePathSet & references ) override; + StorePath addToStoreFromDump(Source & dump, std::string_view name, + FileIngestionMethod method, HashType hashAlgo, RepairFlag repair, const StorePathSet & references) override; StorePath addToStore(const string & name, const Path & srcPath, FileIngestionMethod method, HashType hashAlgo, diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc index b76ad702b..8861d2c7b 100644 --- a/src/libstore/build/local-derivation-goal.cc +++ b/src/libstore/build/local-derivation-goal.cc @@ -1208,7 +1208,7 @@ struct RestrictedStore : public virtual RestrictedStoreConfig, public virtual Lo return path; } - StorePath addToStoreFromDump(Source & dump, const string & name, + StorePath addToStoreFromDump(Source & dump, std::string_view name, FileIngestionMethod method = FileIngestionMethod::Recursive, HashType hashAlgo = htSHA256, RepairFlag repair = NoRepair, const StorePathSet & references = StorePathSet()) override { diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 284e385e6..1a02b916a 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -1318,7 +1318,7 @@ void LocalStore::addToStore(const ValidPathInfo & info, Source & source, } -StorePath LocalStore::addToStoreFromDump(Source & source0, const string & name, +StorePath LocalStore::addToStoreFromDump(Source & source0, std::string_view name, FileIngestionMethod method, HashType hashAlgo, RepairFlag repair, const StorePathSet & references) { /* For computing the store path. */ diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index 8cf9c68b3..46aed9bcb 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -144,7 +144,7 @@ public: void addToStore(const ValidPathInfo & info, Source & source, RepairFlag repair, CheckSigsFlag checkSigs) override; - StorePath addToStoreFromDump(Source & dump, const string & name, + StorePath addToStoreFromDump(Source & dump, std::string_view name, FileIngestionMethod method, HashType hashAlgo, RepairFlag repair, const StorePathSet & references) override; StorePath addTextToStore(const string & name, const string & s, diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 573becfbd..c6f083dea 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -500,7 +500,7 @@ std::optional RemoteStore::queryPathFromHashPart(const std::string & ref RemoteStore::addCAToStore( Source & dump, - const string & name, + std::string_view name, ContentAddressMethod caMethod, const StorePathSet & references, RepairFlag repair) @@ -582,7 +582,7 @@ ref RemoteStore::addCAToStore( } -StorePath RemoteStore::addToStoreFromDump(Source & dump, const string & name, +StorePath RemoteStore::addToStoreFromDump(Source & dump, std::string_view name, FileIngestionMethod method, HashType hashType, RepairFlag repair, const StorePathSet & references) { return addCAToStore(dump, name, FixedOutputHashMethod{ .fileIngestionMethod = method, .hashType = hashType }, references, repair)->path; diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh index b91d25fa9..55cfd5cc6 100644 --- a/src/libstore/remote-store.hh +++ b/src/libstore/remote-store.hh @@ -66,13 +66,13 @@ public: /* Add a content-addressable store path. `dump` will be drained. */ ref addCAToStore( Source & dump, - const string & name, + std::string_view name, ContentAddressMethod caMethod, const StorePathSet & references, RepairFlag repair); /* Add a content-addressable store path. Does not support references. `dump` will be drained. */ - StorePath addToStoreFromDump(Source & dump, const string & name, + StorePath addToStoreFromDump(Source & dump, std::string_view name, FileIngestionMethod method = FileIngestionMethod::Recursive, HashType hashAlgo = htSHA256, RepairFlag repair = NoRepair, const StorePathSet & references = StorePathSet()) override; void addToStore(const ValidPathInfo & info, Source & nar, diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 4068f8f35..90d2e93ed 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -499,7 +499,7 @@ public: false). `dump` may be drained */ // FIXME: remove? - virtual StorePath addToStoreFromDump(Source & dump, const string & name, + virtual StorePath addToStoreFromDump(Source & dump, std::string_view name, FileIngestionMethod method = FileIngestionMethod::Recursive, HashType hashAlgo = htSHA256, RepairFlag repair = NoRepair, const StorePathSet & references = StorePathSet()) { unsupported("addToStoreFromDump"); } From aa5b83d93ce1b7bb67bf81ceda7ebf7706b1efa0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 15 Feb 2022 14:33:31 +0100 Subject: [PATCH 027/251] InputScheme::fetch(): Return a StorePath instead of a Tree --- src/libfetchers/fetchers.cc | 12 ++++++------ src/libfetchers/fetchers.hh | 3 +-- src/libfetchers/git.cc | 14 ++++---------- src/libfetchers/github.cc | 9 +++------ src/libfetchers/indirect.cc | 2 +- src/libfetchers/mercurial.cc | 14 ++++---------- src/libfetchers/path.cc | 7 ++----- src/libfetchers/tarball.cc | 8 ++++---- 8 files changed, 25 insertions(+), 44 deletions(-) diff --git a/src/libfetchers/fetchers.cc b/src/libfetchers/fetchers.cc index e158d914b..c06ccb929 100644 --- a/src/libfetchers/fetchers.cc +++ b/src/libfetchers/fetchers.cc @@ -124,15 +124,13 @@ std::pair Input::fetch(ref store) const debug("using substituted/cached input '%s' in '%s'", to_string(), store->printStorePath(storePath)); - auto actualPath = store->toRealPath(storePath); - - return {fetchers::Tree(std::move(actualPath), std::move(storePath)), *this}; + return {Tree { .actualPath = store->toRealPath(storePath), .storePath = std::move(storePath) }, *this}; } catch (Error & e) { debug("substitution of input '%s' failed: %s", to_string(), e.what()); } } - auto [tree, input] = [&]() -> std::pair { + auto [storePath, input] = [&]() -> std::pair { try { return scheme->fetch(store, *this); } catch (Error & e) { @@ -141,8 +139,10 @@ std::pair Input::fetch(ref store) const } }(); - if (tree.actualPath == "") - tree.actualPath = store->toRealPath(tree.storePath); + Tree tree { + .actualPath = store->toRealPath(storePath), + .storePath = storePath, + }; auto narHash = store->queryPathInfo(tree.storePath)->narHash; input.attrs.insert_or_assign("narHash", narHash.to_string(SRI, true)); diff --git a/src/libfetchers/fetchers.hh b/src/libfetchers/fetchers.hh index c43b047a7..2836af5fa 100644 --- a/src/libfetchers/fetchers.hh +++ b/src/libfetchers/fetchers.hh @@ -16,7 +16,6 @@ struct Tree { Path actualPath; StorePath storePath; - Tree(Path && actualPath, StorePath && storePath) : actualPath(actualPath), storePath(std::move(storePath)) {} }; struct InputScheme; @@ -131,7 +130,7 @@ struct InputScheme virtual void markChangedFile(const Input & input, std::string_view file, std::optional commitMsg); - virtual std::pair fetch(ref store, const Input & input) = 0; + virtual std::pair fetch(ref store, const Input & input) = 0; }; void registerInputScheme(std::shared_ptr && fetcher); diff --git a/src/libfetchers/git.cc b/src/libfetchers/git.cc index 544d2ffbf..c3f0f8c8f 100644 --- a/src/libfetchers/git.cc +++ b/src/libfetchers/git.cc @@ -172,7 +172,7 @@ struct GitInputScheme : InputScheme return {isLocal, isLocal ? url.path : url.base}; } - std::pair fetch(ref store, const Input & _input) override + std::pair fetch(ref store, const Input & _input) override { Input input(_input); @@ -197,17 +197,14 @@ struct GitInputScheme : InputScheme }; auto makeResult = [&](const Attrs & infoAttrs, StorePath && storePath) - -> std::pair + -> std::pair { assert(input.getRev()); assert(!_input.getRev() || _input.getRev() == input.getRev()); if (!shallow) input.attrs.insert_or_assign("revCount", getIntAttr(infoAttrs, "revCount")); input.attrs.insert_or_assign("lastModified", getIntAttr(infoAttrs, "lastModified")); - return { - Tree(store->toRealPath(storePath), std::move(storePath)), - input - }; + return {std::move(storePath), input}; }; if (input.getRev()) { @@ -285,10 +282,7 @@ struct GitInputScheme : InputScheme "lastModified", haveCommits ? std::stoull(runProgram("git", true, { "-C", actualUrl, "log", "-1", "--format=%ct", "--no-show-signature", "HEAD" })) : 0); - return { - Tree(store->toRealPath(storePath), std::move(storePath)), - input - }; + return {std::move(storePath), input}; } } diff --git a/src/libfetchers/github.cc b/src/libfetchers/github.cc index 1c539b80e..8ba6935f9 100644 --- a/src/libfetchers/github.cc +++ b/src/libfetchers/github.cc @@ -180,7 +180,7 @@ struct GitArchiveInputScheme : InputScheme virtual DownloadUrl getDownloadUrl(const Input & input) const = 0; - std::pair fetch(ref store, const Input & _input) override + std::pair fetch(ref store, const Input & _input) override { Input input(_input); @@ -199,10 +199,7 @@ struct GitArchiveInputScheme : InputScheme if (auto res = getCache()->lookup(store, immutableAttrs)) { input.attrs.insert_or_assign("lastModified", getIntAttr(res->first, "lastModified")); - return { - Tree(store->toRealPath(res->second), std::move(res->second)), - input - }; + return {std::move(res->second), input}; } auto url = getDownloadUrl(input); @@ -221,7 +218,7 @@ struct GitArchiveInputScheme : InputScheme tree.storePath, true); - return {std::move(tree), input}; + return {std::move(tree.storePath), input}; } }; diff --git a/src/libfetchers/indirect.cc b/src/libfetchers/indirect.cc index 10e59919a..9288fc6cf 100644 --- a/src/libfetchers/indirect.cc +++ b/src/libfetchers/indirect.cc @@ -94,7 +94,7 @@ struct IndirectInputScheme : InputScheme return input; } - std::pair fetch(ref store, const Input & input) override + std::pair fetch(ref store, const Input & input) override { throw Error("indirect input '%s' cannot be fetched directly", input.to_string()); } diff --git a/src/libfetchers/mercurial.cc b/src/libfetchers/mercurial.cc index d52d4641b..5123bcda4 100644 --- a/src/libfetchers/mercurial.cc +++ b/src/libfetchers/mercurial.cc @@ -143,7 +143,7 @@ struct MercurialInputScheme : InputScheme return {isLocal, isLocal ? url.path : url.base}; } - std::pair fetch(ref store, const Input & _input) override + std::pair fetch(ref store, const Input & _input) override { Input input(_input); @@ -193,10 +193,7 @@ struct MercurialInputScheme : InputScheme auto storePath = store->addToStore(input.getName(), actualUrl, FileIngestionMethod::Recursive, htSHA256, filter); - return { - Tree(store->toRealPath(storePath), std::move(storePath)), - input - }; + return {std::move(storePath), input}; } } @@ -212,15 +209,12 @@ struct MercurialInputScheme : InputScheme }; auto makeResult = [&](const Attrs & infoAttrs, StorePath && storePath) - -> std::pair + -> std::pair { assert(input.getRev()); assert(!_input.getRev() || _input.getRev() == input.getRev()); input.attrs.insert_or_assign("revCount", getIntAttr(infoAttrs, "revCount")); - return { - Tree(store->toRealPath(storePath), std::move(storePath)), - input - }; + return {std::move(storePath), input}; }; if (input.getRev()) { diff --git a/src/libfetchers/path.cc b/src/libfetchers/path.cc index 07e543c53..59e228e97 100644 --- a/src/libfetchers/path.cc +++ b/src/libfetchers/path.cc @@ -80,7 +80,7 @@ struct PathInputScheme : InputScheme // nothing to do } - std::pair fetch(ref store, const Input & input) override + std::pair fetch(ref store, const Input & input) override { std::string absPath; auto path = getStrAttr(input.attrs, "path"); @@ -115,10 +115,7 @@ struct PathInputScheme : InputScheme // FIXME: try to substitute storePath. storePath = store->addToStore("source", absPath); - return { - Tree(store->toRealPath(*storePath), std::move(*storePath)), - input - }; + return {std::move(*storePath), input}; } }; diff --git a/src/libfetchers/tarball.cc b/src/libfetchers/tarball.cc index c933475ca..74c8097ff 100644 --- a/src/libfetchers/tarball.cc +++ b/src/libfetchers/tarball.cc @@ -126,7 +126,7 @@ std::pair downloadTarball( if (cached && !cached->expired) return { - Tree(store->toRealPath(cached->storePath), std::move(cached->storePath)), + Tree { .actualPath = store->toRealPath(cached->storePath), .storePath = std::move(cached->storePath) }, getIntAttr(cached->infoAttrs, "lastModified") }; @@ -163,7 +163,7 @@ std::pair downloadTarball( immutable); return { - Tree(store->toRealPath(*unpackedStorePath), std::move(*unpackedStorePath)), + Tree { .actualPath = store->toRealPath(*unpackedStorePath), .storePath = std::move(*unpackedStorePath) }, lastModified, }; } @@ -225,10 +225,10 @@ struct TarballInputScheme : InputScheme return true; } - std::pair fetch(ref store, const Input & input) override + std::pair fetch(ref store, const Input & input) override { auto tree = downloadTarball(store, getStrAttr(input.attrs, "url"), input.getName(), false).first; - return {std::move(tree), input}; + return {std::move(tree.storePath), input}; } }; From 1bec333788df9b1c9d9c68a428cfc79568d87cf2 Mon Sep 17 00:00:00 2001 From: Guillaume Maudoux Date: Thu, 17 Feb 2022 09:32:15 +0100 Subject: [PATCH 028/251] Create to daemon-socket folder during install --- scripts/install-multi-user.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/install-multi-user.sh b/scripts/install-multi-user.sh index 33e4eaa14..d3ed53d09 100644 --- a/scripts/install-multi-user.sh +++ b/scripts/install-multi-user.sh @@ -609,7 +609,7 @@ EOF fi fi _sudo "to make the basic directory structure of Nix (part 1)" \ - install -dv -m 0755 /nix /nix/var /nix/var/log /nix/var/log/nix /nix/var/log/nix/drvs /nix/var/nix{,/db,/gcroots,/profiles,/temproots,/userpool} /nix/var/nix/{gcroots,profiles}/per-user + install -dv -m 0755 /nix /nix/var /nix/var/log /nix/var/log/nix /nix/var/log/nix/drvs /nix/var/nix{,/db,/gcroots,/profiles,/temproots,/userpool,/daemon-socket} /nix/var/nix/{gcroots,profiles}/per-user _sudo "to make the basic directory structure of Nix (part 2)" \ install -dv -g "$NIX_BUILD_GROUP_NAME" -m 1775 /nix/store From f56dd3a36bc8a325028588fd5500cbc33fa48a26 Mon Sep 17 00:00:00 2001 From: Taeer Bar-Yam Date: Thu, 17 Feb 2022 13:59:32 -0500 Subject: [PATCH 029/251] make flake template welcomeText markdown --- src/nix/flake-init.md | 14 ++++++++++---- src/nix/flake.cc | 5 +++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/nix/flake-init.md b/src/nix/flake-init.md index c8bcee375..c13b22248 100644 --- a/src/nix/flake-init.md +++ b/src/nix/flake-init.md @@ -37,8 +37,8 @@ A flake can declare templates through its `templates` and * `path`: The path of the directory to be copied. -* `welcomeText`: A block of text to display when a user initializes a new flake - based on this template. +* `welcomeText`: A block of markdown text to display when a user initializes a + new flake based on this template. Here is an example: @@ -50,8 +50,14 @@ outputs = { self }: { path = ./rust; description = "A simple Rust/Cargo project"; welcomeText = '' - You've created a simple Rust/Cargo template. - Visit https://www.rust-lang.org/ for more info. + # Simple Rust/Cargo Template + ## Intended usage + The intended usage of this flake is... + + ## More info + - [Rust language](https://www.rust-lang.org/) + - [Rust on the NixOS Wiki](https://nixos.wiki/wiki/Rust) + - ... ''; }; diff --git a/src/nix/flake.cc b/src/nix/flake.cc index f5d34c10f..ac14bed74 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -13,6 +13,7 @@ #include "registry.hh" #include "json.hh" #include "eval-cache.hh" +#include "markdown.hh" #include #include @@ -741,8 +742,8 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand } auto welcomeText = cursor->maybeGetAttr("welcomeText"); if (welcomeText) { - notice("\n----------\n"); - notice(welcomeText->getString()); + notice("\n"); + notice(renderMarkdownToTerminal(welcomeText->getString())); } } }; From 219fa2e43dedbbc7589474f1644da88974690baa Mon Sep 17 00:00:00 2001 From: Taeer Bar-Yam Date: Thu, 17 Feb 2022 15:17:20 -0500 Subject: [PATCH 030/251] add release notes for welcomeText --- doc/manual/src/release-notes/rl-next.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/manual/src/release-notes/rl-next.md b/doc/manual/src/release-notes/rl-next.md index ad8c27dbc..80eed9397 100644 --- a/doc/manual/src/release-notes/rl-next.md +++ b/doc/manual/src/release-notes/rl-next.md @@ -7,3 +7,9 @@ implemented. * `nix store ping` now reports the version of the remote Nix daemon. + +* `nix flake {init,new}` now display information about which files have been + created. + +* Templates can now define a `welcomeText` attribute, which is printed out by + `nix flake {init,new} --template