From 8499f32fb2e7fdf09e97d0beb1fe78bef5900d93 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Fri, 12 Feb 2021 21:51:36 +0000 Subject: [PATCH 01/25] New "indexed" installable syntax: `!` Being conservative and only doing a single output name for now. --- src/libcmd/installables.cc | 42 +++++++++++++++++++++++++++++++++- src/nix/nix.md | 10 ++++++++ tests/build-explicit-output.sh | 17 ++++++++++++++ tests/build.sh | 5 ++-- tests/local.mk | 1 + 5 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 tests/build-explicit-output.sh diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 5d3026c1a..cf7681d0d 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -349,6 +349,31 @@ struct InstallableStorePath : Installable } }; +struct InstallableIndexedStorePath : Installable +{ + ref store; + DerivedPath::Built req; + + InstallableIndexedStorePath(ref store, DerivedPath::Built && req) + : store(store), req(std::move(req)) + { } + + std::string what() override + { + return req.to_string(*store); + } + + DerivedPathsWithHints toDerivedPathsWithHints() override + { + std::map> outputs; + for (auto & output : req.outputs) + outputs.insert_or_assign(output, std::nullopt); + return { + DerivedPathWithHints { DerivedPathWithHints::Built { req.drvPath, std::move(outputs) } } + }; + } +}; + DerivedPathsWithHints InstallableValue::toDerivedPathsWithHints() { DerivedPathsWithHints res; @@ -638,7 +663,22 @@ std::vector> SourceExprCommand::parseInstallables( ex = std::current_exception(); } - if (s.find('/') != std::string::npos) { + auto found = s.rfind('!'); + if (found != std::string::npos) { + try { + result.push_back(std::make_shared( + store, + DerivedPath::Built::parse(*store, s))); + continue; + } catch (BadStorePath &) { + } catch (...) { + if (!ex) + ex = std::current_exception(); + } + } + + found = s.find('/'); + if (found != std::string::npos) { try { result.push_back(std::make_shared(store, store->followLinksToStorePath(s))); continue; diff --git a/src/nix/nix.md b/src/nix/nix.md index d10de7c01..22cc9d476 100644 --- a/src/nix/nix.md +++ b/src/nix/nix.md @@ -94,6 +94,16 @@ the Nix store. Here are the recognised types of installables: If you want to operate on the store derivation itself, pass the `--derivation` flag. +* **Indexed store derivations**: `/nix/store/p7gp6lxdg32h4ka1q398wd9r2zkbbz2v-hello-2.10.drv!out` + + Store derivations can be indexed with a specific output name. This + allows finer control versus just specifying a derivation (without + `--derivation`) and getting all the outputs. + + This is especially useful for (currently unstable) floating content + addressed derivations, which do not have precomputed output paths that + can be used instead. + * **Nix attributes**: `--file /path/to/nixpkgs hello` When the `-f` / `--file` *path* option is given, installables are diff --git a/tests/build-explicit-output.sh b/tests/build-explicit-output.sh new file mode 100644 index 000000000..17930c2c0 --- /dev/null +++ b/tests/build-explicit-output.sh @@ -0,0 +1,17 @@ +source common.sh + +drv=$(nix eval -f multiple-outputs.nix --raw a.drvPath) +if nix build "$drv!not-an-output" --json; then + fail "'not-an-output' should fail to build" +fi + +nix build "$drv!first" --json | jq --exit-status ' + (.[0] | + (.drvPath | match(".*multiple-outputs-a.drv")) and + (.outputs | + .first and + (has("second") | not))) +' +# TODO use +# (.first | match(".*multiple-outputs-a-first")) and +# once we make it put the result paths in the buildables. diff --git a/tests/build.sh b/tests/build.sh index aa54b88eb..5a2819336 100644 --- a/tests/build.sh +++ b/tests/build.sh @@ -4,8 +4,9 @@ expectedJSONRegex='\[\{"drvPath":".*multiple-outputs-a.drv","outputs":\{"first": nix build -f multiple-outputs.nix --json a.all b.all | jq --exit-status ' (.[0] | (.drvPath | match(".*multiple-outputs-a.drv")) and - (.outputs.first | match(".*multiple-outputs-a-first")) and - (.outputs.second | match(".*multiple-outputs-a-second"))) + (.outputs | + (.first | match(".*multiple-outputs-a-first")) and + (.second | match(".*multiple-outputs-a-second")))) and (.[1] | (.drvPath | match(".*multiple-outputs-b.drv")) and (.outputs.out | match(".*multiple-outputs-b"))) diff --git a/tests/local.mk b/tests/local.mk index e7e85f97e..1d3e89499 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -41,6 +41,7 @@ nix_tests = \ describe-stores.sh \ flakes.sh \ build.sh \ + build-explicit-output.sh \ compute-levels.sh \ ca/build.sh \ ca/substitute.sh \ From 6951b26ed0a806c03ad73069ccc925ef6ac158e6 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Fri, 1 Apr 2022 03:57:51 +0000 Subject: [PATCH 02/25] Require (new) computed-derivations experimental feature for ! installable --- src/libcmd/installables.cc | 1 + src/libutil/experimental-features.cc | 1 + src/libutil/experimental-features.hh | 1 + tests/build-explicit-output.sh | 3 +++ 4 files changed, 6 insertions(+) diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 1d44ffe84..ab13f11df 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -740,6 +740,7 @@ std::vector> SourceExprCommand::parseInstallables( result.push_back(std::make_shared( store, DerivedPath::Built::parse(*store, s))); + settings.requireExperimentalFeature(Xp::ComputedDerivations); continue; } catch (BadStorePath &) { } catch (...) { diff --git a/src/libutil/experimental-features.cc b/src/libutil/experimental-features.cc index e033a4116..c1e574c0d 100644 --- a/src/libutil/experimental-features.cc +++ b/src/libutil/experimental-features.cc @@ -13,6 +13,7 @@ std::map stringifiedXpFeatures = { { Xp::RecursiveNix, "recursive-nix" }, { Xp::NoUrlLiterals, "no-url-literals" }, { Xp::FetchClosure, "fetch-closure" }, + { Xp::ComputedDerivations, "computed-derivations" }, }; const std::optional parseExperimentalFeature(const std::string_view & name) diff --git a/src/libutil/experimental-features.hh b/src/libutil/experimental-features.hh index 3a254b423..58e082c72 100644 --- a/src/libutil/experimental-features.hh +++ b/src/libutil/experimental-features.hh @@ -22,6 +22,7 @@ enum struct ExperimentalFeature RecursiveNix, NoUrlLiterals, FetchClosure, + ComputedDerivations, // RFC 92 }; /** diff --git a/tests/build-explicit-output.sh b/tests/build-explicit-output.sh index fcb263913..0f2f428db 100644 --- a/tests/build-explicit-output.sh +++ b/tests/build-explicit-output.sh @@ -1,5 +1,8 @@ source common.sh +enableFeatures "computed-derivations" +restartDaemon + drv=$(nix eval -f multiple-outputs.nix --raw a.drvPath) if nix build "$drv!not-an-output" --json; then fail "'not-an-output' should fail to build" From fda2224b591c2667d18fb815f117f48b45a54cb1 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Thu, 7 Apr 2022 19:45:38 +0000 Subject: [PATCH 03/25] Add release notes mark experimental --- doc/manual/src/release-notes/rl-next.md | 3 +++ src/nix/nix.md | 2 ++ 2 files changed, 5 insertions(+) diff --git a/doc/manual/src/release-notes/rl-next.md b/doc/manual/src/release-notes/rl-next.md index 8c8c0fd41..97627cc96 100644 --- a/doc/manual/src/release-notes/rl-next.md +++ b/doc/manual/src/release-notes/rl-next.md @@ -40,3 +40,6 @@ As before, the old output will continue to work, but `nix flake check` will issue a warning about it. + +* Add experimental *indexed store derivations* installable syntax, part of the + the `computed-derivations` experimental feature. diff --git a/src/nix/nix.md b/src/nix/nix.md index 4919763c4..691aa137b 100644 --- a/src/nix/nix.md +++ b/src/nix/nix.md @@ -132,6 +132,8 @@ the Nix store. Here are the recognised types of installables: * **Indexed store derivations**: `/nix/store/p7gp6lxdg32h4ka1q398wd9r2zkbbz2v-hello-2.10.drv!out` + *(Experimental, part of by the `computed-derivations` experimental feature.)* + Store derivations can be indexed with a specific output name. This allows finer control versus just specifying a derivation (without `--derivation`) and getting all the outputs. From 49ad315c0357116787ef45a1249009b6bc00301f Mon Sep 17 00:00:00 2001 From: John Ericson Date: Thu, 12 May 2022 20:10:02 +0000 Subject: [PATCH 04/25] Use `^` not `!` in indexed store derivations installable syntax Match the other syntax that was recently added --- src/libcmd/installables.cc | 8 +++++--- src/libstore/derived-path.cc | 11 ++++------- src/libstore/derived-path.hh | 2 +- src/nix/nix.md | 2 +- tests/build-explicit-output.sh | 4 ++-- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index e0a95118d..575e7f696 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -799,11 +799,12 @@ std::vector> SourceExprCommand::parseInstallables( for (auto & s : ss) { std::exception_ptr ex; - if (s.rfind('!') != std::string::npos) { + auto found = s.rfind('^'); + if (found != std::string::npos) { try { result.push_back(std::make_shared( store, - DerivedPath::Built::parse(*store, s))); + DerivedPath::Built::parse(*store, s.substr(0, found), s.substr(found + 1)))); settings.requireExperimentalFeature(Xp::ComputedDerivations); continue; } catch (BadStorePath &) { @@ -813,7 +814,8 @@ std::vector> SourceExprCommand::parseInstallables( } } - if (s.find('/') != std::string::npos) { + found = s.find('/'); + if (found != std::string::npos) { try { result.push_back(std::make_shared(store, store->followLinksToStorePath(s))); continue; diff --git a/src/libstore/derived-path.cc b/src/libstore/derived-path.cc index 44587ae78..11a3f5e23 100644 --- a/src/libstore/derived-path.cc +++ b/src/libstore/derived-path.cc @@ -93,12 +93,9 @@ DerivedPath::Opaque DerivedPath::Opaque::parse(const Store & store, std::string_ return {store.parseStorePath(s)}; } -DerivedPath::Built DerivedPath::Built::parse(const Store & store, std::string_view s) +DerivedPath::Built DerivedPath::Built::parse(const Store & store, std::string_view drvS, std::string_view outputsS) { - size_t n = s.find("!"); - assert(n != s.npos); - auto drvPath = store.parseStorePath(s.substr(0, n)); - auto outputsS = s.substr(n + 1); + auto drvPath = store.parseStorePath(drvS); std::set outputs; if (outputsS != "*") outputs = tokenizeString>(outputsS, ","); @@ -107,10 +104,10 @@ DerivedPath::Built DerivedPath::Built::parse(const Store & store, std::string_vi DerivedPath DerivedPath::parse(const Store & store, std::string_view s) { - size_t n = s.find("!"); + size_t n = s.rfind("!"); return n == s.npos ? (DerivedPath) DerivedPath::Opaque::parse(store, s) - : (DerivedPath) DerivedPath::Built::parse(store, s); + : (DerivedPath) DerivedPath::Built::parse(store, s.substr(0, n), s.substr(n + 1)); } RealisedPath::Set BuiltPath::toRealisedPaths(Store & store) const diff --git a/src/libstore/derived-path.hh b/src/libstore/derived-path.hh index 24a0ae773..fab1292a7 100644 --- a/src/libstore/derived-path.hh +++ b/src/libstore/derived-path.hh @@ -47,7 +47,7 @@ struct DerivedPathBuilt { std::set outputs; std::string to_string(const Store & store) const; - static DerivedPathBuilt parse(const Store & store, std::string_view); + static DerivedPathBuilt parse(const Store & store, std::string_view, std::string_view); nlohmann::json toJSON(ref store) const; bool operator < (const DerivedPathBuilt & b) const diff --git a/src/nix/nix.md b/src/nix/nix.md index 34c763c69..32112d38d 100644 --- a/src/nix/nix.md +++ b/src/nix/nix.md @@ -130,7 +130,7 @@ the Nix store. Here are the recognised types of installables: If you want to operate on the store derivation itself, pass the `--derivation` flag. -* **Indexed store derivations**: `/nix/store/p7gp6lxdg32h4ka1q398wd9r2zkbbz2v-hello-2.10.drv!out` +* **Indexed store derivations**: `/nix/store/p7gp6lxdg32h4ka1q398wd9r2zkbbz2v-hello-2.10.drv^out` *(Experimental, part of by the `computed-derivations` experimental feature.)* diff --git a/tests/build-explicit-output.sh b/tests/build-explicit-output.sh index 0f2f428db..68fd2f128 100644 --- a/tests/build-explicit-output.sh +++ b/tests/build-explicit-output.sh @@ -4,11 +4,11 @@ enableFeatures "computed-derivations" restartDaemon drv=$(nix eval -f multiple-outputs.nix --raw a.drvPath) -if nix build "$drv!not-an-output" --json; then +if nix build "$drv^not-an-output" --json; then fail "'not-an-output' should fail to build" fi -nix build "$drv!first" --json | jq --exit-status ' +nix build "$drv^first" --json | jq --exit-status ' (.[0] | (.drvPath | match(".*multiple-outputs-a.drv")) and (.outputs | From f3262bc2165af90fd20f04f74243aa75137767a2 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Thu, 14 Jul 2022 16:36:00 -0400 Subject: [PATCH 05/25] Combine `InstallableStorePath` with `InstallableIndexedStorePath` No behavior should be changed, the `isDerivation` logic is moved from the methods to the constructor. --- src/libcmd/installables.cc | 82 +++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 45 deletions(-) diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index b78581a7c..7b8860a88 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -395,53 +395,21 @@ static StorePath getDeriver( struct InstallableStorePath : Installable { ref store; - StorePath storePath; + DerivedPath req; InstallableStorePath(ref store, StorePath && storePath) - : store(store), storePath(std::move(storePath)) { } + : store(store), + req(storePath.isDerivation() + ? (DerivedPath) DerivedPath::Built { + .drvPath = std::move(storePath), + .outputs = {}, + } + : (DerivedPath) DerivedPath::Opaque { + .path = std::move(storePath), + }) + { } - std::string what() const override { return store->printStorePath(storePath); } - - DerivedPaths toDerivedPaths() override - { - if (storePath.isDerivation()) { - auto drv = store->readDerivation(storePath); - return { - DerivedPath::Built { - .drvPath = storePath, - .outputs = drv.outputNames(), - } - }; - } else { - return { - DerivedPath::Opaque { - .path = storePath, - } - }; - } - } - - StorePathSet toDrvPaths(ref store) override - { - if (storePath.isDerivation()) { - return {storePath}; - } else { - return {getDeriver(store, *this, storePath)}; - } - } - - std::optional getStorePath() override - { - return storePath; - } -}; - -struct InstallableIndexedStorePath : Installable -{ - ref store; - DerivedPath::Built req; - - InstallableIndexedStorePath(ref store, DerivedPath::Built && req) + InstallableStorePath(ref store, DerivedPath && req) : store(store), req(std::move(req)) { } @@ -454,6 +422,30 @@ struct InstallableIndexedStorePath : Installable { return { req }; } + + StorePathSet toDrvPaths(ref store) override + { + return std::visit(overloaded { + [&](const DerivedPath::Built & bfd) -> StorePathSet { + return { bfd.drvPath }; + }, + [&](const DerivedPath::Opaque & bo) -> StorePathSet { + return { getDeriver(store, *this, bo.path) }; + }, + }, req.raw()); + } + + std::optional getStorePath() override + { + return std::visit(overloaded { + [&](const DerivedPath::Built & bfd) { + return bfd.drvPath; + }, + [&](const DerivedPath::Opaque & bo) { + return bo.path; + }, + }, req.raw()); + } }; DerivedPaths InstallableValue::toDerivedPaths() @@ -819,7 +811,7 @@ std::vector> SourceExprCommand::parseInstallables( auto found = s.rfind('^'); if (found != std::string::npos) { try { - result.push_back(std::make_shared( + result.push_back(std::make_shared( store, DerivedPath::Built::parse(*store, s.substr(0, found), s.substr(found + 1)))); settings.requireExperimentalFeature(Xp::ComputedDerivations); From 8735f55decab03ecf3571f756a22abc3b3dc6304 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Thu, 14 Jul 2022 20:22:46 -0400 Subject: [PATCH 06/25] Fix bug, test more, document more --- src/libstore/derived-path.cc | 6 +++++- src/nix/nix.md | 5 +++-- tests/build-explicit-output.sh | 32 ++++++++++++++++++++++++++++++-- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/libstore/derived-path.cc b/src/libstore/derived-path.cc index 11a3f5e23..f6a0c01df 100644 --- a/src/libstore/derived-path.cc +++ b/src/libstore/derived-path.cc @@ -97,8 +97,12 @@ DerivedPath::Built DerivedPath::Built::parse(const Store & store, std::string_vi { auto drvPath = store.parseStorePath(drvS); std::set outputs; - if (outputsS != "*") + if (outputsS != "*") { outputs = tokenizeString>(outputsS, ","); + if (outputs.empty()) + throw Error( + "Explicit list of wanted outputs '%s' must not be empty. Consider using '*' as a wildcard meaning all outputs if no output in particular is wanted.", outputsS); + } return {drvPath, outputs}; } diff --git a/src/nix/nix.md b/src/nix/nix.md index 32112d38d..5d669e8b1 100644 --- a/src/nix/nix.md +++ b/src/nix/nix.md @@ -134,8 +134,9 @@ the Nix store. Here are the recognised types of installables: *(Experimental, part of by the `computed-derivations` experimental feature.)* - Store derivations can be indexed with a specific output name. This - allows finer control versus just specifying a derivation (without + Store derivations can be indexed with a non-empty comma-separated list + of specific output names, or `*` meaning all ouptuts. This allows + finer control versus just specifying a derivation (without `--derivation`) and getting all the outputs. This is especially useful for (currently unstable) floating content diff --git a/tests/build-explicit-output.sh b/tests/build-explicit-output.sh index 68fd2f128..a4cb1c5ad 100644 --- a/tests/build-explicit-output.sh +++ b/tests/build-explicit-output.sh @@ -1,14 +1,24 @@ source common.sh +set -o pipefail + enableFeatures "computed-derivations" restartDaemon drv=$(nix eval -f multiple-outputs.nix --raw a.drvPath) -if nix build "$drv^not-an-output" --json; then +if nix build "$drv^not-an-output" --no-link --json; then fail "'not-an-output' should fail to build" fi -nix build "$drv^first" --json | jq --exit-status ' +if nix build "$drv^" --no-link --json; then + fail "'empty outputs list' should fail to build" +fi + +if nix build "$drv^*nope" --no-link --json; then + fail "'* must be entire string' should fail to build" +fi + +nix build "$drv^first" --no-link --json | jq --exit-status ' (.[0] | (.drvPath | match(".*multiple-outputs-a.drv")) and (.outputs | @@ -16,3 +26,21 @@ nix build "$drv^first" --json | jq --exit-status ' (.first | match(".*multiple-outputs-a-first")) and (has("second") | not))) ' + +nix build "$drv^first,second" --no-link --json | jq --exit-status ' + (.[0] | + (.drvPath | match(".*multiple-outputs-a.drv")) and + (.outputs | + (keys | length == 2) and + (.first | match(".*multiple-outputs-a-first")) and + (.second | match(".*multiple-outputs-a-second")))) +' + +nix build "$drv^*" --no-link --json | jq --exit-status ' + (.[0] | + (.drvPath | match(".*multiple-outputs-a.drv")) and + (.outputs | + (keys | length == 2) and + (.first | match(".*multiple-outputs-a-first")) and + (.second | match(".*multiple-outputs-a-second")))) +' From 279ecf7cdee94b3b5e37e4ade3af3a6d20ca9cde Mon Sep 17 00:00:00 2001 From: John Ericson Date: Fri, 15 Jul 2022 13:29:15 +0000 Subject: [PATCH 07/25] Remove `computed-derivations` experimental feature We don't need it yet. --- doc/manual/src/release-notes/rl-next.md | 3 +-- src/libcmd/installables.cc | 1 - src/libutil/experimental-features.cc | 1 - src/libutil/experimental-features.hh | 1 - src/nix/nix.md | 2 -- tests/build-explicit-output.sh | 3 --- 6 files changed, 1 insertion(+), 10 deletions(-) diff --git a/doc/manual/src/release-notes/rl-next.md b/doc/manual/src/release-notes/rl-next.md index 3bb12c013..7047e2421 100644 --- a/doc/manual/src/release-notes/rl-next.md +++ b/doc/manual/src/release-notes/rl-next.md @@ -1,4 +1,3 @@ # Release X.Y (202?-??-??) -* Add experimental *indexed store derivations* installable syntax, part of the - the `computed-derivations` experimental feature. +* Add *indexed store derivations* installable syntax. diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 7b8860a88..0641e99ff 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -814,7 +814,6 @@ std::vector> SourceExprCommand::parseInstallables( result.push_back(std::make_shared( store, DerivedPath::Built::parse(*store, s.substr(0, found), s.substr(found + 1)))); - settings.requireExperimentalFeature(Xp::ComputedDerivations); continue; } catch (BadStorePath &) { } catch (...) { diff --git a/src/libutil/experimental-features.cc b/src/libutil/experimental-features.cc index 6b2dd02e6..fa79cca6b 100644 --- a/src/libutil/experimental-features.cc +++ b/src/libutil/experimental-features.cc @@ -14,7 +14,6 @@ std::map stringifiedXpFeatures = { { Xp::NoUrlLiterals, "no-url-literals" }, { Xp::FetchClosure, "fetch-closure" }, { Xp::ReplFlake, "repl-flake" }, - { Xp::ComputedDerivations, "computed-derivations" }, }; const std::optional parseExperimentalFeature(const std::string_view & name) diff --git a/src/libutil/experimental-features.hh b/src/libutil/experimental-features.hh index 4cb2708dd..d09ab025c 100644 --- a/src/libutil/experimental-features.hh +++ b/src/libutil/experimental-features.hh @@ -23,7 +23,6 @@ enum struct ExperimentalFeature NoUrlLiterals, FetchClosure, ReplFlake, - ComputedDerivations, // RFC 92 }; /** diff --git a/src/nix/nix.md b/src/nix/nix.md index 5d669e8b1..ede88ebde 100644 --- a/src/nix/nix.md +++ b/src/nix/nix.md @@ -132,8 +132,6 @@ the Nix store. Here are the recognised types of installables: * **Indexed store derivations**: `/nix/store/p7gp6lxdg32h4ka1q398wd9r2zkbbz2v-hello-2.10.drv^out` - *(Experimental, part of by the `computed-derivations` experimental feature.)* - Store derivations can be indexed with a non-empty comma-separated list of specific output names, or `*` meaning all ouptuts. This allows finer control versus just specifying a derivation (without diff --git a/tests/build-explicit-output.sh b/tests/build-explicit-output.sh index a4cb1c5ad..45320d6e3 100644 --- a/tests/build-explicit-output.sh +++ b/tests/build-explicit-output.sh @@ -2,9 +2,6 @@ source common.sh set -o pipefail -enableFeatures "computed-derivations" -restartDaemon - drv=$(nix eval -f multiple-outputs.nix --raw a.drvPath) if nix build "$drv^not-an-output" --no-link --json; then fail "'not-an-output' should fail to build" From 0e4ec98ae8a4ec60b24ebd676a9ace0f4ca81da8 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Fri, 15 Jul 2022 09:49:23 -0400 Subject: [PATCH 08/25] Fix typo in docs Thanks! Co-authored-by: Eelco Dolstra --- src/nix/nix.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nix/nix.md b/src/nix/nix.md index ede88ebde..29ad195ae 100644 --- a/src/nix/nix.md +++ b/src/nix/nix.md @@ -133,7 +133,7 @@ the Nix store. Here are the recognised types of installables: * **Indexed store derivations**: `/nix/store/p7gp6lxdg32h4ka1q398wd9r2zkbbz2v-hello-2.10.drv^out` Store derivations can be indexed with a non-empty comma-separated list - of specific output names, or `*` meaning all ouptuts. This allows + of specific output names, or `*` meaning all outputs. This allows finer control versus just specifying a derivation (without `--derivation`) and getting all the outputs. From 12461e246b02371c6b6981b4e65985e9397474e1 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Fri, 15 Jul 2022 13:59:32 +0000 Subject: [PATCH 09/25] Leverage existing docs for new store-path^outputs syntax --- doc/manual/src/release-notes/rl-next.md | 2 +- src/nix/nix.md | 32 ++++++++++++++----------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/doc/manual/src/release-notes/rl-next.md b/doc/manual/src/release-notes/rl-next.md index 7047e2421..36b759a10 100644 --- a/doc/manual/src/release-notes/rl-next.md +++ b/doc/manual/src/release-notes/rl-next.md @@ -1,3 +1,3 @@ # Release X.Y (202?-??-??) -* Add *indexed store derivations* installable syntax. +* Allow explicitly selecting outputs with *store derivations* installable syntax too. diff --git a/src/nix/nix.md b/src/nix/nix.md index 29ad195ae..811936024 100644 --- a/src/nix/nix.md +++ b/src/nix/nix.md @@ -130,17 +130,6 @@ the Nix store. Here are the recognised types of installables: If you want to operate on the store derivation itself, pass the `--derivation` flag. -* **Indexed store derivations**: `/nix/store/p7gp6lxdg32h4ka1q398wd9r2zkbbz2v-hello-2.10.drv^out` - - Store derivations can be indexed with a non-empty comma-separated list - of specific output names, or `*` meaning all outputs. This allows - finer control versus just specifying a derivation (without - `--derivation`) and getting all the outputs. - - This is especially useful for (currently unstable) floating content - addressed derivations, which do not have precomputed output paths that - can be used instead. - * **Nix attributes**: `--file /path/to/nixpkgs hello` When the `-f` / `--file` *path* option is given, installables are @@ -175,6 +164,13 @@ operate are determined as follows: … ``` + and likewise, using a store path to a "drv" file to specify the derivation: + + ```console + # nix build '/nix/store/gzaflydcr6sb3567hap9q6srzx8ggdgg-glibc-2.33-78.drv^dev,static' + … + ``` + * You can also specify that *all* outputs should be used using the syntax *installable*`^*`. For example, the following shows the size of all outputs of the `glibc` package in the binary cache: @@ -188,9 +184,17 @@ operate are determined as follows: /nix/store/q6580lr01jpcsqs4r5arlh4ki2c1m9rv-glibc-2.33-123-dev 44200560 ``` -* If you didn't specify the desired outputs, but the derivation has an - attribute `meta.outputsToInstall`, Nix will use those outputs. For - example, since the package `nixpkgs#libxml2` has this attribute: + and likewise, again using a store path to a "drv" file to specify the derivation: + + ```console + # nix path-info -S --eval-store auto --store https://cache.nixos.org '/nix/store/gzaflydcr6sb3567hap9q6srzx8ggdgg-glibc-2.33-78.drv^*' + … + ``` + +* If you didn't specify the desired outputs, but the derivation comes + from an expression which has an attribute `meta.outputsToInstall`, Nix + will use those outputs. For example, since the package + `nixpkgs#libxml2` has this attribute: ```console # nix eval 'nixpkgs#libxml2.meta.outputsToInstall' From 173dcb0af9249487c2d9ad5de7218fcf203873bd Mon Sep 17 00:00:00 2001 From: Florian Friesdorf Date: Tue, 22 Nov 2022 12:46:55 +0000 Subject: [PATCH 10/25] Don't reverse stack trace when showing When debugging nix expressions the outermost trace tends to be more useful than the innermost. It is therefore printed last to save developers from scrolling. --- src/libutil/error.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 9172f67a6..9cac6ac91 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -287,7 +287,7 @@ std::ostream & showErrorInfo(std::ostream & out, const ErrorInfo & einfo, bool s // traces if (showTrace && !einfo.traces.empty()) { - for (auto iter = einfo.traces.rbegin(); iter != einfo.traces.rend(); ++iter) { + for (auto iter = einfo.traces.begin(); iter != einfo.traces.end(); ++iter) { oss << "\n" << "… " << iter->hint.str() << "\n"; if (iter->pos.has_value() && (*iter->pos)) { From d269976be6def2928e6a315ab2b85b947f4308f2 Mon Sep 17 00:00:00 2001 From: Florian Friesdorf Date: Tue, 22 Nov 2022 16:45:58 +0000 Subject: [PATCH 11/25] Show stack trace above error message Save developers from scrolling by displaying the error message last, below the stack trace. --- src/libutil/error.cc | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 9cac6ac91..449baaad1 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -262,6 +262,28 @@ std::ostream & showErrorInfo(std::ostream & out, const ErrorInfo & einfo, bool s prefix += ":" ANSI_NORMAL " "; std::ostringstream oss; + + // traces + if (showTrace && !einfo.traces.empty()) { + for (auto iter = einfo.traces.begin(); iter != einfo.traces.end(); ++iter) { + oss << "\n" << "… " << iter->hint.str() << "\n"; + + if (iter->pos.has_value() && (*iter->pos)) { + auto pos = iter->pos.value(); + oss << "\n"; + printAtPos(pos, oss); + + auto loc = getCodeLines(pos); + if (loc.has_value()) { + oss << "\n"; + printCodeLines(oss, "", pos, *loc); + oss << "\n"; + } + } + } + oss << "\n" << prefix; + } + oss << einfo.msg << "\n"; if (einfo.errPos.has_value() && *einfo.errPos) { @@ -285,26 +307,6 @@ std::ostream & showErrorInfo(std::ostream & out, const ErrorInfo & einfo, bool s "?" << std::endl; } - // traces - if (showTrace && !einfo.traces.empty()) { - for (auto iter = einfo.traces.begin(); iter != einfo.traces.end(); ++iter) { - oss << "\n" << "… " << iter->hint.str() << "\n"; - - if (iter->pos.has_value() && (*iter->pos)) { - auto pos = iter->pos.value(); - oss << "\n"; - printAtPos(pos, oss); - - auto loc = getCodeLines(pos); - if (loc.has_value()) { - oss << "\n"; - printCodeLines(oss, "", pos, *loc); - oss << "\n"; - } - } - } - } - out << indent(prefix, std::string(filterANSIEscapes(prefix, true).size(), ' '), chomp(oss.str())); return out; From 7b122d43a49a3bf05436cb2c9b23934ff4bcba2c Mon Sep 17 00:00:00 2001 From: John Ericson Date: Mon, 28 Nov 2022 10:39:28 -0500 Subject: [PATCH 12/25] Fix stack context notes to not rely on order Make everything be in the form "while ..." (most things were already), and in particular *don't* use other propositions that must go after or before specific "while ..." clauses to make sense. --- src/libexpr/eval.cc | 2 +- src/libexpr/flake/flake.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 6955aacbf..0d9226d3b 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1660,7 +1660,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & (lambda.name ? concatStrings("'", symbols[lambda.name], "'") : "anonymous lambda")); - addErrorTrace(e, pos, "from call site%s", ""); + addErrorTrace(e, pos, "while evaluating call site%s", ""); } throw; } diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc index 6b5d6f6b3..6344fb253 100644 --- a/src/libexpr/flake/flake.cc +++ b/src/libexpr/flake/flake.cc @@ -143,7 +143,7 @@ static FlakeInput parseFlakeInput(EvalState & state, } catch (Error & e) { e.addTrace( state.positions[attr.pos], - hintfmt("in flake attribute '%s'", state.symbols[attr.name])); + hintfmt("while evaluating flake attribute '%s'", state.symbols[attr.name])); throw; } } @@ -152,7 +152,7 @@ static FlakeInput parseFlakeInput(EvalState & state, try { input.ref = FlakeRef::fromAttrs(attrs); } catch (Error & e) { - e.addTrace(state.positions[pos], hintfmt("in flake input")); + e.addTrace(state.positions[pos], hintfmt("while evaluating flake input")); throw; } else { From 8618c6cc75e19ed658649bd806b218de954ea3bc Mon Sep 17 00:00:00 2001 From: Florian Friesdorf Date: Fri, 9 Dec 2022 17:36:25 +0000 Subject: [PATCH 13/25] Simplify loop, feedback from @tfc and @Ericson2314 --- src/libutil/error.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 449baaad1..3bb3efb0e 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -265,11 +265,11 @@ std::ostream & showErrorInfo(std::ostream & out, const ErrorInfo & einfo, bool s // traces if (showTrace && !einfo.traces.empty()) { - for (auto iter = einfo.traces.begin(); iter != einfo.traces.end(); ++iter) { - oss << "\n" << "… " << iter->hint.str() << "\n"; + for (const auto & trace : einfo.traces) { + oss << "\n" << "… " << trace.hint.str() << "\n"; - if (iter->pos.has_value() && (*iter->pos)) { - auto pos = iter->pos.value(); + if (trace.pos.has_value() && (*trace.pos)) { + auto pos = trace.pos.value(); oss << "\n"; printAtPos(pos, oss); From dc075dcdd0306adec911ec8d898b723f464f7c0a Mon Sep 17 00:00:00 2001 From: John Ericson Date: Mon, 12 Dec 2022 16:26:10 -0500 Subject: [PATCH 14/25] Apply suggestions from code review Co-authored-by: Eelco Dolstra --- src/libstore/derived-path.cc | 2 +- src/nix/nix.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstore/derived-path.cc b/src/libstore/derived-path.cc index 7fe797aa1..05c2303db 100644 --- a/src/libstore/derived-path.cc +++ b/src/libstore/derived-path.cc @@ -93,7 +93,7 @@ DerivedPath::Built DerivedPath::Built::parse(const Store & store, std::string_vi DerivedPath DerivedPath::parse(const Store & store, std::string_view s) { - size_t n = s.rfind("!"); + size_t n = s.find("!"); return n == s.npos ? (DerivedPath) DerivedPath::Opaque::parse(store, s) : (DerivedPath) DerivedPath::Built::parse(store, s.substr(0, n), s.substr(n + 1)); diff --git a/src/nix/nix.md b/src/nix/nix.md index 811936024..6ff27e479 100644 --- a/src/nix/nix.md +++ b/src/nix/nix.md @@ -187,7 +187,7 @@ operate are determined as follows: and likewise, again using a store path to a "drv" file to specify the derivation: ```console - # nix path-info -S --eval-store auto --store https://cache.nixos.org '/nix/store/gzaflydcr6sb3567hap9q6srzx8ggdgg-glibc-2.33-78.drv^*' + # nix path-info -S '/nix/store/gzaflydcr6sb3567hap9q6srzx8ggdgg-glibc-2.33-78.drv^*' … ``` From c7cce3e4e1dc82c504bb4d717e55dce3b1ae008a Mon Sep 17 00:00:00 2001 From: John Ericson Date: Mon, 12 Dec 2022 16:29:29 -0500 Subject: [PATCH 15/25] Improve release notes --- doc/manual/src/release-notes/rl-next.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/doc/manual/src/release-notes/rl-next.md b/doc/manual/src/release-notes/rl-next.md index a56dc25a2..15c309bdb 100644 --- a/doc/manual/src/release-notes/rl-next.md +++ b/doc/manual/src/release-notes/rl-next.md @@ -3,4 +3,13 @@ * The `repeat` and `enforce-determinism` options have been removed since they had been broken under many circumstances for a long time. -* Allow explicitly selecting outputs with *store derivations* installable syntax too. \ No newline at end of file +* Allow explicitly selecting outputs in a store derivation installable, just like we can do with other sorts of installables. + For example, + ```shell-session + $ nix-build /nix/store/gzaflydcr6sb3567hap9q6srzx8ggdgg-glibc-2.33-78.drv^dev` + ``` + now works just as + ```shell-session + $ nix-build glibc^dev` + ``` + does already. From 672ee882318f3ae97de068a44e4c09bdf82d04ef Mon Sep 17 00:00:00 2001 From: Rick van Schijndel Date: Mon, 12 Dec 2022 23:31:30 +0100 Subject: [PATCH 16/25] support building with --enable-gc=no Some minor changes fixing the build without boehm. Fixes NixOS#6250 --- src/libexpr/eval.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 6955aacbf..515987db6 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -45,7 +45,7 @@ static char * allocString(size_t size) #if HAVE_BOEHMGC t = (char *) GC_MALLOC_ATOMIC(size); #else - t = malloc(size); + t = (char *) malloc(size); #endif if (!t) throw std::bad_alloc(); return t; @@ -471,9 +471,6 @@ EvalState::EvalState( #if HAVE_BOEHMGC , valueAllocCache(std::allocate_shared(traceable_allocator(), nullptr)) , env1AllocCache(std::allocate_shared(traceable_allocator(), nullptr)) -#else - , valueAllocCache(std::make_shared(nullptr)) - , env1AllocCache(std::make_shared(nullptr)) #endif , baseEnv(allocEnv(128)) , staticBaseEnv{std::make_shared(false, nullptr)} From d8c1c24c78ebeb1f695e29a489be567118eb073e Mon Sep 17 00:00:00 2001 From: John Ericson Date: Mon, 12 Dec 2022 17:32:24 -0500 Subject: [PATCH 17/25] Adjust docs --- src/nix/nix.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/nix/nix.md b/src/nix/nix.md index 6ff27e479..529d5f796 100644 --- a/src/nix/nix.md +++ b/src/nix/nix.md @@ -190,11 +190,9 @@ operate are determined as follows: # nix path-info -S '/nix/store/gzaflydcr6sb3567hap9q6srzx8ggdgg-glibc-2.33-78.drv^*' … ``` - -* If you didn't specify the desired outputs, but the derivation comes - from an expression which has an attribute `meta.outputsToInstall`, Nix - will use those outputs. For example, since the package - `nixpkgs#libxml2` has this attribute: +* If you didn't specify the desired outputs, but the derivation hs an + attribute `meta.outputsToInstall`, Nix will use those outputs. For + example, since the package `nixpkgs#libxml2` has this attribute: ```console # nix eval 'nixpkgs#libxml2.meta.outputsToInstall' @@ -204,6 +202,9 @@ operate are determined as follows: a command like `nix shell nixpkgs#libxml2` will provide only those two outputs by default. + Note that a store derivation (given by `.drv` file store path) doesn't have + any attributes like `meta`, and thus this case doesn't apply to it. + * Otherwise, Nix will use all outputs of the derivation. # Nix stores From c886b1856184fc180603435197a10ea20df8bcfb Mon Sep 17 00:00:00 2001 From: John Ericson Date: Mon, 12 Dec 2022 17:34:57 -0500 Subject: [PATCH 18/25] Merge new tests into `build.sh` --- tests/build-explicit-output.sh | 43 ---------------------------------- tests/build.sh | 42 +++++++++++++++++++++++++++++++++ tests/local.mk | 1 - 3 files changed, 42 insertions(+), 44 deletions(-) delete mode 100644 tests/build-explicit-output.sh diff --git a/tests/build-explicit-output.sh b/tests/build-explicit-output.sh deleted file mode 100644 index 45320d6e3..000000000 --- a/tests/build-explicit-output.sh +++ /dev/null @@ -1,43 +0,0 @@ -source common.sh - -set -o pipefail - -drv=$(nix eval -f multiple-outputs.nix --raw a.drvPath) -if nix build "$drv^not-an-output" --no-link --json; then - fail "'not-an-output' should fail to build" -fi - -if nix build "$drv^" --no-link --json; then - fail "'empty outputs list' should fail to build" -fi - -if nix build "$drv^*nope" --no-link --json; then - fail "'* must be entire string' should fail to build" -fi - -nix build "$drv^first" --no-link --json | jq --exit-status ' - (.[0] | - (.drvPath | match(".*multiple-outputs-a.drv")) and - (.outputs | - (keys | length == 1) and - (.first | match(".*multiple-outputs-a-first")) and - (has("second") | not))) -' - -nix build "$drv^first,second" --no-link --json | jq --exit-status ' - (.[0] | - (.drvPath | match(".*multiple-outputs-a.drv")) and - (.outputs | - (keys | length == 2) and - (.first | match(".*multiple-outputs-a-first")) and - (.second | match(".*multiple-outputs-a-second")))) -' - -nix build "$drv^*" --no-link --json | jq --exit-status ' - (.[0] | - (.drvPath | match(".*multiple-outputs-a.drv")) and - (.outputs | - (keys | length == 2) and - (.first | match(".*multiple-outputs-a-first")) and - (.second | match(".*multiple-outputs-a-second")))) -' diff --git a/tests/build.sh b/tests/build.sh index 3a3d773b1..036fb037e 100644 --- a/tests/build.sh +++ b/tests/build.sh @@ -58,6 +58,48 @@ nix build -f multiple-outputs.nix --json 'e^*' --no-link | jq --exit-status ' (.outputs | keys == ["a", "b", "c"])) ' +# Test building from raw store path to drv not expression. + +drv=$(nix eval -f multiple-outputs.nix --raw a.drvPath) +if nix build "$drv^not-an-output" --no-link --json; then + fail "'not-an-output' should fail to build" +fi + +if nix build "$drv^" --no-link --json; then + fail "'empty outputs list' should fail to build" +fi + +if nix build "$drv^*nope" --no-link --json; then + fail "'* must be entire string' should fail to build" +fi + +nix build "$drv^first" --no-link --json | jq --exit-status ' + (.[0] | + (.drvPath | match(".*multiple-outputs-a.drv")) and + (.outputs | + (keys | length == 1) and + (.first | match(".*multiple-outputs-a-first")) and + (has("second") | not))) +' + +nix build "$drv^first,second" --no-link --json | jq --exit-status ' + (.[0] | + (.drvPath | match(".*multiple-outputs-a.drv")) and + (.outputs | + (keys | length == 2) and + (.first | match(".*multiple-outputs-a-first")) and + (.second | match(".*multiple-outputs-a-second")))) +' + +nix build "$drv^*" --no-link --json | jq --exit-status ' + (.[0] | + (.drvPath | match(".*multiple-outputs-a.drv")) and + (.outputs | + (keys | length == 2) and + (.first | match(".*multiple-outputs-a-first")) and + (.second | match(".*multiple-outputs-a-second")))) +' + # Make sure that `--impure` works (regression test for https://github.com/NixOS/nix/issues/6488) nix build --impure -f multiple-outputs.nix --json e --no-link | jq --exit-status ' (.[0] | diff --git a/tests/local.mk b/tests/local.mk index aff595d3b..340817ec3 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -98,7 +98,6 @@ nix_tests = \ ssh-relay.sh \ plugins.sh \ build.sh \ - build-explicit-output.sh \ ca/nix-run.sh \ selfref-gc.sh ca/selfref-gc.sh \ db-migration.sh \ From 32ae715db1771342fc356f1521cdda9ecd453358 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Mon, 12 Dec 2022 17:37:45 -0500 Subject: [PATCH 19/25] Fix typos in the docs Thanks! Co-authored-by: Valentin Gagarin --- src/nix/nix.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nix/nix.md b/src/nix/nix.md index 529d5f796..723d3c87e 100644 --- a/src/nix/nix.md +++ b/src/nix/nix.md @@ -184,13 +184,13 @@ operate are determined as follows: /nix/store/q6580lr01jpcsqs4r5arlh4ki2c1m9rv-glibc-2.33-123-dev 44200560 ``` - and likewise, again using a store path to a "drv" file to specify the derivation: + and likewise, using a store path to a "drv" file to specify the derivation: ```console # nix path-info -S '/nix/store/gzaflydcr6sb3567hap9q6srzx8ggdgg-glibc-2.33-78.drv^*' … ``` -* If you didn't specify the desired outputs, but the derivation hs an +* If you didn't specify the desired outputs, but the derivation has an attribute `meta.outputsToInstall`, Nix will use those outputs. For example, since the package `nixpkgs#libxml2` has this attribute: From 2ec6685eb038b295d488ded6e46cc56378e7d646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophane=20Hufschmitt?= Date: Tue, 13 Dec 2022 10:44:07 +0100 Subject: [PATCH 20/25] Build Nix with the GC disabled in hydra Make sure that it still compiles as it's easy to accidentally break one of the `#if` guarded clauses --- flake.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/flake.nix b/flake.nix index 5127ee2a3..4ba3f04b0 100644 --- a/flake.nix +++ b/flake.nix @@ -420,6 +420,8 @@ buildCross = nixpkgs.lib.genAttrs crossSystems (crossSystem: nixpkgs.lib.genAttrs ["x86_64-linux"] (system: self.packages.${system}."nix-${crossSystem}")); + buildNoGc = nixpkgs.lib.genAttrs systems (system: self.packages.${system}.nix.overrideAttrs (a: { configureFlags = (a.configureFlags or []) ++ ["--enable-gc=no"];})); + # Perl bindings for various platforms. perlBindings = nixpkgs.lib.genAttrs systems (system: self.packages.${system}.nix.perl-bindings); From ae27181f16c3b4be011e6ef23d95ff9ccdaae76b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sol=C3=A8ne=20Rapenne?= Date: Tue, 13 Dec 2022 11:44:56 +0100 Subject: [PATCH 21/25] documentation: fix link to definition --- src/libcmd/common-eval-args.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcmd/common-eval-args.cc b/src/libcmd/common-eval-args.cc index 67fc501c9..9efd0158d 100644 --- a/src/libcmd/common-eval-args.cc +++ b/src/libcmd/common-eval-args.cc @@ -77,7 +77,7 @@ MixEvalArgs::MixEvalArgs() branch in the `nixpkgs` repository. The URLs of the tarballs from the official `nixos.org` channels - (see [the manual page for `nix-channel`](nix-channel.md)) can be + (see [the manual page for `nix-channel`](../nix-channel.md)) can be abbreviated as `channel:`. For instance, the following two flags are equivalent: From e43b0f5b129109ae3785431d470728cf69e1c621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sol=C3=A8ne=20Rapenne?= Date: Tue, 13 Dec 2022 11:46:03 +0100 Subject: [PATCH 22/25] documentation: link flake URL term to definition --- src/libcmd/common-eval-args.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcmd/common-eval-args.cc b/src/libcmd/common-eval-args.cc index 9efd0158d..0e321e5e4 100644 --- a/src/libcmd/common-eval-args.cc +++ b/src/libcmd/common-eval-args.cc @@ -86,7 +86,7 @@ MixEvalArgs::MixEvalArgs() -I nixpkgs=https://nixos.org/channels/nixos-21.05/nixexprs.tar.xz ``` - You can also fetch source trees using flake URLs and add them to the + You can also fetch source trees using [flake URLs](./nix3-flake.md#url-like-syntax) and add them to the search path. For instance, ``` From 09860c16ce526a079d3bd5e8d8bb6f26dc259b93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sol=C3=A8ne=20Rapenne?= Date: Tue, 13 Dec 2022 11:46:33 +0100 Subject: [PATCH 23/25] documentation: use sections instead of list items --- src/nix/flake.md | 73 ++++++++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/src/nix/flake.md b/src/nix/flake.md index a1ab43281..810e9ebea 100644 --- a/src/nix/flake.md +++ b/src/nix/flake.md @@ -18,51 +18,56 @@ values such as packages or NixOS modules provided by the flake). Flake references (*flakerefs*) are a way to specify the location of a flake. These have two different forms: -* An attribute set representation, e.g. - ```nix - { - type = "github"; - owner = "NixOS"; - repo = "nixpkgs"; - } - ``` +## Attribute set representation - The only required attribute is `type`. The supported types are - listed below. +Example: -* A URL-like syntax, e.g. +```nix +{ + type = "github"; + owner = "NixOS"; + repo = "nixpkgs"; +} +``` - ``` - github:NixOS/nixpkgs - ``` +The only required attribute is `type`. The supported types are +listed below. - These are used on the command line as a more convenient alternative - to the attribute set representation. For instance, in the command +## URL-like syntax - ```console - # nix build github:NixOS/nixpkgs#hello - ``` +Example: - `github:NixOS/nixpkgs` is a flake reference (while `hello` is an - output attribute). They are also allowed in the `inputs` attribute - of a flake, e.g. +``` +github:NixOS/nixpkgs +``` - ```nix - inputs.nixpkgs.url = github:NixOS/nixpkgs; - ``` +These are used on the command line as a more convenient alternative +to the attribute set representation. For instance, in the command - is equivalent to +```console +# nix build github:NixOS/nixpkgs#hello +``` - ```nix - inputs.nixpkgs = { - type = "github"; - owner = "NixOS"; - repo = "nixpkgs"; - }; - ``` +`github:NixOS/nixpkgs` is a flake reference (while `hello` is an +output attribute). They are also allowed in the `inputs` attribute +of a flake, e.g. -## Examples +```nix +inputs.nixpkgs.url = github:NixOS/nixpkgs; +``` + +is equivalent to + +```nix +inputs.nixpkgs = { + type = "github"; + owner = "NixOS"; + repo = "nixpkgs"; +}; +``` + +### Examples Here are some examples of flake references in their URL-like representation: From 129ece7ce9b88fb79d3f68d030df4e06c4e291cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Na=C3=AFm=20Favier?= Date: Tue, 13 Dec 2022 15:49:40 +0100 Subject: [PATCH 24/25] doc: fix links --- doc/manual/src/release-notes/rl-2.12.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/manual/src/release-notes/rl-2.12.md b/doc/manual/src/release-notes/rl-2.12.md index 82de22cb4..e2045d7bf 100644 --- a/doc/manual/src/release-notes/rl-2.12.md +++ b/doc/manual/src/release-notes/rl-2.12.md @@ -17,12 +17,12 @@ The `uid-range` [system feature] requires the [`auto-allocate-uids`] setting to be enabled. - [system feature]: (../command-ref/conf-file.md#conf-system-features) + [system feature]: ../command-ref/conf-file.md#conf-system-features * Nix can now automatically pick UIDs for builds, removing the need to create `nixbld*` user accounts. See [`auto-allocate-uids`]. - [`auto-allocate-uids`]: (../command-ref/conf-file.md#conf-auto-allocate-uids) + [`auto-allocate-uids`]: ../command-ref/conf-file.md#conf-auto-allocate-uids * On Linux, Nix has experimental support for running builds inside a cgroup. See From 1f3c0a3c1dde7e0348c085e0fbb60729cb067d86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Na=C3=AFm=20Favier?= Date: Wed, 14 Dec 2022 00:40:30 +0100 Subject: [PATCH 25/25] Allow disabling build users by unsetting `build-users-group` Unsetting `build-users-group` (without `auto-allocate-uids` enabled) gives the following error: ``` src/libstore/lock.cc:25: static std::unique_ptr nix::SimpleUserLock::acquire(): Assertion `settings.buildUsersGroup != ""' failed. ``` Fix the logic in `useBuildUsers` and document the default value for `build-users-group`. --- src/libstore/globals.hh | 5 ++++- src/libstore/lock.cc | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index 54a5d0fc7..274a15dd7 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -281,7 +281,10 @@ public: `NIX_REMOTE` is empty, the uid under which the Nix daemon runs if `NIX_REMOTE` is `daemon`). Obviously, this should not be used in multi-user settings with untrusted users. - )"}; + + Defaults to `nixbld` when running as root, *empty* otherwise. + )", + {}, false}; Setting autoAllocateUids{this, false, "auto-allocate-uids", R"( diff --git a/src/libstore/lock.cc b/src/libstore/lock.cc index 2858137d6..d02d20b4c 100644 --- a/src/libstore/lock.cc +++ b/src/libstore/lock.cc @@ -185,7 +185,7 @@ std::unique_ptr acquireUserLock(uid_t nrIds, bool useChroot) bool useBuildUsers() { #if __linux__ - static bool b = (settings.buildUsersGroup != "" || settings.startId.get() != 0) && getuid() == 0; + static bool b = (settings.buildUsersGroup != "" || settings.autoAllocateUids) && getuid() == 0; return b; #elif __APPLE__ static bool b = settings.buildUsersGroup != "" && getuid() == 0;