aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/manual/change-authors.yml5
-rw-r--r--doc/manual/rl-next/fod-failure-includes-url.md16
-rw-r--r--doc/manual/rl-next/registry-add-shorthand-only.md10
-rw-r--r--doc/manual/src/contributing/testing.md3
-rw-r--r--meson.build1
-rw-r--r--src/libexpr/flake/flakeref.cc6
-rw-r--r--src/libstore/build/local-derivation-goal.cc5
-rw-r--r--src/libstore/gc.cc28
-rw-r--r--src/libutil/url-parts.hh3
-rw-r--r--src/libutil/url.cc1
-rw-r--r--src/nix/registry-add.md5
-rw-r--r--src/nix/registry.cc8
-rw-r--r--tests/functional/build.sh5
-rw-r--r--tests/functional/flakes/flakes.sh11
-rw-r--r--tests/functional/fod-failing.nix2
15 files changed, 85 insertions, 24 deletions
diff --git a/doc/manual/change-authors.yml b/doc/manual/change-authors.yml
index 5894ce821..28a20b25f 100644
--- a/doc/manual/change-authors.yml
+++ b/doc/manual/change-authors.yml
@@ -44,6 +44,11 @@ cole-h:
display_name: Cole Helbling
github: cole-h
+delan:
+ display_name: delan
+ forgejo: delan
+ github: delan
+
edolstra:
display_name: Eelco Dolstra
github: edolstra
diff --git a/doc/manual/rl-next/fod-failure-includes-url.md b/doc/manual/rl-next/fod-failure-includes-url.md
new file mode 100644
index 000000000..43179aa52
--- /dev/null
+++ b/doc/manual/rl-next/fod-failure-includes-url.md
@@ -0,0 +1,16 @@
+---
+synopsis: "Hash mismatch diagnostics for fixed-output derivations include the URL"
+cls: [1536]
+credits: [jade]
+category: Improvements
+---
+
+Now, when building fixed-output derivations, Lix will guess the URL that was used in the derivation using the `url` or `urls` properties in the derivation environment.
+This is a layering violation but making these diagnostics tractable when there are multiple instances of the `AAAA` hash is too significant of an improvement to pass it up.
+
+```
+error: hash mismatch in fixed-output derivation '/nix/store/sjfw324j4533lwnpmr5z4icpb85r63ai-x1.drv':
+ likely URL: https://meow.puppy.forge/puppy.tar.gz
+ specified: sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+ got: sha256-a1Qvp3FOOkWpL9kFHgugU1ok5UtRPSu+NwCZKbbaEro=
+```
diff --git a/doc/manual/rl-next/registry-add-shorthand-only.md b/doc/manual/rl-next/registry-add-shorthand-only.md
new file mode 100644
index 000000000..72f972b0a
--- /dev/null
+++ b/doc/manual/rl-next/registry-add-shorthand-only.md
@@ -0,0 +1,10 @@
+---
+synopsis: "`nix registry add` now requires a shorthand flakeref on the 'from' side"
+cls: 1494
+credits: delan
+category: Improvements
+---
+
+The 'from' argument must now be a shorthand flakeref like `nixpkgs` or `nixpkgs/nixos-20.03`, making it harder to accidentally swap the 'from' and 'to' arguments.
+
+Registry entries that map from other flake URLs can still be specified in registry.json, the `nix.registry` option in NixOS, or the `--override-flake` option in the CLI, but they are not guaranteed to work correctly.
diff --git a/doc/manual/src/contributing/testing.md b/doc/manual/src/contributing/testing.md
index 84836b891..b6b5318e0 100644
--- a/doc/manual/src/contributing/testing.md
+++ b/doc/manual/src/contributing/testing.md
@@ -433,9 +433,6 @@ I grepped `src/` for `get[eE]nv\("` to find the mentions in Lix code.
- `NIX_PROFILE` - Selects which profile `nix-env` will operate on. Documented elsewhere.
- `NIX_SSHOPTS` - Options passed to `ssh(1)` when using a ssh remote store.
Incorrectly documented on `nix-copy-closure` which is *surely* not the only place they are used??
-- `_NIX_TEST_NO_LSOF` - Used on non-Linux, non-macOS platforms to disable using `lsof` when finding gc roots.
-
- Since https://git.lix.systems/lix-project/lix/issues/156 was fixed, this should probably just be removed as it was a bad workaround for a macOS issue.
- `_NIX_TEST_GC_SYNC_1` - Path to a pipe that is used to block the GC briefly to validate invariants from the test suite.
- `_NIX_TEST_GC_SYNC_2` - Path to a pipe that is used to block the GC briefly to validate invariants from the test suite.
- `_NIX_TEST_FREE_SPACE_FILE` - Path to a file containing a decimal number with the free space that the GC is to believe it has.
diff --git a/meson.build b/meson.build
index 0cb2030e7..7d8a3a315 100644
--- a/meson.build
+++ b/meson.build
@@ -432,6 +432,7 @@ add_project_arguments(
'-Wimplicit-fallthrough',
'-Werror=switch',
'-Werror=switch-enum',
+ '-Werror=unused-result',
'-Wdeprecated-copy',
'-Wignored-qualifiers',
# Enable assertions in libstdc++ by default. Harmless on libc++. Benchmarked
diff --git a/src/libexpr/flake/flakeref.cc b/src/libexpr/flake/flakeref.cc
index 1c90bfc43..a95df04ba 100644
--- a/src/libexpr/flake/flakeref.cc
+++ b/src/libexpr/flake/flakeref.cc
@@ -85,8 +85,8 @@ std::pair<FlakeRef, std::string> parseFlakeRefWithFragment(
+ "(?:#(" + queryRegex + "))?",
std::regex::ECMAScript);
- static std::regex flakeRegex(
- "((" + flakeIdRegexS + ")(?:/(?:" + refAndOrRevRegex + "))?)"
+ static std::regex flakeShorthandRegex(
+ flakeShorthandRegexS
+ "(?:#(" + queryRegex + "))?",
std::regex::ECMAScript);
@@ -95,7 +95,7 @@ std::pair<FlakeRef, std::string> parseFlakeRefWithFragment(
/* Check if 'url' is a flake ID. This is an abbreviated syntax for
'flake:<flake-id>?ref=<ref>&rev=<rev>'. */
- if (std::regex_match(url, match, flakeRegex)) {
+ if (std::regex_match(url, match, flakeShorthandRegex)) {
auto parsedURL = ParsedURL{
.url = url,
.base = "flake:" + match.str(1),
diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc
index 968f669ec..1dd2ad8aa 100644
--- a/src/libstore/build/local-derivation-goal.cc
+++ b/src/libstore/build/local-derivation-goal.cc
@@ -2546,9 +2546,12 @@ SingleDrvOutputs LocalDerivationGoal::registerOutputs()
/* Throw an error after registering the path as
valid. */
worker.hashMismatch = true;
+ // XXX: shameless layering violation hack that makes the hash mismatch error at least not utterly worthless
+ auto guessedUrl = getOr(drv->env, "urls", getOr(drv->env, "url", "(unknown)"));
delayedException = std::make_exception_ptr(
- BuildError("hash mismatch in fixed-output derivation '%s':\n specified: %s\n got: %s",
+ BuildError("hash mismatch in fixed-output derivation '%s':\n likely URL: %s\n specified: %s\n got: %s",
worker.store.printStorePath(drvPath),
+ guessedUrl,
wanted.to_string(SRI, true),
got.to_string(SRI, true)));
}
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index d58e3c8eb..02234d404 100644
--- a/src/libstore/gc.cc
+++ b/src/libstore/gc.cc
@@ -321,22 +321,20 @@ Roots LocalStore::findRoots(bool censor)
void LocalStore::findPlatformRoots(UncheckedRoots & unchecked)
{
- // lsof is really slow on OS X. This actually causes the gc-concurrent.sh test to fail.
- // See: https://github.com/NixOS/nix/issues/3011
- // Because of this we disable lsof when running the tests.
- if (getEnv("_NIX_TEST_NO_LSOF") != "1") {
- try {
- std::regex lsofRegex(R"(^n(/.*)$)");
- auto lsofLines =
- tokenizeString<std::vector<std::string>>(runProgram(LSOF, true, { "-n", "-w", "-F", "n" }), "\n");
- for (const auto & line : lsofLines) {
- std::smatch match;
- if (std::regex_match(line, match, lsofRegex))
- unchecked[match[1]].emplace("{lsof}");
- }
- } catch (ExecError & e) {
- /* lsof not installed, lsof failed */
+ // N.B. This is (read: undertested!) fallback code only used for
+ // non-Darwin, non-Linux platforms. Both major platforms have
+ // platform-specific code in src/libstore/platform/
+ try {
+ std::regex lsofRegex(R"(^n(/.*)$)");
+ auto lsofLines =
+ tokenizeString<std::vector<std::string>>(runProgram(LSOF, true, { "-n", "-w", "-F", "n" }), "\n");
+ for (const auto & line : lsofLines) {
+ std::smatch match;
+ if (std::regex_match(line, match, lsofRegex))
+ unchecked[match[1]].emplace("{lsof}");
}
+ } catch (ExecError & e) {
+ /* lsof not installed, lsof failed */
}
}
diff --git a/src/libutil/url-parts.hh b/src/libutil/url-parts.hh
index 6efcc7e50..1f570567c 100644
--- a/src/libutil/url-parts.hh
+++ b/src/libutil/url-parts.hh
@@ -46,4 +46,7 @@ const static std::string refAndOrRevRegex = "(?:(" + revRegexS + ")|(?:(" + refR
const static std::string flakeIdRegexS = "[a-zA-Z][a-zA-Z0-9_-]*";
extern std::regex flakeIdRegex;
+const static std::string flakeShorthandRegexS = "((" + flakeIdRegexS + ")(?:/(?:" + refAndOrRevRegex + "))?)";
+extern std::regex flakeShorthandRegex;
+
}
diff --git a/src/libutil/url.cc b/src/libutil/url.cc
index 46688cef5..87146ca56 100644
--- a/src/libutil/url.cc
+++ b/src/libutil/url.cc
@@ -9,6 +9,7 @@ std::regex refRegex(refRegexS, std::regex::ECMAScript);
std::regex badGitRefRegex(badGitRefRegexS, std::regex::ECMAScript);
std::regex revRegex(revRegexS, std::regex::ECMAScript);
std::regex flakeIdRegex(flakeIdRegexS, std::regex::ECMAScript);
+std::regex flakeShorthandRegex(flakeShorthandRegexS, std::regex::ECMAScript);
ParsedURL parseURL(const std::string & url)
{
diff --git a/src/nix/registry-add.md b/src/nix/registry-add.md
index a947fa0b3..90b54a596 100644
--- a/src/nix/registry-add.md
+++ b/src/nix/registry-add.md
@@ -31,8 +31,9 @@ R""(
# Description
This command adds an entry to the user registry that maps flake
-reference *from-url* to flake reference *to-url*. If an entry for
-*from-url* already exists, it is overwritten.
+reference *from-url* to flake reference *to-url*, where *from-url*
+must be a shorthand like 'nixpkgs' or 'nixpkgs/nixos-20.03'. If an
+entry for *from-url* already exists, it is overwritten.
Entries can be removed using [`nix registry
remove`](./nix3-registry-remove.md).
diff --git a/src/nix/registry.cc b/src/nix/registry.cc
index f509ccae8..9619b85d4 100644
--- a/src/nix/registry.cc
+++ b/src/nix/registry.cc
@@ -5,6 +5,7 @@
#include "flake/flake.hh"
#include "store-api.hh"
#include "fetchers.hh"
+#include "url-parts.hh"
#include "registry.hh"
using namespace nix;
@@ -109,7 +110,14 @@ struct CmdRegistryAdd : MixEvalArgs, Command, RegistryCommand
void run() override
{
+ std::smatch match;
+ if (!std::regex_match(fromUrl, match, flakeShorthandRegex)) {
+ throw UsageError("'from-url' argument must be a shorthand like 'nixpkgs' or 'nixpkgs/nixos-20.03'");
+ }
auto fromRef = parseFlakeRef(fromUrl);
+ if (fromRef.input.direct) {
+ throw UsageError("'from-url' argument must be an indirect flakeref like 'nixpkgs' or 'flake:nixpkgs'");
+ }
auto toRef = parseFlakeRef(toUrl);
auto registry = getRegistry();
fetchers::Attrs extraAttrs;
diff --git a/tests/functional/build.sh b/tests/functional/build.sh
index 95a20dc6a..a540cf8fd 100644
--- a/tests/functional/build.sh
+++ b/tests/functional/build.sh
@@ -142,6 +142,8 @@ test "$(<<<"$out" grep -E '^error:' | wc -l)" = 2
<<<"$out" grepQuiet -E "hash mismatch in fixed-output derivation '.*-x1\\.drv'"
<<<"$out" grepQuiet -vE "hash mismatch in fixed-output derivation '.*-x3\\.drv'"
<<<"$out" grepQuiet -vE "hash mismatch in fixed-output derivation '.*-x2\\.drv'"
+<<<"$out" grepQuiet -E "likely URL: https://meow.puppy.forge/puppy.tar.gz"
+<<<"$out" grepQuiet -vE "likely URL: https://kitty.forge/cat.tar.gz"
<<<"$out" grepQuiet -E "error: build of '.*-x[1-4]\\.drv\\^out', '.*-x[1-4]\\.drv\\^out', '.*-x[1-4]\\.drv\\^out', '.*-x[1-4]\\.drv\\^out' failed"
out="$(nix build -f fod-failing.nix -L x1 x2 x3 --keep-going 2>&1)" && status=0 || status=$?
@@ -151,6 +153,9 @@ test "$(<<<"$out" grep -E '^error:' | wc -l)" = 4
<<<"$out" grepQuiet -E "hash mismatch in fixed-output derivation '.*-x1\\.drv'"
<<<"$out" grepQuiet -E "hash mismatch in fixed-output derivation '.*-x3\\.drv'"
<<<"$out" grepQuiet -E "hash mismatch in fixed-output derivation '.*-x2\\.drv'"
+<<<"$out" grepQuiet -E "likely URL: https://meow.puppy.forge/puppy.tar.gz"
+<<<"$out" grepQuiet -E "likely URL: https://kitty.forge/cat.tar.gz"
+<<<"$out" grepQuiet -E "likely URL: \(unknown\)"
<<<"$out" grepQuiet -E "error: build of '.*-x[1-3]\\.drv\\^out', '.*-x[1-3]\\.drv\\^out', '.*-x[1-3]\\.drv\\^out' failed"
out="$(nix build -f fod-failing.nix -L x4 2>&1)" && status=0 || status=$?
diff --git a/tests/functional/flakes/flakes.sh b/tests/functional/flakes/flakes.sh
index 68a2fd2ce..97dc6d818 100644
--- a/tests/functional/flakes/flakes.sh
+++ b/tests/functional/flakes/flakes.sh
@@ -366,6 +366,17 @@ nix registry pin flake1 flake3
nix registry remove flake1
[[ $(nix registry list | wc -l) == 5 ]]
+# 'nix registry add' should accept flake shorthands (with or without branch or rev)
+# in the from argument, but reject fully-qualified from-urls (direct or indirect).
+nix registry add nixpkgz github:NixOS/nixpkgz
+nix registry remove nixpkgz
+nix registry add nixpkgz/branch github:NixOS/nixpkgz
+nix registry remove nixpkgz/branch
+nix registry add nixpkgz/branch/1db42b7fe3878f3f5f7a4f2dc210772fd080e205 github:NixOS/nixpkgz
+nix registry remove nixpkgz/branch/1db42b7fe3878f3f5f7a4f2dc210772fd080e205
+! nix registry add flake:nixpkgz github:NixOS/nixpkgz
+! nix registry add github:NixOS/nixpkgz github:NixOS/nixpkgz
+
# Test 'nix registry list' with a disabled global registry.
nix registry add user-flake1 git+file://$flake1Dir
nix registry add user-flake2 git+file://$flake2Dir
diff --git a/tests/functional/fod-failing.nix b/tests/functional/fod-failing.nix
index 37c04fe12..b63fbd900 100644
--- a/tests/functional/fod-failing.nix
+++ b/tests/functional/fod-failing.nix
@@ -6,6 +6,7 @@ rec {
''
echo $name > $out
'';
+ url = "https://meow.puppy.forge/puppy.tar.gz";
outputHashMode = "recursive";
outputHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
};
@@ -15,6 +16,7 @@ rec {
''
echo $name > $out
'';
+ urls = "https://kitty.forge/cat.tar.gz";
outputHashMode = "recursive";
outputHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
};