diff --git a/docker.nix b/docker.nix index b23a9637f..a9489e5b0 100644 --- a/docker.nix +++ b/docker.nix @@ -193,13 +193,11 @@ let in '' { - ${ - lib.concatStringsSep "\n" ( - builtins.map (output: '' - ${output} = { outPath = "${lib.getOutput output drv}"; }; - '') outputs - ) - } + ${lib.concatStringsSep "\n" ( + builtins.map (output: '' + ${output} = { outPath = "${lib.getOutput output drv}"; }; + '') outputs + )} outputs = [ ${lib.concatStringsSep " " (builtins.map (x: "\"${x}\"") outputs)} ]; name = "${drv.name}"; outPath = "${drv}"; @@ -361,7 +359,8 @@ let "org.opencontainers.image.source" = "https://git.lix.systems/lix-project/lix"; "org.opencontainers.image.vendor" = "Lix project"; "org.opencontainers.image.version" = pkgs.nix.version; - "org.opencontainers.image.description" = "Minimal Lix container image, with some batteries included."; + "org.opencontainers.image.description" = + "Minimal Lix container image, with some batteries included."; } // lib.optionalAttrs (lixRevision != null) { "org.opencontainers.image.revision" = lixRevision; }; }; diff --git a/flake.lock b/flake.lock index 2368467f5..2e6701d2b 100644 --- a/flake.lock +++ b/flake.lock @@ -16,6 +16,22 @@ "type": "github" } }, + "lowdown-src": { + "flake": false, + "locked": { + "lastModified": 1633514407, + "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=", + "owner": "kristapsdz", + "repo": "lowdown", + "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8", + "type": "github" + }, + "original": { + "owner": "kristapsdz", + "repo": "lowdown", + "type": "github" + } + }, "nix2container": { "flake": false, "locked": { @@ -32,18 +48,44 @@ "type": "github" } }, - "nixpkgs": { + "nix_2_18": { + "inputs": { + "flake-compat": [ + "flake-compat" + ], + "lowdown-src": "lowdown-src", + "nixpkgs": "nixpkgs", + "nixpkgs-regression": [ + "nixpkgs-regression" + ] + }, "locked": { - "lastModified": 1733348545, - "narHash": "sha256-b4JrUmqT0vFNx42aEN9LTWOHomkTKL/ayLopflVf81U=", + "lastModified": 1730375271, + "narHash": "sha256-RrOFlDGmRXcVRV2p2HqHGqvzGNyWoD0Dado/BNlJ1SI=", "owner": "NixOS", - "repo": "nixpkgs", - "rev": "9ecb50d2fae8680be74c08bb0a995c5383747f89", + "repo": "nix", + "rev": "0f665ff6779454f2117dcc32e44380cda7f45523", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-24.11-small", + "ref": "2.18.9", + "repo": "nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1705033721, + "narHash": "sha256-K5eJHmL1/kev6WuqyqqbS1cdNnSidIZ3jeqJ7GbrYnQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a1982c92d8980a0114372973cbdfe0a307f1bdea", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.05-small", "repo": "nixpkgs", "type": "github" } @@ -64,6 +106,22 @@ "type": "github" } }, + "nixpkgs_2": { + "locked": { + "lastModified": 1749522908, + "narHash": "sha256-eWANkhWXFL1MmaxzsZ9bhLCNT8OVs7CC+OXaSDGlA8A=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e5cb99555c45a13dcc5f1317462238530b0066b7", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-25.05-small", + "repo": "nixpkgs", + "type": "github" + } + }, "pre-commit-hooks": { "flake": false, "locked": { @@ -84,7 +142,8 @@ "inputs": { "flake-compat": "flake-compat", "nix2container": "nix2container", - "nixpkgs": "nixpkgs", + "nix_2_18": "nix_2_18", + "nixpkgs": "nixpkgs_2", "nixpkgs-regression": "nixpkgs-regression", "pre-commit-hooks": "pre-commit-hooks" } diff --git a/flake.nix b/flake.nix index 5c6ab138d..a73399a8d 100644 --- a/flake.nix +++ b/flake.nix @@ -2,8 +2,19 @@ description = "Lix: A modern, delicious implementation of the Nix package manager"; inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11-small"; + nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05-small"; nixpkgs-regression.url = "github:NixOS/nixpkgs/215d4d0fd80ca5163643b03a33fde804a29cc1e2"; + + # Required because Nix 2.18 is not in Nixpkgs ≥ 25.05 anymore. + nix_2_18 = { + url = "github:NixOS/nix/2.18.9"; + # NOTE(Raito): this is not possible because patches on libseccomp does not apply anymore on this Nix. + # Let's keep the latest known nixpkgs useable with Nix 2.18 for our tests. + # inputs.nixpkgs.follows = "nixpkgs"; + inputs.nixpkgs-regression.follows = "nixpkgs-regression"; + inputs.flake-compat.follows = "flake-compat"; + }; + pre-commit-hooks = { url = "github:cachix/git-hooks.nix"; flake = false; @@ -25,6 +36,7 @@ nixpkgs-regression, pre-commit-hooks, nix2container, + nix_2_18, flake-compat, }: @@ -159,6 +171,11 @@ { nixStable = prev.nix; + # Nix 2.18 has been removed from Nixpkgs ≥ 25.05, so we need to reintroduce it ourselves for our tests. + nixVersions = prev.nixVersions // { + nix_2_18 = nix_2_18.outputs.packages.${currentStdenv.hostPlatform.system}.default; + }; + # Forward from the previous stage as we don’t want it to pick the lowdown override nixUnstable = prev.nixUnstable; @@ -351,10 +368,12 @@ name = "nixpkgs-lib-tests"; paths = [ testWithNix ] - # NOTE: nixpkgs 24.11 is being ... *creative*, and requires this dance to override + # NOTE: nixpkgs 25.05 is being ... *creative*, and requires this dance to override # the evaluator used for the test. it will break again in the future, don't worry. ++ lib.optionals pkgs.stdenv.isLinux [ - (pkgs.callPackage "${nixpkgs}/ci/eval" { nixVersions.nix_2_24 = nix; }).attrpathsSuperset + ((pkgs.callPackage "${nixpkgs}/ci/eval" { nixVersions.latest = nix; }).attrpathsSuperset { + evalSystem = system; + }) ]; } ); diff --git a/lix/libexpr/nixexpr.hh b/lix/libexpr/nixexpr.hh index 6321a0803..18bafa3ee 100644 --- a/lix/libexpr/nixexpr.hh +++ b/lix/libexpr/nixexpr.hh @@ -226,7 +226,7 @@ struct ExprAttrs AttrDef() { }; template - const T & chooseByKind(const T & plain, const T & inherited, const T & inheritedFrom) const + T chooseByKind(const T & plain, const T & inherited, const T & inheritedFrom) const { switch (kind) { case Kind::Plain: diff --git a/lix/libexpr/parser/grammar.hh b/lix/libexpr/parser/grammar.hh index 701b40505..c239a37d1 100644 --- a/lix/libexpr/parser/grammar.hh +++ b/lix/libexpr/parser/grammar.hh @@ -644,10 +644,13 @@ struct nothing : p::nothing { static_assert(!std::is_base_of_v); }; - - template -struct operator_semantics { +struct operator_semantics +{ +private: + operator_semantics() = default; + friend Self; +public: struct has_attr : grammar::v1::op::has_attr { AttrPathT path; }; @@ -730,5 +733,4 @@ struct operator_semantics { return popExpr(); } }; - } diff --git a/lix/libstore/crypto.cc b/lix/libstore/crypto.cc index 650e05e06..accec4db0 100644 --- a/lix/libstore/crypto.cc +++ b/lix/libstore/crypto.cc @@ -45,8 +45,15 @@ std::string SecretKey::signDetached(std::string_view data) const { unsigned char sig[crypto_sign_BYTES]; unsigned long long sigLen; - crypto_sign_detached(sig, &sigLen, charptr_cast(data.data()), data.size(), - charptr_cast(key.data())); + crypto_sign_detached( + sig, + &sigLen, + // the following is not a string function so no null termination issues are possible here. + // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage) + charptr_cast(data.data()), + data.size(), + charptr_cast(key.data()) + ); return name + ":" + base64Encode(std::string(reinterpret_cast(sig), sigLen)); } diff --git a/lix/libstore/sqlite.cc b/lix/libstore/sqlite.cc index e053fc660..5c0afd7ca 100644 --- a/lix/libstore/sqlite.cc +++ b/lix/libstore/sqlite.cc @@ -146,7 +146,7 @@ SQLiteStmt::Use::~Use() SQLiteStmt::Use & SQLiteStmt::Use::operator () (std::string_view value, bool notNull) { if (notNull) { - if (sqlite3_bind_text(stmt, curArg++, value.data(), -1, SQLITE_TRANSIENT) != SQLITE_OK) + if (sqlite3_bind_text(stmt, curArg++, value.data(), value.length(), SQLITE_TRANSIENT) != SQLITE_OK) SQLiteError::throw_(stmt.db, "binding argument"); } else bind(); diff --git a/lix/libutil/compression.cc b/lix/libutil/compression.cc index cf211bc48..a6bc8c0f9 100644 --- a/lix/libutil/compression.cc +++ b/lix/libutil/compression.cc @@ -259,6 +259,7 @@ struct BrotliCompressionSink : ChunkedCompressionSink void writeInternal(std::string_view data) override { + // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage) auto next_in = charptr_cast(data.data()); size_t avail_in = data.size(); uint8_t * next_out = outbuf; diff --git a/lix/libutil/file-system.cc b/lix/libutil/file-system.cc index c4a07bba8..0344ba0dc 100644 --- a/lix/libutil/file-system.cc +++ b/lix/libutil/file-system.cc @@ -518,7 +518,7 @@ static void _deletePath(const Path & path, uint64_t & bytesFreed) throw SysError("opening directory '%1%'", path); } - _deletePath(dirfd.get(), baseNameOf(path).data(), bytesFreed); + _deletePath(dirfd.get(), std::string(baseNameOf(path)), bytesFreed); } diff --git a/lix/libutil/json-utils.cc b/lix/libutil/json-utils.cc index 204f7b411..c018b9085 100644 --- a/lix/libutil/json-utils.cc +++ b/lix/libutil/json-utils.cc @@ -38,6 +38,6 @@ const nlohmann::json & ensureType( nlohmann::json(expectedType).type_name(), value.type_name()); - return value; + return value; // NOLINT(bugprone-return-const-ref-from-parameter) } } diff --git a/lix/libutil/logging.hh b/lix/libutil/logging.hh index 1afa103e1..58f76a39a 100644 --- a/lix/libutil/logging.hh +++ b/lix/libutil/logging.hh @@ -253,12 +253,12 @@ extern Verbosity verbosity; * level. Note that this has to be implemented as a macro to ensure that the * arguments are evaluated lazily. */ -#define printMsgUsing(loggerParam, level, args...) \ - do { \ - auto __lvl = level; \ - if (__lvl <= nix::verbosity) { \ - loggerParam->log(__lvl, fmt(args)); \ - } \ +#define printMsgUsing(loggerParam, level, args...) \ + do { \ + auto _lix_logger_print_lvl = level; \ + if (_lix_logger_print_lvl <= nix::verbosity) { \ + loggerParam->log(_lix_logger_print_lvl, fmt(args)); \ + } \ } while (0) #define printMsg(level, args...) printMsgUsing(logger, level, args) diff --git a/lix/libutil/references.cc b/lix/libutil/references.cc index 952b14195..61122d370 100644 --- a/lix/libutil/references.cc +++ b/lix/libutil/references.cc @@ -53,7 +53,7 @@ void RefScanSink::operator () (std::string_view data) previous fragment and the start of the current fragment. */ auto s = tail; auto tailLen = std::min(data.size(), refLength); - s.append(data.data(), tailLen); + s.append(data.data(), tailLen); // NOLINT(bugprone-suspicious-stringview-data-usage) search(s, hashes, seen); search(data, hashes, seen); diff --git a/lix/libutil/types.hh b/lix/libutil/types.hh index 89d277448..9bf5f08ae 100644 --- a/lix/libutil/types.hh +++ b/lix/libutil/types.hh @@ -68,13 +68,19 @@ typename T::mapped_type * get(T & map, const typename T::key_type & key) /** * Get a value for the specified key from an associate container, or a default value if the key isn't present. */ -template -const typename T::mapped_type & getOr(T & map, +template +const typename T::mapped_type & getOr( + T & map [[clang::lifetimebound]], const typename T::key_type & key, - const typename T::mapped_type & defaultValue) + const typename T::mapped_type & defaultValue [[clang::lifetimebound]] +) { auto i = map.find(key); - if (i == map.end()) return defaultValue; + if (i == map.end()) { + /* FIXME(Raito): `[[clang::lifetimebound]]` has no effect on `defaultValue` warning. */ + // NOLINTNEXTLINE(bugprone-return-const-ref-from-parameter) + return defaultValue; + } return i->second; } diff --git a/nix-support/editline.patch b/nix-support/editline.patch deleted file mode 100644 index df31cfdc4..000000000 --- a/nix-support/editline.patch +++ /dev/null @@ -1,106 +0,0 @@ -From d0f2a5bc2300b96b2434c7838184c1dfd6a639f5 Mon Sep 17 00:00:00 2001 -From: Rebecca Turner -Date: Sun, 8 Sep 2024 15:42:42 -0700 -Subject: [PATCH 1/2] Recognize Meta+Left and Meta+Right - -Recognize `Alt-Left` and `Alt-Right` for navigating by words in more -terminals/shells/platforms. - -I'm not sure exactly where to find canonical documentation for these -codes, but this seems to match what my terminal produces (macOS + iTerm2 -+ Fish + Tmux). - -It might also be nice to have some more support for editing the bindings -for these characters; sequences of more than one character are not -supported by `el_bind_key` and similar. - -Originally from: https://github.com/troglobit/editline/pull/70 -This patch is applied upstream: https://gerrit.lix.systems/c/lix/+/1883 - ---- - src/editline.c | 29 +++++++++++++++++++++++++++-- - 1 file changed, 27 insertions(+), 2 deletions(-) - -diff --git a/src/editline.c b/src/editline.c -index 5ec9afb..d1cfbbc 100644 ---- a/src/editline.c -+++ b/src/editline.c -@@ -1034,6 +1034,30 @@ static el_status_t meta(void) - return CSeof; - - #ifdef CONFIG_ANSI_ARROWS -+ /* See: https://en.wikipedia.org/wiki/ANSI_escape_code */ -+ /* Recognize ANSI escapes for `Meta+Left` and `Meta+Right`. */ -+ if (c == '\e') { -+ switch (tty_get()) { -+ case '[': -+ { -+ switch (tty_get()) { -+ /* \e\e[C = Meta+Left */ -+ case 'C': return fd_word(); -+ /* \e\e[D = Meta+Right */ -+ case 'D': return bk_word(); -+ default: -+ break; -+ } -+ -+ return el_ring_bell(); -+ } -+ default: -+ break; -+ } -+ -+ return el_ring_bell(); -+ } -+ - /* Also include VT-100 arrows. */ - if (c == '[' || c == 'O') { - switch (tty_get()) { -@@ -1043,6 +1067,7 @@ static el_status_t meta(void) - char seq[4] = { 0 }; - seq[0] = tty_get(); - -+ /* \e[1~ */ - if (seq[0] == '~') - return beg_line(); /* Home */ - -@@ -1050,9 +1075,9 @@ static el_status_t meta(void) - seq[c] = tty_get(); - - if (!strncmp(seq, ";5C", 3)) -- return fd_word(); /* Ctrl+Right */ -+ return fd_word(); /* \e[1;5C = Ctrl+Right */ - if (!strncmp(seq, ";5D", 3)) -- return bk_word(); /* Ctrl+Left */ -+ return bk_word(); /* \e[1;5D = Ctrl+Left */ - - break; - } - -From 4c4455353a0a88bee09d5f27c28f81f747682fed Mon Sep 17 00:00:00 2001 -From: Rebecca Turner -Date: Mon, 9 Sep 2024 09:44:44 -0700 -Subject: [PATCH 2/2] Add support for \e[1;3C and \e[1;3D - ---- - src/editline.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/src/editline.c b/src/editline.c -index d1cfbbc..350b5cb 100644 ---- a/src/editline.c -+++ b/src/editline.c -@@ -1074,9 +1074,11 @@ static el_status_t meta(void) - for (c = 1; c < 3; c++) - seq[c] = tty_get(); - -- if (!strncmp(seq, ";5C", 3)) -+ if (!strncmp(seq, ";5C", 3) -+ || !strncmp(seq, ";3C", 3)) - return fd_word(); /* \e[1;5C = Ctrl+Right */ -- if (!strncmp(seq, ";5D", 3)) -+ if (!strncmp(seq, ";5D", 3) -+ || !strncmp(seq, ";3D", 3)) - return bk_word(); /* \e[1;5D = Ctrl+Left */ - - break; diff --git a/package.nix b/package.nix index 01155b1ea..211a44cae 100644 --- a/package.nix +++ b/package.nix @@ -86,14 +86,6 @@ boehmgc-nix = boehmgc.override { enableLargeConfig = true; }; editline-lix = editline.overrideAttrs (prev: { - patches = (prev.patches or [ ]) ++ [ - # Recognize `Alt-Left` and `Alt-Right` for navigating by words in more - # terminals/shells/platforms. - # - # See: https://github.com/troglobit/editline/pull/70 - ./nix-support/editline.patch - ]; - configureFlags = (prev.configureFlags or [ ]) ++ [ # Enable SIGSTOP (Ctrl-Z) behavior. (lib.enableFeature true "sigstop") diff --git a/tests/nixos/fetchurl.nix b/tests/nixos/fetchurl.nix index abcec125f..1626e1c03 100644 --- a/tests/nixos/fetchurl.nix +++ b/tests/nixos/fetchurl.nix @@ -76,7 +76,7 @@ in # Fetching from a server with an untrusted cert should fail. err = machine.fail("nix build --no-substitute --expr 'import { url = \"https://bad/index.html\"; hash = \"sha256-rsBwZF/lPuOzdjBZN2E08FjMM3JHyXit0Xi2zN+wAZ8=\"; }' 2>&1") print(err) - assert "SSL peer certificate or SSH remote key was not OK" in err + assert "SSL certificate problem: self-signed certificate" in err # Fetching from a server with a trusted cert should work via environment variable override. machine.succeed("NIX_SSL_CERT_FILE=/tmp/cafile.pem nix build --no-substitute --expr 'import { url = \"https://bad/index.html\"; hash = \"sha256-rsBwZF/lPuOzdjBZN2E08FjMM3JHyXit0Xi2zN+wAZ8=\"; }'") diff --git a/tests/nixos/nix-copy-closure.nix b/tests/nixos/nix-copy-closure.nix index cd25fbbd0..d6d4ae4f3 100644 --- a/tests/nixos/nix-copy-closure.nix +++ b/tests/nixos/nix-copy-closure.nix @@ -45,12 +45,12 @@ in { server.wait_for_unit("network-online.target") client.wait_for_unit("network-online.target") - client.succeed("mkdir -m 700 /root/.ssh") + client.succeed("mkdir -m 700 /root/.ssh || [[ -d /root/.ssh ]]") client.copy_from_host("key", "/root/.ssh/id_ed25519") client.succeed("chmod 600 /root/.ssh/id_ed25519") # Install the SSH key on the server. - server.succeed("mkdir -m 700 /root/.ssh") + server.succeed("mkdir -m 700 /root/.ssh || [[ -d /root/.ssh ]]") server.copy_from_host("key.pub", "/root/.ssh/authorized_keys") server.wait_for_unit("sshd.service") client.succeed(f"ssh -o StrictHostKeyChecking=no {server.name} 'echo hello world' >&2")