From 201515be8317cb4f3d33d0fe87b68406a9366672 Mon Sep 17 00:00:00 2001 From: emaryn Date: Sat, 3 May 2025 01:21:35 +0800 Subject: [PATCH 01/82] ior: 3.3.0 -> 4.0.0 Diff: https://github.com/hpc/ior/compare/3.3.0...4.0.0 --- pkgs/by-name/io/ior/package.nix | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/pkgs/by-name/io/ior/package.nix b/pkgs/by-name/io/ior/package.nix index d0c018ebdcaf..78a197edf480 100644 --- a/pkgs/by-name/io/ior/package.nix +++ b/pkgs/by-name/io/ior/package.nix @@ -5,20 +5,25 @@ mpi, perl, autoreconfHook, + pkg-config, }: -stdenv.mkDerivation rec { +stdenv.mkDerivation (finalAttrs: { pname = "ior"; - version = "3.3.0"; + version = "4.0.0"; src = fetchFromGitHub { owner = "hpc"; repo = "ior"; - rev = version; - sha256 = "sha256-pSjptDfiPlaToXe1yHyk9MQMC9PqcVSjqAmWLD11iOM="; + tag = finalAttrs.version; + hash = "sha256-WsfJWHHfkiHZ+rPk6ck6mDErTXwt6Dhgm+yqOtw4Fvo="; }; - nativeBuildInputs = [ autoreconfHook ]; + nativeBuildInputs = [ + autoreconfHook + pkg-config + ]; + buildInputs = [ mpi perl @@ -26,11 +31,11 @@ stdenv.mkDerivation rec { enableParallelBuilding = true; - meta = with lib; { + meta = { homepage = "https://ior.readthedocs.io/en/latest/"; description = "Parallel file system I/O performance test"; - license = licenses.gpl2Only; - platforms = platforms.linux; - maintainers = with maintainers; [ bzizou ]; + license = lib.licenses.gpl2Only; + platforms = lib.platforms.linux; + maintainers = with lib.maintainers; [ bzizou ]; }; -} +}) From ce8c8feab9aeef8c086f262e2b00e60152a3e602 Mon Sep 17 00:00:00 2001 From: emaryn Date: Fri, 9 May 2025 11:27:38 +0800 Subject: [PATCH 02/82] multimarkdown: 6.6.0 -> 6.7.0 Diff: https://github.com/fletcher/MultiMarkdown-6/compare/6.6.0...6.7.0 --- pkgs/by-name/mu/multimarkdown/package.nix | 25 ++++++++--------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/pkgs/by-name/mu/multimarkdown/package.nix b/pkgs/by-name/mu/multimarkdown/package.nix index 20b53464d92c..b69eb9fc27d1 100644 --- a/pkgs/by-name/mu/multimarkdown/package.nix +++ b/pkgs/by-name/mu/multimarkdown/package.nix @@ -7,35 +7,28 @@ pkg-config, }: -stdenv.mkDerivation rec { +stdenv.mkDerivation (finalAttrs: { pname = "multimarkdown"; - version = "6.6.0"; + version = "6.7.0"; src = fetchFromGitHub { owner = "fletcher"; repo = "MultiMarkdown-6"; - rev = version; - hash = "sha256-emJbY0wucoc/GdjlILoeqjwuwuPpTjXTqZN0gUKOyLg="; + tag = finalAttrs.version; + hash = "sha256-b6yCn0NFpONI7WwfjDOc0d2nCKMIiUXi+rsnytiNc0Q="; }; postPatch = '' patchShebangs tools/enumsToPerl.pl ''; - postInstall = '' - # Move files from $out/ to sub directories to prevent conflicts - # with other packages: - mkdir -p $out/share/doc/multimarkdown/ - mv $out/LICENSE.txt $out/README.txt $out/share/doc/multimarkdown/ - ''; - nativeBuildInputs = [ cmake perl pkg-config ]; - meta = with lib; { + meta = { homepage = "https://fletcher.github.io/MultiMarkdown-6/introduction.html"; description = "Derivative of Markdown that adds new syntax features"; longDescription = '' @@ -59,8 +52,8 @@ stdenv.mkDerivation rec { - glossary entries (LaTeX only) - document metadata (e.g. title, author, date, etc.) ''; - license = with licenses; [ mit ]; - platforms = platforms.all; - maintainers = with maintainers; [ ]; + license = with lib.licenses; [ mit ]; + platforms = lib.platforms.all; + maintainers = with lib.maintainers; [ ]; }; -} +}) From 84e39aaeaada5b58b16fd943e0bbe07df6b1c81d Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Fri, 23 May 2025 02:27:51 +0900 Subject: [PATCH 03/82] stockfish: remove unused input --- pkgs/by-name/st/stockfish/package.nix | 1 - 1 file changed, 1 deletion(-) diff --git a/pkgs/by-name/st/stockfish/package.nix b/pkgs/by-name/st/stockfish/package.nix index 50216db2b95e..ce899bd21d90 100644 --- a/pkgs/by-name/st/stockfish/package.nix +++ b/pkgs/by-name/st/stockfish/package.nix @@ -3,7 +3,6 @@ stdenv, fetchurl, fetchFromGitHub, - apple-sdk, }: let From b153f78ae7c0826606d508116ed9e570440f8a18 Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Fri, 23 May 2025 02:30:16 +0900 Subject: [PATCH 04/82] stockfish: add updateScript --- pkgs/by-name/st/stockfish/package.nix | 39 ++++++++++++++++++++++++--- pkgs/by-name/st/stockfish/update.bash | 20 ++++++++++++++ 2 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 pkgs/by-name/st/stockfish/update.bash diff --git a/pkgs/by-name/st/stockfish/package.nix b/pkgs/by-name/st/stockfish/package.nix index ce899bd21d90..9aea351623ff 100644 --- a/pkgs/by-name/st/stockfish/package.nix +++ b/pkgs/by-name/st/stockfish/package.nix @@ -3,6 +3,11 @@ stdenv, fetchurl, fetchFromGitHub, + _experimental-update-script-combinators, + nix-update-script, + writeShellApplication, + nix, + gnugrep, }: let @@ -24,16 +29,18 @@ let # These files can be found in src/evaluate.h nnueBigFile = "nn-1111cefa1111.nnue"; + nnueBigHash = "sha256-ERHO+hERa3cWG9SxTatMUPJuWSDHVvSGFZK+Pc1t4XQ="; nnueBig = fetchurl { name = nnueBigFile; url = "https://tests.stockfishchess.org/api/nn/${nnueBigFile}"; - sha256 = "sha256-ERHO+hERa3cWG9SxTatMUPJuWSDHVvSGFZK+Pc1t4XQ="; + hash = nnueBigHash; }; nnueSmallFile = "nn-37f18f62d772.nnue"; + nnueSmallHash = "sha256-N/GPYtdy8xB+HWqso4mMEww8hvKrY+ZVX7vKIGNaiZ0="; nnueSmall = fetchurl { name = nnueSmallFile; url = "https://tests.stockfishchess.org/api/nn/${nnueSmallFile}"; - sha256 = "sha256-N/GPYtdy8xB+HWqso4mMEww8hvKrY+ZVX7vKIGNaiZ0="; + hash = nnueSmallHash; }; in @@ -44,8 +51,8 @@ stdenv.mkDerivation rec { src = fetchFromGitHub { owner = "official-stockfish"; repo = "Stockfish"; - rev = "sf_${version}"; - sha256 = "sha256-oXvLaC5TEUPlHjhm7tOxpNPY88QxYHFw+Cev3Q8NEeQ="; + tag = "sf_${version}"; + hash = "sha256-oXvLaC5TEUPlHjhm7tOxpNPY88QxYHFw+Cev3Q8NEeQ="; }; postUnpack = '' @@ -63,6 +70,30 @@ stdenv.mkDerivation rec { enableParallelBuilding = true; + passthru = { + updateScript = _experimental-update-script-combinators.sequence [ + (nix-update-script { + extraArgs = [ "--version-regex=^sf_([\\d.]+)$" ]; + }) + (lib.getExe (writeShellApplication { + name = "${pname}-nnue-updater"; + runtimeInputs = [ + nix + gnugrep + ]; + runtimeEnv = { + PNAME = pname; + PKG_FILE = builtins.toString ./package.nix; + NNUE_BIG_FILE = nnueBigFile; + NNUE_BIG_HASH = nnueBigHash; + NNUE_SMALL_FILE = nnueSmallFile; + NNUE_SMALL_HASH = nnueSmallHash; + }; + text = builtins.readFile ./update.bash; + })) + ]; + }; + meta = with lib; { homepage = "https://stockfishchess.org/"; description = "Strong open source chess engine"; diff --git a/pkgs/by-name/st/stockfish/update.bash b/pkgs/by-name/st/stockfish/update.bash new file mode 100644 index 000000000000..aaf294fd027d --- /dev/null +++ b/pkgs/by-name/st/stockfish/update.bash @@ -0,0 +1,20 @@ +new_src="$(nix-build --attr "pkgs.$PNAME.src" --no-out-link)" +new_nnue_big_file="$(grep --perl-regexp --only-matching 'EvalFileDefaultNameBig "\Knn-(\w+).nnue' "$new_src/src/evaluate.h")" +new_nnue_small_file="$(grep --perl-regexp --only-matching 'EvalFileDefaultNameSmall "\Knn-(\w+).nnue' "$new_src/src/evaluate.h")" +new_nnue_big_hash="$( + nix hash convert --hash-algo sha256 "$( + nix-prefetch-url --type sha256 "https://tests.stockfishchess.org/api/nn/$new_nnue_big_file" + )" +)" +new_nnue_small_hash="$( + nix hash convert --hash-algo sha256 "$( + nix-prefetch-url --type sha256 "https://tests.stockfishchess.org/api/nn/$new_nnue_small_file" + )" +)" + +pkg_body="$(<"$PKG_FILE")" +pkg_body="${pkg_body//"$NNUE_BIG_FILE"/"$new_nnue_big_file"}" +pkg_body="${pkg_body//"$NNUE_BIG_HASH"/"$new_nnue_big_hash"}" +pkg_body="${pkg_body//"$NNUE_SMALL_FILE"/"$new_nnue_small_file"}" +pkg_body="${pkg_body//"$NNUE_SMALL_HASH"/"$new_nnue_small_hash"}" +echo "$pkg_body" >"$PKG_FILE" From 32b302b7cc43c23c8d414a59552061a018aba7e8 Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Fri, 23 May 2025 03:17:35 +0900 Subject: [PATCH 05/82] stockfish: add versionCheckHook --- pkgs/by-name/st/stockfish/package.nix | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkgs/by-name/st/stockfish/package.nix b/pkgs/by-name/st/stockfish/package.nix index 9aea351623ff..3ac27539e6da 100644 --- a/pkgs/by-name/st/stockfish/package.nix +++ b/pkgs/by-name/st/stockfish/package.nix @@ -3,6 +3,7 @@ stdenv, fetchurl, fetchFromGitHub, + versionCheckHook, _experimental-update-script-combinators, nix-update-script, writeShellApplication, @@ -70,6 +71,13 @@ stdenv.mkDerivation rec { enableParallelBuilding = true; + nativeInstallCheckInputs = [ + versionCheckHook + ]; + doInstallCheck = true; + versionCheckProgram = "${placeholder "out"}/bin/stockfish"; + versionCheckProgramArg = "--help"; + passthru = { updateScript = _experimental-update-script-combinators.sequence [ (nix-update-script { From 41e85ee7c1a81da0d68cf11df2710e1a1f9310af Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Fri, 23 May 2025 03:23:11 +0900 Subject: [PATCH 06/82] stockfish: 17 -> 17.1 Diff: https://github.com/official-stockfish/Stockfish/compare/sf_17...sf_17.1 --- pkgs/by-name/st/stockfish/package.nix | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkgs/by-name/st/stockfish/package.nix b/pkgs/by-name/st/stockfish/package.nix index 3ac27539e6da..02cfd355f012 100644 --- a/pkgs/by-name/st/stockfish/package.nix +++ b/pkgs/by-name/st/stockfish/package.nix @@ -29,8 +29,8 @@ let "unknown"; # These files can be found in src/evaluate.h - nnueBigFile = "nn-1111cefa1111.nnue"; - nnueBigHash = "sha256-ERHO+hERa3cWG9SxTatMUPJuWSDHVvSGFZK+Pc1t4XQ="; + nnueBigFile = "nn-1c0000000000.nnue"; + nnueBigHash = "sha256-HAAAAAAApn1imZnZMtDDc/dFDOQ80S0FYoaPTq+a4q0="; nnueBig = fetchurl { name = nnueBigFile; url = "https://tests.stockfishchess.org/api/nn/${nnueBigFile}"; @@ -47,13 +47,13 @@ in stdenv.mkDerivation rec { pname = "stockfish"; - version = "17"; + version = "17.1"; src = fetchFromGitHub { owner = "official-stockfish"; repo = "Stockfish"; tag = "sf_${version}"; - hash = "sha256-oXvLaC5TEUPlHjhm7tOxpNPY88QxYHFw+Cev3Q8NEeQ="; + hash = "sha256-c8o1d7/yPnF3Eo7M/MSzYuYQr2qt2tIwyu7WfuKMAzg="; }; postUnpack = '' From ada07fa89d7c24a9d84d291d1b645863e4705871 Mon Sep 17 00:00:00 2001 From: "R. Ryantm" Date: Fri, 23 May 2025 19:20:43 +0000 Subject: [PATCH 07/82] neuron: 8.2.6 -> 8.2.7 --- pkgs/by-name/ne/neuron/package.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/by-name/ne/neuron/package.nix b/pkgs/by-name/ne/neuron/package.nix index d6b7098654bc..5456114455d3 100644 --- a/pkgs/by-name/ne/neuron/package.nix +++ b/pkgs/by-name/ne/neuron/package.nix @@ -24,7 +24,7 @@ let in stdenv.mkDerivation (finalAttrs: { pname = "neuron"; - version = "8.2.6"; + version = "8.2.7"; # format is for pythonModule conversion format = "other"; @@ -64,7 +64,7 @@ stdenv.mkDerivation (finalAttrs: { python3.pkgs.mpi4py ] ++ optionals useRx3d [ - python3.pkgs.cython_0 # NOTE: cython<3 is required as of 8.2.6 + python3.pkgs.cython_0 # NOTE: cython<3 is required as of 8.2.7 python3.pkgs.numpy ]; @@ -99,7 +99,7 @@ stdenv.mkDerivation (finalAttrs: { repo = "nrn"; rev = finalAttrs.version; fetchSubmodules = true; - hash = "sha256-xASBpsF8rIzrb5G+4Qi6rvWC2wqL7nAGlSeMsBAI6WM="; + hash = "sha256-dmpx0Wud0IhdFvvTJuW/w1Uq6vFYaNal9n27LAqV1Qc="; }; meta = with lib; { From a46dd57329b76fe3907ba3c5c83abe4d4a5716ef Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Mon, 26 May 2025 23:57:23 +0900 Subject: [PATCH 08/82] biz-ud-gothic: init at 1.051 --- pkgs/by-name/bi/biz-ud-gothic/package.nix | 41 +++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 pkgs/by-name/bi/biz-ud-gothic/package.nix diff --git a/pkgs/by-name/bi/biz-ud-gothic/package.nix b/pkgs/by-name/bi/biz-ud-gothic/package.nix new file mode 100644 index 000000000000..17db66a647e5 --- /dev/null +++ b/pkgs/by-name/bi/biz-ud-gothic/package.nix @@ -0,0 +1,41 @@ +{ + lib, + stdenvNoCC, + fetchzip, + nix-update-script, +}: + +stdenvNoCC.mkDerivation (finalAttrs: { + pname = "biz-ud-gothic"; + version = "1.051"; + + src = fetchzip { + # Sticking with this assets file due to ongoing discussions. + # We may switch to a different asset once the issue is resolved or clarifications are provided. + # ref: https://github.com/googlefonts/morisawa-biz-ud-gothic/issues/47 + url = "https://github.com/googlefonts/morisawa-biz-ud-gothic/releases/download/v${finalAttrs.version}/morisawa-biz-ud-gothic-fonts.zip"; + hash = "sha256-7PlIrQX1fnFHXm7mjfoOCVp3GSnLT2GlVZdSoZbh/s4="; + }; + + installPhase = '' + runHook preInstall + + install -Dm444 fonts/ttf/*.ttf -t "$out/share/fonts/truetype/" + + runHook postInstall + ''; + + passthru = { + updateScript = nix-update-script { }; + }; + + meta = { + description = "Universal Design Japanese font"; + homepage = "https://github.com/googlefonts/morisawa-biz-ud-gothic"; + license = lib.licenses.ofl; + maintainers = with lib.maintainers; [ + kachick + ]; + platforms = lib.platforms.all; + }; +}) From ebed8fb6dc2cbe9cf89b9ce8e6bbe3faf0986b08 Mon Sep 17 00:00:00 2001 From: June Stepp Date: Sat, 3 May 2025 22:02:13 -0500 Subject: [PATCH 09/82] maintainers: add junestepp --- maintainers/maintainer-list.nix | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix index d9731063b760..d0f623a81dd5 100644 --- a/maintainers/maintainer-list.nix +++ b/maintainers/maintainer-list.nix @@ -12509,6 +12509,13 @@ githubId = 39434424; name = "Felix Springer"; }; + junestepp = { + email = "git@junestepp.me"; + github = "junestepp"; + githubId = 26205306; + name = "June Stepp"; + keys = [ { fingerprint = "2561 0243 2233 CFE6 E13E 3C33 348C 6EB3 39AE C582"; } ]; + }; junjihashimoto = { email = "junji.hashimoto@gmail.com"; github = "junjihashimoto"; From 168a5e08bae4045943603d694e924d4e82378bc7 Mon Sep 17 00:00:00 2001 From: Ross Smyth <18294397+RossSmyth@users.noreply.github.com> Date: Mon, 26 May 2025 23:49:27 -0400 Subject: [PATCH 10/82] mpvScripts.easycrop: init at 0-unstable-2018-01-24 --- .../video/mpv/scripts/easycrop.nix | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 pkgs/applications/video/mpv/scripts/easycrop.nix diff --git a/pkgs/applications/video/mpv/scripts/easycrop.nix b/pkgs/applications/video/mpv/scripts/easycrop.nix new file mode 100644 index 000000000000..1ed3d648cb2d --- /dev/null +++ b/pkgs/applications/video/mpv/scripts/easycrop.nix @@ -0,0 +1,44 @@ +{ + lib, + buildLua, + fetchFromGitHub, + unstableGitUpdater, +}: + +buildLua { + pname = "easycrop"; + version = "0-unstable-2018-01-24"; + + src = fetchFromGitHub { + owner = "aidanholm"; + repo = "mpv-easycrop"; + rev = "b8a67bb9039e19dec54d92ea57076c0c98e981aa"; + hash = "sha256-VRQP8j/Z/OvVqrEpvWcLmJFotxbTRynHoqvfIQIQmqY="; + }; + + scriptPath = "easycrop.lua"; + + passthru.updateScript = unstableGitUpdater { }; + + meta = { + description = "Manually crop videos during playback in mpv"; + longDescription = '' + A simple mpv script for manually cropping videos with ease. + + - Works during video playback + - No need to re-encode or modify video files + + Press "c" to begin cropping. Click at one corner of the desired + cropping rectangle, and click a second time at the opposite + corner; the video will be cropped immediately. Pressing "c" again + will undo the current crop. + + If you wish to use a key other than "c" to crop, the keybind + `easy_crop` can be changed. + ''; + homepage = "https://github.com/aidanholm/mpv-easycrop"; + license = lib.licenses.gpl3; + platforms = lib.platforms.all; + maintainers = with lib.maintainers; [ RossSmyth ]; + }; +} From 158bfaf735401219af77573e80c2892cdfc02ac4 Mon Sep 17 00:00:00 2001 From: Thomas Sowell Date: Wed, 28 May 2025 18:44:11 -0800 Subject: [PATCH 11/82] wiremix: init at 0.4.0 --- pkgs/by-name/wi/wiremix/package.nix | 38 +++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 pkgs/by-name/wi/wiremix/package.nix diff --git a/pkgs/by-name/wi/wiremix/package.nix b/pkgs/by-name/wi/wiremix/package.nix new file mode 100644 index 000000000000..92f040b05e59 --- /dev/null +++ b/pkgs/by-name/wi/wiremix/package.nix @@ -0,0 +1,38 @@ +{ + lib, + fetchCrate, + rustPlatform, + pkg-config, + pipewire, +}: + +rustPlatform.buildRustPackage rec { + pname = "wiremix"; + version = "0.4.0"; + + src = fetchCrate { + inherit pname version; + hash = "sha256-LtwKG3phUuNgwXlAJMhZkOenYHGyXGRhNcr6+WKxVz0="; + }; + + useFetchCargoVendor = true; + cargoHash = "sha256-Qc+VubikiYox1zqy2HO3InRI8aFT8AorrFZBQhNGFOQ="; + + nativeBuildInputs = [ + pkg-config + rustPlatform.bindgenHook + ]; + buildInputs = [ pipewire ]; + + meta = { + description = "Simple TUI mixer for PipeWire"; + mainProgram = "wiremix"; + homepage = "https://github.com/tsowell/wiremix"; + license = with lib.licenses; [ + asl20 + mit + ]; + maintainers = with lib.maintainers; [ tsowell ]; + platforms = lib.platforms.linux; + }; +} From 62f1946374dc9d463544293244ffc596f22b5c59 Mon Sep 17 00:00:00 2001 From: Kira Bruneau Date: Thu, 29 May 2025 01:36:16 -0400 Subject: [PATCH 12/82] mangohud: hardcode libGL & libX11 --- pkgs/tools/graphics/mangohud/default.nix | 5 +++- .../mangohud/hardcode-dependencies.patch | 27 ++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/pkgs/tools/graphics/mangohud/default.nix b/pkgs/tools/graphics/mangohud/default.nix index cba3c24f70d8..b565ce52b92c 100644 --- a/pkgs/tools/graphics/mangohud/default.nix +++ b/pkgs/tools/graphics/mangohud/default.nix @@ -10,6 +10,8 @@ gnused, xdg-utils, dbus, + libGL, + libX11, hwdata, mangohud32, addDriverRunpath, @@ -20,7 +22,6 @@ ninja, pkg-config, unzip, - libX11, wayland, libXNVCtrl, nlohmann_json, @@ -138,6 +139,8 @@ stdenv.mkDerivation (finalAttrs: { ]; libdbus = dbus.lib; + libGL = libGL; + libX11 = libX11; inherit hwdata; }) ]; diff --git a/pkgs/tools/graphics/mangohud/hardcode-dependencies.patch b/pkgs/tools/graphics/mangohud/hardcode-dependencies.patch index c19b2081c97f..14589826208d 100644 --- a/pkgs/tools/graphics/mangohud/hardcode-dependencies.patch +++ b/pkgs/tools/graphics/mangohud/hardcode-dependencies.patch @@ -11,8 +11,33 @@ index 7379af1..4eef3fe 100644 SPDLOG_ERROR("Could not load libdbus-1.so.3"); return false; } +diff --git a/src/loaders/loader_glx.cpp b/src/loaders/loader_glx.cpp +index aa453b8..0f6479d 100644 +--- a/src/loaders/loader_glx.cpp ++++ b/src/loaders/loader_glx.cpp +@@ -23,7 +23,7 @@ bool glx_loader::Load() { + handle = real_dlopen("glxtrace.so", RTLD_LAZY); + #endif + if (!handle) +- handle = real_dlopen("libGL.so.1", RTLD_LAZY); ++ handle = real_dlopen("@libGL@/lib/libGL.so.1", RTLD_LAZY); + if (!handle) { + SPDLOG_ERROR("Failed to open " MANGOHUD_ARCH " libGL.so.1: {}", dlerror()); + return false; +diff --git a/src/loaders/loader_x11.cpp b/src/loaders/loader_x11.cpp +index 214fd50..2f08857 100644 +--- a/src/loaders/loader_x11.cpp ++++ b/src/loaders/loader_x11.cpp +@@ -110,6 +110,6 @@ static std::shared_ptr loader; + std::shared_ptr get_libx11() + { + if (!loader) +- loader = std::make_shared("libX11.so.6"); ++ loader = std::make_shared("@libX11@/lib/libX11.so.6"); + return loader; + } diff --git a/src/logging.cpp b/src/logging.cpp -index ca986d4..c4d99ea 100644 +index 4ef7023..e24f6da 100644 --- a/src/logging.cpp +++ b/src/logging.cpp @@ -28,8 +28,12 @@ string exec(string command) { From a6826b41036446fd2e66e0af48c88e2eaef6585f Mon Sep 17 00:00:00 2001 From: June Stepp Date: Sat, 3 May 2025 22:44:07 -0500 Subject: [PATCH 13/82] anki: add withAddons `anki.withAddons` creates a wrapped version of Anki with all the addons provided to the function installed. --- pkgs/games/anki/addons/anki-utils.nix | 126 ++++++++++++++++++ pkgs/games/anki/addons/default.nix | 6 + pkgs/games/anki/default.nix | 5 + .../patches/allow-setting-addons-folder.patch | 15 +++ pkgs/games/anki/with-addons.nix | 107 +++++++++++++++ pkgs/top-level/all-packages.nix | 2 + 6 files changed, 261 insertions(+) create mode 100644 pkgs/games/anki/addons/anki-utils.nix create mode 100644 pkgs/games/anki/addons/default.nix create mode 100644 pkgs/games/anki/patches/allow-setting-addons-folder.patch create mode 100644 pkgs/games/anki/with-addons.nix diff --git a/pkgs/games/anki/addons/anki-utils.nix b/pkgs/games/anki/addons/anki-utils.nix new file mode 100644 index 000000000000..e2247ebac874 --- /dev/null +++ b/pkgs/games/anki/addons/anki-utils.nix @@ -0,0 +1,126 @@ +{ + lib, + stdenv, + symlinkJoin, + lndir, + formats, + runCommand, +}: +{ + buildAnkiAddon = lib.extendMkDerivation { + constructDrv = stdenv.mkDerivation; + extendDrvArgs = + finalAttrs: + { + pname, + version, + src, + sourceRoot ? "", + configurePhase ? '' + runHook preConfigure + runHook postConfigure + '', + buildPhase ? '' + runHook preBuild + runHook postBuild + '', + dontPatchELF ? true, + dontStrip ? true, + nativeBuildInputs ? [ ], + passthru ? { }, + meta ? { }, + # Script run after "user_files" folder is populated. + # Used when an add-on needs to process and change "user_files" based + # on what the user added to it. + processUserFiles ? "", + ... + }: + { + inherit + version + src + sourceRoot + configurePhase + buildPhase + dontPatchELF + dontStrip + nativeBuildInputs + ; + + pname = "anki-addon-${pname}"; + + installPrefix = "share/anki/addons/${pname}"; + + installPhase = '' + runHook preInstall + + mkdir -p "$out/$installPrefix" + find . -mindepth 1 -maxdepth 1 | xargs -d'\n' mv -t "$out/$installPrefix/" + + runHook postInstall + ''; + + passthru = { + withConfig = + { + # JSON add-on config. The available options for an add-on are in its + # config.json file. + # See https://addon-docs.ankiweb.net/addon-config.html#config-json + config ? { }, + # Path to a folder to be merged with the add-on "user_files" folder. + # See https://addon-docs.ankiweb.net/addon-config.html#user-files. + userFiles ? null, + }: + let + metaConfigFormat = formats.json { }; + addonMetaConfig = metaConfigFormat.generate "meta.json" { inherit config; }; + in + symlinkJoin { + pname = "${finalAttrs.pname}-with-config"; + inherit (finalAttrs) version meta; + + paths = [ + finalAttrs.finalPackage + ]; + + postBuild = '' + cd $out/${finalAttrs.installPrefix} + + rm -f meta.json + ln -s ${addonMetaConfig} meta.json + + mkdir -p user_files + ${ + if (userFiles != null) then + '' + ${lndir}/bin/lndir -silent "${userFiles}" user_files + '' + else + "" + } + + ${processUserFiles} + ''; + }; + } // passthru; + + meta = { + platforms = lib.platforms.all; + } // meta; + }; + }; + + buildAnkiAddonsDir = + addonPackages: + let + addonDirs = map (pkg: "${pkg}/share/anki/addons") addonPackages; + addons = lib.concatMapStringsSep " " (p: "${p}/*") addonDirs; + in + runCommand "anki-addons" { } '' + mkdir $out + [[ '${addons}' ]] || exit 0 + for addon in ${addons}; do + ln -s "$addon" $out/ + done + ''; +} diff --git a/pkgs/games/anki/addons/default.nix b/pkgs/games/anki/addons/default.nix new file mode 100644 index 000000000000..e4090644a690 --- /dev/null +++ b/pkgs/games/anki/addons/default.nix @@ -0,0 +1,6 @@ +{ + callPackage, +}: +{ + +} diff --git a/pkgs/games/anki/default.nix b/pkgs/games/anki/default.nix index 8e1d69a26acf..3025afbe092d 100644 --- a/pkgs/games/anki/default.nix +++ b/pkgs/games/anki/default.nix @@ -10,6 +10,7 @@ lame, mpv-unwrapped, ninja, + callPackage, nixosTests, nodejs, nodejs-slim, @@ -129,6 +130,8 @@ python3.pkgs.buildPythonApplication { ./patches/disable-auto-update.patch ./patches/remove-the-gl-library-workaround.patch ./patches/skip-formatting-python-code.patch + # Used in with-addons.nix + ./patches/allow-setting-addons-folder.patch ]; inherit cargoDeps yarnOfflineCache; @@ -301,6 +304,7 @@ python3.pkgs.buildPythonApplication { ''; passthru = { + withAddons = ankiAddons: callPackage ./with-addons.nix { inherit ankiAddons; }; tests.anki-sync-server = nixosTests.anki-sync-server; }; @@ -324,6 +328,7 @@ python3.pkgs.buildPythonApplication { inherit (mesa.meta) platforms; maintainers = with maintainers; [ euank + junestepp oxij ]; # Reported to crash at launch on darwin (as of 2.1.65) diff --git a/pkgs/games/anki/patches/allow-setting-addons-folder.patch b/pkgs/games/anki/patches/allow-setting-addons-folder.patch new file mode 100644 index 000000000000..12f7846267d5 --- /dev/null +++ b/pkgs/games/anki/patches/allow-setting-addons-folder.patch @@ -0,0 +1,15 @@ +diff --git a/qt/aqt/profiles.py b/qt/aqt/profiles.py +index 469908c1b2..34612d6e08 100644 +--- a/qt/aqt/profiles.py ++++ b/qt/aqt/profiles.py +@@ -310,7 +310,9 @@ def profileFolder(self, create: bool = True) -> str: + return path + + def addonFolder(self) -> str: +- return self._ensureExists(os.path.join(self.base, "addons21")) ++ path = Path(os.environ.get("ANKI_ADDONS") or Path(self.base) / "addons21") ++ path.mkdir(parents=True, exist_ok=True) ++ return str(path.resolve()) + + def backupFolder(self) -> str: + return self._ensureExists(os.path.join(self.profileFolder(), "backups")) diff --git a/pkgs/games/anki/with-addons.nix b/pkgs/games/anki/with-addons.nix new file mode 100644 index 000000000000..d47c2c16f316 --- /dev/null +++ b/pkgs/games/anki/with-addons.nix @@ -0,0 +1,107 @@ +{ + lib, + symlinkJoin, + makeWrapper, + anki, + anki-utils, + writeTextDir, + ankiAddons ? [ ], +}: +/* + `ankiAddons` + : A set of Anki add-ons to be installed. Here's a an example: + + ~~~ + pkgs.anki.withAddons [ + # When the add-on is already available in nixpkgs + pkgs.ankiAddons.anki-connect + + # When the add-on is not available in nixpkgs + (pkgs.anki-utils.buildAnkiAddon (finalAttrs: { + pname = "recolor"; + version = "3.1"; + src = pkgs.fetchFromGitHub { + owner = "AnKing-VIP"; + repo = "AnkiRecolor"; + rev = finalAttrs.version; + sparseCheckout = [ "src/addon" ]; + hash = "sha256-28DJq2l9DP8O6OsbNQCZ0pm4S6CQ3Yz0Vfvlj+iQw8Y="; + }; + sourceRoot = "source/src/addon"; + })) + + # When the add-on needs to be configured + pkgs.ankiAddons.passfail2.withConfig { + config = { + again_button_name = "not quite"; + good_button_name = "excellent"; + }; + + user_files = ./dir-to-be-merged-into-addon-user-files-dir; + }; + ] + ~~~ + + The original `anki` executable will be wrapped so that it uses the addons from + `ankiAddons`. + + This only works with Anki versions patched to support the `ANKI_ADDONS` environment + variable. `pkgs.anki` has this, but `pkgs.anki-bin` does not. +*/ +let + defaultAddons = [ + (anki-utils.buildAnkiAddon { + pname = "nixos"; + version = "1.0"; + src = writeTextDir "__init__.py" '' + import aqt + from aqt.qt import QMessageBox + import json + + def addons_dialog_will_show(dialog: aqt.addons.AddonsDialog) -> None: + dialog.setEnabled(False) + QMessageBox.information( + dialog, + "NixOS Info", + ("These add-ons are managed by NixOS.
" + "See " + "github.com/NixOS/nixpkgs/tree/master/pkgs/games/anki/with-addons.nix") + ) + + def addon_tried_to_write_config(module: str, conf: dict) -> None: + message_box = QMessageBox( + QMessageBox.Icon.Warning, + "NixOS Info", + (f"The add-on module: \"{module}\" tried to update its config.
" + "See " + "github.com/NixOS/nixpkgs/tree/master/pkgs/games/anki/with-addons.nix" + " for how to configure add-ons managed by NixOS.") + ) + message_box.setDetailedText(json.dumps(conf)) + message_box.exec() + + aqt.gui_hooks.addons_dialog_will_show.append(addons_dialog_will_show) + aqt.mw.addonManager.writeConfig = addon_tried_to_write_config + ''; + meta.maintainers = with lib.maintainers; [ junestepp ]; + }) + ]; +in +symlinkJoin { + inherit (anki) version; + pname = "${anki.pname}-with-addons"; + + paths = [ anki ]; + + nativeBuildInputs = [ makeWrapper ]; + postBuild = '' + wrapProgram $out/bin/anki \ + --set ANKI_ADDONS "${anki-utils.buildAnkiAddonsDir (ankiAddons ++ defaultAddons)}" + ''; + + meta = builtins.removeAttrs anki.meta [ + "name" + "outputsToInstall" + "position" + ]; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 21affad468e6..0907a7424602 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -14902,6 +14902,8 @@ with pkgs; amoeba-data = callPackage ../games/amoeba/data.nix { }; anki = callPackage ../games/anki { }; + anki-utils = callPackage ../games/anki/addons/anki-utils.nix { }; + ankiAddons = recurseIntoAttrs (callPackage ../games/anki/addons { }); anki-bin = callPackage ../games/anki/bin.nix { }; anki-sync-server = callPackage ../games/anki/sync-server.nix { }; From b5b252067914513d3df98717be44c32dc99918c5 Mon Sep 17 00:00:00 2001 From: Justin Bedo Date: Fri, 30 May 2025 09:21:28 +1000 Subject: [PATCH 14/82] strobealign: init 0.16.1 --- pkgs/by-name/st/strobealign/package.nix | 38 +++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 pkgs/by-name/st/strobealign/package.nix diff --git a/pkgs/by-name/st/strobealign/package.nix b/pkgs/by-name/st/strobealign/package.nix new file mode 100644 index 000000000000..0dd0a976f512 --- /dev/null +++ b/pkgs/by-name/st/strobealign/package.nix @@ -0,0 +1,38 @@ +{ + stdenv, + lib, + fetchFromGitHub, + cmake, + pkg-config, + isa-l, + zlib, +}: +stdenv.mkDerivation (self: { + pname = "strobealign"; + version = "0.16.1"; + + src = fetchFromGitHub { + owner = "ksahlin"; + repo = "strobealign"; + tag = "v${self.version}"; + hash = "sha256-RZxIT6iwanRuPk2sWv/QRkUaPMdterOKCo30FPZHC8o="; + }; + + nativeBuildInputs = [ + cmake + pkg-config + ]; + buildInputs = [ + zlib + isa-l + ]; + + meta = { + description = "Read aligner for short reads"; + mainProgram = "strobealign"; + license = lib.licenses.mit; + homepage = "https://github.com/ksahlin/strobealign"; + maintainers = [ lib.maintainers.jbedo ]; + platforms = lib.platforms.unix; + }; +}) From d0c2fbd21b465770eb546b4dff6c649656dd1842 Mon Sep 17 00:00:00 2001 From: VuiMuich Date: Fri, 30 May 2025 12:28:44 +0200 Subject: [PATCH 15/82] iwmenu: init at 0.2.0 --- pkgs/by-name/iw/iwmenu/package.nix | 40 ++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 pkgs/by-name/iw/iwmenu/package.nix diff --git a/pkgs/by-name/iw/iwmenu/package.nix b/pkgs/by-name/iw/iwmenu/package.nix new file mode 100644 index 000000000000..e42d3c12c42a --- /dev/null +++ b/pkgs/by-name/iw/iwmenu/package.nix @@ -0,0 +1,40 @@ +{ + dbus, + fetchFromGitHub, + lib, + iwd, + rustPlatform, +}: + +rustPlatform.buildRustPackage rec { + pname = "iwmenu"; + version = "0.2.0"; + + src = fetchFromGitHub { + owner = "e-tho"; + repo = "iwmenu"; + tag = "v${version}"; + hash = "sha256-F1w2Lp0/iXUHh0PXAZ/wD78C2uVtAcWlEKqBI5I/hnE="; + }; + + cargoHash = "sha256-NjA8n11pOytXsotEQurYxDHPhwXG5vpdlyscmVUIzfA="; + + buildInputs = [ + dbus + iwd + ]; + + meta = { + homepage = "https://github.com/e-tho/iwmenu"; + description = "Launcher-driven Wi-Fi manager for Linux"; + longDescription = '' + Use `iwmenu --launcher ` + Supported launchers are: `dmenu`, `fuzzel`, `rofi`, `walker` and `custom` with `stdin` + for details refer to https://github.com/e-tho/iwmenu/blob/main/README.md#usage + ''; + mainProgram = "iwmenu"; + platforms = lib.platforms.linux; + license = lib.licenses.gpl3Plus; + maintainers = with lib.maintainers; [ vuimuich ]; + }; +} From d6adcac86404c9d9ef82dbe898f3b01fcc6dc0cf Mon Sep 17 00:00:00 2001 From: "R. Ryantm" Date: Sun, 1 Jun 2025 02:24:12 +0000 Subject: [PATCH 16/82] zsh-forgit: 25.05.0 -> 25.06.0 --- pkgs/by-name/zs/zsh-forgit/package.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/by-name/zs/zsh-forgit/package.nix b/pkgs/by-name/zs/zsh-forgit/package.nix index 646708ebdf1b..222a45ca9fc2 100644 --- a/pkgs/by-name/zs/zsh-forgit/package.nix +++ b/pkgs/by-name/zs/zsh-forgit/package.nix @@ -15,13 +15,13 @@ stdenvNoCC.mkDerivation (finalAttrs: { pname = "zsh-forgit"; - version = "25.05.0"; + version = "25.06.0"; src = fetchFromGitHub { owner = "wfxr"; repo = "forgit"; tag = finalAttrs.version; - hash = "sha256-U+MtgunPEmo/kv/lQI2BBi2WUBgt3wFkaUdfRzJWoGQ="; + hash = "sha256-D1we3pOPXNsK8KgEaRBAmD5eH1i2ud4zX1GwYbOyZvY="; }; strictDeps = true; From 73524f5008f156eaaf521fbc380fc7e8e10daa1f Mon Sep 17 00:00:00 2001 From: "R. Ryantm" Date: Mon, 2 Jun 2025 07:52:06 +0000 Subject: [PATCH 17/82] git-town: 20.2.0 -> 21.0.0 --- pkgs/by-name/gi/git-town/package.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/by-name/gi/git-town/package.nix b/pkgs/by-name/gi/git-town/package.nix index 471f2c3d0ff1..5eca702dc9d6 100644 --- a/pkgs/by-name/gi/git-town/package.nix +++ b/pkgs/by-name/gi/git-town/package.nix @@ -13,13 +13,13 @@ buildGoModule rec { pname = "git-town"; - version = "20.2.0"; + version = "21.0.0"; src = fetchFromGitHub { owner = "git-town"; repo = "git-town"; tag = "v${version}"; - hash = "sha256-q1wiqE2pd1qLw0nTw3CEpJybGia+KwRacgejofk4kJ8="; + hash = "sha256-Wnp3qkF7e358uGftBy5vi3GandyZsAyxESvgUFB7mmM="; }; vendorHash = null; From 74dcbe1cee27642ba5b694821bb4cf8a7e100eb2 Mon Sep 17 00:00:00 2001 From: DontEatOreo <57304299+DontEatOreo@users.noreply.github.com> Date: Sun, 19 Jan 2025 12:25:44 +0200 Subject: [PATCH 18/82] shottr: init at 1.8.1 --- pkgs/by-name/sh/shottr/package.nix | 65 ++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 pkgs/by-name/sh/shottr/package.nix diff --git a/pkgs/by-name/sh/shottr/package.nix b/pkgs/by-name/sh/shottr/package.nix new file mode 100644 index 000000000000..4de63b3f11a3 --- /dev/null +++ b/pkgs/by-name/sh/shottr/package.nix @@ -0,0 +1,65 @@ +{ + lib, + stdenvNoCC, + fetchurl, + writeShellApplication, + cacert, + curl, + common-updater-scripts, + pup, + undmg, +}: + +stdenvNoCC.mkDerivation (finalAttrs: { + pname = "shottr"; + version = "1.8.1"; + + src = fetchurl { + url = "https://shottr.cc/dl/Shottr-${finalAttrs.version}.dmg"; + hash = "sha256-I3LNLuhIRdjKDn79HWRK2B/tVsV+1aGt/aY442y3r2I="; + }; + + nativeBuildInputs = [ undmg ]; + + sourceRoot = "."; + + installPhase = '' + runHook preInstall + + mkdir -p "$out/Applications" + cp -R Shottr.app "$out/Applications" + + mkdir -p "$out/bin" + ln -s "$out/Applications/Shottr.app/Contents/MacOS/Shottr" "$out/bin/shottr" + + runHook postInstall + ''; + + passthru.updateScript = lib.getExe (writeShellApplication { + name = "shottr-update-script"; + runtimeInputs = [ + cacert + common-updater-scripts + curl + pup + ]; + text = '' + version="$(curl -s https://shottr.cc/newversion.html \ + | pup 'a[href*="Shottr-"] attr{href}' \ + | sed -E 's|/dl/Shottr-||' \ + | sed -E 's|\.dmg||')" + update-source-version shottr "$version" + ''; + }); + + meta = { + changelog = "https://shottr.cc/newversion.html"; + description = "MacOS screenshot app with scrolling screenshots, OCR, annotation and measurement instruments"; + homepage = "https://shottr.cc/"; + license = lib.licenses.unfree; + mainProgram = "shottr"; + maintainers = with lib.maintainers; [ donteatoreo ]; + platforms = lib.platforms.darwin; + sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ]; + }; +}) From 365fe8dbe5964d4832c2ba72da3bcfe80a221d3d Mon Sep 17 00:00:00 2001 From: "R. Ryantm" Date: Mon, 2 Jun 2025 18:57:17 +0000 Subject: [PATCH 19/82] sesh: 2.13.0 -> 2.14.0 --- pkgs/by-name/se/sesh/package.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/by-name/se/sesh/package.nix b/pkgs/by-name/se/sesh/package.nix index 2eaa1c09b4d7..98409eb9b19a 100644 --- a/pkgs/by-name/se/sesh/package.nix +++ b/pkgs/by-name/se/sesh/package.nix @@ -5,13 +5,13 @@ }: buildGoModule rec { pname = "sesh"; - version = "2.13.0"; + version = "2.14.0"; src = fetchFromGitHub { owner = "joshmedeski"; repo = "sesh"; rev = "v${version}"; - hash = "sha256-YFvUYacuvyzNXwY+y9kI4tPlrlojDuZpR7VaTGdVqb8="; + hash = "sha256-Dla43xI6y7J9M18IloSm1uDeHAhfslU56Z0Q3nVzjIk="; }; vendorHash = "sha256-3wNp1meUoUFPa2CEgKjuWcu4I6sxta3FPFvCb9QMQhQ="; From af93405bb34e3717f8639b08483631128fceb628 Mon Sep 17 00:00:00 2001 From: Colin Hooper Date: Tue, 3 Jun 2025 15:05:28 +0100 Subject: [PATCH 20/82] brave: set CHROME_WRAPPER to brave --- pkgs/by-name/br/brave/make-brave.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkgs/by-name/br/brave/make-brave.nix b/pkgs/by-name/br/brave/make-brave.nix index 9b098c5213dc..aecc20af7dc2 100644 --- a/pkgs/by-name/br/brave/make-brave.nix +++ b/pkgs/by-name/br/brave/make-brave.nix @@ -205,7 +205,8 @@ stdenv.mkDerivation { # Fix path to bash in $BINARYWRAPPER substituteInPlace $BINARYWRAPPER \ - --replace /bin/bash ${stdenv.shell} + --replace /bin/bash ${stdenv.shell} \ + --replace-fail 'CHROME_WRAPPER' 'WRAPPER' ln -sf $BINARYWRAPPER $out/bin/brave @@ -263,6 +264,7 @@ stdenv.mkDerivation { coreutils ] } + --set CHROME_WRAPPER ${pname} ${optionalString (enableFeatures != [ ]) '' --add-flags "--enable-features=${strings.concatStringsSep "," enableFeatures}\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+,WaylandWindowDecorations --enable-wayland-ime=true}}" ''} From 7b3197bc1d5ed03c305704dfe008ad213e921f1f Mon Sep 17 00:00:00 2001 From: Sarah Clark Date: Tue, 3 Jun 2025 12:30:13 -0700 Subject: [PATCH 21/82] python3Packages.curve25519-donna: remove as obsolete No maintainer, last change in 2015, no dependents. --- .../curve25519-donna/default.nix | 23 ------------------- pkgs/top-level/python-aliases.nix | 1 + pkgs/top-level/python-packages.nix | 2 -- 3 files changed, 1 insertion(+), 25 deletions(-) delete mode 100644 pkgs/development/python-modules/curve25519-donna/default.nix diff --git a/pkgs/development/python-modules/curve25519-donna/default.nix b/pkgs/development/python-modules/curve25519-donna/default.nix deleted file mode 100644 index 8ff358be6905..000000000000 --- a/pkgs/development/python-modules/curve25519-donna/default.nix +++ /dev/null @@ -1,23 +0,0 @@ -{ - lib, - buildPythonPackage, - fetchPypi, -}: - -buildPythonPackage rec { - pname = "curve25519-donna"; - version = "1.3"; - format = "setuptools"; - - src = fetchPypi { - inherit pname version; - sha256 = "1w0vkjyh4ki9n98lr2hg09f1lr1g3pz48kshrlic01ba6pasj60q"; - }; - - meta = with lib; { - description = "Python wrapper for the portable curve25519-donna implementation"; - homepage = "http://code.google.com/p/curve25519-donna/"; - license = licenses.bsd3; - maintainers = [ ]; - }; -} diff --git a/pkgs/top-level/python-aliases.nix b/pkgs/top-level/python-aliases.nix index ae174ee65244..edfdea7789a9 100644 --- a/pkgs/top-level/python-aliases.nix +++ b/pkgs/top-level/python-aliases.nix @@ -166,6 +166,7 @@ mapAliases ({ cryptacular = throw "cryptacular was removed, because it was disabled on all python version since 3.6 and last updated in 2021"; # Added 2024-05-13 cryptography_vectors = "cryptography_vectors is no longer exposed in python*Packages because it is used for testing cryptography only."; # Added 2022-03-23 cufflinks = throw "cufflinks has removed, since it is abandoned and broken"; # added 2025-02-16 + curve25519-donna = throw "curve25519-donna was removed, since it is abandoned and unmaintained since 2015"; # added 2025-06-03 cx_Freeze = cx-freeze; # added 2023-08-02 cx_oracle = cx-oracle; # added 2024-01-03 d2to1 = throw "d2to1 is archived and no longer works with setuptools v68"; # added 2023-07-30 diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 3aad48eeb4c9..0c0ebf216344 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -3078,8 +3078,6 @@ self: super: with self; { curtsies = callPackage ../development/python-modules/curtsies { }; - curve25519-donna = callPackage ../development/python-modules/curve25519-donna { }; - curvefitgui = callPackage ../development/python-modules/curvefitgui { }; customtkinter = callPackage ../development/python-modules/customtkinter { }; From 78c34e97c66149fa8266cf83e668b7e296e1d4cc Mon Sep 17 00:00:00 2001 From: Jacob Koziej Date: Tue, 3 Jun 2025 21:09:34 -0400 Subject: [PATCH 22/82] boring: init at 0.11.4 --- pkgs/by-name/bo/boring/package.nix | 56 ++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 pkgs/by-name/bo/boring/package.nix diff --git a/pkgs/by-name/bo/boring/package.nix b/pkgs/by-name/bo/boring/package.nix new file mode 100644 index 000000000000..4ba545f08c5f --- /dev/null +++ b/pkgs/by-name/bo/boring/package.nix @@ -0,0 +1,56 @@ +{ + boring, + buildGoModule, + fetchFromGitHub, + installShellFiles, + lib, + stdenv, + testers, +}: + +buildGoModule (finalAttrs: { + pname = "boring"; + version = "0.11.4"; + + src = fetchFromGitHub { + owner = "alebeck"; + repo = "boring"; + tag = finalAttrs.version; + hash = "sha256-N0GVXtw6Gp6iHKBD2Lk6FX8XaUnkPgZduPaczYdApAs="; + }; + + nativeBuildInputs = [ + installShellFiles + ]; + + vendorHash = "sha256-j8A0F+o3EnzJdge+T/gHAwRGwzC86oD6ddZejUs/C7o="; + + ldflags = [ + "-s" + "-w" + "-X main.version=${finalAttrs.version}" + ]; + + postInstall = lib.optionalString (stdenv.buildPlatform.canExecute stdenv.hostPlatform) '' + installShellCompletion --cmd boring \ + --bash <($out/bin/boring --shell bash) \ + --fish <($out/bin/boring --shell fish) \ + --zsh <($out/bin/boring --shell zsh) + ''; + + passthru.tests.version = testers.testVersion { + package = boring; + command = "boring version"; + version = "boring ${finalAttrs.version}"; + }; + + meta = { + description = "SSH tunnel manager"; + homepage = "https://github.com/alebeck/boring"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ + jacobkoziej + ]; + mainProgram = "boring"; + }; +}) From 5356518e99f80f6e5abcfe1d671bb8619cb71a69 Mon Sep 17 00:00:00 2001 From: SkohTV Date: Wed, 4 Jun 2025 13:17:11 +0200 Subject: [PATCH 23/82] minizincide: add desktop file --- pkgs/development/tools/minizinc/ide.nix | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pkgs/development/tools/minizinc/ide.nix b/pkgs/development/tools/minizinc/ide.nix index 13e26ff9d44b..53d8bcd9ce2e 100644 --- a/pkgs/development/tools/minizinc/ide.nix +++ b/pkgs/development/tools/minizinc/ide.nix @@ -7,6 +7,8 @@ qtwebsockets, minizinc, makeWrapper, + copyDesktopItems, + makeDesktopItem, }: let @@ -31,12 +33,30 @@ stdenv.mkDerivation rec { nativeBuildInputs = [ qmake makeWrapper + copyDesktopItems ]; buildInputs = [ qtbase qtwebsockets ]; + desktopItems = [ + (makeDesktopItem { + name = "minizinc"; + desktopName = "MiniZincIDE"; + icon = "minizinc"; + comment = meta.description; + exec = "MiniZincIDE"; + type = "Application"; + terminal = false; + categories = [ + "Science" + "Development" + "Education" + ]; + }) + ]; + sourceRoot = "${src.name}/MiniZincIDE"; dontWrapQtApps = true; From 4e69dca94536351974d672d821e8050291ceb73e Mon Sep 17 00:00:00 2001 From: Ethan Carter Edwards Date: Wed, 4 Jun 2025 08:57:30 -0400 Subject: [PATCH 24/82] lillydap: fix update script In response to: https://github.com/NixOS/nixpkgs/pull/413888 Signed-off-by: Ethan Carter Edwards --- pkgs/by-name/li/lillydap/package.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/by-name/li/lillydap/package.nix b/pkgs/by-name/li/lillydap/package.nix index d095f3a4a8ca..115673095020 100644 --- a/pkgs/by-name/li/lillydap/package.nix +++ b/pkgs/by-name/li/lillydap/package.nix @@ -6,7 +6,7 @@ gperf, arpa2cm, quickder, - nix-update-script, + gitUpdater, }: stdenv.mkDerivation (finalAttrs: { @@ -32,7 +32,7 @@ stdenv.mkDerivation (finalAttrs: { quickder ]; - passthru.updateScript = nix-update-script { }; + passthru.updateScript = gitUpdater { rev-prefix = "v"; }; meta = { description = "Little LDAP: Event-driven, lock-free kernel for dynamic data servers, clients, filters"; From 11930b4e1eea595b9ff130cb573816e8c6399a5b Mon Sep 17 00:00:00 2001 From: Francesco Gazzetta Date: Thu, 5 Jun 2025 13:48:07 +0200 Subject: [PATCH 25/82] ladybird: 0-unstable-2025-05-24 -> 0-unstable-2025-06-03 --- .../la/ladybird/001-revert-fake-skia-update.patch | 13 ------------- pkgs/by-name/la/ladybird/package.nix | 15 ++++----------- 2 files changed, 4 insertions(+), 24 deletions(-) delete mode 100644 pkgs/by-name/la/ladybird/001-revert-fake-skia-update.patch diff --git a/pkgs/by-name/la/ladybird/001-revert-fake-skia-update.patch b/pkgs/by-name/la/ladybird/001-revert-fake-skia-update.patch deleted file mode 100644 index 257fa212fc55..000000000000 --- a/pkgs/by-name/la/ladybird/001-revert-fake-skia-update.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/vcpkg.json b/vcpkg.json -index 5a824884b2..e4193aa45f 100644 ---- a/vcpkg.json -+++ b/vcpkg.json -@@ -199,7 +199,7 @@ - }, - { - "name": "skia", -- "version": "134#2" -+ "version": "129#0" - }, - { - "name": "sqlite3", diff --git a/pkgs/by-name/la/ladybird/package.nix b/pkgs/by-name/la/ladybird/package.nix index 45cc7bd1b20d..7c054e74e004 100644 --- a/pkgs/by-name/la/ladybird/package.nix +++ b/pkgs/by-name/la/ladybird/package.nix @@ -38,22 +38,15 @@ let in stdenv.mkDerivation (finalAttrs: { pname = "ladybird"; - version = "0-unstable-2025-05-24"; + version = "0-unstable-2025-06-03"; src = fetchFromGitHub { owner = "LadybirdWebBrowser"; repo = "ladybird"; - rev = "fbd1f771613fc6f13fcc20dcad04c7065633a2c2"; - hash = "sha256-Gtfnq46JrzfpcapMr6Ez+5BNQ59H/Djsgp7n6QvMSUM="; + rev = "4c54a28c45be4e8185158d40a37e083e038a6465"; + hash = "sha256-YHWkG2RJk6NaouRvis2L+njtYWKB7T569y1Tq+mYdz0="; }; - patches = [ - # Revert https://github.com/LadybirdBrowser/ladybird/commit/51d189198d3fc61141fc367dc315c7f50492a57e - # This commit doesn't update the skia used by ladybird vcpkg, but it does update the skia that - # that cmake wants. - ./001-revert-fake-skia-update.patch - ]; - postPatch = '' sed -i '/iconutil/d' UI/CMakeLists.txt @@ -146,7 +139,7 @@ stdenv.mkDerivation (finalAttrs: { # ld: [...]/OESVertexArrayObject.cpp.o: undefined reference to symbol 'glIsVertexArrayOES' # ld: [...]/libGL.so.1: error adding symbols: DSO missing from command line # https://github.com/LadybirdBrowser/ladybird/issues/371#issuecomment-2616415434 - env.NIX_LDFLAGS = "-lGL"; + env.NIX_LDFLAGS = "-lGL -lfontconfig"; postInstall = lib.optionalString stdenv.hostPlatform.isDarwin '' mkdir -p $out/Applications $out/bin From cb645ca716cca6e976b988c5949aae4c7fd80bf3 Mon Sep 17 00:00:00 2001 From: transcaffeine Date: Sat, 24 May 2025 16:30:43 +0200 Subject: [PATCH 26/82] element-web-unwrapped: 1.11.100 -> 1.11.102 Release notes: - https://github.com/element-hq/element-web/releases/tag/v1.11.101 - https://github.com/element-hq/element-web/releases/tag/v1.11.102 Changelog: https://github.com/element-hq/element-web/compare/v1.11.100...v1.11.102 --- pkgs/by-name/el/element-web-unwrapped/element-web-pin.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/by-name/el/element-web-unwrapped/element-web-pin.nix b/pkgs/by-name/el/element-web-unwrapped/element-web-pin.nix index 2fb0517243dc..bf3c641d42d4 100644 --- a/pkgs/by-name/el/element-web-unwrapped/element-web-pin.nix +++ b/pkgs/by-name/el/element-web-unwrapped/element-web-pin.nix @@ -1,7 +1,7 @@ { - "version" = "1.11.100"; + "version" = "1.11.102"; "hashes" = { - "webSrcHash" = "sha256-FiYjWOJ50Vhbs9vgEqK64HTVtwSuy4/BZAkPK4c6DXQ="; - "webYarnHash" = "sha256-C1yVJHU9ClTJHQfMLkdZEeRWVVu68eJp2kxnIlLinY8="; + "webSrcHash" = "sha256-B21fBRcksX8MoyWiqf1sa9yowJ/Z/wcM3vEqslunv7A="; + "webYarnHash" = "sha256-NXoGMEJM4uxFMCb5YX0ue9hgxe22hzG0MTeAOaBrJO4="; }; } From 84458a3fcd32fe1119ee8899098938334fecd08e Mon Sep 17 00:00:00 2001 From: transcaffeine Date: Sat, 24 May 2025 16:46:33 +0200 Subject: [PATCH 27/82] element-desktop: 1.11.110 -> 1.11.102 Release notes: - https://github.com/element-hq/element-desktop/releases/tag/v1.11.101 - https://github.com/element-hq/element-desktop/releases/tag/v1.11.102 Changelog: https://github.com/element-hq/element-desktop/compare/v1.11.100...v1.11.102 Updates electron from 35 to 36. Re-introduces the same mechanism for the yarnOfflineCache as #381196, as the problem described in there is back again. --- .../element-desktop/element-desktop-pin.nix | 6 +-- pkgs/by-name/el/element-desktop/package.nix | 33 +++++++++++----- pkgs/by-name/el/element-desktop/yarn.nix | 38 +++++++++++++++++++ 3 files changed, 65 insertions(+), 12 deletions(-) create mode 100644 pkgs/by-name/el/element-desktop/yarn.nix diff --git a/pkgs/by-name/el/element-desktop/element-desktop-pin.nix b/pkgs/by-name/el/element-desktop/element-desktop-pin.nix index 1a72d1488ab6..178e8c7b5ce6 100644 --- a/pkgs/by-name/el/element-desktop/element-desktop-pin.nix +++ b/pkgs/by-name/el/element-desktop/element-desktop-pin.nix @@ -1,7 +1,7 @@ { - "version" = "1.11.100"; + "version" = "1.11.102"; "hashes" = { - "desktopSrcHash" = "sha256-qlKZkBPWcD1eyEetCrIKsSXmodg6DYCmENfY+UT7Khc="; - "desktopYarnHash" = "sha256-wuRAeb4IpA2Ihr3ohaMPvFsaMod4Bg8o9lm8yzStwmk="; + "desktopSrcHash" = "sha256-wefoN8Nk31lwJFYbBRoKfy+0n69yVg6jskqP6aTHApE="; + "desktopYarnHash" = "sha256-/Gy/sYk8EBWU07zXwPl0zsDW5ADRq1j5PH4lPFe8dxk="; }; } diff --git a/pkgs/by-name/el/element-desktop/package.nix b/pkgs/by-name/el/element-desktop/package.nix index 84a743771187..d6436f36b6a0 100644 --- a/pkgs/by-name/el/element-desktop/package.nix +++ b/pkgs/by-name/el/element-desktop/package.nix @@ -4,15 +4,15 @@ fetchFromGitHub, makeWrapper, makeDesktopItem, - yarnConfigHook, + yarn, nodejs, - fetchYarnDeps, jq, - electron_35, + electron_36, element-web, sqlcipher, callPackage, desktopToDarwinBundle, + typescript, useKeytar ? true, # command line arguments which are always set commandLineArgs ? "", @@ -22,7 +22,7 @@ let pinData = import ./element-desktop-pin.nix; inherit (pinData.hashes) desktopSrcHash desktopYarnHash; executableName = "element-desktop"; - electron = electron_35; + electron = electron_36; keytar = callPackage ./keytar { inherit electron; }; @@ -41,16 +41,22 @@ stdenv.mkDerivation ( hash = desktopSrcHash; }; - offlineCache = fetchYarnDeps { - yarnLock = finalAttrs.src + "/yarn.lock"; - sha256 = desktopYarnHash; + # TODO: fetchYarnDeps currently does not deal properly with a dependency + # declared as a pin to a commit in a specific git repository. + # While it does download everything correctly, `yarn install --offline` + # always wants to `git ls-remote` to the repository, ignoring the local + # cached tarball. + offlineCache = callPackage ./yarn.nix { + inherit (finalAttrs) version src; + hash = desktopYarnHash; }; nativeBuildInputs = [ - yarnConfigHook nodejs makeWrapper jq + yarn + typescript ] ++ lib.optionals stdenv.hostPlatform.isDarwin [ desktopToDarwinBundle ]; inherit seshat; @@ -60,13 +66,21 @@ stdenv.mkDerivation ( # this shouldn't be in the closure just for unused scripts. dontPatchShebangs = true; + configurePhase = '' + mkdir -p node_modules/ + cp -r $offlineCache/node_modules/* node_modules/ + substituteInPlace package.json --replace-fail "tsx " "node node_modules/tsx/dist/cli.mjs " + ''; + buildPhase = '' runHook preBuild yarn --offline run build:ts - yarn --offline run i18n + node node_modules/matrix-web-i18n/scripts/gen-i18n.js + yarn --offline run i18n:sort yarn --offline run build:res + chmod -R a+w node_modules/keytar-forked rm -rf node_modules/matrix-seshat node_modules/keytar-forked ${lib.optionalString useKeytar "ln -s ${keytar} node_modules/keytar-forked"} ln -s $seshat node_modules/matrix-seshat @@ -82,6 +96,7 @@ stdenv.mkDerivation ( ln -s '${element-web}' "$out/share/element/webapp" cp -r '.' "$out/share/element/electron" cp -r './res/img' "$out/share/element" + chmod -R "a+w" "$out/share/element/electron/node_modules" rm -rf "$out/share/element/electron/node_modules" cp -r './node_modules' "$out/share/element/electron" cp $out/share/element/electron/lib/i18n/strings/en_EN.json $out/share/element/electron/lib/i18n/strings/en-us.json diff --git a/pkgs/by-name/el/element-desktop/yarn.nix b/pkgs/by-name/el/element-desktop/yarn.nix new file mode 100644 index 000000000000..5a1274349537 --- /dev/null +++ b/pkgs/by-name/el/element-desktop/yarn.nix @@ -0,0 +1,38 @@ +{ + stdenvNoCC, + yarn, + cacert, + git, + version, + src, + hash, +}: +stdenvNoCC.mkDerivation { + pname = "element-desktop-yarn-deps"; + inherit version src; + + nativeBuildInputs = [ + cacert + yarn + git + ]; + + dontInstall = true; + + NODE_EXTRA_CA_CERTS = "${cacert}/etc/ssl/certs/ca-bundle.crt"; + + buildPhase = '' + export HOME=$(mktemp -d) + export YARN_ENABLE_TELEMETRY=0 + + yarn install --frozen-lockfile --ignore-platform --skip-integrity-check --ignore-scripts --no-progress --non-interactive + + mkdir -p $out/node_modules + cp -r node_modules/* $out/node_modules/ + ''; + + dontPatchShebangs = true; + + outputHash = hash; + outputHashMode = "recursive"; +} From 3ff8082ba9845184c09bd5929569e46c40c75483 Mon Sep 17 00:00:00 2001 From: Nadir Ishiguro <23151917+nadir-ishiguro@users.noreply.github.com> Date: Fri, 6 Jun 2025 16:12:31 +0200 Subject: [PATCH 28/82] kopia-ui: 0.20.0 -> 0.20.1 Changelogs: - https://github.com/kopia/kopia/releases/tag/v0.20.1 --- pkgs/by-name/ko/kopia-ui/fix-paths.patch | 75 +++++++++++++++--------- pkgs/by-name/ko/kopia-ui/package.nix | 6 +- 2 files changed, 51 insertions(+), 30 deletions(-) diff --git a/pkgs/by-name/ko/kopia-ui/fix-paths.patch b/pkgs/by-name/ko/kopia-ui/fix-paths.patch index 22744100099e..8086285f0df4 100644 --- a/pkgs/by-name/ko/kopia-ui/fix-paths.patch +++ b/pkgs/by-name/ko/kopia-ui/fix-paths.patch @@ -1,42 +1,63 @@ diff --git a/public/utils.js b/public/utils.js -index 3cd38b63..54152694 100644 +index c5963e41..30f72965 100644 --- a/public/utils.js +++ b/public/utils.js -@@ -17,7 +17,7 @@ const osShortName = function () { +@@ -17,7 +17,7 @@ const osShortName = (function () { export function iconsPath() { - if (!app.isPackaged) { -- return path.join(__dirname, "..", "resources", osShortName, "icons"); -+ return path.join(__dirname, "..", "..", "icons"); - } + if (!app.isPackaged) { +- return path.join(__dirname, "..", "resources", osShortName, "icons"); ++ return path.join(__dirname, "..", "..", "icons"); + } - return path.join(process.resourcesPath, "icons"); -@@ -25,26 +25,14 @@ export function iconsPath() { + return path.join(process.resourcesPath, "icons"); +@@ -25,47 +25,14 @@ export function iconsPath() { export function publicPath() { - if (!app.isPackaged) { -- return path.join(__dirname, "..", "public"); -+ return path.join(__dirname, "..", "..", "public"); - } + if (!app.isPackaged) { +- return path.join(__dirname, "..", "public"); ++ return path.join(__dirname, "..", "..", "public"); + } - return process.resourcesPath; + return process.resourcesPath; } export function defaultServerBinary() { -- if (!app.isPackaged) { -- return { -- "mac": path.join(__dirname, "..", "..", "dist", "kopia_darwin_amd64", "kopia"), -- "win": path.join(__dirname, "..", "..", "dist", "kopia_windows_amd64", "kopia.exe"), -- "linux": path.join(__dirname, "..", "..", "dist", "kopia_linux_amd64", "kopia"), -- }[osShortName] -- } -- +- if (!app.isPackaged) { - return { -- "mac": path.join(process.resourcesPath, "server", "kopia"), -- "win": path.join(process.resourcesPath, "server", "kopia.exe"), -- "linux": path.join(process.resourcesPath, "server", "kopia"), -- }[osShortName] -+ return "KOPIA" +- mac: path.join( +- __dirname, +- "..", +- "..", +- "dist", +- "kopia_darwin_amd64", +- "kopia", +- ), +- win: path.join( +- __dirname, +- "..", +- "..", +- "dist", +- "kopia_windows_amd64", +- "kopia.exe", +- ), +- linux: path.join( +- __dirname, +- "..", +- "..", +- "dist", +- "kopia_linux_amd64", +- "kopia", +- ), +- }[osShortName]; +- } +- +- return { +- mac: path.join(process.resourcesPath, "server", "kopia"), +- win: path.join(process.resourcesPath, "server", "kopia.exe"), +- linux: path.join(process.resourcesPath, "server", "kopia"), +- }[osShortName]; ++ return "KOPIA"; } export function selectByOS(x) { - return x[osShortName] + return x[osShortName]; diff --git a/pkgs/by-name/ko/kopia-ui/package.nix b/pkgs/by-name/ko/kopia-ui/package.nix index 3becaeac4ecd..989146e16853 100644 --- a/pkgs/by-name/ko/kopia-ui/package.nix +++ b/pkgs/by-name/ko/kopia-ui/package.nix @@ -10,12 +10,12 @@ kopia, }: let - version = "0.20.0"; + version = "0.20.1"; src = fetchFromGitHub { owner = "kopia"; repo = "kopia"; tag = "v${version}"; - hash = "sha256-AM9Mpy+9ZCvEtFtzYC87vqCNpLxO+yWVd4th9DDQ2QI="; + hash = "sha256-hKtrHv7MQjA/AQ/frjP2tPT6zqVPPGnBxYuhWtUgIl0="; }; in buildNpmPackage { @@ -24,7 +24,7 @@ buildNpmPackage { sourceRoot = "${src.name}/app"; - npmDepsHash = "sha256-FXPfZnqpuI6NgHk81HEJ7Hj8xCpXD0BKJgFeQ/Oce04="; + npmDepsHash = "sha256-5gXM5aLsUsJhxbt6IKY4Sg4SBI9ATe248K1TyZThg/0="; makeCacheWritable = true; nativeBuildInputs = [ From d494acad37d085063620360962402982ad26d500 Mon Sep 17 00:00:00 2001 From: "R. Ryantm" Date: Sat, 7 Jun 2025 09:23:32 +0000 Subject: [PATCH 29/82] storj-uplink: 1.128.4 -> 1.130.6 --- pkgs/by-name/st/storj-uplink/package.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/by-name/st/storj-uplink/package.nix b/pkgs/by-name/st/storj-uplink/package.nix index 30c770ea82a9..b1bcb44831eb 100644 --- a/pkgs/by-name/st/storj-uplink/package.nix +++ b/pkgs/by-name/st/storj-uplink/package.nix @@ -6,18 +6,18 @@ buildGoModule rec { pname = "storj-uplink"; - version = "1.128.4"; + version = "1.130.6"; src = fetchFromGitHub { owner = "storj"; repo = "storj"; rev = "v${version}"; - hash = "sha256-7CH//aZ7DOXIP6A1gAZpiFO55LrLtBhvtZl/tVhYl8g="; + hash = "sha256-5IFMIiDP+HmR/yc7OQjs23lO5Cw12lZBsD8oIo2CaLE="; }; subPackages = [ "cmd/uplink" ]; - vendorHash = "sha256-CTcFTEKj5s43OlrIC7lOh3Lh/6k8/Igckv0zwrdGKbE="; + vendorHash = "sha256-PnRnnl3uFs889eYQbD+oNvDtJgNepNIJ90KTjnGthI8="; ldflags = [ "-s" From 165ad6efdc86942cb7a0639549b5fdd970c4cc4c Mon Sep 17 00:00:00 2001 From: rnhmjoj Date: Sat, 7 Jun 2025 16:12:28 +0200 Subject: [PATCH 30/82] cie-middleware-linux: 1.5.6 -> 1.5.9 --- .../by-name/ci/cie-middleware-linux/deps.json | 138 +++---- .../ci/cie-middleware-linux/package.nix | 13 +- .../use-system-podofo.patch | 343 ------------------ 3 files changed, 75 insertions(+), 419 deletions(-) delete mode 100644 pkgs/by-name/ci/cie-middleware-linux/use-system-podofo.patch diff --git a/pkgs/by-name/ci/cie-middleware-linux/deps.json b/pkgs/by-name/ci/cie-middleware-linux/deps.json index a1554a15e26f..593cd2e1b767 100644 --- a/pkgs/by-name/ci/cie-middleware-linux/deps.json +++ b/pkgs/by-name/ci/cie-middleware-linux/deps.json @@ -14,28 +14,28 @@ "jar": "sha256-CV/R3HeIjAc/C+OaAYFW7lJnInmLCd6eKF7yE14W6sQ=", "pom": "sha256-NQkZQkMk4nUKPdwvobzmqQrIziklaYpgqbTR1uSSL/4=" }, - "com/diffplug/durian#durian-swt.os/4.2.2": { - "jar": "sha256-a1Mca0vlgaizLq2GHdwVwsk7IMZl+00z4DgUg8JERfQ=", - "module": "sha256-rVlQLGknZu48M0vkliigDctNka4aSPJjLitxUStDXPk=", - "pom": "sha256-GzxJFP1eLM4pZq1wdWY5ZBFFwdNCB3CTV4Py3yY2kIU=" + "com/diffplug/durian#durian-swt.os/4.3.0": { + "jar": "sha256-geK2Oafkvm3JtyRXE88G9cq1HynbLha5tXZFyW/eKIQ=", + "module": "sha256-IFNqlfL+sr9DBRKMaq7Lb9idxFeYqchfJgK4qAnXUNs=", + "pom": "sha256-Q1z/VXiZht7arXF/aPuo1UgklHhWLc2EsirU1lZvRAs=" }, - "com/diffplug/spotless#com.diffplug.spotless.gradle.plugin/6.25.0": { - "pom": "sha256-9FyCsS+qzYWs1HTrppkyL6XeqIQIskfQ5L3pQSkIIjo=" + "com/diffplug/spotless#com.diffplug.spotless.gradle.plugin/7.0.2": { + "pom": "sha256-7R3td6KWpv4hpQJ5ySbAe+FK98CMJDfTaFxw/Pa7oC0=" }, - "com/diffplug/spotless#spotless-lib-extra/2.45.0": { - "jar": "sha256-YCy7zTgo7pz7LjCn+bMDNcaScTB3FBTUzdKU0h/ly2c=", - "module": "sha256-9pnkNfTlzgPbYJpHaO6wNj1uB8ZfvPrx/GKcTnbuf7A=", - "pom": "sha256-5x2LkRDdSNLn9KVLi/uozlWpbmteu9T0OpJGZJz1b7A=" + "com/diffplug/spotless#spotless-lib-extra/3.0.2": { + "jar": "sha256-sOd3RtYz1EXnhImsPQitLqGzU3xNBk5KvkbMQtYjA+s=", + "module": "sha256-vSVeQkQbWRehU8U9z5fP08IEevN2zF3Yu1Z/aEAWtFk=", + "pom": "sha256-IVesGayscKzQRQH8WbvJZNsZD1tx5O1e/s6o5c9o7Os=" }, - "com/diffplug/spotless#spotless-lib/2.45.0": { - "jar": "sha256-sllply4dmAKAyirlKRl+2bMWCq5ItQbPGTXwG9Exhmc=", - "module": "sha256-+x+8+TUAczrHWcp99E8P9mVTEze0LaAS4on/CINNiQ8=", - "pom": "sha256-WKd8IsQLIc8m29tCEwFu9HrM9bBwchfHkyqQ9D+PMNw=" + "com/diffplug/spotless#spotless-lib/3.0.2": { + "jar": "sha256-P5p/38WwOsIIlINBcJEMFcTyuE7UzjZ3iYowetWJg3w=", + "module": "sha256-E1WLrsCR6gDxYmXNNSOBePT+ejv61zXel214XUF/ss0=", + "pom": "sha256-jxtFo4m6Jeel8DvZ8KS9BKp+dHXgku6C1VUJYrLPdV8=" }, - "com/diffplug/spotless#spotless-plugin-gradle/6.25.0": { - "jar": "sha256-9euQikxdpGKZ51Q/qtoEAtLEt31Yx7Qy1Lblk0mygKM=", - "module": "sha256-RoHRe/PJIF2DeOynBcAAywzJjcx40DATy2iJjGvSx0Q=", - "pom": "sha256-q1ZuPYS2w/rHqPySXy279TzZdZywOvPAfQ3EN9OXqNo=" + "com/diffplug/spotless#spotless-plugin-gradle/7.0.2": { + "jar": "sha256-WaNMT4SkjUyNkp4viZBjaeZUduwEmaQ96Hw+QSeXfNU=", + "module": "sha256-rxC8mydsNqlNcRh+kVhwJ1yyRVZTntzqGYpYL30Tsws=", + "pom": "sha256-JyVoPfbvTNSIr+sgANqJIpQcqQ513D49uFIupxWKaMQ=" }, "com/googlecode/concurrent-trees#concurrent-trees/2.6.1": { "jar": "sha256-BONySYTipcv1VgbPo3KlvT08XSohUzpwBOPN5Tl2H6U=", @@ -59,31 +59,31 @@ "module": "sha256-akesUDZOZZhFlAH7hvm2z832N7mzowRbHMM8v0xAghg=", "pom": "sha256-rrO3CiTBA+0MVFQfNfXFEdJ85gyuN2pZbX1lNpf4zJU=" }, - "commons-codec#commons-codec/1.16.0": { - "jar": "sha256-VllfsgsLhbyR0NUD2tULt/G5r8Du1d/6bLslkpAASE0=", - "pom": "sha256-bLWVeBnfOTlW/TEaOgw/XuwevEm6Wy0J8/ROYWf6PnQ=" + "commons-codec#commons-codec/1.17.0": { + "jar": "sha256-9wDegKwnDQNE/ep0aCAdi5yAXlxkgzHDYZ8u4GfM/Fk=", + "pom": "sha256-wBxM2l5Aj0HtHYPkoKFwz1OAG2M4q6SfD5BHhrwSFPw=" }, - "dev/equo/ide#solstice/1.7.5": { - "jar": "sha256-BuFLxDrMMx2ra16iAfxnNk7RI/mCyF+lEx8IF+1lrk8=", - "module": "sha256-eYp7cGdyE27iijLt2GOx6fgWE6NJhAXXS+ilyb6/9U8=", - "pom": "sha256-20U7urXn2opDE5sNzTuuZykzIfKcTZH1p5XZ/2xS3d8=" + "dev/equo/ide#solstice/1.8.1": { + "jar": "sha256-bluizOgTvh1xzNwuzz5JJxsU5pG/u7GhFM86MOdzsQ0=", + "module": "sha256-pnYDnqavCPJXtG4Hwr8VcaRqTUtbnMuGw/yY0H+v6hs=", + "pom": "sha256-arSo7K4qu9NrkZ0Lm5+yTBdxSPE+U2TJegxu4Ro/xCY=" }, - "org/apache#apache/29": { - "pom": "sha256-PkkDcXSCC70N9jQgqXclWIY5iVTCoGKR+mH3J6w1s3c=" + "org/apache#apache/31": { + "pom": "sha256-VV0MnqppwEKv+SSSe5OB6PgXQTbTVe6tRFIkRS5ikcw=" }, - "org/apache/commons#commons-parent/58": { - "pom": "sha256-LUsS4YiZBjq9fHUni1+pejcp2Ah4zuy2pA2UbpwNVZA=" + "org/apache/commons#commons-parent/69": { + "pom": "sha256-1Q2pw5vcqCPWGNG0oDtz8ZZJf8uGFv0NpyfIYjWSqbs=" }, - "org/eclipse/jgit#org.eclipse.jgit-parent/6.7.0.202309050840-r": { - "pom": "sha256-u56FQW2Y0HMfx2f41w6EaAQWAdZnKuItsqx5n3qjkR8=" + "org/eclipse/jgit#org.eclipse.jgit-parent/6.10.0.202406032230-r": { + "pom": "sha256-8tNTmgp5Iv15RwgsGQHSCQ2uB0mGsi2r2XO0OYzR6i4=" }, - "org/eclipse/jgit#org.eclipse.jgit/6.7.0.202309050840-r": { - "jar": "sha256-tWRHfQkiQaqrUMhKxd0aw3XAGCBE1+VlnTpgqQ4ugBo=", - "pom": "sha256-BNB83b8ZjfpuRIuan7lA94HAEq2T2eqCBv4KTTplwZI=" + "org/eclipse/jgit#org.eclipse.jgit/6.10.0.202406032230-r": { + "jar": "sha256-Q/kvOttoGl8wBrl56NNBwSqM/YAp8ofEK88KgDd1Za4=", + "pom": "sha256-BVlUQr62ogYQi2c6qcZpLIPkHfGDF33GcROxzD9Sgd0=" }, - "org/eclipse/platform#org.eclipse.osgi/3.18.300": { - "jar": "sha256-urlD5Y7dFzCSOGctunpFrsni2svd24GKjPF3I+oT+iI=", - "pom": "sha256-4nl2N1mZxUJ/y8//PzvCD77a+tiqRRArN59cL5fI/rQ=" + "org/eclipse/platform#org.eclipse.osgi/3.18.500": { + "jar": "sha256-gLJ11YN5cjspHqZQJJzDgJyPELNPeKr5iBMs1tQ0q04=", + "pom": "sha256-4o9b4Azk7Sx+SAnsrQW5UwfzWhflhWAHhri97juk2Wg=" }, "org/jetbrains#annotations/13.0": { "jar": "sha256-rOKhDcji1f00kl7KwD5JiLLA+FFlDJS4zvSbob0RFHg=", @@ -114,9 +114,9 @@ "jar": "sha256-VemJxRK4CQd5n4VDCfO8d4LFs9E5MkQtA3nVxHJxFQQ=", "pom": "sha256-fin79z/fceBnnT3ufmgP1XNGT6AWRKT1irgZ0sCI09I=" }, - "org/junit#junit-bom/5.9.3": { - "module": "sha256-tAH9JZAeWCpSSqU0PEs54ovFbiSWHBBpvytLv87ka5M=", - "pom": "sha256-TQMpzZ5y8kIOXKFXJMv+b/puX9KIg2FRYnEZD9w0Ltc=" + "org/junit#junit-bom/5.10.2": { + "module": "sha256-3iOxFLPkEZqP5usXvtWjhSgWaYus5nBxV51tkn67CAo=", + "pom": "sha256-Fp3ZBKSw9lIM/+ZYzGIpK/6fPBSpifqSEgckzeQ6mWg=" }, "org/slf4j#slf4j-api/1.7.36": { "jar": "sha256-0+9XXj5JeWeNwBvx3M5RAhSTtNEft/G+itmCh3wWocA=", @@ -137,31 +137,31 @@ } }, "https://repo.maven.apache.org/maven2": { - "com/google/code/gson#gson-parent/2.11.0": { - "pom": "sha256-issfO3Km8CaRasBzW62aqwKT1Sftt7NlMn3vE6k2e3o=" + "com/google/code/gson#gson-parent/2.12.1": { + "pom": "sha256-yeewt+Mb574iaEl5wGgAHGUssRPE5u2JTjm2Q97gf8E=" }, - "com/google/code/gson#gson/2.11.0": { - "jar": "sha256-V5KNblpu3rKr03cKj5W6RNzkXzsjt6ncKzCcWBVSp4s=", - "pom": "sha256-wOVHvqmYiI5uJcWIapDnYicryItSdTQ90sBd7Wyi42A=" + "com/google/code/gson#gson/2.12.1": { + "jar": "sha256-6+4T1ft0d81/HMAQ4MNW34yoBwlxUkjal/eeNcy0++w=", + "pom": "sha256-C1c17IX0UoLx4sdpd5gAQnsVCoFj9AUJOpKAtxyrGXg=" }, - "com/google/errorprone#error_prone_annotations/2.27.0": { - "jar": "sha256-JMkjNyxY410LnxagKJKbua7cd1IYZ8J08r0HNd9bofU=", - "pom": "sha256-TKWjXWEjXhZUmsNG0eNFUc3w/ifoSqV+A8vrJV6k5do=" + "com/google/errorprone#error_prone_annotations/2.36.0": { + "jar": "sha256-d0QOJwsLyaJJkDxaB2w2pyLEiGyk9CZ18pA6HFPtYaU=", + "pom": "sha256-15z9N8hfdta3VMdQHuHchEe3smQsI4LXeCUhZr0zHpw=" }, - "com/google/errorprone#error_prone_parent/2.27.0": { - "pom": "sha256-+oGCnQSVWd9pJ/nJpv1rvQn4tQ5tRzaucsgwC2w9dlQ=" + "com/google/errorprone#error_prone_parent/2.36.0": { + "pom": "sha256-Okz8imvtYetI6Wl5b8MeoNJwtj5nBZmUamGIOttwlNw=" }, "commons-io#commons-io/2.18.0": { "jar": "sha256-88oPjWPEDiOlbVQQHGDV7e4Ta0LYS/uFvHljCTEJz4s=", "pom": "sha256-Y9lpQetE35yQ0q2yrYw/aZwuBl5wcEXF2vcT/KUrz8o=" }, - "commons-logging#commons-logging/1.3.3": { - "jar": "sha256-WCj5bAnYhvmxoJk8eASyfPT87IU0UXFk9RN6yLZ+qbk=", - "pom": "sha256-El1hQurD93REC6cCwF8o+eCYxS0QcSrhFJast3EGs7o=" + "commons-logging#commons-logging/1.3.4": { + "jar": "sha256-vC3+MvHvBlCeagZRRMGt97Qg6r8RqH8wvRJ/j6ozIBY=", + "pom": "sha256-1L2jSJKqzL9PrTP8MjqKqQfvnXmYRlnaJJRMCoa/CGU=" }, - "net/java/dev/jna#jna/5.15.0": { - "jar": "sha256-pWQVjSirUSf8apWAKO1UJ5/gmZZixGQltqOwmipSCU0=", - "pom": "sha256-J2YC/zZ6TDkVXa7MHoy1T0eJ5dgN+Qo6i2YD8d61ngU=" + "net/java/dev/jna#jna/5.17.0": { + "jar": "sha256-s6lAjnxR4I7w47/MCPRD9uwPYZG6jNfBjVPSsi5b28A=", + "pom": "sha256-UBoP8F2EpK0Q9t4lvpT0k5i3CjG+jzoO2fTGtE++/uQ=" }, "org/apache#apache/32": { "pom": "sha256-z9hywOwn9Trmj0PbwP7N7YrddzB5pTr705DkB7Qs5y8=" @@ -169,26 +169,26 @@ "org/apache#apache/33": { "pom": "sha256-14vYUkxfg4ChkKZSVoZimpXf5RLfIRETg6bYwJI6RBU=" }, - "org/apache/commons#commons-parent/71": { - "pom": "sha256-lbe+cPMWrkyiL2+90I3iGC6HzYdKZQ3nw9M4anR6gqM=" + "org/apache/commons#commons-parent/72": { + "pom": "sha256-Q0Xev8dnsa6saKvdcvxn0YtSHUs5A3KhG2P/DFhrIyA=" }, "org/apache/commons#commons-parent/78": { "pom": "sha256-Ai0gLmVe3QTyoQ7L5FPZKXeSTTg4Ckyow1nxgXqAMg4=" }, - "org/apache/pdfbox#fontbox/3.0.3": { - "jar": "sha256-ZWkMPzmwShTRLBf0mYwVGGzod9Pi7CIscIV348wCgDA=", - "pom": "sha256-sik+UDqncEMGEVD4hGg9f2FMz1Fjvi0PBSyinzx2d+I=" + "org/apache/pdfbox#fontbox/3.0.4": { + "jar": "sha256-Le7GIy9dbTsxJ2WS0xaArpcir1fSTLD3bacOK6DpnhI=", + "pom": "sha256-8MzDMOmyDYlXigqHArR6OZvNYojCOG10/6uPjjAoROg=" }, - "org/apache/pdfbox#pdfbox-io/3.0.3": { - "jar": "sha256-Ej6jGHtJfFTmYdUMPIZ0eb93Zo/0UOUHEMZY8rtGh7o=", - "pom": "sha256-EXAbuMWnNaSzFA9zroM6KBzqCeO8P583kbmpenRekNQ=" + "org/apache/pdfbox#pdfbox-io/3.0.4": { + "jar": "sha256-ep1HRvLhOh4i9O/kf7r5mXY8rqQXSFNa+ToB7txQ9VQ=", + "pom": "sha256-YLURdX737TBIv4LH2ClvcdC8RwAgEYQzqzs+OEC/jqU=" }, - "org/apache/pdfbox#pdfbox-parent/3.0.3": { - "pom": "sha256-yGXhzv8Jq1Kwh+cmDE8V025bW4vk/+IERvqkCiygvcw=" + "org/apache/pdfbox#pdfbox-parent/3.0.4": { + "pom": "sha256-w5j++zUez/mTEYCNftU0bnHzVrETS9c6JQTLgXB9tFE=" }, - "org/apache/pdfbox#pdfbox/3.0.3": { - "jar": "sha256-W+ONLsgWkbBdU163IN5NxWbF0H5aBHMfoAZo0VOotKY=", - "pom": "sha256-vgiV9rLCDzEdYjXJam/SqsECsxkE0/TDnqUll3WwcAg=" + "org/apache/pdfbox#pdfbox/3.0.4": { + "jar": "sha256-CaD/J9b4Sh3EAGDLCgHezyrU75HDa8kbmDbCVL6KrkU=", + "pom": "sha256-098DLfK90jT+NwMO+sNXa6Yj/Jf1ERNUxMUq13dfkOQ=" }, "org/junit#junit-bom/5.11.0-M2": { "module": "sha256-hkd6vPSQ1soFmqmXPLEI0ipQb0nRpVabsyzGy/Q8LM4=", diff --git a/pkgs/by-name/ci/cie-middleware-linux/package.nix b/pkgs/by-name/ci/cie-middleware-linux/package.nix index 7647f20c69a7..ba54e6231fa0 100644 --- a/pkgs/by-name/ci/cie-middleware-linux/package.nix +++ b/pkgs/by-name/ci/cie-middleware-linux/package.nix @@ -21,13 +21,13 @@ let pname = "cie-middleware-linux"; - version = "1.5.6"; + version = "1.5.9"; src = fetchFromGitHub { owner = "M0rf30"; repo = "cie-middleware-linux"; rev = version; - sha256 = "sha256-2P/1hQTmeQ6qE7RgAeLOZTszcLcIpa2XX1S2ahXRHcc="; + hash = "sha256-2UMKxanF35oBNBtIqfU46QUYJwXiTU1xCrCMqzqetgI="; }; gradle = gradle_8; @@ -61,8 +61,6 @@ stdenv.mkDerivation { libxml2 ]; - patches = [ ./use-system-podofo.patch ]; - postPatch = '' # substitute the cieid command with this $out/bin/cieid substituteInPlace libs/pkcs11/src/CSP/AbilitaCIE.cpp \ @@ -114,6 +112,7 @@ stdenv.mkDerivation { popd # Install the Java application + ls cie-java/build/libs/CIEID-standalone.jar install -Dm755 cie-java/build/libs/CIEID-standalone.jar \ "$out/share/cieid/cieid.jar" @@ -123,11 +122,11 @@ stdenv.mkDerivation { --add-flags "-Djna.library.path='$out/lib:${libraries}'" \ --add-flags '-Dawt.useSystemAAFontSettings=on' \ --add-flags "-cp $out/share/cieid/cieid.jar" \ - --add-flags "it.ipzs.cieid.MainApplication" + --add-flags "app.m0rf30.cieid.MainApplication" # Install other files - install -Dm644 data/cieid.desktop "$out/share/applications/cieid.desktop" - install -Dm755 data/logo.png "$out/share/pixmaps/cieid.png" + install -Dm644 data/app.m0rf30.cieid.desktop -t "$out/share/applications" + install -Dm755 data/app.m0rf30.cieid.svg -t "$out/share/pixmaps" install -Dm644 LICENSE "$out/share/licenses/cieid/LICENSE" ''; diff --git a/pkgs/by-name/ci/cie-middleware-linux/use-system-podofo.patch b/pkgs/by-name/ci/cie-middleware-linux/use-system-podofo.patch deleted file mode 100644 index 52806d4f96e8..000000000000 --- a/pkgs/by-name/ci/cie-middleware-linux/use-system-podofo.patch +++ /dev/null @@ -1,343 +0,0 @@ -commit c9ac4243a6def08790bbf5552bb31894169596ca -Author: rnhmjoj -Date: Wed Apr 3 12:54:58 2024 +0200 - - use system podofo - -diff --git a/libs/meson.build b/libs/meson.build -index 3ee31c1..5022ba8 100644 ---- a/libs/meson.build -+++ b/libs/meson.build -@@ -16,21 +16,15 @@ curl_dep = dependency('libcurl') - fontconfig_dep = dependency('fontconfig') - freetype_dep = dependency('freetype2') - png_dep = dependency('libpng') --podofo_dep = cpp.find_library('libpodofo', dirs: libdir) -+podofo_dep = dependency('libpodofo') - libxml2_dep = dependency('libxml-2.0', required: false) - xml2_dep = dependency('xml2', required: false) - zlib_dep = dependency('zlib') - - inc_so = include_directories('pkcs11/src/.', 'shared/src/') - --inc_a = include_directories( -- 'sign-sdk/include', -- 'sign-sdk/include/podofo', -- 'sign-sdk/include/podofo/include', -- 'sign-sdk/include/podofo/include/podofo', -- 'sign-sdk/src', -- 'shared/src/', --) -+inc_a = include_directories('sign-sdk/include', 'sign-sdk/src', 'shared/src/') -+ - cie_pkcs11_sources = [ - 'shared/src/Util/log.cpp', - 'shared/src/Util/funccallinfo.cpp', -diff --git a/libs/sign-sdk/include/PdfSignatureGenerator.h b/libs/sign-sdk/include/PdfSignatureGenerator.h -index 93ab445..65d438f 100644 ---- a/libs/sign-sdk/include/PdfSignatureGenerator.h -+++ b/libs/sign-sdk/include/PdfSignatureGenerator.h -@@ -10,9 +10,7 @@ - #ifndef _PDFSIGNATUREGENERATOR_H_ - #define _PDFSIGNATUREGENERATOR_H_ - #include "Util/UUCByteArray.h" --#include "podofo/doc/PdfSignOutputDevice.h" --#include "podofo/doc/PdfSignatureField.h" --#include "podofo/podofo.h" -+#include - - using namespace PoDoFo; - using namespace std; -@@ -60,7 +58,11 @@ class PdfSignatureGenerator { - const double getHeight(int pageIndex); - - private: -- PdfMemDocument* m_pPdfDocument; -+ PdfDocument* m_pPdfDocument; -+ -+ PdfMemDocument* m_pPdfMemDocument; -+ -+ PdfWriter* m_pPdfWriter; - - PdfSignatureField* m_pSignatureField; - -diff --git a/libs/sign-sdk/src/PdfSignatureGenerator.cpp b/libs/sign-sdk/src/PdfSignatureGenerator.cpp -index 44ef54a..e8b8c8e 100644 ---- a/libs/sign-sdk/src/PdfSignatureGenerator.cpp -+++ b/libs/sign-sdk/src/PdfSignatureGenerator.cpp -@@ -27,7 +27,7 @@ int GetNumberOfSignatures(PdfMemDocument* pPdfDocument); - USE_LOG; - - PdfSignatureGenerator::PdfSignatureGenerator() -- : m_pPdfDocument(NULL), -+ : m_pPdfMemDocument(NULL), - m_pSignatureField(NULL), - m_pSignOutputDevice(NULL), - m_pFinalOutDevice(NULL), -@@ -37,7 +37,7 @@ PdfSignatureGenerator::PdfSignatureGenerator() - } - - PdfSignatureGenerator::~PdfSignatureGenerator() { -- if (m_pPdfDocument) delete m_pPdfDocument; -+ if (m_pPdfMemDocument) delete m_pPdfMemDocument; - - if (m_pSignatureField) delete m_pSignatureField; - -@@ -51,21 +51,21 @@ PdfSignatureGenerator::~PdfSignatureGenerator() { - } - - int PdfSignatureGenerator::Load(const char* pdf, int len) { -- if (m_pPdfDocument) delete m_pPdfDocument; -+ if (m_pPdfMemDocument) delete m_pPdfMemDocument; - - try { - printf("PDF LENGTH"); - printf("%i", len); - printf("STOP"); - -- m_pPdfDocument = new PdfMemDocument(); -- m_pPdfDocument->Load(pdf, len); -- printf("OK m_pPdfDocument"); -- int nSigns = PDFVerifier::GetNumberOfSignatures(m_pPdfDocument); -+ m_pPdfMemDocument = new PdfMemDocument(); -+ m_pPdfMemDocument->Load(pdf); -+ printf("OK m_pPdfMemDocument"); -+ int nSigns = PDFVerifier::GetNumberOfSignatures(m_pPdfMemDocument); - printf("OK nSigns: %d", nSigns); - - if (nSigns > 0) { -- m_pPdfDocument->SetIncrementalUpdates(true); -+ m_pPdfWriter->PdfWriter::SetIncrementalUpdate(true); - } - m_actualLen = len; - -@@ -82,14 +82,8 @@ void PdfSignatureGenerator::AddFont(const char* szFontName, - // printf(szFontName); - // printf(szFontPath); - -- m_pPdfDocument->CreateFont( -- szFontName, false, false, -- PdfEncodingFactory::GlobalWinAnsiEncodingInstance(), -- PdfFontCache::eFontCreationFlags_AutoSelectBase14, true, szFontPath); -- m_pPdfDocument->CreateFont( -- szFontName, true, false, -- PdfEncodingFactory::GlobalWinAnsiEncodingInstance(), -- PdfFontCache::eFontCreationFlags_AutoSelectBase14, true, szFontPath); -+ m_pPdfDocument->PoDoFo::PdfDocument::CreateFont( szFontName, false, PdfEncodingFactory::GlobalWinAnsiEncodingInstance(), PdfFontCache::eFontCreationFlags_AutoSelectBase14, true); -+ m_pPdfDocument->PoDoFo::PdfDocument::CreateFont( szFontName, true, PdfEncodingFactory::GlobalWinAnsiEncodingInstance(), PdfFontCache::eFontCreationFlags_AutoSelectBase14, true); - } - - void PdfSignatureGenerator::InitSignature( -@@ -130,7 +124,7 @@ void PdfSignatureGenerator::InitSignature( - - if (m_pSignatureField) delete m_pSignatureField; - -- PdfPage* pPage = m_pPdfDocument->GetPage(pageIndex); -+ PdfPage* pPage = m_pPdfMemDocument->GetPage(pageIndex); - PdfRect cropBox = pPage->GetCropBox(); - - float left0 = left * cropBox.GetWidth(); -@@ -145,15 +139,14 @@ void PdfSignatureGenerator::InitSignature( - - LOG_DBG((0, "InitSignature", "PdfSignatureField")); - -- m_pSignatureField = new PdfSignatureField( -- pPage, rect, m_pPdfDocument, PdfString(szFieldName), szSubFilter); -+ m_pSignatureField = new PdfSignatureField(pPage, rect, m_pPdfMemDocument); - - LOG_DBG((0, "InitSignature", "PdfSignatureField OK")); - - if (szReason && szReason[0]) { - PdfString reason(szReason); - PdfString reasonLabel(szReasonLabel); -- m_pSignatureField->SetSignatureReason(reasonLabel, reason); -+ m_pSignatureField->SetSignatureReason(reason); - } - - LOG_DBG((0, "InitSignature", "szReason OK")); -@@ -161,7 +154,7 @@ void PdfSignatureGenerator::InitSignature( - if (szLocation && szLocation[0]) { - PdfString location(szLocation); - PdfString locationLabel(szLocationLabel); -- m_pSignatureField->SetSignatureLocation(locationLabel, location); -+ m_pSignatureField->SetSignatureLocation(location); - } - - LOG_DBG((0, "InitSignature", "szLocation OK")); -@@ -171,54 +164,42 @@ void PdfSignatureGenerator::InitSignature( - - LOG_DBG((0, "InitSignature", "Date OK")); - -- if (szName && szName[0]) { -- PdfString name(szName); -- PdfString nameLabel(szNameLabel); -- m_pSignatureField->SetSignatureName(nameLabel, name); -- } -- -- LOG_DBG((0, "InitSignature", "szName OK")); -- -- m_pSignatureField->SetSignatureSize(SIGNATURE_SIZE); -+ m_pSignOutputDevice->PdfSignOutputDevice::SetSignatureSize(SIGNATURE_SIZE); - - LOG_DBG((0, "InitSignature", "SIGNATURE_SIZE OK")); - -- // if((szImagePath && szImagePath[0]) || (szDescription && szDescription[0])) -- if (width * height > 0) { -- try { -- // m_pSignatureField->SetFontSize(5); -- m_pSignatureField->SetAppearance(szImagePath, szDescription); -- LOG_DBG((0, "InitSignature", "SetAppearance OK")); -- } catch (PdfError& error) { -- LOG_ERR((0, "InitSignature", "SetAppearance error: %s, %s", -- PdfError::ErrorMessage(error.GetError()), error.what())); -- } catch (PdfError* perror) { -- LOG_ERR((0, "InitSignature", "SetAppearance error2: %s, %s", -- PdfError::ErrorMessage(perror->GetError()), perror->what())); -- } catch (std::exception& ex) { -- LOG_ERR( -- (0, "InitSignature", "SetAppearance std exception, %s", ex.what())); -- } catch (std::exception* pex) { -- LOG_ERR((0, "InitSignature", "SetAppearance std exception2, %s", -- pex->what())); -- } catch (...) { -- LOG_ERR((0, "InitSignature", "SetAppearance unknown error")); -- } -- } -+ // if (width * height > 0) { -+ // try { -+ // m_pSignatureField->SetAppearance(szImagePath, szDescription); -+ // LOG_DBG((0, "InitSignature", "SetAppearance OK")); -+ // } catch (PdfError& error) { -+ // LOG_ERR((0, "InitSignature", "SetAppearance error: %s, %s", -+ // PdfError::ErrorMessage(error.GetError()), error.what())); -+ // } catch (PdfError* perror) { -+ // LOG_ERR((0, "InitSignature", "SetAppearance error2: %s, %s", -+ // PdfError::ErrorMessage(perror->GetError()), perror->what())); -+ // } catch (std::exception& ex) { -+ // LOG_ERR( -+ // (0, "InitSignature", "SetAppearance std exception, %s", -+ // ex.what())); -+ // } catch (std::exception* pex) { -+ // LOG_ERR((0, "InitSignature", "SetAppearance std exception2, %s", -+ // pex->what())); -+ // } catch (...) { -+ // LOG_ERR((0, "InitSignature", "SetAppearance unknown error")); -+ // } -+ // } - -- if (szGraphometricData && szGraphometricData[0]) -- m_pSignatureField->SetGraphometricData( -- PdfString("Aruba_Sign_Biometric_Data"), PdfString(szGraphometricData), -- PdfString(szVersion)); -+ // if (szGraphometricData && szGraphometricData[0]) -+ // m_pSignatureField->SetGraphometricData( -+ // PdfString("Aruba_Sign_Biometric_Data"), -+ // PdfString(szGraphometricData), PdfString(szVersion)); - -- LOG_DBG((0, "InitSignature", "szGraphometricData OK")); -+ // LOG_DBG((0, "InitSignature", "szGraphometricData OK")); - - LOG_DBG((0, "InitSignature", "m_actualLen %d", m_actualLen)); - // crea il nuovo doc con il campo di firma -- int fulllen = m_actualLen * 2 + SIGNATURE_SIZE * 2 + -- (szGraphometricData -- ? (strlen(szGraphometricData) + strlen(szVersion) + 100) -- : 0); -+ int fulllen = m_actualLen * 2 + SIGNATURE_SIZE * 2; - - int mainDoclen = 0; - m_pMainDocbuffer = NULL; -@@ -227,7 +208,7 @@ void PdfSignatureGenerator::InitSignature( - LOG_DBG((0, "InitSignature", "fulllen %d", fulllen)); - m_pMainDocbuffer = new char[fulllen]; - PdfOutputDevice pdfOutDevice(m_pMainDocbuffer, fulllen); -- m_pPdfDocument->Write(&pdfOutDevice); -+ m_pPdfMemDocument->Write(&pdfOutDevice); - mainDoclen = pdfOutDevice.GetLength(); - } catch (::PoDoFo::PdfError err) { - if (m_pMainDocbuffer) { -@@ -301,32 +282,32 @@ void PdfSignatureGenerator::GetSignedPdf(UUCByteArray& signedPdf) { - } - - const double PdfSignatureGenerator::getWidth(int pageIndex) { -- if (m_pPdfDocument) { -- PdfPage* pPage = m_pPdfDocument->GetPage(pageIndex); -+ if (m_pPdfMemDocument) { -+ PdfPage* pPage = m_pPdfMemDocument->GetPage(pageIndex); - return pPage->GetPageSize().GetWidth(); - } - return 0; - } - - const double PdfSignatureGenerator::getHeight(int pageIndex) { -- if (m_pPdfDocument) { -- PdfPage* pPage = m_pPdfDocument->GetPage(pageIndex); -+ if (m_pPdfMemDocument) { -+ PdfPage* pPage = m_pPdfMemDocument->GetPage(pageIndex); - return pPage->GetPageSize().GetHeight(); - } - return 0; - } - - const double PdfSignatureGenerator::lastSignatureY(int left, int bottom) { -- if (!m_pPdfDocument) return -1; -+ if (!m_pPdfMemDocument) return -1; - /// Find the document catalog dictionary -- const PdfObject* const trailer = m_pPdfDocument->GetTrailer(); -+ const PdfObject* const trailer = m_pPdfMemDocument->GetTrailer(); - if (!trailer->IsDictionary()) return -1; - const PdfObject* const catalogRef = - trailer->GetDictionary().GetKey(PdfName("Root")); - if (catalogRef == 0 || !catalogRef->IsReference()) - return -2; // throw std::invalid_argument("Invalid /Root entry"); - const PdfObject* const catalog = -- m_pPdfDocument->GetObjects().GetObject(catalogRef->GetReference()); -+ m_pPdfMemDocument->GetObjects().GetObject(catalogRef->GetReference()); - if (catalog == 0 || !catalog->IsDictionary()) - return -3; // throw std::invalid_argument("Invalid or non-dictionary - // referenced by /Root entry"); -@@ -336,8 +317,8 @@ const double PdfSignatureGenerator::lastSignatureY(int left, int bottom) { - catalog->GetDictionary().GetKey(PdfName("AcroForm")); - if (acroFormValue == 0) return bottom; - if (acroFormValue->IsReference()) -- acroFormValue = -- m_pPdfDocument->GetObjects().GetObject(acroFormValue->GetReference()); -+ acroFormValue = m_pPdfMemDocument->GetObjects().GetObject( -+ acroFormValue->GetReference()); - - if (!acroFormValue->IsDictionary()) return bottom; - -@@ -346,8 +327,8 @@ const double PdfSignatureGenerator::lastSignatureY(int left, int bottom) { - if (fieldsValue == 0) return bottom; - - if (fieldsValue->IsReference()) -- fieldsValue = -- m_pPdfDocument->GetObjects().GetObject(acroFormValue->GetReference()); -+ fieldsValue = m_pPdfMemDocument->GetObjects().GetObject( -+ acroFormValue->GetReference()); - - if (!fieldsValue->IsArray()) return bottom; - -@@ -360,8 +341,8 @@ const double PdfSignatureGenerator::lastSignatureY(int left, int bottom) { - - for (unsigned int i = 0; i < array.size(); i++) { - const PdfObject* pObj = -- m_pPdfDocument->GetObjects().GetObject(array[i].GetReference()); -- if (IsSignatureField(m_pPdfDocument, pObj)) { -+ m_pPdfMemDocument->GetObjects().GetObject(array[i].GetReference()); -+ if (IsSignatureField(m_pPdfMemDocument, pObj)) { - const PdfObject* const keyRect = - pObj->GetDictionary().GetKey(PdfName("Rect")); - if (keyRect == 0) { -diff --git a/libs/sign-sdk/src/disigonsdk.cpp b/libs/sign-sdk/src/disigonsdk.cpp -index 250c93f..84e1b0b 100644 ---- a/libs/sign-sdk/src/disigonsdk.cpp -+++ b/libs/sign-sdk/src/disigonsdk.cpp -@@ -5,6 +5,7 @@ - - #include - #include -+#include - #include - #include - From c712a2d78cfaf8259fb41bff6015bc80c9423467 Mon Sep 17 00:00:00 2001 From: rnhmjoj Date: Sat, 7 Jun 2025 16:43:10 +0200 Subject: [PATCH 31/82] cie-middleware-linux: try re-enabling darwin --- pkgs/by-name/ci/cie-middleware-linux/package.nix | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkgs/by-name/ci/cie-middleware-linux/package.nix b/pkgs/by-name/ci/cie-middleware-linux/package.nix index ba54e6231fa0..0495b82c0693 100644 --- a/pkgs/by-name/ci/cie-middleware-linux/package.nix +++ b/pkgs/by-name/ci/cie-middleware-linux/package.nix @@ -145,8 +145,6 @@ stdenv.mkDerivation { ''; license = licenses.bsd3; platforms = platforms.unix; - # Note: fails due to a lot of broken type conversions - badPlatforms = platforms.darwin; maintainers = with maintainers; [ rnhmjoj ]; }; } From 6276e0953073bf5db53530ce8c49014593ec499c Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Sat, 7 Jun 2025 19:36:24 +0200 Subject: [PATCH 32/82] workflows/backport: cancel concurrent runs When backporting a change to 24.11 and 25.05 at the same time by adding the two labels immediately *after* merging the PR, three backport jobs will run concurrently: One for the merge and one for each label added. Each of those jobs will try to create both PRs, which will lead to two of the jobs failing for sure. With a concurrency group and cancelling in-progress jobs, only one of those jobs will remain. This reduces notification noise. --- .github/workflows/backport.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index ea184fb914a4..117dbc09b2ee 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -9,6 +9,10 @@ on: pull_request_target: types: [closed, labeled] +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + permissions: contents: read issues: write From 30b2aaa0edaa1e99b4031667691307064b752c01 Mon Sep 17 00:00:00 2001 From: "R. Ryantm" Date: Sun, 8 Jun 2025 06:47:30 +0000 Subject: [PATCH 33/82] linuxPackages.prl-tools: 20.3.1-55959 -> 20.3.2-55975 --- pkgs/os-specific/linux/prl-tools/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/os-specific/linux/prl-tools/default.nix b/pkgs/os-specific/linux/prl-tools/default.nix index 4e7b391f840a..ba2fe72e1277 100644 --- a/pkgs/os-specific/linux/prl-tools/default.nix +++ b/pkgs/os-specific/linux/prl-tools/default.nix @@ -43,13 +43,13 @@ let in stdenv.mkDerivation (finalAttrs: { pname = "prl-tools"; - version = "20.3.1-55959"; + version = "20.3.2-55975"; # We download the full distribution to extract prl-tools-lin.iso from # => ${dmg}/Parallels\ Desktop.app/Contents/Resources/Tools/prl-tools-lin.iso src = fetchurl { url = "https://download.parallels.com/desktop/v${lib.versions.major finalAttrs.version}/${finalAttrs.version}/ParallelsDesktop-${finalAttrs.version}.dmg"; - hash = "sha256-/J6NouI2htptG06Undeg1rUfbWUu6q/nV2P9D+sS7OA="; + hash = "sha256-eazDR+eSUcp81XdRfYRHIt7E4FNCEjsh0M0wYQQYmMQ="; }; hardeningDisable = [ From a35490b72db1b186c82b63bf2b1fc4d692eba45a Mon Sep 17 00:00:00 2001 From: "R. Ryantm" Date: Sun, 8 Jun 2025 11:18:05 +0000 Subject: [PATCH 34/82] geminicommit: 0.4.0 -> 0.4.1 --- pkgs/by-name/ge/geminicommit/package.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/by-name/ge/geminicommit/package.nix b/pkgs/by-name/ge/geminicommit/package.nix index ff58bebd43bd..2b69183918c9 100644 --- a/pkgs/by-name/ge/geminicommit/package.nix +++ b/pkgs/by-name/ge/geminicommit/package.nix @@ -8,16 +8,16 @@ buildGoModule (finalAttrs: { pname = "geminicommit"; - version = "0.4.0"; + version = "0.4.1"; src = fetchFromGitHub { owner = "tfkhdyt"; repo = "geminicommit"; tag = "v${finalAttrs.version}"; - hash = "sha256-hJevJkniyICUUr1UyS0A5SKuuYRU0dGHMWzF99Yr2Eo="; + hash = "sha256-QUI5JI1udOo3IOXegoes3pwwgSfxXIjxXIPsA5SuAJo="; }; - vendorHash = "sha256-IfqlPg+HPcOfjlwwuLi2/R21UD83xQzWyUmzM7JSDEs="; + vendorHash = "sha256-AFm+1RQ6sMSe+kY/cw1Ly/8WEj2/yk0nJQiEJzV6jKg="; nativeBuildInputs = [ installShellFiles From 5f4effe804243ebf55a38d196e15e8c14e94c186 Mon Sep 17 00:00:00 2001 From: Bobby Rong Date: Sun, 8 Jun 2025 08:44:44 +0000 Subject: [PATCH 35/82] xfce.libxfce4windowing: 4.20.2 -> 4.20.3 https://gitlab.xfce.org/xfce/libxfce4windowing/-/compare/libxfce4windowing-4.20.2...libxfce4windowing-4.20.3 --- pkgs/desktops/xfce/core/libxfce4windowing/default.nix | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pkgs/desktops/xfce/core/libxfce4windowing/default.nix b/pkgs/desktops/xfce/core/libxfce4windowing/default.nix index a79d48d52927..0112316d4c83 100644 --- a/pkgs/desktops/xfce/core/libxfce4windowing/default.nix +++ b/pkgs/desktops/xfce/core/libxfce4windowing/default.nix @@ -2,6 +2,7 @@ stdenv, lib, mkXfceDerivation, + python3, wayland-scanner, glib, gtk3, @@ -22,12 +23,13 @@ mkXfceDerivation { category = "xfce"; pname = "libxfce4windowing"; - version = "4.20.2"; + version = "4.20.3"; - sha256 = "sha256-Xw1hs854K5dZCAYoBMoqJzdSxPRFUYqEpWxg4DLSK5Q="; + sha256 = "sha256-l58cTz28UPSVfoIpjBCoSwcqdUJfG9e4UlhVYPyEeAs="; nativeBuildInputs = [ + python3 wayland-scanner ] ++ lib.optionals withIntrospection [ @@ -46,6 +48,10 @@ mkXfceDerivation { wlr-protocols ]; + postPatch = '' + patchShebangs xdt-gen-visibility + ''; + meta = { description = "Windowing concept abstraction library for X11 and Wayland"; license = lib.licenses.lgpl21Plus; From 4c1ec45e5abf6d18b3b3972845384f565ff1d4f9 Mon Sep 17 00:00:00 2001 From: June Stepp Date: Sat, 3 May 2025 22:46:34 -0500 Subject: [PATCH 36/82] ankiAddons.adjust-sound-volume: init at 0.0.6 --- .../addons/adjust-sound-volume/default.nix | 23 +++++++++++++++++++ pkgs/games/anki/addons/default.nix | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 pkgs/games/anki/addons/adjust-sound-volume/default.nix diff --git a/pkgs/games/anki/addons/adjust-sound-volume/default.nix b/pkgs/games/anki/addons/adjust-sound-volume/default.nix new file mode 100644 index 000000000000..cdeb7d3d727a --- /dev/null +++ b/pkgs/games/anki/addons/adjust-sound-volume/default.nix @@ -0,0 +1,23 @@ +{ + lib, + anki-utils, + fetchFromGitHub, + nix-update-script, +}: +anki-utils.buildAnkiAddon (finalAttrs: { + pname = "adjust-sound-volume"; + version = "0.0.6"; + src = fetchFromGitHub { + owner = "mnogu"; + repo = "adjust-sound-volume"; + rev = "v${finalAttrs.version}"; + hash = "sha256-6reIUz+tHKd4KQpuofLa/tIL5lCloj3yODZ8Cz29jFU="; + }; + passthru.updateScript = nix-update-script { }; + meta = { + description = "Add a new menu item for adjusting the sound volume"; + homepage = "https://github.com/mnogu/adjust-sound-volume"; + license = lib.licenses.agpl3Plus; + maintainers = with lib.maintainers; [ junestepp ]; + }; +}) diff --git a/pkgs/games/anki/addons/default.nix b/pkgs/games/anki/addons/default.nix index e4090644a690..e4808f566295 100644 --- a/pkgs/games/anki/addons/default.nix +++ b/pkgs/games/anki/addons/default.nix @@ -2,5 +2,5 @@ callPackage, }: { - + adjust-sound-volume = callPackage ./adjust-sound-volume { }; } From 2d98ddf69951424c57714216844f848e03f92062 Mon Sep 17 00:00:00 2001 From: June Stepp Date: Sat, 3 May 2025 22:48:03 -0500 Subject: [PATCH 37/82] ankiAddons.anki-connect: init at 24.7.25.0 --- .../anki/addons/anki-connect/default.nix | 27 +++++++++++++++++++ pkgs/games/anki/addons/default.nix | 2 ++ 2 files changed, 29 insertions(+) create mode 100644 pkgs/games/anki/addons/anki-connect/default.nix diff --git a/pkgs/games/anki/addons/anki-connect/default.nix b/pkgs/games/anki/addons/anki-connect/default.nix new file mode 100644 index 000000000000..27a0411e52f7 --- /dev/null +++ b/pkgs/games/anki/addons/anki-connect/default.nix @@ -0,0 +1,27 @@ +{ + lib, + anki-utils, + fetchFromSourcehut, + nix-update-script, +}: +anki-utils.buildAnkiAddon (finalAttrs: { + pname = "anki-connect"; + version = "24.7.25.0"; + src = fetchFromSourcehut { + owner = "~foosoft"; + repo = "anki-connect"; + rev = finalAttrs.version; + hash = "sha256-N98EoCE/Bx+9QUQVeU64FXHXSek7ASBVv1b9ltJ4G1U="; + }; + sourceRoot = "${finalAttrs.src.name}/plugin"; + passthru.updateScript = nix-update-script { }; + meta = { + description = '' + Enable external applications such as Yomichan to communicate + with Anki over a simple HTTP API + ''; + homepage = "https://foosoft.net/projects/anki-connect/"; + license = lib.licenses.gpl3Plus; + maintainers = with lib.maintainers; [ junestepp ]; + }; +}) diff --git a/pkgs/games/anki/addons/default.nix b/pkgs/games/anki/addons/default.nix index e4808f566295..f63f75a27499 100644 --- a/pkgs/games/anki/addons/default.nix +++ b/pkgs/games/anki/addons/default.nix @@ -3,4 +3,6 @@ }: { adjust-sound-volume = callPackage ./adjust-sound-volume { }; + + anki-connect = callPackage ./anki-connect { }; } From f0e483d06dd2bdaa512d9131415482b76dcda7f9 Mon Sep 17 00:00:00 2001 From: June Stepp Date: Sat, 3 May 2025 22:50:12 -0500 Subject: [PATCH 38/82] ankiAddons.passfail2: init at 0.3.0-unstable-2024-10-17 --- pkgs/games/anki/addons/default.nix | 2 ++ pkgs/games/anki/addons/passfail2/default.nix | 34 ++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 pkgs/games/anki/addons/passfail2/default.nix diff --git a/pkgs/games/anki/addons/default.nix b/pkgs/games/anki/addons/default.nix index f63f75a27499..842e2fbc9c2d 100644 --- a/pkgs/games/anki/addons/default.nix +++ b/pkgs/games/anki/addons/default.nix @@ -5,4 +5,6 @@ adjust-sound-volume = callPackage ./adjust-sound-volume { }; anki-connect = callPackage ./anki-connect { }; + + passfail2 = callPackage ./passfail2 { }; } diff --git a/pkgs/games/anki/addons/passfail2/default.nix b/pkgs/games/anki/addons/passfail2/default.nix new file mode 100644 index 000000000000..73746c1a568a --- /dev/null +++ b/pkgs/games/anki/addons/passfail2/default.nix @@ -0,0 +1,34 @@ +{ + lib, + anki-utils, + fetchFromGitHub, + nix-update-script, +}: +anki-utils.buildAnkiAddon (finalAttrs: { + pname = "passfail2"; + version = "0.3.0-unstable-2024-10-17"; + src = fetchFromGitHub { + owner = "lambdadog"; + repo = "passfail2"; + rev = "d5313e4f1217e968b36edbc0a4fe92386209ffe6"; + hash = "sha256-HMe6/fHpYj/MN0dUFj3W71vK7qqcp9l1xm8SAiKkJLs="; + }; + buildPhase = '' + runHook preBuild + + substitute build_info.py.in build_info.py \ + --replace-fail '$version' '"${finalAttrs.version}"' + + runHook postBuild + ''; + passthru.updateScript = nix-update-script { }; + meta = { + description = '' + Replaces the default Anki review buttons with only two options: + “Fail” and “Pass” + ''; + homepage = "https://github.com/lambdadog/passfail2"; + license = lib.licenses.gpl3Plus; + maintainers = with lib.maintainers; [ junestepp ]; + }; +}) From 133b3319e54d9fe5383a525c8ad4a207c23f4354 Mon Sep 17 00:00:00 2001 From: June Stepp Date: Sat, 3 May 2025 22:51:52 -0500 Subject: [PATCH 39/82] ankiAddons.reviewer-refocus-card: init at 0-unstable-2022-12-24 --- pkgs/games/anki/addons/default.nix | 2 ++ .../addons/reviewer-refocus-card/default.nix | 30 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 pkgs/games/anki/addons/reviewer-refocus-card/default.nix diff --git a/pkgs/games/anki/addons/default.nix b/pkgs/games/anki/addons/default.nix index 842e2fbc9c2d..bcbfc15523f5 100644 --- a/pkgs/games/anki/addons/default.nix +++ b/pkgs/games/anki/addons/default.nix @@ -7,4 +7,6 @@ anki-connect = callPackage ./anki-connect { }; passfail2 = callPackage ./passfail2 { }; + + reviewer-refocus-card = callPackage ./reviewer-refocus-card { }; } diff --git a/pkgs/games/anki/addons/reviewer-refocus-card/default.nix b/pkgs/games/anki/addons/reviewer-refocus-card/default.nix new file mode 100644 index 000000000000..6fde24afd22e --- /dev/null +++ b/pkgs/games/anki/addons/reviewer-refocus-card/default.nix @@ -0,0 +1,30 @@ +{ + lib, + anki-utils, + fetchFromGitHub, + nix-update-script, +}: +anki-utils.buildAnkiAddon (finalAttrs: { + pname = "reviewer-refocus-card"; + version = "0-unstable-2022-12-24"; + src = fetchFromGitHub { + owner = "glutanimate"; + repo = "anki-addons-misc"; + rev = "7b981836e0a6637a1853f3e8d73d022ab95fed31"; + sparseCheckout = [ "src/reviewer_refocus_card" ]; + hash = "sha256-181hyc4ED+0lBzn1FnrBvNIYIUQF8xEDB3uHK6SkpHw="; + }; + sourceRoot = "${finalAttrs.src.name}/src/reviewer_refocus_card"; + passthru.updateScript = nix-update-script { + extraArgs = [ "--version=branch" ]; + }; + meta = { + description = '' + Set focus to the card area, allowing you to scroll through your cards using + Page Up / Page Down, etc + ''; + homepage = "https://github.com/glutanimate/anki-addons-misc"; + license = lib.licenses.agpl3Only; + maintainers = with lib.maintainers; [ junestepp ]; + }; +}) From 6eebb20365bfe01caaf27b10acc876e84f282620 Mon Sep 17 00:00:00 2001 From: June Stepp Date: Sat, 3 May 2025 22:53:56 -0500 Subject: [PATCH 40/82] ankiAddons.yomichan-forvo-server: init at 0-unstable-2024-10-21 --- pkgs/games/anki/addons/default.nix | 2 ++ .../addons/yomichan-forvo-server/default.nix | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 pkgs/games/anki/addons/yomichan-forvo-server/default.nix diff --git a/pkgs/games/anki/addons/default.nix b/pkgs/games/anki/addons/default.nix index bcbfc15523f5..7f60c7e29e25 100644 --- a/pkgs/games/anki/addons/default.nix +++ b/pkgs/games/anki/addons/default.nix @@ -9,4 +9,6 @@ passfail2 = callPackage ./passfail2 { }; reviewer-refocus-card = callPackage ./reviewer-refocus-card { }; + + yomichan-forvo-server = callPackage ./yomichan-forvo-server { }; } diff --git a/pkgs/games/anki/addons/yomichan-forvo-server/default.nix b/pkgs/games/anki/addons/yomichan-forvo-server/default.nix new file mode 100644 index 000000000000..751798f6e3a6 --- /dev/null +++ b/pkgs/games/anki/addons/yomichan-forvo-server/default.nix @@ -0,0 +1,25 @@ +{ + lib, + anki-utils, + fetchFromGitHub, + nix-update-script, +}: +anki-utils.buildAnkiAddon { + pname = "yomichan-forvo-server"; + version = "0-unstable-2024-10-21"; + src = fetchFromGitHub { + owner = "jamesnicolas"; + repo = "yomichan-forvo-server"; + rev = "364fc6d5d10969f516e0fa283460dfaf08c98e15"; + hash = "sha256-Jpee9hkXCiBmSW7hzJ1rAg45XVIiLC8WENc09+ySFVI="; + }; + passthru.updateScript = nix-update-script { + extraArgs = [ "--version=branch" ]; + }; + meta = { + description = "Audio server for yomichan that scrapes forvo for audio files"; + homepage = "https://github.com/jamesnicolas/yomichan-forvo-server"; + license = lib.licenses.unlicense; + maintainers = with lib.maintainers; [ junestepp ]; + }; +} From 8dc12689a0a6e07d9e977e741c04c3a5df240d5f Mon Sep 17 00:00:00 2001 From: June Stepp Date: Sat, 3 May 2025 22:55:54 -0500 Subject: [PATCH 41/82] ankiAddons.local-audio-yomichan: init at 0-unstable-2025-04-26 --- pkgs/games/anki/addons/default.nix | 2 + .../addons/local-audio-yomichan/default.nix | 73 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 pkgs/games/anki/addons/local-audio-yomichan/default.nix diff --git a/pkgs/games/anki/addons/default.nix b/pkgs/games/anki/addons/default.nix index 7f60c7e29e25..57560aad77c4 100644 --- a/pkgs/games/anki/addons/default.nix +++ b/pkgs/games/anki/addons/default.nix @@ -6,6 +6,8 @@ anki-connect = callPackage ./anki-connect { }; + local-audio-yomichan = callPackage ./local-audio-yomichan { }; + passfail2 = callPackage ./passfail2 { }; reviewer-refocus-card = callPackage ./reviewer-refocus-card { }; diff --git a/pkgs/games/anki/addons/local-audio-yomichan/default.nix b/pkgs/games/anki/addons/local-audio-yomichan/default.nix new file mode 100644 index 000000000000..7ba361c8590c --- /dev/null +++ b/pkgs/games/anki/addons/local-audio-yomichan/default.nix @@ -0,0 +1,73 @@ +{ + lib, + anki-utils, + fetchFromGitHub, + python3, + nix-update-script, +}: +anki-utils.buildAnkiAddon (finalAttrs: { + pname = "local-audio-yomichan"; + version = "0-unstable-2025-04-26"; + src = fetchFromGitHub { + owner = "yomidevs"; + repo = "local-audio-yomichan"; + rev = "34750f1d8ca1cb473128fea7976a4d981e5e78a4"; + sparseCheckout = [ "plugin" ]; + hash = "sha256-2gyggcvxParay+1B7Sg2COKyocoxaRO1WTz+ymdRp4w="; + }; + sourceRoot = "${finalAttrs.src.name}/plugin"; + processUserFiles = '' + # Addon will try to load extra stuff unless Python package name is "plugin". + temp=$(mktemp -d) + ln -s $PWD $temp/plugin + # Addoon expects `user_files` dir at `$XDG_DATA_HOME/local-audio-yomichan` + ln -s $PWD/user_files $temp/local-audio-yomichan + + PYTHONPATH=$temp \ + WO_ANKI=1 \ + XDG_DATA_HOME=$temp \ + ${lib.getExe python3} -c \ + "from plugin import db_utils; \ + db_utils.init_db()" + ''; + passthru.updateScript = nix-update-script { + extraArgs = [ "--version=branch" ]; + }; + meta = { + description = "Run a local audio server for Yomitan"; + longDescription = '' + This add-on must be configured with an audio collection. + + Example: + + ```nix + pkgs.ankiAddons.local-audio-yomichan.withConfig { + userFiles = + let + audio-collection = + pkgs.runCommand "local-yomichan-audio-collection" + { + outputHashMode = "recursive"; + outputHash = "sha256-NxbcXh2SDPfCd+ZHAWT5JdxRecNbT4Xpo0pxX5/DOfo="; + + src = pkgs.requireFile { + name = "local-yomichan-audio-collection-2023-06-11-opus.tar.xz"; + url = "https://github.com/yomidevs/local-audio-yomichan?tab=readme-ov-file#steps"; + sha256 = "1xsxp8iggklv77rj972mqaa1i8f9hvr3ir0r2mwfqcdz4q120hr1"; + }; + } + ''' + mkdir -p $out + cd $out + tar -xf "$src" + '''; + in + "''${audio-collection}/user_files"; + } + ``` + ''; + homepage = "https://github.com/yomidevs/local-audio-yomichan"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ junestepp ]; + }; +}) From e9216c0d4cecf55013a275abea07076136dea8d5 Mon Sep 17 00:00:00 2001 From: June Stepp Date: Thu, 15 May 2025 13:29:45 -0500 Subject: [PATCH 42/82] ankiAddons.recolor: init at 3.1 --- pkgs/games/anki/addons/default.nix | 2 ++ pkgs/games/anki/addons/recolor/default.nix | 27 ++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 pkgs/games/anki/addons/recolor/default.nix diff --git a/pkgs/games/anki/addons/default.nix b/pkgs/games/anki/addons/default.nix index 57560aad77c4..d602b1ea877e 100644 --- a/pkgs/games/anki/addons/default.nix +++ b/pkgs/games/anki/addons/default.nix @@ -10,6 +10,8 @@ passfail2 = callPackage ./passfail2 { }; + recolor = callPackage ./recolor { }; + reviewer-refocus-card = callPackage ./reviewer-refocus-card { }; yomichan-forvo-server = callPackage ./yomichan-forvo-server { }; diff --git a/pkgs/games/anki/addons/recolor/default.nix b/pkgs/games/anki/addons/recolor/default.nix new file mode 100644 index 000000000000..3e60b0193904 --- /dev/null +++ b/pkgs/games/anki/addons/recolor/default.nix @@ -0,0 +1,27 @@ +{ + lib, + anki-utils, + fetchFromGitHub, + nix-update-script, +}: +anki-utils.buildAnkiAddon (finalAttrs: { + pname = "recolor"; + version = "3.1"; + src = fetchFromGitHub { + owner = "AnKing-VIP"; + repo = "AnkiRecolor"; + rev = finalAttrs.version; + sparseCheckout = [ "src/addon" ]; + hash = "sha256-28DJq2l9DP8O6OsbNQCZ0pm4S6CQ3Yz0Vfvlj+iQw8Y="; + }; + sourceRoot = "${finalAttrs.src.name}/src/addon"; + passthru.updateScript = nix-update-script { }; + meta = { + description = "ReColor your Anki desktop to whatever aesthetic you like"; + homepage = "https://github.com/AnKing-VIP/AnkiRecolor"; + # No license file, but it can be assumed to be AGPL3 based on + # https://ankiweb.net/account/terms. + license = lib.licenses.agpl3Only; + maintainers = with lib.maintainers; [ junestepp ]; + }; +}) From 4ac7f4bc10a85a943b95eb827ce313c05ecfe937 Mon Sep 17 00:00:00 2001 From: Peder Bergebakken Sundt Date: Sun, 8 Jun 2025 16:37:50 +0200 Subject: [PATCH 43/82] harper: 0.40.0 -> 0.41.0 Changelog: https://github.com/Automattic/harper/releases/tag/v0.41.0 --- pkgs/by-name/ha/harper/package.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/by-name/ha/harper/package.nix b/pkgs/by-name/ha/harper/package.nix index ea6eca7fe723..1a7c92eda526 100644 --- a/pkgs/by-name/ha/harper/package.nix +++ b/pkgs/by-name/ha/harper/package.nix @@ -7,18 +7,18 @@ rustPlatform.buildRustPackage rec { pname = "harper"; - version = "0.40.0"; + version = "0.41.0"; src = fetchFromGitHub { owner = "Automattic"; repo = "harper"; rev = "v${version}"; - hash = "sha256-QrIRfAehrKgJwAB3pWfSpIUnIwRLjuuRbTEgUpCe2LM="; + hash = "sha256-o5F9gDeHFq2U9q/kRQVn4otbbQVV4tg6n5Ap7Dwm7oI="; }; buildAndTestSubdir = "harper-ls"; useFetchCargoVendor = true; - cargoHash = "sha256-hkr7gNRwY+L45Efk6mWPrykj60n3ChryBKRFCC4W1Q0="; + cargoHash = "sha256-KgcsLzFrN+ZDgV6cZmkUv4tUt5ko4+giHq19NjfuF74="; passthru.updateScript = nix-update-script { }; From cfcdbad6375bc115b1cf09b98c38f0cb2703c209 Mon Sep 17 00:00:00 2001 From: Emily Date: Sat, 7 Jun 2025 02:38:06 +0100 Subject: [PATCH 44/82] =?UTF-8?q?nixos/man-db:=20fix=20cross=E2=80=90compi?= =?UTF-8?q?lation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I don’t love this, but it seems to be the best we can do. --- nixos/modules/misc/man-db.nix | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/nixos/modules/misc/man-db.nix b/nixos/modules/misc/man-db.nix index 56b935c97597..dc6af4fe9692 100644 --- a/nixos/modules/misc/man-db.nix +++ b/nixos/modules/misc/man-db.nix @@ -69,10 +69,19 @@ in environment.systemPackages = [ cfg.package ]; environment.etc."man_db.conf".text = let + # We unfortunately can’t use the customized `cfg.package` when + # cross‐compiling. Instead we detect that situation and work + # around it by using the vanilla one, like the OpenSSH module. + buildPackage = + if pkgs.stdenv.buildPlatform.canExecute pkgs.stdenv.hostPlatform then + cfg.package + else + pkgs.buildPackages.man-db; + manualCache = pkgs.runCommand "man-cache" { - nativeBuildInputs = [ cfg.package ]; + nativeBuildInputs = [ buildPackage ]; } '' echo "MANDB_MAP ${cfg.manualPages}/share/man $out" > man.conf From e41ea86af129e0b736b8579a00dd6c2cf8952e27 Mon Sep 17 00:00:00 2001 From: "R. Ryantm" Date: Sun, 8 Jun 2025 17:54:41 +0000 Subject: [PATCH 45/82] mpls: 0.15.2 -> 0.15.3 --- pkgs/by-name/mp/mpls/package.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/by-name/mp/mpls/package.nix b/pkgs/by-name/mp/mpls/package.nix index 0e9abac8f657..baca6ca2a8d9 100644 --- a/pkgs/by-name/mp/mpls/package.nix +++ b/pkgs/by-name/mp/mpls/package.nix @@ -7,13 +7,13 @@ }: buildGoModule rec { pname = "mpls"; - version = "0.15.2"; + version = "0.15.3"; src = fetchFromGitHub { owner = "mhersson"; repo = "mpls"; tag = "v${version}"; - hash = "sha256-UQIGg31OJ8vTqlj5JLYxOxg9oS0+PXPcdocAJbUgpzY="; + hash = "sha256-MGrvJOnjNNXU8Z9rqDIacb5awKxf50xYeNkY06U4cUk="; }; vendorHash = "sha256-n3DG3sR7HOQPQJW1t1qC94EKkDBgXpdmjUWtLzAE7kY="; From 0aa93417d819f5bfa6e1600b47aea5c516b2103b Mon Sep 17 00:00:00 2001 From: "R. Ryantm" Date: Sun, 8 Jun 2025 21:50:04 +0000 Subject: [PATCH 46/82] dependabot-cli: 1.65.0 -> 1.66.0 --- pkgs/by-name/de/dependabot-cli/package.nix | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pkgs/by-name/de/dependabot-cli/package.nix b/pkgs/by-name/de/dependabot-cli/package.nix index ccce75d5721c..fef777d03e45 100644 --- a/pkgs/by-name/de/dependabot-cli/package.nix +++ b/pkgs/by-name/de/dependabot-cli/package.nix @@ -12,20 +12,20 @@ }: let pname = "dependabot-cli"; - version = "1.65.0"; + version = "1.66.0"; # `tag` is what `dependabot` uses to find the relevant docker images. tag = "nixpkgs-dependabot-cli-${version}"; # Get these hashes from # nix run nixpkgs#nix-prefetch-docker -- --image-name ghcr.io/github/dependabot-update-job-proxy/dependabot-update-job-proxy --image-tag latest --final-image-name dependabot-update-job-proxy --final-image-tag ${tag} - updateJobProxy.imageDigest = "sha256:ef245bd38aaa3cf89cafcffe0630d3ad3cff840488a2051a48517454e7f42368"; - updateJobProxy.hash = "sha256-yndoGLpyV2MiIs0QXbF/W0xJ6jtmnw/ezL54VM80/CI="; + updateJobProxy.imageDigest = "sha256:0b0d8c67cad11fa0885fcc3fe0add06638c29c19f05a83f80077d5dbb70c2037"; + updateJobProxy.hash = "sha256-7O/1NYdhtmO+MAwfu8BSaJQ1RVkXrFPBpfRy0N7p1lQ="; # Get these hashes from # nix run nixpkgs#nix-prefetch-docker -- --image-name ghcr.io/dependabot/dependabot-updater-github-actions --image-tag latest --final-image-name dependabot-updater-github-actions --final-image-tag ${tag} - updaterGitHubActions.imageDigest = "sha256:adeaa00b4ae49e942adccec76d4487a393eebd0dec27cd75a3cdf6cc46d801d7"; - updaterGitHubActions.hash = "sha256-ni9rSEpeo0gIdYy2CIIpnIWg0kttoTnvRwbZ71QwmIg="; + updaterGitHubActions.imageDigest = "sha256:11de6594db1c23e7ed4a6b621e8584b4a3b34484d51f2f8aa850c21fbce9094f"; + updaterGitHubActions.hash = "sha256-cImOCW7tggBWEPlmE55b4OFMxf/+VGLoqx0tRualowo="; in buildGoModule { inherit pname version; @@ -34,10 +34,10 @@ buildGoModule { owner = "dependabot"; repo = "cli"; rev = "v${version}"; - hash = "sha256-A7CPn0YDeyr+d1OUde2TGfSt3eCfrK4k3S7NWsvCGx0="; + hash = "sha256-9VgcQgiNv1v6+jnaWK10yccC1ILSxiIj9ZCIhHY57jk="; }; - vendorHash = "sha256-pnB1SkuEGm0KfkDfjnoff5fZRsAgD5w2H4UwsD3Jlbo="; + vendorHash = "sha256-gENlo1EPzsML+HkDBg4a2VGTUhyKY8AhlpHVszYWBno="; ldflags = [ "-s" From 5b89278f4799eb0c6aeac381248ed5f4ee411740 Mon Sep 17 00:00:00 2001 From: Boris Nagaev Date: Sun, 8 Jun 2025 21:00:20 -0300 Subject: [PATCH 47/82] flutter332: 3.32.0 -> 3.32.2 --- .../compilers/flutter/versions/3_32/data.json | 92 +++++++++---------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/pkgs/development/compilers/flutter/versions/3_32/data.json b/pkgs/development/compilers/flutter/versions/3_32/data.json index a4e1d1db18c4..ace17df24812 100644 --- a/pkgs/development/compilers/flutter/versions/3_32/data.json +++ b/pkgs/development/compilers/flutter/versions/3_32/data.json @@ -1,73 +1,73 @@ { - "version": "3.32.0", - "engineVersion": "18818009497c581ede5d8a3b8b833b81d00cebb7", + "version": "3.32.2", + "engineVersion": "109150893958777c8f2215f6cfd3e89e984e8dea", "engineSwiftShaderHash": "sha256-ATVcuxqPHqHOWYyO7DoX9LdgUiO3INUi7m9Mc6ccc1M=", "engineSwiftShaderRev": "d040a5bab638bf7c226235c95787ba6288bb6416", "channel": "stable", "engineHashes": { "aarch64-linux": { - "aarch64-linux": "sha256-zGlgnVbNPZ9OX5VFxaajc8xqPKftzZMkyem2NLk8EH8=", - "x86_64-linux": "sha256-zGlgnVbNPZ9OX5VFxaajc8xqPKftzZMkyem2NLk8EH8=" + "aarch64-linux": "sha256-l/7p9fPVPIx/CqT4xTUPQLlBU18aZSlimamELMgkAjY=", + "x86_64-linux": "sha256-l/7p9fPVPIx/CqT4xTUPQLlBU18aZSlimamELMgkAjY=" }, "x86_64-linux": { - "aarch64-linux": "sha256-TWwsPtAnkQzsvNLUd5Q3G80ALeh7nM/XV4M6rfBvUGY=", - "x86_64-linux": "sha256-TWwsPtAnkQzsvNLUd5Q3G80ALeh7nM/XV4M6rfBvUGY=" + "aarch64-linux": "sha256-6shoelu1oOcTbzXlFcAOsVMF3b/3RZ2vHuMEXvKyzbo=", + "x86_64-linux": "sha256-6shoelu1oOcTbzXlFcAOsVMF3b/3RZ2vHuMEXvKyzbo=" } }, - "dartVersion": "3.8.0", + "dartVersion": "3.8.1", "dartHash": { - "x86_64-linux": "sha256-/b6dNwqeMymHKI4cz2ggfVtcHWtdsrlVyEZ1Z2G0RKw=", - "aarch64-linux": "sha256-tXIeGM7n1lx9GOwOMEFapiW0sHBlhupx5NCAtFd73Pk=", - "x86_64-darwin": "sha256-wD9Z3J29N4ecWKmCetj5GnbTQ8LiJ1tZFEbPuG6ny5w=", - "aarch64-darwin": "sha256-IIFn6OTpTH8LzwZzF7V8yUrhHkjavMUWX7n62YEMABk=" + "x86_64-linux": "sha256-3eE40VMwrPFD502lIaz+CkD7mBnSI/WqJ3C4DVQ01Z4=", + "aarch64-linux": "sha256-0GXCO00ar5532h+cXBEIe8BhGVKOuGuoPzr1M00muh4=", + "x86_64-darwin": "sha256-S3iGDVLollApke2SnXAcV919qsDTVmz5Gf9fTletr00=", + "aarch64-darwin": "sha256-haHQks9N1mBIqRsYg9sOLw7ra7gC708gsTWfKxvIK1c=" }, - "flutterHash": "sha256-Wk84RfnPvPVVnnbwGcnHIcRnu3Kizo2AkRQbVSEw+1M=", + "flutterHash": "sha256-bL+WRW9tOLEXeAwZKgwN4y8Vj6s6FOCUm3JJilLCkY8=", "artifactHashes": { "android": { - "aarch64-darwin": "sha256-+YUzIG/qUFb4X2ftR6Gf0h1mt/5Dy59B7QD09X1XVYY=", - "aarch64-linux": "sha256-lZIo8AGzrXant29kfiOKlfQ0SJAPXpsdZCaKfqxn0zA=", - "x86_64-darwin": "sha256-+YUzIG/qUFb4X2ftR6Gf0h1mt/5Dy59B7QD09X1XVYY=", - "x86_64-linux": "sha256-lZIo8AGzrXant29kfiOKlfQ0SJAPXpsdZCaKfqxn0zA=" + "aarch64-darwin": "sha256-VW1JzE6NfpGk2WFyPnvgkhlc+/dgkVtfPJ3HLF2SxjM=", + "aarch64-linux": "sha256-aNZyIBedC35v2/lePY1UcJYP3Wh0JccPrsABHlhdoOI=", + "x86_64-darwin": "sha256-VW1JzE6NfpGk2WFyPnvgkhlc+/dgkVtfPJ3HLF2SxjM=", + "x86_64-linux": "sha256-aNZyIBedC35v2/lePY1UcJYP3Wh0JccPrsABHlhdoOI=" }, "fuchsia": { - "aarch64-darwin": "sha256-F4uNyPIt6FSVCSOjR6mtgHHMMcJd3pAdT4uEiBJSASk=", - "aarch64-linux": "sha256-F4uNyPIt6FSVCSOjR6mtgHHMMcJd3pAdT4uEiBJSASk=", - "x86_64-darwin": "sha256-F4uNyPIt6FSVCSOjR6mtgHHMMcJd3pAdT4uEiBJSASk=", - "x86_64-linux": "sha256-F4uNyPIt6FSVCSOjR6mtgHHMMcJd3pAdT4uEiBJSASk=" + "aarch64-darwin": "sha256-8Jo1dP2uugp75BjQvvgvxnCJI0oyLlClJ2YaaiSkJzs=", + "aarch64-linux": "sha256-8Jo1dP2uugp75BjQvvgvxnCJI0oyLlClJ2YaaiSkJzs=", + "x86_64-darwin": "sha256-8Jo1dP2uugp75BjQvvgvxnCJI0oyLlClJ2YaaiSkJzs=", + "x86_64-linux": "sha256-8Jo1dP2uugp75BjQvvgvxnCJI0oyLlClJ2YaaiSkJzs=" }, "ios": { - "aarch64-darwin": "sha256-HlGXG7hyi4oCdN4bGP6GYa++rTruZC7v+laR4733xS4=", - "aarch64-linux": "sha256-HlGXG7hyi4oCdN4bGP6GYa++rTruZC7v+laR4733xS4=", - "x86_64-darwin": "sha256-HlGXG7hyi4oCdN4bGP6GYa++rTruZC7v+laR4733xS4=", - "x86_64-linux": "sha256-HlGXG7hyi4oCdN4bGP6GYa++rTruZC7v+laR4733xS4=" + "aarch64-darwin": "sha256-75DZ9m1yxybk/xP2UMDr/thBtP2q3iOHPakxxHRbIWs=", + "aarch64-linux": "sha256-75DZ9m1yxybk/xP2UMDr/thBtP2q3iOHPakxxHRbIWs=", + "x86_64-darwin": "sha256-75DZ9m1yxybk/xP2UMDr/thBtP2q3iOHPakxxHRbIWs=", + "x86_64-linux": "sha256-75DZ9m1yxybk/xP2UMDr/thBtP2q3iOHPakxxHRbIWs=" }, "linux": { - "aarch64-darwin": "sha256-y/xxUQK/9GeXjMTUPZSGhfP83rJzCm1Pd2PMjnAHdnk=", - "aarch64-linux": "sha256-y/xxUQK/9GeXjMTUPZSGhfP83rJzCm1Pd2PMjnAHdnk=", - "x86_64-darwin": "sha256-P5UQiY4QHLJQMmTpTfTFfh6QrqelhWyaGpSXNtM8vJE=", - "x86_64-linux": "sha256-P5UQiY4QHLJQMmTpTfTFfh6QrqelhWyaGpSXNtM8vJE=" + "aarch64-darwin": "sha256-7gGCUYERyMdga0bgxWo2ZCn9yUwIKKBOuzXvNfWS6Bw=", + "aarch64-linux": "sha256-7gGCUYERyMdga0bgxWo2ZCn9yUwIKKBOuzXvNfWS6Bw=", + "x86_64-darwin": "sha256-VlkWtHFJc8AbzvQbEL8IzXNpkrz4hIR7yK+gRHH1Qtc=", + "x86_64-linux": "sha256-VlkWtHFJc8AbzvQbEL8IzXNpkrz4hIR7yK+gRHH1Qtc=" }, "macos": { - "aarch64-darwin": "sha256-FkvjRiKWa/FUITdwK1ldLCcsfjs8nrH7L0mXGHnVIko=", - "aarch64-linux": "sha256-FkvjRiKWa/FUITdwK1ldLCcsfjs8nrH7L0mXGHnVIko=", - "x86_64-darwin": "sha256-FkvjRiKWa/FUITdwK1ldLCcsfjs8nrH7L0mXGHnVIko=", - "x86_64-linux": "sha256-FkvjRiKWa/FUITdwK1ldLCcsfjs8nrH7L0mXGHnVIko=" + "aarch64-darwin": "sha256-fonn1C8JJ/Dpid6eyzqgTw5jm4dgdt1KF+sd0d5wRNc=", + "aarch64-linux": "sha256-fonn1C8JJ/Dpid6eyzqgTw5jm4dgdt1KF+sd0d5wRNc=", + "x86_64-darwin": "sha256-fonn1C8JJ/Dpid6eyzqgTw5jm4dgdt1KF+sd0d5wRNc=", + "x86_64-linux": "sha256-fonn1C8JJ/Dpid6eyzqgTw5jm4dgdt1KF+sd0d5wRNc=" }, "universal": { - "aarch64-darwin": "sha256-bt/UiY3t1wZUnpMo1uVQPdlG/7X+OrAOZRXIaXKH3Ls=", - "aarch64-linux": "sha256-NShVNyK6Cx5bddhv6hg3rM+QPczrm2MmHCgb14h78SA=", - "x86_64-darwin": "sha256-zXSufTmlyaHM0fJinirUfB3XjD3dzKFD6iyhUADsyQY=", - "x86_64-linux": "sha256-MQw71FYYuLKd60cwMddAjVe9vgwx8MR4xVe0Z9J7uAo=" + "aarch64-darwin": "sha256-XXktfE+Rx2kj+4PYlWZmfHCRheWDF1K+kCo1McnjZao=", + "aarch64-linux": "sha256-jRJ5OLuoV0b/Rd7SpYmyjCL7ED8iWjawvS8ZMAqVowE=", + "x86_64-darwin": "sha256-lTudK0BzZznIOAc2bTildCLg0ZeLJX19suhG4ZgH1Eo=", + "x86_64-linux": "sha256-M41bQrf1amzW1QGkq37gNgN5zh3v4/+OuBxp4CWUSqI=" }, "web": { - "aarch64-darwin": "sha256-dpMJQsUd98X+tmUnqRZQ1o5g334i7dyxBNvg2znJeaE=", - "aarch64-linux": "sha256-dpMJQsUd98X+tmUnqRZQ1o5g334i7dyxBNvg2znJeaE=", - "x86_64-darwin": "sha256-dpMJQsUd98X+tmUnqRZQ1o5g334i7dyxBNvg2znJeaE=", - "x86_64-linux": "sha256-dpMJQsUd98X+tmUnqRZQ1o5g334i7dyxBNvg2znJeaE=" + "aarch64-darwin": "sha256-l6/ZekcmlueBP7DdAuQpjGuYc6MFlMSWW4tnU2PixNU=", + "aarch64-linux": "sha256-l6/ZekcmlueBP7DdAuQpjGuYc6MFlMSWW4tnU2PixNU=", + "x86_64-darwin": "sha256-l6/ZekcmlueBP7DdAuQpjGuYc6MFlMSWW4tnU2PixNU=", + "x86_64-linux": "sha256-l6/ZekcmlueBP7DdAuQpjGuYc6MFlMSWW4tnU2PixNU=" }, "windows": { - "x86_64-darwin": "sha256-3ZfYqlyjBaBaZjxp9k2DCsD4QZL/+fbXfCFxX3i4Q/Q=", - "x86_64-linux": "sha256-3ZfYqlyjBaBaZjxp9k2DCsD4QZL/+fbXfCFxX3i4Q/Q=" + "x86_64-darwin": "sha256-zxVV76R80bRqzJaWCBj9RlLkpB4HmX1iTYcdLAbiqT4=", + "x86_64-linux": "sha256-zxVV76R80bRqzJaWCBj9RlLkpB4HmX1iTYcdLAbiqT4=" } }, "pubspecLock": { @@ -266,11 +266,11 @@ "dependency": "direct main", "description": { "name": "dds", - "sha256": "4e206d308bd94595af42e4a561948ef8dba211c9db47f4360c48a5a1f8b44cb5", + "sha256": "76fc5140ce4e8922711bbe6dfd3713283ecc7f386c52fc7f594cd5f3e6b80633", "url": "https://pub.dev" }, "source": "hosted", - "version": "5.0.0" + "version": "5.0.2" }, "dds_service_extensions": { "dependency": "direct main", @@ -286,11 +286,11 @@ "dependency": "direct main", "description": { "name": "devtools_shared", - "sha256": "fa71f07006dfdf3f226ec76db95a4bad156820c081452cc99d18a4f291001bee", + "sha256": "659e2d65aa5ef5c3551163811c5c6fa1b973b3df80d8cac6f618035edcdc1096", "url": "https://pub.dev" }, "source": "hosted", - "version": "11.2.0" + "version": "11.2.1" }, "dtd": { "dependency": "direct main", From 61ccd7ea75ba85594eb116069d058e6e9828c750 Mon Sep 17 00:00:00 2001 From: Audrey Dutcher Date: Sun, 8 Jun 2025 19:11:54 -0700 Subject: [PATCH 48/82] stdenv/freebsd: add missing rewriteURL parameter --- pkgs/stdenv/freebsd/default.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/pkgs/stdenv/freebsd/default.nix b/pkgs/stdenv/freebsd/default.nix index b52c8ea37244..568fe19bd44f 100644 --- a/pkgs/stdenv/freebsd/default.nix +++ b/pkgs/stdenv/freebsd/default.nix @@ -501,6 +501,7 @@ in inherit lib; inherit (self) stdenvNoCC; inherit (prevStage) curl; + inherit (config) rewriteURL; }; gettext = super.gettext.overrideAttrs { NIX_CFLAGS_COMPILE = "-DHAVE_ICONV=1"; # we clearly have iconv. what do you want? From 344411f02ca9fd13162c5d14858de467ed6c6d0b Mon Sep 17 00:00:00 2001 From: Audrey Dutcher Date: Sun, 8 Jun 2025 19:39:45 -0700 Subject: [PATCH 49/82] fakeroot: only include libcap on linux --- pkgs/by-name/fa/fakeroot/package.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/by-name/fa/fakeroot/package.nix b/pkgs/by-name/fa/fakeroot/package.nix index 414880911221..a7fbca8e3305 100644 --- a/pkgs/by-name/fa/fakeroot/package.nix +++ b/pkgs/by-name/fa/fakeroot/package.nix @@ -41,7 +41,7 @@ stdenv.mkDerivation (finalAttrs: { autoreconfHook po4a ]; - buildInputs = lib.optional (!stdenv.hostPlatform.isDarwin) libcap; + buildInputs = lib.optional stdenv.hostPlatform.isLinux libcap; postUnpack = '' sed -i \ From 15c984b2a509c3e3149067cf4f1ffd6a45f4368c Mon Sep 17 00:00:00 2001 From: "R. Ryantm" Date: Mon, 9 Jun 2025 02:41:07 +0000 Subject: [PATCH 50/82] python3Packages.pyngrok: 7.2.9 -> 7.2.11 --- pkgs/development/python-modules/pyngrok/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/development/python-modules/pyngrok/default.nix b/pkgs/development/python-modules/pyngrok/default.nix index 619d98e60636..5a6f3d32b490 100644 --- a/pkgs/development/python-modules/pyngrok/default.nix +++ b/pkgs/development/python-modules/pyngrok/default.nix @@ -9,14 +9,14 @@ buildPythonPackage rec { pname = "pyngrok"; - version = "7.2.9"; + version = "7.2.11"; pyproject = true; disabled = pythonOlder "3.8"; src = fetchPypi { inherit pname version; - hash = "sha256-Ixt/1Kel6CZajWFQ07o8gtnf/UCe2u23LE5isy3kT5E="; + hash = "sha256-n4iQOJvZWrwA7KE4Rsj0haDbZmfcBZh+uY/eNDrfslo="; }; build-system = [ From a2f45eecc1321263707bb62ca6d781d6794f1c3c Mon Sep 17 00:00:00 2001 From: Audrey Dutcher Date: Sun, 8 Jun 2025 19:40:20 -0700 Subject: [PATCH 51/82] freebsd.filterSource: don't build rsync with tests --- .../bsd/freebsd/pkgs/filterSource.nix | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/pkgs/os-specific/bsd/freebsd/pkgs/filterSource.nix b/pkgs/os-specific/bsd/freebsd/pkgs/filterSource.nix index 09674056d9cd..80dad06be8f8 100644 --- a/pkgs/os-specific/bsd/freebsd/pkgs/filterSource.nix +++ b/pkgs/os-specific/bsd/freebsd/pkgs/filterSource.nix @@ -21,12 +21,17 @@ in runCommand "${pname}-filtered-src" { nativeBuildInputs = [ - (pkgsBuildBuild.rsync.override { - enableZstd = false; - enableXXHash = false; - enableOpenSSL = false; - enableLZ4 = false; - }) + ( + (pkgsBuildBuild.rsync.override { + enableZstd = false; + enableXXHash = false; + enableOpenSSL = false; + enableLZ4 = false; + }).overrideAttrs + { + doCheck = false; + } + ) ]; } '' From ec7b23cc8a9df4d738b347e91a44de2533097426 Mon Sep 17 00:00:00 2001 From: Audrey Dutcher Date: Sun, 8 Jun 2025 19:40:48 -0700 Subject: [PATCH 52/82] stdenv/freebsd: provide libiconv for early boot --- pkgs/stdenv/freebsd/default.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkgs/stdenv/freebsd/default.nix b/pkgs/stdenv/freebsd/default.nix index 568fe19bd44f..7485cf1ce6eb 100644 --- a/pkgs/stdenv/freebsd/default.nix +++ b/pkgs/stdenv/freebsd/default.nix @@ -230,6 +230,7 @@ let ]; }; iconv = linkBootstrap { paths = [ "bin/iconv" ]; }; + libiconv = linkBootstrap { paths = [ "include/iconv.h" ]; }; patch = linkBootstrap { paths = [ "bin/patch" ]; }; gnutar = linkBootstrap { paths = [ "bin/tar" ]; }; gawk = linkBootstrap { @@ -486,6 +487,7 @@ in diffutils findutils iconv + libiconv patch gnutar gawk From 0d46fda9746f50f5e1d69950000b5ff8c6941a28 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Sun, 25 May 2025 16:24:19 +0200 Subject: [PATCH 53/82] nixos/vmalert: support multiple instances vmalert only supports a single datasource for querying metrics and managing alerts. Because of that, we need two instances to manage alerts for both VictoriaLogs and VictoriaMetrics. This is strongly inspired by the change made to Redis, i.e. a new `instances` option was introduced with each option inside it. With `mkRenamedOptionModule` it's ensured that existing configurations still evaluate to the same result. --- doc/release-notes/rl-2511.section.md | 3 + .../manual/release-notes/rl-2305.section.md | 2 +- nixos/modules/services/monitoring/vmalert.nix | 261 +++++++++++------- nixos/tests/victoriametrics/vmalert.nix | 2 +- 4 files changed, 159 insertions(+), 109 deletions(-) diff --git a/doc/release-notes/rl-2511.section.md b/doc/release-notes/rl-2511.section.md index 02b08039812b..9214f1d49bfc 100644 --- a/doc/release-notes/rl-2511.section.md +++ b/doc/release-notes/rl-2511.section.md @@ -23,6 +23,9 @@ - Added `rewriteURL` attribute to the nixpkgs `config`, to allow for rewriting the URLs downloaded by `fetchurl`. +- `vmalert` now supports multiple instances with the option `services.vmalert.instances."".enable` + et al.. + ## Nixpkgs Library {#sec-nixpkgs-release-25.11-lib} diff --git a/nixos/doc/manual/release-notes/rl-2305.section.md b/nixos/doc/manual/release-notes/rl-2305.section.md index cae573c3452a..7ffe079977af 100644 --- a/nixos/doc/manual/release-notes/rl-2305.section.md +++ b/nixos/doc/manual/release-notes/rl-2305.section.md @@ -105,7 +105,7 @@ In addition to numerous new and updated packages, this release has the following - [ivpn](https://www.ivpn.net/), a secure, private VPN with fast WireGuard connections. Available as [services.ivpn](#opt-services.ivpn.enable). -- [vmalert](https://victoriametrics.com/), an alerting engine for VictoriaMetrics. Available as [services.vmalert](#opt-services.vmalert.enable). +- [vmalert](https://victoriametrics.com/), an alerting engine for VictoriaMetrics. Available as [services.vmalert.instances](#opt-services.vmalert.instances._name_.enable). - [jellyseerr](https://github.com/Fallenbagel/jellyseerr), a web-based requests manager for Jellyfin, forked from Overseerr. Available as [services.jellyseerr](#opt-services.jellyseerr.enable). diff --git a/nixos/modules/services/monitoring/vmalert.nix b/nixos/modules/services/monitoring/vmalert.nix index 438d067643fb..0baaa039e395 100644 --- a/nixos/modules/services/monitoring/vmalert.nix +++ b/nixos/modules/services/monitoring/vmalert.nix @@ -10,9 +10,9 @@ let format = pkgs.formats.yaml { }; - confOpts = concatStringsSep " \\\n" ( - mapAttrsToList mkLine (filterAttrs (_: v: v != false) cfg.settings) - ); + mkConfOpts = + settings: + concatStringsSep " \\\n" (mapAttrsToList mkLine (filterAttrs (_: v: v != false) settings)); confType = with types; let @@ -33,124 +33,171 @@ let concatMapStringsSep " " (v: "-${key}=${escapeShellArg (toString v)}") value else "-${key}=${escapeShellArg (toString value)}"; + + vmalertName = name: "vmalert" + lib.optionalString (name != "") ("-" + name); + enabledInstances = lib.filterAttrs (name: conf: conf.enable) config.services.vmalert.instances; in { + imports = [ + (lib.mkRenamedOptionModule + [ "services" "vmalert" "enable" ] + [ "services" "vmalert" "instances" "" "enable" ] + ) + (lib.mkRenamedOptionModule + [ "services" "vmalert" "rules" ] + [ "services" "vmalert" "instances" "" "rules" ] + ) + (lib.mkRenamedOptionModule + [ "services" "vmalert" "settings" ] + [ "services" "vmalert" "instances" "" "settings" ] + ) + ]; + # interface - options.services.vmalert = { - enable = lib.mkOption { - type = lib.types.bool; - default = false; - description = '' - Wether to enable VictoriaMetrics's `vmalert`. + options.services.vmalert.package = mkPackageOption pkgs "victoriametrics" { }; - `vmalert` evaluates alerting and recording rules against a data source, sends notifications via Alertmanager. - ''; - }; + options.services.vmalert.instances = mkOption { + default = { }; - package = mkPackageOption pkgs "victoriametrics" { }; + description = '' + Define multiple instances of vmalert. + ''; - settings = mkOption { - type = types.submodule { - freeformType = confType; - options = { + type = types.attrsOf ( + types.submodule ( + { name, config, ... }: + { + options = { + enable = lib.mkOption { + type = lib.types.bool; + default = false; + description = '' + Wether to enable VictoriaMetrics's `vmalert`. - "datasource.url" = mkOption { - type = types.nonEmptyStr; - example = "http://localhost:8428"; - description = '' - Datasource compatible with Prometheus HTTP API. - ''; + `vmalert` evaluates alerting and recording rules against a data source, sends notifications via Alertmanager. + ''; + }; + + settings = mkOption { + type = types.submodule { + freeformType = confType; + options = { + + "datasource.url" = mkOption { + type = types.nonEmptyStr; + example = "http://localhost:8428"; + description = '' + Datasource compatible with Prometheus HTTP API. + ''; + }; + + "notifier.url" = mkOption { + type = with types; listOf nonEmptyStr; + default = [ ]; + example = [ "http://127.0.0.1:9093" ]; + description = '' + Prometheus Alertmanager URL. List all Alertmanager URLs if it runs in the cluster mode to ensure high availability. + ''; + }; + + "rule" = mkOption { + type = with types; listOf path; + description = '' + Path to the files with alerting and/or recording rules. + + ::: {.note} + Consider using the {option}`services.vmalert.instances..rules` option as a convenient alternative for declaring rules + directly in the `nix` language. + ::: + ''; + }; + + }; + }; + default = { }; + example = { + "datasource.url" = "http://localhost:8428"; + "datasource.disableKeepAlive" = true; + "datasource.showURL" = false; + "rule" = [ + "http:///path/to/rules" + "dir/*.yaml" + ]; + }; + description = '' + `vmalert` configuration, passed via command line flags. Refer to + + for details on supported values. + ''; + }; + + rules = mkOption { + type = format.type; + default = { }; + example = { + group = [ + { + name = "TestGroup"; + rules = [ + { + alert = "ExampleAlertAlwaysFiring"; + expr = '' + sum by(job) + (up == 1) + ''; + } + ]; + } + ]; + }; + description = '' + A list of the given alerting or recording rules against configured `"datasource.url"` compatible with + Prometheus HTTP API for `vmalert` to execute. Refer to + + for details on supported values. + ''; + }; }; - "notifier.url" = mkOption { - type = with types; listOf nonEmptyStr; - default = [ ]; - example = [ "http://127.0.0.1:9093" ]; - description = '' - Prometheus Alertmanager URL. List all Alertmanager URLs if it runs in the cluster mode to ensure high availability. - ''; - }; - - "rule" = mkOption { - type = with types; listOf path; - description = '' - Path to the files with alerting and/or recording rules. - - ::: {.note} - Consider using the {option}`services.vmalert.rules` option as a convenient alternative for declaring rules - directly in the `nix` language. - ::: - ''; - }; - - }; - }; - default = { }; - example = { - "datasource.url" = "http://localhost:8428"; - "datasource.disableKeepAlive" = true; - "datasource.showURL" = false; - "rule" = [ - "http:///path/to/rules" - "dir/*.yaml" - ]; - }; - description = '' - `vmalert` configuration, passed via command line flags. Refer to - - for details on supported values. - ''; - }; - - rules = mkOption { - type = format.type; - default = { }; - example = { - group = [ - { - name = "TestGroup"; - rules = [ - { - alert = "ExampleAlertAlwaysFiring"; - expr = '' - sum by(job) - (up == 1) - ''; - } + config = { + settings.rule = [ + "/etc/${vmalertName name}/rules.yml" ]; - } - ]; - }; - description = '' - A list of the given alerting or recording rules against configured `"datasource.url"` compatible with - Prometheus HTTP API for `vmalert` to execute. Refer to - - for details on supported values. - ''; - }; + }; + } + ) + ); }; # implementation - config = mkIf cfg.enable { + config = mkIf (enabledInstances != { }) { + environment.etc = lib.mapAttrs' ( + name: + { rules, ... }: + lib.nameValuePair "${vmalertName name}/rules.yml" { + source = format.generate "rules.yml" rules; + } + ) enabledInstances; - environment.etc."vmalert/rules.yml".source = format.generate "rules.yml" cfg.rules; + systemd.services = lib.mapAttrs' ( + name: + { settings, ... }: + let + name' = vmalertName name; + in + lib.nameValuePair name' { + description = "vmalert service"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + reloadTriggers = [ config.environment.etc."${name'}/rules.yml".source ]; - services.vmalert.settings.rule = [ - "/etc/vmalert/rules.yml" - ]; - - systemd.services.vmalert = { - description = "vmalert service"; - wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; - reloadTriggers = [ config.environment.etc."vmalert/rules.yml".source ]; - - serviceConfig = { - DynamicUser = true; - Restart = "on-failure"; - ExecStart = "${cfg.package}/bin/vmalert ${confOpts}"; - ExecReload = ''${pkgs.coreutils}/bin/kill -SIGHUP "$MAINPID"''; - }; - }; + serviceConfig = { + DynamicUser = true; + Restart = "on-failure"; + ExecStart = "${cfg.package}/bin/vmalert ${mkConfOpts settings}"; + ExecReload = ''${pkgs.coreutils}/bin/kill -SIGHUP "$MAINPID"''; + }; + } + ) enabledInstances; }; } diff --git a/nixos/tests/victoriametrics/vmalert.nix b/nixos/tests/victoriametrics/vmalert.nix index f92c35a82010..aa5026cbd8f6 100644 --- a/nixos/tests/victoriametrics/vmalert.nix +++ b/nixos/tests/victoriametrics/vmalert.nix @@ -55,7 +55,7 @@ import ../make-test-python.nix ( }; }; - services.vmalert = { + services.vmalert.instances."" = { enable = true; settings = { "datasource.url" = "http://localhost:8428"; # victoriametrics' api From 827ec2499b454f104f9fbef86b81ba0267cea74e Mon Sep 17 00:00:00 2001 From: Bryan Lai Date: Mon, 9 Jun 2025 17:09:44 +0800 Subject: [PATCH 54/82] geminicommit: rename mainProgram & add versionCheckHook --- pkgs/by-name/ge/geminicommit/package.nix | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/pkgs/by-name/ge/geminicommit/package.nix b/pkgs/by-name/ge/geminicommit/package.nix index 2b69183918c9..2c83ac9c285a 100644 --- a/pkgs/by-name/ge/geminicommit/package.nix +++ b/pkgs/by-name/ge/geminicommit/package.nix @@ -4,6 +4,7 @@ fetchFromGitHub, installShellFiles, stdenv, + versionCheckHook, }: buildGoModule (finalAttrs: { @@ -26,9 +27,18 @@ buildGoModule (finalAttrs: { postInstall = let cmd = finalAttrs.meta.mainProgram; + goDefaultCmd = finalAttrs.pname; in - lib.optionalString (with stdenv; buildPlatform.canExecute hostPlatform) '' - # `geminicommit` requires write permissions to $HOME for its `config.toml` + # The official github released binary is renamed since v0.4.1, + # see: https://github.com/tfkhdyt/geminicommit/releases/tag/v0.4.1 + # Here we link the old name (which is also the `go build` default name) + # for backward compatibility: + '' + mv $out/bin/${goDefaultCmd} $out/bin/${cmd} + ln -s $out/bin/${cmd} $out/bin/${goDefaultCmd} + '' + + lib.optionalString (with stdenv; buildPlatform.canExecute hostPlatform) '' + # `gmc` requires write permissions to $HOME for its `config.toml` # ... which is automatically initiated on startup export HOME=$(mktemp -d) @@ -39,11 +49,17 @@ buildGoModule (finalAttrs: { done ''; + nativeInstallCheckInputs = [ + versionCheckHook + ]; + + doInstallCheck = true; + meta = { description = "CLI that generates git commit messages with Google Gemini AI"; homepage = "https://github.com/tfkhdyt/geminicommit"; license = lib.licenses.gpl3Only; maintainers = with lib.maintainers; [ bryango ]; - mainProgram = "geminicommit"; + mainProgram = "gmc"; }; }) From 66d53b3e782e1b6c406fed9c7a4bb232c6bd386c Mon Sep 17 00:00:00 2001 From: Lorenz Leutgeb Date: Mon, 2 Jun 2025 17:49:56 +0200 Subject: [PATCH 55/82] =?UTF-8?q?radicle-node:=201.1.0=20=E2=86=92=201.2.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...5b5b5ad715e2b812087947281f0add9aa05e.patch | 22 ------------------- pkgs/by-name/ra/radicle-node/package.nix | 12 ++++------ 2 files changed, 4 insertions(+), 30 deletions(-) delete mode 100644 pkgs/by-name/ra/radicle-node/61865b5b5ad715e2b812087947281f0add9aa05e.patch diff --git a/pkgs/by-name/ra/radicle-node/61865b5b5ad715e2b812087947281f0add9aa05e.patch b/pkgs/by-name/ra/radicle-node/61865b5b5ad715e2b812087947281f0add9aa05e.patch deleted file mode 100644 index 742ac55a7f54..000000000000 --- a/pkgs/by-name/ra/radicle-node/61865b5b5ad715e2b812087947281f0add9aa05e.patch +++ /dev/null @@ -1,22 +0,0 @@ -commit 61865b5b5ad715e2b812087947281f0add9aa05e -Author: Fintan Halpenny -Date: 2024-11-19 14:38:38 +0100 - - cob: fix documentation - - `no_run` will compile but not run the code. Use `ignore` instead, and also added - `rust` for syntax highlighting. - -diff --git a/radicle-cob/src/backend/git/stable.rs b/radicle-cob/src/backend/git/stable.rs -index 0d8ea27b..ef18ae55 100644 ---- a/radicle-cob/src/backend/git/stable.rs -+++ b/radicle-cob/src/backend/git/stable.rs -@@ -53,7 +53,7 @@ pub fn read_timestamp() -> i64 { - /// - /// # Usage - /// --/// ```no_run -+/// ```rust, ignore - /// let oid1 = with_advanced_timestamp(|| cob.update("New revision OID")); - /// let oid2 = with_advanced_timestamp(|| cob.update("Another revision OID")); - /// ``` diff --git a/pkgs/by-name/ra/radicle-node/package.nix b/pkgs/by-name/ra/radicle-node/package.nix index 22dab16a679e..1dd45c64f398 100644 --- a/pkgs/by-name/ra/radicle-node/package.nix +++ b/pkgs/by-name/ra/radicle-node/package.nix @@ -19,20 +19,16 @@ }: rustPlatform.buildRustPackage rec { pname = "radicle-node"; - version = "1.1.0"; + version = "1.2.0"; env.RADICLE_VERSION = version; src = fetchgit { url = "https://seed.radicle.xyz/z3gqcJUoA1n9HaHKufZs5FCSGazv5.git"; - rev = "refs/namespaces/z6MksFqXN3Yhqk8pTJdUGLwATkRfQvwZXPqR2qMEhbS9wzpT/refs/tags/v${version}"; - hash = "sha256-M4oz9tWjI/eqV4Gz1b512MEmvsZ5u3R9y6P9VeeH9CA="; + rev = "refs/namespaces/z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM/refs/tags/v${version}"; + hash = "sha256-RB8yDfttVTkZmk01ubLkwrwD6IYo3Ehe7bPosJzoQk4="; }; useFetchCargoVendor = true; - cargoHash = "sha256-SzwBQxTqQafHDtH8+OWkAMDnKh3AH0PeSMBWpHprQWM="; - - patches = [ - ./61865b5b5ad715e2b812087947281f0add9aa05e.patch - ]; + cargoHash = "sha256-/6VlRwWtJfHf6tXD2HJUTbThwTYeZFTJqtaxclrm3+c="; nativeBuildInputs = [ asciidoctor From afa09e5e8525f6753fec6b9b45fd76b198edf235 Mon Sep 17 00:00:00 2001 From: Lorenz Leutgeb Date: Mon, 2 Jun 2025 19:13:07 +0200 Subject: [PATCH 56/82] radicle-node: Preserve Git commit hash and date Co-authored-by: Defelo Co-authored-by: Martin Joerg --- pkgs/by-name/ra/radicle-node/package.nix | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/pkgs/by-name/ra/radicle-node/package.nix b/pkgs/by-name/ra/radicle-node/package.nix index 1dd45c64f398..9024e11bddde 100644 --- a/pkgs/by-name/ra/radicle-node/package.nix +++ b/pkgs/by-name/ra/radicle-node/package.nix @@ -25,7 +25,13 @@ rustPlatform.buildRustPackage rec { src = fetchgit { url = "https://seed.radicle.xyz/z3gqcJUoA1n9HaHKufZs5FCSGazv5.git"; rev = "refs/namespaces/z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM/refs/tags/v${version}"; - hash = "sha256-RB8yDfttVTkZmk01ubLkwrwD6IYo3Ehe7bPosJzoQk4="; + hash = "sha256-AWgLhL6GslE3r2FcZu2imV5ZtEKlUD+a4C5waRGO2lM="; + leaveDotGit = true; + postFetch = '' + git -C $out rev-parse HEAD > $out/.git_head + git -C $out log -1 --pretty=%ct HEAD > $out/.git_time + rm -rf $out/.git + ''; }; useFetchCargoVendor = true; cargoHash = "sha256-/6VlRwWtJfHf6tXD2HJUTbThwTYeZFTJqtaxclrm3+c="; @@ -37,6 +43,11 @@ rustPlatform.buildRustPackage rec { ]; nativeCheckInputs = [ git ]; + preBuild = '' + export GIT_HEAD=$(<$src/.git_head) + export SOURCE_DATE_EPOCH=$(<$src/.git_time) + ''; + # tests regularly time out on aarch64 doCheck = stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isx86; From 853e5dd9210bbb352b96065fafdfca16c5a1f621 Mon Sep 17 00:00:00 2001 From: Julian Stecklina Date: Mon, 9 Jun 2025 11:11:54 +0200 Subject: [PATCH 57/82] git-machete: move to pkgs/by-name --- .../gi/git-machete/package.nix} | 19 ++++++++++--------- pkgs/top-level/all-packages.nix | 2 -- 2 files changed, 10 insertions(+), 11 deletions(-) rename pkgs/{applications/version-management/git-machete/default.nix => by-name/gi/git-machete/package.nix} (88%) diff --git a/pkgs/applications/version-management/git-machete/default.nix b/pkgs/by-name/gi/git-machete/package.nix similarity index 88% rename from pkgs/applications/version-management/git-machete/default.nix rename to pkgs/by-name/gi/git-machete/package.nix index 5b9db51a215f..6dc30fe03830 100644 --- a/pkgs/applications/version-management/git-machete/default.nix +++ b/pkgs/by-name/gi/git-machete/package.nix @@ -1,15 +1,13 @@ { lib, - buildPythonApplication, - pytest-mock, - pytestCheckHook, + python3, fetchFromGitHub, installShellFiles, git, nix-update-script, }: -buildPythonApplication rec { +python3.pkgs.buildPythonApplication rec { pname = "git-machete"; version = "3.34.1"; @@ -22,11 +20,14 @@ buildPythonApplication rec { nativeBuildInputs = [ installShellFiles ]; - nativeCheckInputs = [ - git - pytest-mock - pytestCheckHook - ]; + nativeCheckInputs = + [ + git + ] + ++ (with python3.pkgs; [ + pytest-mock + pytestCheckHook + ]); disabledTests = [ # Requires fully functioning shells including zsh modules and bash diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 9465ef1cb5d8..31f5b7fe7c9e 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -1307,8 +1307,6 @@ with pkgs; git-imerge = python3Packages.callPackage ../applications/version-management/git-imerge { }; - git-machete = python3Packages.callPackage ../applications/version-management/git-machete { }; - git-publish = python3Packages.callPackage ../applications/version-management/git-publish { }; git-recent = callPackage ../applications/version-management/git-recent { From e69549d30754d32886aee26633baaa58851991b4 Mon Sep 17 00:00:00 2001 From: Marie Ramlow Date: Mon, 9 Jun 2025 09:23:39 +0000 Subject: [PATCH 58/82] vencord: 1.12.2 -> 1.12.3 --- pkgs/by-name/ve/vencord/package.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/by-name/ve/vencord/package.nix b/pkgs/by-name/ve/vencord/package.nix index 5d5ecefbee0d..b9aff387a8b7 100644 --- a/pkgs/by-name/ve/vencord/package.nix +++ b/pkgs/by-name/ve/vencord/package.nix @@ -15,13 +15,13 @@ stdenv.mkDerivation (finalAttrs: { pname = "vencord"; - version = "1.12.2"; + version = "1.12.3"; src = fetchFromGitHub { owner = "Vendicated"; repo = "Vencord"; rev = "v${finalAttrs.version}"; - hash = "sha256-a4lbeuXEHDMDko8wte7jUdJ0yUcjfq3UPQAuSiz1UQU="; + hash = "sha256-fOZXgyA61G+D7otNNO8d89ghR/GiYPJ7vSZtj9TeGuU="; }; pnpmDeps = pnpm_10.fetchDeps { From 94552b6dbd0f2ec978758d8812f82ed76d4cb4b8 Mon Sep 17 00:00:00 2001 From: natsukium Date: Wed, 4 Jun 2025 03:48:12 +0900 Subject: [PATCH 59/82] python314: address CVE-2025-4517, CVE-2025-4330, CVE-2025-4138, CVE-2024-12718, CVE-2025-4435 https://mail.python.org/archives/list/security-announce@python.org/thread/MAXIJJCUUMCL7ATZNDVEGGHUMQMUUKLG/ https://www.cve.org/CVERecord?id=CVE-2025-4517 https://www.cve.org/CVERecord?id=CVE-2025-4330 https://www.cve.org/CVERecord?id=CVE-2025-4138 https://www.cve.org/CVERecord?id=CVE-2024-12718 https://www.cve.org/CVERecord?id=CVE-2025-4435 --- .../python/cpython/3.14/CVE-2025-4517.patch | 2055 +++++++++++++++++ .../interpreters/python/cpython/default.nix | 3 + 2 files changed, 2058 insertions(+) create mode 100644 pkgs/development/interpreters/python/cpython/3.14/CVE-2025-4517.patch diff --git a/pkgs/development/interpreters/python/cpython/3.14/CVE-2025-4517.patch b/pkgs/development/interpreters/python/cpython/3.14/CVE-2025-4517.patch new file mode 100644 index 000000000000..5ad45fdde9fa --- /dev/null +++ b/pkgs/development/interpreters/python/cpython/3.14/CVE-2025-4517.patch @@ -0,0 +1,2055 @@ +From 9e0ac76d96cf80b49055f6d6b9a6763fb9215c2a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C5=81ukasz=20Langa?= +Date: Tue, 3 Jun 2025 14:05:00 +0200 +Subject: [PATCH] [3.14] gh-135034: Normalize link targets in tarfile, add + `os.path.realpath(strict='allow_missing')` (gh-135037) (gh-135065) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Addresses CVEs 2024-12718, 2025-4138, 2025-4330, and 2025-4517. + +(cherry picked from commit 3612d8f51741b11f36f8fb0494d79086bac9390a) + +Signed-off-by: Łukasz Langa +Co-authored-by: Petr Viktorin +Co-authored-by: Seth Michael Larson +Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> +Co-authored-by: Serhiy Storchaka +--- + Doc/library/os.path.rst | 32 +- + Doc/library/tarfile.rst | 20 ++ + Doc/whatsnew/3.14.rst | 32 ++ + Lib/genericpath.py | 11 +- + Lib/ntpath.py | 38 ++- + Lib/posixpath.py | 57 ++-- + Lib/tarfile.py | 163 +++++++-- + Lib/test/test_ntpath.py | 216 ++++++++++-- + Lib/test/test_posixpath.py | 252 +++++++++++--- + Lib/test/test_tarfile.py | 310 +++++++++++++++++- + ...-06-02-11-32-23.gh-issue-135034.RLGjbp.rst | 6 + + 11 files changed, 967 insertions(+), 170 deletions(-) + create mode 100644 Misc/NEWS.d/next/Security/2025-06-02-11-32-23.gh-issue-135034.RLGjbp.rst + +diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst +index ecbbc1d7605f9f..f72aee19d8f332 100644 +--- a/Doc/library/os.path.rst ++++ b/Doc/library/os.path.rst +@@ -408,9 +408,26 @@ the :mod:`glob` module.) + system). On Windows, this function will also resolve MS-DOS (also called 8.3) + style names such as ``C:\\PROGRA~1`` to ``C:\\Program Files``. + +- If a path doesn't exist or a symlink loop is encountered, and *strict* is +- ``True``, :exc:`OSError` is raised. If *strict* is ``False`` these errors +- are ignored, and so the result might be missing or otherwise inaccessible. ++ By default, the path is evaluated up to the first component that does not ++ exist, is a symlink loop, or whose evaluation raises :exc:`OSError`. ++ All such components are appended unchanged to the existing part of the path. ++ ++ Some errors that are handled this way include "access denied", "not a ++ directory", or "bad argument to internal function". Thus, the ++ resulting path may be missing or inaccessible, may still contain ++ links or loops, and may traverse non-directories. ++ ++ This behavior can be modified by keyword arguments: ++ ++ If *strict* is ``True``, the first error encountered when evaluating the path is ++ re-raised. ++ In particular, :exc:`FileNotFoundError` is raised if *path* does not exist, ++ or another :exc:`OSError` if it is otherwise inaccessible. ++ ++ If *strict* is :py:data:`os.path.ALLOW_MISSING`, errors other than ++ :exc:`FileNotFoundError` are re-raised (as with ``strict=True``). ++ Thus, the returned path will not contain any symbolic links, but the named ++ file and some of its parent directories may be missing. + + .. note:: + This function emulates the operating system's procedure for making a path +@@ -429,6 +446,15 @@ the :mod:`glob` module.) + .. versionchanged:: 3.10 + The *strict* parameter was added. + ++ .. versionchanged:: next ++ The :py:data:`~os.path.ALLOW_MISSING` value for the *strict* parameter ++ was added. ++ ++.. data:: ALLOW_MISSING ++ ++ Special value used for the *strict* argument in :func:`realpath`. ++ ++ .. versionadded:: next + + .. function:: relpath(path, start=os.curdir) + +diff --git a/Doc/library/tarfile.rst b/Doc/library/tarfile.rst +index f9cb5495e60cd2..7cec108a5bd41d 100644 +--- a/Doc/library/tarfile.rst ++++ b/Doc/library/tarfile.rst +@@ -255,6 +255,15 @@ The :mod:`tarfile` module defines the following exceptions: + Raised to refuse extracting a symbolic link pointing outside the destination + directory. + ++.. exception:: LinkFallbackError ++ ++ Raised to refuse emulating a link (hard or symbolic) by extracting another ++ archive member, when that member would be rejected by the filter location. ++ The exception that was raised to reject the replacement member is available ++ as :attr:`!BaseException.__context__`. ++ ++ .. versionadded:: next ++ + + The following constants are available at the module level: + +@@ -1068,6 +1077,12 @@ reused in custom filters: + Implements the ``'data'`` filter. + In addition to what ``tar_filter`` does: + ++ - Normalize link targets (:attr:`TarInfo.linkname`) using ++ :func:`os.path.normpath`. ++ Note that this removes internal ``..`` components, which may change the ++ meaning of the link if the path in :attr:`!TarInfo.linkname` traverses ++ symbolic links. ++ + - :ref:`Refuse ` to extract links (hard or soft) + that link to absolute paths, or ones that link outside the destination. + +@@ -1099,6 +1114,10 @@ reused in custom filters: + Note that this filter does not block *all* dangerous archive features. + See :ref:`tarfile-further-verification` for details. + ++ .. versionchanged:: next ++ ++ Link targets are now normalized. ++ + + .. _tarfile-extraction-refuse: + +@@ -1127,6 +1146,7 @@ Here is an incomplete list of things to consider: + * Extract to a :func:`new temporary directory ` + to prevent e.g. exploiting pre-existing links, and to make it easier to + clean up after a failed extraction. ++* Disallow symbolic links if you do not need the functionality. + * When working with untrusted data, use external (e.g. OS-level) limits on + disk, memory and CPU usage. + * Check filenames against an allow-list of characters +diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst +index 561d1a8914b50c..1e6a3615963ff4 100644 +--- a/Doc/whatsnew/3.14.rst ++++ b/Doc/whatsnew/3.14.rst +@@ -1608,6 +1608,16 @@ os + (Contributed by Cody Maloney in :gh:`129205`.) + + ++os.path ++------- ++ ++* The *strict* parameter to :func:`os.path.realpath` accepts a new value, ++ :data:`os.path.ALLOW_MISSING`. ++ If used, errors other than :exc:`FileNotFoundError` will be re-raised; ++ the resulting path can be missing but it will be free of symlinks. ++ (Contributed by Petr Viktorin for :cve:`2025-4517`.) ++ ++ + pathlib + ------- + +@@ -1796,6 +1806,28 @@ sysconfig + (Contributed by Xuehai Pan in :gh:`131799`.) + + ++tarfile ++------- ++ ++* :func:`~tarfile.data_filter` now normalizes symbolic link targets in order to ++ avoid path traversal attacks. ++ (Contributed by Petr Viktorin in :gh:`127987` and :cve:`2025-4138`.) ++* :func:`~tarfile.TarFile.extractall` now skips fixing up directory attributes ++ when a directory was removed or replaced by another kind of file. ++ (Contributed by Petr Viktorin in :gh:`127987` and :cve:`2024-12718`.) ++* :func:`~tarfile.TarFile.extract` and :func:`~tarfile.TarFile.extractall` ++ now (re-)apply the extraction filter when substituting a link (hard or ++ symbolic) with a copy of another archive member, and when fixing up ++ directory attributes. ++ The former raises a new exception, :exc:`~tarfile.LinkFallbackError`. ++ (Contributed by Petr Viktorin for :cve:`2025-4330` and :cve:`2024-12718`.) ++* :func:`~tarfile.TarFile.extract` and :func:`~tarfile.TarFile.extractall` ++ no longer extract rejected members when ++ :func:`~tarfile.TarFile.errorlevel` is zero. ++ (Contributed by Matt Prodani and Petr Viktorin in :gh:`112887` ++ and :cve:`2025-4435`.) ++ ++ + threading + --------- + +diff --git a/Lib/genericpath.py b/Lib/genericpath.py +index ba7b0a13c7f81d..9363f564aab7a6 100644 +--- a/Lib/genericpath.py ++++ b/Lib/genericpath.py +@@ -8,7 +8,7 @@ + + __all__ = ['commonprefix', 'exists', 'getatime', 'getctime', 'getmtime', + 'getsize', 'isdevdrive', 'isdir', 'isfile', 'isjunction', 'islink', +- 'lexists', 'samefile', 'sameopenfile', 'samestat'] ++ 'lexists', 'samefile', 'sameopenfile', 'samestat', 'ALLOW_MISSING'] + + + # Does a path exist? +@@ -189,3 +189,12 @@ def _check_arg_types(funcname, *args): + f'os.PathLike object, not {s.__class__.__name__!r}') from None + if hasstr and hasbytes: + raise TypeError("Can't mix strings and bytes in path components") from None ++ ++# A singleton with a true boolean value. ++@object.__new__ ++class ALLOW_MISSING: ++ """Special value for use in realpath().""" ++ def __repr__(self): ++ return 'os.path.ALLOW_MISSING' ++ def __reduce__(self): ++ return self.__class__.__name__ +diff --git a/Lib/ntpath.py b/Lib/ntpath.py +index 52ff2af743af6c..9cdc16480f9afe 100644 +--- a/Lib/ntpath.py ++++ b/Lib/ntpath.py +@@ -29,7 +29,7 @@ + "abspath","curdir","pardir","sep","pathsep","defpath","altsep", + "extsep","devnull","realpath","supports_unicode_filenames","relpath", + "samefile", "sameopenfile", "samestat", "commonpath", "isjunction", +- "isdevdrive"] ++ "isdevdrive", "ALLOW_MISSING"] + + def _get_bothseps(path): + if isinstance(path, bytes): +@@ -601,9 +601,10 @@ def abspath(path): + from nt import _findfirstfile, _getfinalpathname, readlink as _nt_readlink + except ImportError: + # realpath is a no-op on systems without _getfinalpathname support. +- realpath = abspath ++ def realpath(path, *, strict=False): ++ return abspath(path) + else: +- def _readlink_deep(path): ++ def _readlink_deep(path, ignored_error=OSError): + # These error codes indicate that we should stop reading links and + # return the path we currently have. + # 1: ERROR_INVALID_FUNCTION +@@ -636,7 +637,7 @@ def _readlink_deep(path): + path = old_path + break + path = normpath(join(dirname(old_path), path)) +- except OSError as ex: ++ except ignored_error as ex: + if ex.winerror in allowed_winerror: + break + raise +@@ -645,7 +646,7 @@ def _readlink_deep(path): + break + return path + +- def _getfinalpathname_nonstrict(path): ++ def _getfinalpathname_nonstrict(path, ignored_error=OSError): + # These error codes indicate that we should stop resolving the path + # and return the value we currently have. + # 1: ERROR_INVALID_FUNCTION +@@ -673,17 +674,18 @@ def _getfinalpathname_nonstrict(path): + try: + path = _getfinalpathname(path) + return join(path, tail) if tail else path +- except OSError as ex: ++ except ignored_error as ex: + if ex.winerror not in allowed_winerror: + raise + try: + # The OS could not resolve this path fully, so we attempt + # to follow the link ourselves. If we succeed, join the tail + # and return. +- new_path = _readlink_deep(path) ++ new_path = _readlink_deep(path, ++ ignored_error=ignored_error) + if new_path != path: + return join(new_path, tail) if tail else new_path +- except OSError: ++ except ignored_error: + # If we fail to readlink(), let's keep traversing + pass + # If we get these errors, try to get the real name of the file without accessing it. +@@ -691,7 +693,7 @@ def _getfinalpathname_nonstrict(path): + try: + name = _findfirstfile(path) + path, _ = split(path) +- except OSError: ++ except ignored_error: + path, name = split(path) + else: + path, name = split(path) +@@ -721,6 +723,15 @@ def realpath(path, *, strict=False): + if normcase(path) == devnull: + return '\\\\.\\NUL' + had_prefix = path.startswith(prefix) ++ ++ if strict is ALLOW_MISSING: ++ ignored_error = FileNotFoundError ++ strict = True ++ elif strict: ++ ignored_error = () ++ else: ++ ignored_error = OSError ++ + if not had_prefix and not isabs(path): + path = join(cwd, path) + try: +@@ -728,17 +739,16 @@ def realpath(path, *, strict=False): + initial_winerror = 0 + except ValueError as ex: + # gh-106242: Raised for embedded null characters +- # In strict mode, we convert into an OSError. ++ # In strict modes, we convert into an OSError. + # Non-strict mode returns the path as-is, since we've already + # made it absolute. + if strict: + raise OSError(str(ex)) from None + path = normpath(path) +- except OSError as ex: +- if strict: +- raise ++ except ignored_error as ex: + initial_winerror = ex.winerror +- path = _getfinalpathname_nonstrict(path) ++ path = _getfinalpathname_nonstrict(path, ++ ignored_error=ignored_error) + # The path returned by _getfinalpathname will always start with \\?\ - + # strip off that prefix unless it was already provided on the original + # path. +diff --git a/Lib/posixpath.py b/Lib/posixpath.py +index db72ded8826056..d38f3bd5872bcd 100644 +--- a/Lib/posixpath.py ++++ b/Lib/posixpath.py +@@ -36,7 +36,7 @@ + "samefile","sameopenfile","samestat", + "curdir","pardir","sep","pathsep","defpath","altsep","extsep", + "devnull","realpath","supports_unicode_filenames","relpath", +- "commonpath", "isjunction","isdevdrive"] ++ "commonpath", "isjunction","isdevdrive","ALLOW_MISSING"] + + + def _get_sep(path): +@@ -402,10 +402,18 @@ def realpath(filename, *, strict=False): + curdir = '.' + pardir = '..' + getcwd = os.getcwd +- return _realpath(filename, strict, sep, curdir, pardir, getcwd) ++ if strict is ALLOW_MISSING: ++ ignored_error = FileNotFoundError ++ strict = True ++ elif strict: ++ ignored_error = () ++ else: ++ ignored_error = OSError ++ ++ lstat = os.lstat ++ readlink = os.readlink ++ maxlinks = None + +-def _realpath(filename, strict=False, sep=sep, curdir=curdir, pardir=pardir, +- getcwd=os.getcwd, lstat=os.lstat, readlink=os.readlink, maxlinks=None): + # The stack of unresolved path parts. When popped, a special value of None + # indicates that a symlink target has been resolved, and that the original + # symlink path can be retrieved by popping again. The [::-1] slice is a +@@ -477,27 +485,28 @@ def _realpath(filename, strict=False, sep=sep, curdir=curdir, pardir=pardir, + path = newpath + continue + target = readlink(newpath) +- except OSError: +- if strict: +- raise +- path = newpath ++ except ignored_error: ++ pass ++ else: ++ # Resolve the symbolic link ++ if target.startswith(sep): ++ # Symlink target is absolute; reset resolved path. ++ path = sep ++ if maxlinks is None: ++ # Mark this symlink as seen but not fully resolved. ++ seen[newpath] = None ++ # Push the symlink path onto the stack, and signal its specialness ++ # by also pushing None. When these entries are popped, we'll ++ # record the fully-resolved symlink target in the 'seen' mapping. ++ rest.append(newpath) ++ rest.append(None) ++ # Push the unresolved symlink target parts onto the stack. ++ target_parts = target.split(sep)[::-1] ++ rest.extend(target_parts) ++ part_count += len(target_parts) + continue +- # Resolve the symbolic link +- if target.startswith(sep): +- # Symlink target is absolute; reset resolved path. +- path = sep +- if maxlinks is None: +- # Mark this symlink as seen but not fully resolved. +- seen[newpath] = None +- # Push the symlink path onto the stack, and signal its specialness +- # by also pushing None. When these entries are popped, we'll +- # record the fully-resolved symlink target in the 'seen' mapping. +- rest.append(newpath) +- rest.append(None) +- # Push the unresolved symlink target parts onto the stack. +- target_parts = target.split(sep)[::-1] +- rest.extend(target_parts) +- part_count += len(target_parts) ++ # An error occurred and was ignored. ++ path = newpath + + return path + +diff --git a/Lib/tarfile.py b/Lib/tarfile.py +index 212b71f6509740..068aa13ed70356 100644 +--- a/Lib/tarfile.py ++++ b/Lib/tarfile.py +@@ -67,7 +67,7 @@ + "DEFAULT_FORMAT", "open","fully_trusted_filter", "data_filter", + "tar_filter", "FilterError", "AbsoluteLinkError", + "OutsideDestinationError", "SpecialFileError", "AbsolutePathError", +- "LinkOutsideDestinationError"] ++ "LinkOutsideDestinationError", "LinkFallbackError"] + + + #--------------------------------------------------------- +@@ -766,10 +766,22 @@ def __init__(self, tarinfo, path): + super().__init__(f'{tarinfo.name!r} would link to {path!r}, ' + + 'which is outside the destination') + ++class LinkFallbackError(FilterError): ++ def __init__(self, tarinfo, path): ++ self.tarinfo = tarinfo ++ self._path = path ++ super().__init__(f'link {tarinfo.name!r} would be extracted as a ' ++ + f'copy of {path!r}, which was rejected') ++ ++# Errors caused by filters -- both "fatal" and "non-fatal" -- that ++# we consider to be issues with the argument, rather than a bug in the ++# filter function ++_FILTER_ERRORS = (FilterError, OSError, ExtractError) ++ + def _get_filtered_attrs(member, dest_path, for_data=True): + new_attrs = {} + name = member.name +- dest_path = os.path.realpath(dest_path) ++ dest_path = os.path.realpath(dest_path, strict=os.path.ALLOW_MISSING) + # Strip leading / (tar's directory separator) from filenames. + # Include os.sep (target OS directory separator) as well. + if name.startswith(('/', os.sep)): +@@ -779,7 +791,8 @@ def _get_filtered_attrs(member, dest_path, for_data=True): + # For example, 'C:/foo' on Windows. + raise AbsolutePathError(member) + # Ensure we stay in the destination +- target_path = os.path.realpath(os.path.join(dest_path, name)) ++ target_path = os.path.realpath(os.path.join(dest_path, name), ++ strict=os.path.ALLOW_MISSING) + if os.path.commonpath([target_path, dest_path]) != dest_path: + raise OutsideDestinationError(member, target_path) + # Limit permissions (no high bits, and go-w) +@@ -817,6 +830,9 @@ def _get_filtered_attrs(member, dest_path, for_data=True): + if member.islnk() or member.issym(): + if os.path.isabs(member.linkname): + raise AbsoluteLinkError(member) ++ normalized = os.path.normpath(member.linkname) ++ if normalized != member.linkname: ++ new_attrs['linkname'] = normalized + if member.issym(): + target_path = os.path.join(dest_path, + os.path.dirname(name), +@@ -824,7 +840,8 @@ def _get_filtered_attrs(member, dest_path, for_data=True): + else: + target_path = os.path.join(dest_path, + member.linkname) +- target_path = os.path.realpath(target_path) ++ target_path = os.path.realpath(target_path, ++ strict=os.path.ALLOW_MISSING) + if os.path.commonpath([target_path, dest_path]) != dest_path: + raise LinkOutsideDestinationError(member, target_path) + return new_attrs +@@ -2386,30 +2403,58 @@ def extractall(self, path=".", members=None, *, numeric_owner=False, + members = self + + for member in members: +- tarinfo = self._get_extract_tarinfo(member, filter_function, path) ++ tarinfo, unfiltered = self._get_extract_tarinfo( ++ member, filter_function, path) + if tarinfo is None: + continue + if tarinfo.isdir(): + # For directories, delay setting attributes until later, + # since permissions can interfere with extraction and + # extracting contents can reset mtime. +- directories.append(tarinfo) ++ directories.append(unfiltered) + self._extract_one(tarinfo, path, set_attrs=not tarinfo.isdir(), +- numeric_owner=numeric_owner) ++ numeric_owner=numeric_owner, ++ filter_function=filter_function) + + # Reverse sort directories. + directories.sort(key=lambda a: a.name, reverse=True) + ++ + # Set correct owner, mtime and filemode on directories. +- for tarinfo in directories: +- dirpath = os.path.join(path, tarinfo.name) ++ for unfiltered in directories: + try: ++ # Need to re-apply any filter, to take the *current* filesystem ++ # state into account. ++ try: ++ tarinfo = filter_function(unfiltered, path) ++ except _FILTER_ERRORS as exc: ++ self._log_no_directory_fixup(unfiltered, repr(exc)) ++ continue ++ if tarinfo is None: ++ self._log_no_directory_fixup(unfiltered, ++ 'excluded by filter') ++ continue ++ dirpath = os.path.join(path, tarinfo.name) ++ try: ++ lstat = os.lstat(dirpath) ++ except FileNotFoundError: ++ self._log_no_directory_fixup(tarinfo, 'missing') ++ continue ++ if not stat.S_ISDIR(lstat.st_mode): ++ # This is no longer a directory; presumably a later ++ # member overwrote the entry. ++ self._log_no_directory_fixup(tarinfo, 'not a directory') ++ continue + self.chown(tarinfo, dirpath, numeric_owner=numeric_owner) + self.utime(tarinfo, dirpath) + self.chmod(tarinfo, dirpath) + except ExtractError as e: + self._handle_nonfatal_error(e) + ++ def _log_no_directory_fixup(self, member, reason): ++ self._dbg(2, "tarfile: Not fixing up directory %r (%s)" % ++ (member.name, reason)) ++ + def extract(self, member, path="", set_attrs=True, *, numeric_owner=False, + filter=None): + """Extract a member from the archive to the current working directory, +@@ -2425,41 +2470,56 @@ def extract(self, member, path="", set_attrs=True, *, numeric_owner=False, + String names of common filters are accepted. + """ + filter_function = self._get_filter_function(filter) +- tarinfo = self._get_extract_tarinfo(member, filter_function, path) ++ tarinfo, unfiltered = self._get_extract_tarinfo( ++ member, filter_function, path) + if tarinfo is not None: + self._extract_one(tarinfo, path, set_attrs, numeric_owner) + + def _get_extract_tarinfo(self, member, filter_function, path): +- """Get filtered TarInfo (or None) from member, which might be a str""" ++ """Get (filtered, unfiltered) TarInfos from *member* ++ ++ *member* might be a string. ++ ++ Return (None, None) if not found. ++ """ ++ + if isinstance(member, str): +- tarinfo = self.getmember(member) ++ unfiltered = self.getmember(member) + else: +- tarinfo = member ++ unfiltered = member + +- unfiltered = tarinfo ++ filtered = None + try: +- tarinfo = filter_function(tarinfo, path) ++ filtered = filter_function(unfiltered, path) + except (OSError, UnicodeEncodeError, FilterError) as e: + self._handle_fatal_error(e) + except ExtractError as e: + self._handle_nonfatal_error(e) +- if tarinfo is None: ++ if filtered is None: + self._dbg(2, "tarfile: Excluded %r" % unfiltered.name) +- return None ++ return None, None ++ + # Prepare the link target for makelink(). +- if tarinfo.islnk(): +- tarinfo = copy.copy(tarinfo) +- tarinfo._link_target = os.path.join(path, tarinfo.linkname) +- return tarinfo ++ if filtered.islnk(): ++ filtered = copy.copy(filtered) ++ filtered._link_target = os.path.join(path, filtered.linkname) ++ return filtered, unfiltered ++ ++ def _extract_one(self, tarinfo, path, set_attrs, numeric_owner, ++ filter_function=None): ++ """Extract from filtered tarinfo to disk. + +- def _extract_one(self, tarinfo, path, set_attrs, numeric_owner): +- """Extract from filtered tarinfo to disk""" ++ filter_function is only used when extracting a *different* ++ member (e.g. as fallback to creating a symlink) ++ """ + self._check("r") + + try: + self._extract_member(tarinfo, os.path.join(path, tarinfo.name), + set_attrs=set_attrs, +- numeric_owner=numeric_owner) ++ numeric_owner=numeric_owner, ++ filter_function=filter_function, ++ extraction_root=path) + except (OSError, UnicodeEncodeError) as e: + self._handle_fatal_error(e) + except ExtractError as e: +@@ -2517,9 +2577,13 @@ def extractfile(self, member): + return None + + def _extract_member(self, tarinfo, targetpath, set_attrs=True, +- numeric_owner=False): +- """Extract the TarInfo object tarinfo to a physical ++ numeric_owner=False, *, filter_function=None, ++ extraction_root=None): ++ """Extract the filtered TarInfo object tarinfo to a physical + file called targetpath. ++ ++ filter_function is only used when extracting a *different* ++ member (e.g. as fallback to creating a symlink) + """ + # Fetch the TarInfo object for the given name + # and build the destination pathname, replacing +@@ -2548,7 +2612,10 @@ def _extract_member(self, tarinfo, targetpath, set_attrs=True, + elif tarinfo.ischr() or tarinfo.isblk(): + self.makedev(tarinfo, targetpath) + elif tarinfo.islnk() or tarinfo.issym(): +- self.makelink(tarinfo, targetpath) ++ self.makelink_with_filter( ++ tarinfo, targetpath, ++ filter_function=filter_function, ++ extraction_root=extraction_root) + elif tarinfo.type not in SUPPORTED_TYPES: + self.makeunknown(tarinfo, targetpath) + else: +@@ -2631,10 +2698,18 @@ def makedev(self, tarinfo, targetpath): + os.makedev(tarinfo.devmajor, tarinfo.devminor)) + + def makelink(self, tarinfo, targetpath): ++ return self.makelink_with_filter(tarinfo, targetpath, None, None) ++ ++ def makelink_with_filter(self, tarinfo, targetpath, ++ filter_function, extraction_root): + """Make a (symbolic) link called targetpath. If it cannot be created + (platform limitation), we try to make a copy of the referenced file + instead of a link. ++ ++ filter_function is only used when extracting a *different* ++ member (e.g. as fallback to creating a link). + """ ++ keyerror_to_extracterror = False + try: + # For systems that support symbolic and hard links. + if tarinfo.issym(): +@@ -2642,18 +2717,38 @@ def makelink(self, tarinfo, targetpath): + # Avoid FileExistsError on following os.symlink. + os.unlink(targetpath) + os.symlink(tarinfo.linkname, targetpath) ++ return + else: + if os.path.exists(tarinfo._link_target): + os.link(tarinfo._link_target, targetpath) +- else: +- self._extract_member(self._find_link_target(tarinfo), +- targetpath) ++ return + except symlink_exception: ++ keyerror_to_extracterror = True ++ ++ try: ++ unfiltered = self._find_link_target(tarinfo) ++ except KeyError: ++ if keyerror_to_extracterror: ++ raise ExtractError( ++ "unable to resolve link inside archive") from None ++ else: ++ raise ++ ++ if filter_function is None: ++ filtered = unfiltered ++ else: ++ if extraction_root is None: ++ raise ExtractError( ++ "makelink_with_filter: if filter_function is not None, " ++ + "extraction_root must also not be None") + try: +- self._extract_member(self._find_link_target(tarinfo), +- targetpath) +- except KeyError: +- raise ExtractError("unable to resolve link inside archive") from None ++ filtered = filter_function(unfiltered, extraction_root) ++ except _FILTER_ERRORS as cause: ++ raise LinkFallbackError(tarinfo, unfiltered.name) from cause ++ if filtered is not None: ++ self._extract_member(filtered, targetpath, ++ filter_function=filter_function, ++ extraction_root=extraction_root) + + def chown(self, tarinfo, targetpath, numeric_owner): + """Set owner of targetpath according to tarinfo. If numeric_owner +diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py +index f83ef225a6e48e..927a0befcc8c13 100644 +--- a/Lib/test/test_ntpath.py ++++ b/Lib/test/test_ntpath.py +@@ -7,7 +7,8 @@ + import unittest + import warnings + from test.support import cpython_only, os_helper +-from test.support import TestFailed, is_emscripten ++from test.support import TestFailed ++from ntpath import ALLOW_MISSING + from test.support.os_helper import FakePath + from test import test_genericpath + from tempfile import TemporaryFile +@@ -77,6 +78,27 @@ def tester(fn, wantResult): + %(str(fn), str(wantResult), repr(gotResult))) + + ++def _parameterize(*parameters): ++ """Simplistic decorator to parametrize a test ++ ++ Runs the decorated test multiple times in subTest, with a value from ++ 'parameters' passed as an extra positional argument. ++ Calls doCleanups() after each run. ++ ++ Not for general use. Intended to avoid indenting for easier backports. ++ ++ See https://discuss.python.org/t/91827 for discussing generalizations. ++ """ ++ def _parametrize_decorator(func): ++ def _parameterized(self, *args, **kwargs): ++ for parameter in parameters: ++ with self.subTest(parameter): ++ func(self, *args, parameter, **kwargs) ++ self.doCleanups() ++ return _parameterized ++ return _parametrize_decorator ++ ++ + class NtpathTestCase(unittest.TestCase): + def assertPathEqual(self, path1, path2): + if path1 == path2 or _norm(path1) == _norm(path2): +@@ -475,6 +497,27 @@ def test_realpath_curdir(self): + tester("ntpath.realpath('.\\.')", expected) + tester("ntpath.realpath('\\'.join(['.'] * 100))", expected) + ++ def test_realpath_curdir_strict(self): ++ expected = ntpath.normpath(os.getcwd()) ++ tester("ntpath.realpath('.', strict=True)", expected) ++ tester("ntpath.realpath('./.', strict=True)", expected) ++ tester("ntpath.realpath('/'.join(['.'] * 100), strict=True)", expected) ++ tester("ntpath.realpath('.\\.', strict=True)", expected) ++ tester("ntpath.realpath('\\'.join(['.'] * 100), strict=True)", expected) ++ ++ def test_realpath_curdir_missing_ok(self): ++ expected = ntpath.normpath(os.getcwd()) ++ tester("ntpath.realpath('.', strict=ALLOW_MISSING)", ++ expected) ++ tester("ntpath.realpath('./.', strict=ALLOW_MISSING)", ++ expected) ++ tester("ntpath.realpath('/'.join(['.'] * 100), strict=ALLOW_MISSING)", ++ expected) ++ tester("ntpath.realpath('.\\.', strict=ALLOW_MISSING)", ++ expected) ++ tester("ntpath.realpath('\\'.join(['.'] * 100), strict=ALLOW_MISSING)", ++ expected) ++ + def test_realpath_pardir(self): + expected = ntpath.normpath(os.getcwd()) + tester("ntpath.realpath('..')", ntpath.dirname(expected)) +@@ -487,24 +530,59 @@ def test_realpath_pardir(self): + tester("ntpath.realpath('\\'.join(['..'] * 50))", + ntpath.splitdrive(expected)[0] + '\\') + ++ def test_realpath_pardir_strict(self): ++ expected = ntpath.normpath(os.getcwd()) ++ tester("ntpath.realpath('..', strict=True)", ntpath.dirname(expected)) ++ tester("ntpath.realpath('../..', strict=True)", ++ ntpath.dirname(ntpath.dirname(expected))) ++ tester("ntpath.realpath('/'.join(['..'] * 50), strict=True)", ++ ntpath.splitdrive(expected)[0] + '\\') ++ tester("ntpath.realpath('..\\..', strict=True)", ++ ntpath.dirname(ntpath.dirname(expected))) ++ tester("ntpath.realpath('\\'.join(['..'] * 50), strict=True)", ++ ntpath.splitdrive(expected)[0] + '\\') ++ ++ def test_realpath_pardir_missing_ok(self): ++ expected = ntpath.normpath(os.getcwd()) ++ tester("ntpath.realpath('..', strict=ALLOW_MISSING)", ++ ntpath.dirname(expected)) ++ tester("ntpath.realpath('../..', strict=ALLOW_MISSING)", ++ ntpath.dirname(ntpath.dirname(expected))) ++ tester("ntpath.realpath('/'.join(['..'] * 50), strict=ALLOW_MISSING)", ++ ntpath.splitdrive(expected)[0] + '\\') ++ tester("ntpath.realpath('..\\..', strict=ALLOW_MISSING)", ++ ntpath.dirname(ntpath.dirname(expected))) ++ tester("ntpath.realpath('\\'.join(['..'] * 50), strict=ALLOW_MISSING)", ++ ntpath.splitdrive(expected)[0] + '\\') ++ + @os_helper.skip_unless_symlink + @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') +- def test_realpath_basic(self): ++ @_parameterize({}, {'strict': True}, {'strict': ALLOW_MISSING}) ++ def test_realpath_basic(self, kwargs): + ABSTFN = ntpath.abspath(os_helper.TESTFN) + open(ABSTFN, "wb").close() + self.addCleanup(os_helper.unlink, ABSTFN) + self.addCleanup(os_helper.unlink, ABSTFN + "1") + + os.symlink(ABSTFN, ABSTFN + "1") +- self.assertPathEqual(ntpath.realpath(ABSTFN + "1"), ABSTFN) +- self.assertPathEqual(ntpath.realpath(os.fsencode(ABSTFN + "1")), ++ self.assertPathEqual(ntpath.realpath(ABSTFN + "1", **kwargs), ABSTFN) ++ self.assertPathEqual(ntpath.realpath(os.fsencode(ABSTFN + "1"), **kwargs), + os.fsencode(ABSTFN)) + + # gh-88013: call ntpath.realpath with binary drive name may raise a + # TypeError. The drive should not exist to reproduce the bug. + drives = {f"{c}:\\" for c in string.ascii_uppercase} - set(os.listdrives()) + d = drives.pop().encode() +- self.assertEqual(ntpath.realpath(d), d) ++ self.assertEqual(ntpath.realpath(d, strict=False), d) ++ ++ # gh-106242: Embedded nulls and non-strict fallback to abspath ++ if kwargs: ++ with self.assertRaises(OSError): ++ ntpath.realpath(os_helper.TESTFN + "\0spam", ++ **kwargs) ++ else: ++ self.assertEqual(ABSTFN + "\0spam", ++ ntpath.realpath(os_helper.TESTFN + "\0spam", **kwargs)) + + @os_helper.skip_unless_symlink + @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') +@@ -527,51 +605,66 @@ def test_realpath_invalid_paths(self): + self.assertEqual(realpath(path, strict=False), path) + # gh-106242: Embedded nulls should raise OSError (not ValueError) + self.assertRaises(OSError, realpath, path, strict=True) ++ self.assertRaises(OSError, realpath, path, strict=ALLOW_MISSING) + path = ABSTFNb + b'\x00' + self.assertEqual(realpath(path, strict=False), path) + self.assertRaises(OSError, realpath, path, strict=True) ++ self.assertRaises(OSError, realpath, path, strict=ALLOW_MISSING) + path = ABSTFN + '\\nonexistent\\x\x00' + self.assertEqual(realpath(path, strict=False), path) + self.assertRaises(OSError, realpath, path, strict=True) ++ self.assertRaises(OSError, realpath, path, strict=ALLOW_MISSING) + path = ABSTFNb + b'\\nonexistent\\x\x00' + self.assertEqual(realpath(path, strict=False), path) + self.assertRaises(OSError, realpath, path, strict=True) ++ self.assertRaises(OSError, realpath, path, strict=ALLOW_MISSING) + path = ABSTFN + '\x00\\..' + self.assertEqual(realpath(path, strict=False), os.getcwd()) + self.assertEqual(realpath(path, strict=True), os.getcwd()) ++ self.assertEqual(realpath(path, strict=ALLOW_MISSING), os.getcwd()) + path = ABSTFNb + b'\x00\\..' + self.assertEqual(realpath(path, strict=False), os.getcwdb()) + self.assertEqual(realpath(path, strict=True), os.getcwdb()) ++ self.assertEqual(realpath(path, strict=ALLOW_MISSING), os.getcwdb()) + path = ABSTFN + '\\nonexistent\\x\x00\\..' + self.assertEqual(realpath(path, strict=False), ABSTFN + '\\nonexistent') + self.assertRaises(OSError, realpath, path, strict=True) ++ self.assertEqual(realpath(path, strict=ALLOW_MISSING), ABSTFN + '\\nonexistent') + path = ABSTFNb + b'\\nonexistent\\x\x00\\..' + self.assertEqual(realpath(path, strict=False), ABSTFNb + b'\\nonexistent') + self.assertRaises(OSError, realpath, path, strict=True) ++ self.assertEqual(realpath(path, strict=ALLOW_MISSING), ABSTFNb + b'\\nonexistent') + ++ @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') ++ @_parameterize({}, {'strict': True}, {'strict': ALLOW_MISSING}) ++ def test_realpath_invalid_unicode_paths(self, kwargs): ++ realpath = ntpath.realpath ++ ABSTFN = ntpath.abspath(os_helper.TESTFN) ++ ABSTFNb = os.fsencode(ABSTFN) + path = ABSTFNb + b'\xff' +- self.assertRaises(UnicodeDecodeError, realpath, path, strict=False) +- self.assertRaises(UnicodeDecodeError, realpath, path, strict=True) ++ self.assertRaises(UnicodeDecodeError, realpath, path, **kwargs) ++ self.assertRaises(UnicodeDecodeError, realpath, path, **kwargs) + path = ABSTFNb + b'\\nonexistent\\\xff' +- self.assertRaises(UnicodeDecodeError, realpath, path, strict=False) +- self.assertRaises(UnicodeDecodeError, realpath, path, strict=True) ++ self.assertRaises(UnicodeDecodeError, realpath, path, **kwargs) ++ self.assertRaises(UnicodeDecodeError, realpath, path, **kwargs) + path = ABSTFNb + b'\xff\\..' +- self.assertRaises(UnicodeDecodeError, realpath, path, strict=False) +- self.assertRaises(UnicodeDecodeError, realpath, path, strict=True) ++ self.assertRaises(UnicodeDecodeError, realpath, path, **kwargs) ++ self.assertRaises(UnicodeDecodeError, realpath, path, **kwargs) + path = ABSTFNb + b'\\nonexistent\\\xff\\..' +- self.assertRaises(UnicodeDecodeError, realpath, path, strict=False) +- self.assertRaises(UnicodeDecodeError, realpath, path, strict=True) ++ self.assertRaises(UnicodeDecodeError, realpath, path, **kwargs) ++ self.assertRaises(UnicodeDecodeError, realpath, path, **kwargs) + + @os_helper.skip_unless_symlink + @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') +- def test_realpath_relative(self): ++ @_parameterize({}, {'strict': True}, {'strict': ALLOW_MISSING}) ++ def test_realpath_relative(self, kwargs): + ABSTFN = ntpath.abspath(os_helper.TESTFN) + open(ABSTFN, "wb").close() + self.addCleanup(os_helper.unlink, ABSTFN) + self.addCleanup(os_helper.unlink, ABSTFN + "1") + + os.symlink(ABSTFN, ntpath.relpath(ABSTFN + "1")) +- self.assertPathEqual(ntpath.realpath(ABSTFN + "1"), ABSTFN) ++ self.assertPathEqual(ntpath.realpath(ABSTFN + "1", **kwargs), ABSTFN) + + @os_helper.skip_unless_symlink + @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') +@@ -723,7 +816,62 @@ def test_realpath_symlink_loops_strict(self): + + @os_helper.skip_unless_symlink + @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') +- def test_realpath_symlink_prefix(self): ++ def test_realpath_symlink_loops_raise(self): ++ # Symlink loops raise OSError in ALLOW_MISSING mode ++ ABSTFN = ntpath.abspath(os_helper.TESTFN) ++ self.addCleanup(os_helper.unlink, ABSTFN) ++ self.addCleanup(os_helper.unlink, ABSTFN + "1") ++ self.addCleanup(os_helper.unlink, ABSTFN + "2") ++ self.addCleanup(os_helper.unlink, ABSTFN + "y") ++ self.addCleanup(os_helper.unlink, ABSTFN + "c") ++ self.addCleanup(os_helper.unlink, ABSTFN + "a") ++ self.addCleanup(os_helper.unlink, ABSTFN + "x") ++ ++ os.symlink(ABSTFN, ABSTFN) ++ self.assertRaises(OSError, ntpath.realpath, ABSTFN, strict=ALLOW_MISSING) ++ ++ os.symlink(ABSTFN + "1", ABSTFN + "2") ++ os.symlink(ABSTFN + "2", ABSTFN + "1") ++ self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1", ++ strict=ALLOW_MISSING) ++ self.assertRaises(OSError, ntpath.realpath, ABSTFN + "2", ++ strict=ALLOW_MISSING) ++ self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1\\x", ++ strict=ALLOW_MISSING) ++ ++ # Windows eliminates '..' components before resolving links; ++ # realpath is not expected to raise if this removes the loop. ++ self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\.."), ++ ntpath.dirname(ABSTFN)) ++ self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\..\\x"), ++ ntpath.dirname(ABSTFN) + "\\x") ++ ++ os.symlink(ABSTFN + "x", ABSTFN + "y") ++ self.assertPathEqual(ntpath.realpath(ABSTFN + "1\\..\\" ++ + ntpath.basename(ABSTFN) + "y"), ++ ABSTFN + "x") ++ self.assertRaises( ++ OSError, ntpath.realpath, ++ ABSTFN + "1\\..\\" + ntpath.basename(ABSTFN) + "1", ++ strict=ALLOW_MISSING) ++ ++ os.symlink(ntpath.basename(ABSTFN) + "a\\b", ABSTFN + "a") ++ self.assertRaises(OSError, ntpath.realpath, ABSTFN + "a", ++ strict=ALLOW_MISSING) ++ ++ os.symlink("..\\" + ntpath.basename(ntpath.dirname(ABSTFN)) ++ + "\\" + ntpath.basename(ABSTFN) + "c", ABSTFN + "c") ++ self.assertRaises(OSError, ntpath.realpath, ABSTFN + "c", ++ strict=ALLOW_MISSING) ++ ++ # Test using relative path as well. ++ self.assertRaises(OSError, ntpath.realpath, ntpath.basename(ABSTFN), ++ strict=ALLOW_MISSING) ++ ++ @os_helper.skip_unless_symlink ++ @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') ++ @_parameterize({}, {'strict': True}, {'strict': ALLOW_MISSING}) ++ def test_realpath_symlink_prefix(self, kwargs): + ABSTFN = ntpath.abspath(os_helper.TESTFN) + self.addCleanup(os_helper.unlink, ABSTFN + "3") + self.addCleanup(os_helper.unlink, "\\\\?\\" + ABSTFN + "3.") +@@ -738,9 +886,9 @@ def test_realpath_symlink_prefix(self): + f.write(b'1') + os.symlink("\\\\?\\" + ABSTFN + "3.", ABSTFN + "3.link") + +- self.assertPathEqual(ntpath.realpath(ABSTFN + "3link"), ++ self.assertPathEqual(ntpath.realpath(ABSTFN + "3link", **kwargs), + ABSTFN + "3") +- self.assertPathEqual(ntpath.realpath(ABSTFN + "3.link"), ++ self.assertPathEqual(ntpath.realpath(ABSTFN + "3.link", **kwargs), + "\\\\?\\" + ABSTFN + "3.") + + # Resolved paths should be usable to open target files +@@ -750,14 +898,17 @@ def test_realpath_symlink_prefix(self): + self.assertEqual(f.read(), b'1') + + # When the prefix is included, it is not stripped +- self.assertPathEqual(ntpath.realpath("\\\\?\\" + ABSTFN + "3link"), ++ self.assertPathEqual(ntpath.realpath("\\\\?\\" + ABSTFN + "3link", **kwargs), + "\\\\?\\" + ABSTFN + "3") +- self.assertPathEqual(ntpath.realpath("\\\\?\\" + ABSTFN + "3.link"), ++ self.assertPathEqual(ntpath.realpath("\\\\?\\" + ABSTFN + "3.link", **kwargs), + "\\\\?\\" + ABSTFN + "3.") + + @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') + def test_realpath_nul(self): + tester("ntpath.realpath('NUL')", r'\\.\NUL') ++ tester("ntpath.realpath('NUL', strict=False)", r'\\.\NUL') ++ tester("ntpath.realpath('NUL', strict=True)", r'\\.\NUL') ++ tester("ntpath.realpath('NUL', strict=ALLOW_MISSING)", r'\\.\NUL') + + @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') + @unittest.skipUnless(HAVE_GETSHORTPATHNAME, 'need _getshortpathname') +@@ -781,12 +932,20 @@ def test_realpath_cwd(self): + + self.assertPathEqual(test_file_long, ntpath.realpath(test_file_short)) + +- with os_helper.change_cwd(test_dir_long): +- self.assertPathEqual(test_file_long, ntpath.realpath("file.txt")) +- with os_helper.change_cwd(test_dir_long.lower()): +- self.assertPathEqual(test_file_long, ntpath.realpath("file.txt")) +- with os_helper.change_cwd(test_dir_short): +- self.assertPathEqual(test_file_long, ntpath.realpath("file.txt")) ++ for kwargs in {}, {'strict': True}, {'strict': ALLOW_MISSING}: ++ with self.subTest(**kwargs): ++ with os_helper.change_cwd(test_dir_long): ++ self.assertPathEqual( ++ test_file_long, ++ ntpath.realpath("file.txt", **kwargs)) ++ with os_helper.change_cwd(test_dir_long.lower()): ++ self.assertPathEqual( ++ test_file_long, ++ ntpath.realpath("file.txt", **kwargs)) ++ with os_helper.change_cwd(test_dir_short): ++ self.assertPathEqual( ++ test_file_long, ++ ntpath.realpath("file.txt", **kwargs)) + + @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') + def test_realpath_permission(self): +@@ -807,12 +966,15 @@ def test_realpath_permission(self): + # Automatic generation of short names may be disabled on + # NTFS volumes for the sake of performance. + # They're not supported at all on ReFS and exFAT. +- subprocess.run( ++ p = subprocess.run( + # Try to set the short name manually. + ['fsutil.exe', 'file', 'setShortName', test_file, 'LONGFI~1.TXT'], + creationflags=subprocess.DETACHED_PROCESS + ) + ++ if p.returncode: ++ raise unittest.SkipTest('failed to set short name') ++ + try: + self.assertPathEqual(test_file, ntpath.realpath(test_file_short)) + except AssertionError: +diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py +index f3f9895f529470..c45ce6d3ef7820 100644 +--- a/Lib/test/test_posixpath.py ++++ b/Lib/test/test_posixpath.py +@@ -4,7 +4,8 @@ + import random + import sys + import unittest +-from posixpath import realpath, abspath, dirname, basename ++from functools import partial ++from posixpath import realpath, abspath, dirname, basename, ALLOW_MISSING + from test import support + from test import test_genericpath + from test.support import import_helper +@@ -33,6 +34,27 @@ def skip_if_ABSTFN_contains_backslash(test): + msg = "ABSTFN is not a posix path - tests fail" + return [test, unittest.skip(msg)(test)][found_backslash] + ++ ++def _parameterize(*parameters): ++ """Simplistic decorator to parametrize a test ++ ++ Runs the decorated test multiple times in subTest, with a value from ++ 'parameters' passed as an extra positional argument. ++ Does *not* call doCleanups() after each run. ++ ++ Not for general use. Intended to avoid indenting for easier backports. ++ ++ See https://discuss.python.org/t/91827 for discussing generalizations. ++ """ ++ def _parametrize_decorator(func): ++ def _parameterized(self, *args, **kwargs): ++ for parameter in parameters: ++ with self.subTest(parameter): ++ func(self, *args, parameter, **kwargs) ++ return _parameterized ++ return _parametrize_decorator ++ ++ + class PosixPathTest(unittest.TestCase): + + def setUp(self): +@@ -442,32 +464,35 @@ def test_normpath(self): + self.assertEqual(result, expected) + + @skip_if_ABSTFN_contains_backslash +- def test_realpath_curdir(self): +- self.assertEqual(realpath('.'), os.getcwd()) +- self.assertEqual(realpath('./.'), os.getcwd()) +- self.assertEqual(realpath('/'.join(['.'] * 100)), os.getcwd()) ++ @_parameterize({}, {'strict': True}, {'strict': ALLOW_MISSING}) ++ def test_realpath_curdir(self, kwargs): ++ self.assertEqual(realpath('.', **kwargs), os.getcwd()) ++ self.assertEqual(realpath('./.', **kwargs), os.getcwd()) ++ self.assertEqual(realpath('/'.join(['.'] * 100), **kwargs), os.getcwd()) + +- self.assertEqual(realpath(b'.'), os.getcwdb()) +- self.assertEqual(realpath(b'./.'), os.getcwdb()) +- self.assertEqual(realpath(b'/'.join([b'.'] * 100)), os.getcwdb()) ++ self.assertEqual(realpath(b'.', **kwargs), os.getcwdb()) ++ self.assertEqual(realpath(b'./.', **kwargs), os.getcwdb()) ++ self.assertEqual(realpath(b'/'.join([b'.'] * 100), **kwargs), os.getcwdb()) + + @skip_if_ABSTFN_contains_backslash +- def test_realpath_pardir(self): +- self.assertEqual(realpath('..'), dirname(os.getcwd())) +- self.assertEqual(realpath('../..'), dirname(dirname(os.getcwd()))) +- self.assertEqual(realpath('/'.join(['..'] * 100)), '/') ++ @_parameterize({}, {'strict': True}, {'strict': ALLOW_MISSING}) ++ def test_realpath_pardir(self, kwargs): ++ self.assertEqual(realpath('..', **kwargs), dirname(os.getcwd())) ++ self.assertEqual(realpath('../..', **kwargs), dirname(dirname(os.getcwd()))) ++ self.assertEqual(realpath('/'.join(['..'] * 100), **kwargs), '/') + +- self.assertEqual(realpath(b'..'), dirname(os.getcwdb())) +- self.assertEqual(realpath(b'../..'), dirname(dirname(os.getcwdb()))) +- self.assertEqual(realpath(b'/'.join([b'..'] * 100)), b'/') ++ self.assertEqual(realpath(b'..', **kwargs), dirname(os.getcwdb())) ++ self.assertEqual(realpath(b'../..', **kwargs), dirname(dirname(os.getcwdb()))) ++ self.assertEqual(realpath(b'/'.join([b'..'] * 100), **kwargs), b'/') + + @os_helper.skip_unless_symlink + @skip_if_ABSTFN_contains_backslash +- def test_realpath_basic(self): ++ @_parameterize({}, {'strict': ALLOW_MISSING}) ++ def test_realpath_basic(self, kwargs): + # Basic operation. + try: + os.symlink(ABSTFN+"1", ABSTFN) +- self.assertEqual(realpath(ABSTFN), ABSTFN+"1") ++ self.assertEqual(realpath(ABSTFN, **kwargs), ABSTFN+"1") + finally: + os_helper.unlink(ABSTFN) + +@@ -487,90 +512,115 @@ def test_realpath_invalid_paths(self): + path = '/\x00' + self.assertRaises(ValueError, realpath, path, strict=False) + self.assertRaises(ValueError, realpath, path, strict=True) ++ self.assertRaises(ValueError, realpath, path, strict=ALLOW_MISSING) + path = b'/\x00' + self.assertRaises(ValueError, realpath, path, strict=False) + self.assertRaises(ValueError, realpath, path, strict=True) ++ self.assertRaises(ValueError, realpath, path, strict=ALLOW_MISSING) + path = '/nonexistent/x\x00' + self.assertRaises(ValueError, realpath, path, strict=False) + self.assertRaises(FileNotFoundError, realpath, path, strict=True) ++ self.assertRaises(ValueError, realpath, path, strict=ALLOW_MISSING) + path = b'/nonexistent/x\x00' + self.assertRaises(ValueError, realpath, path, strict=False) + self.assertRaises(FileNotFoundError, realpath, path, strict=True) ++ self.assertRaises(ValueError, realpath, path, strict=ALLOW_MISSING) + path = '/\x00/..' + self.assertRaises(ValueError, realpath, path, strict=False) + self.assertRaises(ValueError, realpath, path, strict=True) ++ self.assertRaises(ValueError, realpath, path, strict=ALLOW_MISSING) + path = b'/\x00/..' + self.assertRaises(ValueError, realpath, path, strict=False) + self.assertRaises(ValueError, realpath, path, strict=True) ++ self.assertRaises(ValueError, realpath, path, strict=ALLOW_MISSING) ++ + path = '/nonexistent/x\x00/..' + self.assertRaises(ValueError, realpath, path, strict=False) + self.assertRaises(FileNotFoundError, realpath, path, strict=True) ++ self.assertRaises(ValueError, realpath, path, strict=ALLOW_MISSING) + path = b'/nonexistent/x\x00/..' + self.assertRaises(ValueError, realpath, path, strict=False) + self.assertRaises(FileNotFoundError, realpath, path, strict=True) ++ self.assertRaises(ValueError, realpath, path, strict=ALLOW_MISSING) + + path = '/\udfff' + if sys.platform == 'win32': + self.assertEqual(realpath(path, strict=False), path) + self.assertRaises(FileNotFoundError, realpath, path, strict=True) ++ self.assertEqual(realpath(path, strict=ALLOW_MISSING), path) + else: + self.assertRaises(UnicodeEncodeError, realpath, path, strict=False) + self.assertRaises(UnicodeEncodeError, realpath, path, strict=True) ++ self.assertRaises(UnicodeEncodeError, realpath, path, strict=ALLOW_MISSING) + path = '/nonexistent/\udfff' + if sys.platform == 'win32': + self.assertEqual(realpath(path, strict=False), path) ++ self.assertEqual(realpath(path, strict=ALLOW_MISSING), path) + else: + self.assertRaises(UnicodeEncodeError, realpath, path, strict=False) ++ self.assertRaises(UnicodeEncodeError, realpath, path, strict=ALLOW_MISSING) + self.assertRaises(FileNotFoundError, realpath, path, strict=True) + path = '/\udfff/..' + if sys.platform == 'win32': + self.assertEqual(realpath(path, strict=False), '/') + self.assertRaises(FileNotFoundError, realpath, path, strict=True) ++ self.assertEqual(realpath(path, strict=ALLOW_MISSING), '/') + else: + self.assertRaises(UnicodeEncodeError, realpath, path, strict=False) + self.assertRaises(UnicodeEncodeError, realpath, path, strict=True) ++ self.assertRaises(UnicodeEncodeError, realpath, path, strict=ALLOW_MISSING) + path = '/nonexistent/\udfff/..' + if sys.platform == 'win32': + self.assertEqual(realpath(path, strict=False), '/nonexistent') ++ self.assertEqual(realpath(path, strict=ALLOW_MISSING), '/nonexistent') + else: + self.assertRaises(UnicodeEncodeError, realpath, path, strict=False) ++ self.assertRaises(UnicodeEncodeError, realpath, path, strict=ALLOW_MISSING) + self.assertRaises(FileNotFoundError, realpath, path, strict=True) + + path = b'/\xff' + if sys.platform == 'win32': + self.assertRaises(UnicodeDecodeError, realpath, path, strict=False) + self.assertRaises(UnicodeDecodeError, realpath, path, strict=True) ++ self.assertRaises(UnicodeDecodeError, realpath, path, strict=ALLOW_MISSING) + else: + self.assertEqual(realpath(path, strict=False), path) + if support.is_wasi: + self.assertRaises(OSError, realpath, path, strict=True) ++ self.assertRaises(OSError, realpath, path, strict=ALLOW_MISSING) + else: + self.assertRaises(FileNotFoundError, realpath, path, strict=True) ++ self.assertEqual(realpath(path, strict=ALLOW_MISSING), path) + path = b'/nonexistent/\xff' + if sys.platform == 'win32': + self.assertRaises(UnicodeDecodeError, realpath, path, strict=False) ++ self.assertRaises(UnicodeDecodeError, realpath, path, strict=ALLOW_MISSING) + else: + self.assertEqual(realpath(path, strict=False), path) + if support.is_wasi: + self.assertRaises(OSError, realpath, path, strict=True) ++ self.assertRaises(OSError, realpath, path, strict=ALLOW_MISSING) + else: + self.assertRaises(FileNotFoundError, realpath, path, strict=True) + + @os_helper.skip_unless_symlink + @skip_if_ABSTFN_contains_backslash +- def test_realpath_relative(self): ++ @_parameterize({}, {'strict': ALLOW_MISSING}) ++ def test_realpath_relative(self, kwargs): + try: + os.symlink(posixpath.relpath(ABSTFN+"1"), ABSTFN) +- self.assertEqual(realpath(ABSTFN), ABSTFN+"1") ++ self.assertEqual(realpath(ABSTFN, **kwargs), ABSTFN+"1") + finally: + os_helper.unlink(ABSTFN) + + @os_helper.skip_unless_symlink + @skip_if_ABSTFN_contains_backslash +- def test_realpath_missing_pardir(self): ++ @_parameterize({}, {'strict': ALLOW_MISSING}) ++ def test_realpath_missing_pardir(self, kwargs): + try: + os.symlink(TESTFN + "1", TESTFN) +- self.assertEqual(realpath("nonexistent/../" + TESTFN), ABSTFN + "1") ++ self.assertEqual( ++ realpath("nonexistent/../" + TESTFN, **kwargs), ABSTFN + "1") + finally: + os_helper.unlink(TESTFN) + +@@ -617,37 +667,38 @@ def test_realpath_symlink_loops(self): + + @os_helper.skip_unless_symlink + @skip_if_ABSTFN_contains_backslash +- def test_realpath_symlink_loops_strict(self): ++ @_parameterize({'strict': True}, {'strict': ALLOW_MISSING}) ++ def test_realpath_symlink_loops_strict(self, kwargs): + # Bug #43757, raise OSError if we get into an infinite symlink loop in +- # strict mode. ++ # the strict modes. + try: + os.symlink(ABSTFN, ABSTFN) +- self.assertRaises(OSError, realpath, ABSTFN, strict=True) ++ self.assertRaises(OSError, realpath, ABSTFN, **kwargs) + + os.symlink(ABSTFN+"1", ABSTFN+"2") + os.symlink(ABSTFN+"2", ABSTFN+"1") +- self.assertRaises(OSError, realpath, ABSTFN+"1", strict=True) +- self.assertRaises(OSError, realpath, ABSTFN+"2", strict=True) ++ self.assertRaises(OSError, realpath, ABSTFN+"1", **kwargs) ++ self.assertRaises(OSError, realpath, ABSTFN+"2", **kwargs) + +- self.assertRaises(OSError, realpath, ABSTFN+"1/x", strict=True) +- self.assertRaises(OSError, realpath, ABSTFN+"1/..", strict=True) +- self.assertRaises(OSError, realpath, ABSTFN+"1/../x", strict=True) ++ self.assertRaises(OSError, realpath, ABSTFN+"1/x", **kwargs) ++ self.assertRaises(OSError, realpath, ABSTFN+"1/..", **kwargs) ++ self.assertRaises(OSError, realpath, ABSTFN+"1/../x", **kwargs) + os.symlink(ABSTFN+"x", ABSTFN+"y") + self.assertRaises(OSError, realpath, +- ABSTFN+"1/../" + basename(ABSTFN) + "y", strict=True) ++ ABSTFN+"1/../" + basename(ABSTFN) + "y", **kwargs) + self.assertRaises(OSError, realpath, +- ABSTFN+"1/../" + basename(ABSTFN) + "1", strict=True) ++ ABSTFN+"1/../" + basename(ABSTFN) + "1", **kwargs) + + os.symlink(basename(ABSTFN) + "a/b", ABSTFN+"a") +- self.assertRaises(OSError, realpath, ABSTFN+"a", strict=True) ++ self.assertRaises(OSError, realpath, ABSTFN+"a", **kwargs) + + os.symlink("../" + basename(dirname(ABSTFN)) + "/" + + basename(ABSTFN) + "c", ABSTFN+"c") +- self.assertRaises(OSError, realpath, ABSTFN+"c", strict=True) ++ self.assertRaises(OSError, realpath, ABSTFN+"c", **kwargs) + + # Test using relative path as well. + with os_helper.change_cwd(dirname(ABSTFN)): +- self.assertRaises(OSError, realpath, basename(ABSTFN), strict=True) ++ self.assertRaises(OSError, realpath, basename(ABSTFN), **kwargs) + finally: + os_helper.unlink(ABSTFN) + os_helper.unlink(ABSTFN+"1") +@@ -658,13 +709,14 @@ def test_realpath_symlink_loops_strict(self): + + @os_helper.skip_unless_symlink + @skip_if_ABSTFN_contains_backslash +- def test_realpath_repeated_indirect_symlinks(self): ++ @_parameterize({}, {'strict': True}, {'strict': ALLOW_MISSING}) ++ def test_realpath_repeated_indirect_symlinks(self, kwargs): + # Issue #6975. + try: + os.mkdir(ABSTFN) + os.symlink('../' + basename(ABSTFN), ABSTFN + '/self') + os.symlink('self/self/self', ABSTFN + '/link') +- self.assertEqual(realpath(ABSTFN + '/link'), ABSTFN) ++ self.assertEqual(realpath(ABSTFN + '/link', **kwargs), ABSTFN) + finally: + os_helper.unlink(ABSTFN + '/self') + os_helper.unlink(ABSTFN + '/link') +@@ -672,14 +724,15 @@ def test_realpath_repeated_indirect_symlinks(self): + + @os_helper.skip_unless_symlink + @skip_if_ABSTFN_contains_backslash +- def test_realpath_deep_recursion(self): ++ @_parameterize({}, {'strict': True}, {'strict': ALLOW_MISSING}) ++ def test_realpath_deep_recursion(self, kwargs): + depth = 10 + try: + os.mkdir(ABSTFN) + for i in range(depth): + os.symlink('/'.join(['%d' % i] * 10), ABSTFN + '/%d' % (i + 1)) + os.symlink('.', ABSTFN + '/0') +- self.assertEqual(realpath(ABSTFN + '/%d' % depth), ABSTFN) ++ self.assertEqual(realpath(ABSTFN + '/%d' % depth, **kwargs), ABSTFN) + + # Test using relative path as well. + with os_helper.change_cwd(ABSTFN): +@@ -691,7 +744,8 @@ def test_realpath_deep_recursion(self): + + @os_helper.skip_unless_symlink + @skip_if_ABSTFN_contains_backslash +- def test_realpath_resolve_parents(self): ++ @_parameterize({}, {'strict': ALLOW_MISSING}) ++ def test_realpath_resolve_parents(self, kwargs): + # We also need to resolve any symlinks in the parents of a relative + # path passed to realpath. E.g.: current working directory is + # /usr/doc with 'doc' being a symlink to /usr/share/doc. We call +@@ -702,7 +756,8 @@ def test_realpath_resolve_parents(self): + os.symlink(ABSTFN + "/y", ABSTFN + "/k") + + with os_helper.change_cwd(ABSTFN + "/k"): +- self.assertEqual(realpath("a"), ABSTFN + "/y/a") ++ self.assertEqual(realpath("a", **kwargs), ++ ABSTFN + "/y/a") + finally: + os_helper.unlink(ABSTFN + "/k") + os_helper.rmdir(ABSTFN + "/y") +@@ -710,7 +765,8 @@ def test_realpath_resolve_parents(self): + + @os_helper.skip_unless_symlink + @skip_if_ABSTFN_contains_backslash +- def test_realpath_resolve_before_normalizing(self): ++ @_parameterize({}, {'strict': True}, {'strict': ALLOW_MISSING}) ++ def test_realpath_resolve_before_normalizing(self, kwargs): + # Bug #990669: Symbolic links should be resolved before we + # normalize the path. E.g.: if we have directories 'a', 'k' and 'y' + # in the following hierarchy: +@@ -725,10 +781,10 @@ def test_realpath_resolve_before_normalizing(self): + os.symlink(ABSTFN + "/k/y", ABSTFN + "/link-y") + + # Absolute path. +- self.assertEqual(realpath(ABSTFN + "/link-y/.."), ABSTFN + "/k") ++ self.assertEqual(realpath(ABSTFN + "/link-y/..", **kwargs), ABSTFN + "/k") + # Relative path. + with os_helper.change_cwd(dirname(ABSTFN)): +- self.assertEqual(realpath(basename(ABSTFN) + "/link-y/.."), ++ self.assertEqual(realpath(basename(ABSTFN) + "/link-y/..", **kwargs), + ABSTFN + "/k") + finally: + os_helper.unlink(ABSTFN + "/link-y") +@@ -738,7 +794,8 @@ def test_realpath_resolve_before_normalizing(self): + + @os_helper.skip_unless_symlink + @skip_if_ABSTFN_contains_backslash +- def test_realpath_resolve_first(self): ++ @_parameterize({}, {'strict': True}, {'strict': ALLOW_MISSING}) ++ def test_realpath_resolve_first(self, kwargs): + # Bug #1213894: The first component of the path, if not absolute, + # must be resolved too. + +@@ -748,8 +805,8 @@ def test_realpath_resolve_first(self): + os.symlink(ABSTFN, ABSTFN + "link") + with os_helper.change_cwd(dirname(ABSTFN)): + base = basename(ABSTFN) +- self.assertEqual(realpath(base + "link"), ABSTFN) +- self.assertEqual(realpath(base + "link/k"), ABSTFN + "/k") ++ self.assertEqual(realpath(base + "link", **kwargs), ABSTFN) ++ self.assertEqual(realpath(base + "link/k", **kwargs), ABSTFN + "/k") + finally: + os_helper.unlink(ABSTFN + "link") + os_helper.rmdir(ABSTFN + "/k") +@@ -767,12 +824,67 @@ def test_realpath_unreadable_symlink(self): + self.assertEqual(realpath(ABSTFN + '/foo'), ABSTFN + '/foo') + self.assertEqual(realpath(ABSTFN + '/../foo'), dirname(ABSTFN) + '/foo') + self.assertEqual(realpath(ABSTFN + '/foo/..'), ABSTFN) +- with self.assertRaises(PermissionError): +- realpath(ABSTFN, strict=True) + finally: + os.chmod(ABSTFN, 0o755, follow_symlinks=False) + os_helper.unlink(ABSTFN) + ++ @os_helper.skip_unless_symlink ++ @skip_if_ABSTFN_contains_backslash ++ @unittest.skipIf(os.chmod not in os.supports_follow_symlinks, "Can't set symlink permissions") ++ @unittest.skipIf(sys.platform != "darwin", "only macOS requires read permission to readlink()") ++ @_parameterize({'strict': True}, {'strict': ALLOW_MISSING}) ++ def test_realpath_unreadable_symlink_strict(self, kwargs): ++ try: ++ os.symlink(ABSTFN+"1", ABSTFN) ++ os.chmod(ABSTFN, 0o000, follow_symlinks=False) ++ with self.assertRaises(PermissionError): ++ realpath(ABSTFN, **kwargs) ++ with self.assertRaises(PermissionError): ++ realpath(ABSTFN + '/foo', **kwargs), ++ with self.assertRaises(PermissionError): ++ realpath(ABSTFN + '/../foo', **kwargs) ++ with self.assertRaises(PermissionError): ++ realpath(ABSTFN + '/foo/..', **kwargs) ++ finally: ++ os.chmod(ABSTFN, 0o755, follow_symlinks=False) ++ os.unlink(ABSTFN) ++ ++ @skip_if_ABSTFN_contains_backslash ++ @os_helper.skip_unless_symlink ++ def test_realpath_unreadable_directory(self): ++ try: ++ os.mkdir(ABSTFN) ++ os.mkdir(ABSTFN + '/k') ++ os.chmod(ABSTFN, 0o000) ++ self.assertEqual(realpath(ABSTFN, strict=False), ABSTFN) ++ self.assertEqual(realpath(ABSTFN, strict=True), ABSTFN) ++ self.assertEqual(realpath(ABSTFN, strict=ALLOW_MISSING), ABSTFN) ++ ++ try: ++ os.stat(ABSTFN) ++ except PermissionError: ++ pass ++ else: ++ self.skipTest('Cannot block permissions') ++ ++ self.assertEqual(realpath(ABSTFN + '/k', strict=False), ++ ABSTFN + '/k') ++ self.assertRaises(PermissionError, realpath, ABSTFN + '/k', ++ strict=True) ++ self.assertRaises(PermissionError, realpath, ABSTFN + '/k', ++ strict=ALLOW_MISSING) ++ ++ self.assertEqual(realpath(ABSTFN + '/missing', strict=False), ++ ABSTFN + '/missing') ++ self.assertRaises(PermissionError, realpath, ABSTFN + '/missing', ++ strict=True) ++ self.assertRaises(PermissionError, realpath, ABSTFN + '/missing', ++ strict=ALLOW_MISSING) ++ finally: ++ os.chmod(ABSTFN, 0o755) ++ os_helper.rmdir(ABSTFN + '/k') ++ os_helper.rmdir(ABSTFN) ++ + @skip_if_ABSTFN_contains_backslash + def test_realpath_nonterminal_file(self): + try: +@@ -780,14 +892,27 @@ def test_realpath_nonterminal_file(self): + f.write('test_posixpath wuz ere') + self.assertEqual(realpath(ABSTFN, strict=False), ABSTFN) + self.assertEqual(realpath(ABSTFN, strict=True), ABSTFN) ++ self.assertEqual(realpath(ABSTFN, strict=ALLOW_MISSING), ABSTFN) ++ + self.assertEqual(realpath(ABSTFN + "/", strict=False), ABSTFN) + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/", strict=True) ++ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/", ++ strict=ALLOW_MISSING) ++ + self.assertEqual(realpath(ABSTFN + "/.", strict=False), ABSTFN) + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/.", strict=True) ++ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/.", ++ strict=ALLOW_MISSING) ++ + self.assertEqual(realpath(ABSTFN + "/..", strict=False), dirname(ABSTFN)) + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/..", strict=True) ++ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/..", ++ strict=ALLOW_MISSING) ++ + self.assertEqual(realpath(ABSTFN + "/subdir", strict=False), ABSTFN + "/subdir") + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/subdir", strict=True) ++ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/subdir", ++ strict=ALLOW_MISSING) + finally: + os_helper.unlink(ABSTFN) + +@@ -800,14 +925,27 @@ def test_realpath_nonterminal_symlink_to_file(self): + os.symlink(ABSTFN + "1", ABSTFN) + self.assertEqual(realpath(ABSTFN, strict=False), ABSTFN + "1") + self.assertEqual(realpath(ABSTFN, strict=True), ABSTFN + "1") ++ self.assertEqual(realpath(ABSTFN, strict=ALLOW_MISSING), ABSTFN + "1") ++ + self.assertEqual(realpath(ABSTFN + "/", strict=False), ABSTFN + "1") + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/", strict=True) ++ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/", ++ strict=ALLOW_MISSING) ++ + self.assertEqual(realpath(ABSTFN + "/.", strict=False), ABSTFN + "1") + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/.", strict=True) ++ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/.", ++ strict=ALLOW_MISSING) ++ + self.assertEqual(realpath(ABSTFN + "/..", strict=False), dirname(ABSTFN)) + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/..", strict=True) ++ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/..", ++ strict=ALLOW_MISSING) ++ + self.assertEqual(realpath(ABSTFN + "/subdir", strict=False), ABSTFN + "1/subdir") + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/subdir", strict=True) ++ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/subdir", ++ strict=ALLOW_MISSING) + finally: + os_helper.unlink(ABSTFN) + os_helper.unlink(ABSTFN + "1") +@@ -822,14 +960,27 @@ def test_realpath_nonterminal_symlink_to_symlinks_to_file(self): + os.symlink(ABSTFN + "1", ABSTFN) + self.assertEqual(realpath(ABSTFN, strict=False), ABSTFN + "2") + self.assertEqual(realpath(ABSTFN, strict=True), ABSTFN + "2") ++ self.assertEqual(realpath(ABSTFN, strict=True), ABSTFN + "2") ++ + self.assertEqual(realpath(ABSTFN + "/", strict=False), ABSTFN + "2") + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/", strict=True) ++ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/", ++ strict=ALLOW_MISSING) ++ + self.assertEqual(realpath(ABSTFN + "/.", strict=False), ABSTFN + "2") + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/.", strict=True) ++ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/.", ++ strict=ALLOW_MISSING) ++ + self.assertEqual(realpath(ABSTFN + "/..", strict=False), dirname(ABSTFN)) + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/..", strict=True) ++ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/..", ++ strict=ALLOW_MISSING) ++ + self.assertEqual(realpath(ABSTFN + "/subdir", strict=False), ABSTFN + "2/subdir") + self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/subdir", strict=True) ++ self.assertRaises(NotADirectoryError, realpath, ABSTFN + "/subdir", ++ strict=ALLOW_MISSING) + finally: + os_helper.unlink(ABSTFN) + os_helper.unlink(ABSTFN + "1") +@@ -1017,9 +1168,12 @@ def test_path_normpath(self): + def test_path_abspath(self): + self.assertPathEqual(self.path.abspath) + +- def test_path_realpath(self): ++ @_parameterize({}, {'strict': True}, {'strict': ALLOW_MISSING}) ++ def test_path_realpath(self, kwargs): + self.assertPathEqual(self.path.realpath) + ++ self.assertPathEqual(partial(self.path.realpath, **kwargs)) ++ + def test_path_relpath(self): + self.assertPathEqual(self.path.relpath) + +diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py +index cf218a2bf14369..7055e1ed147a9e 100644 +--- a/Lib/test/test_tarfile.py ++++ b/Lib/test/test_tarfile.py +@@ -2715,6 +2715,31 @@ def test_useful_error_message_when_modules_missing(self): + str(excinfo.exception), + ) + ++ @unittest.skipUnless(os_helper.can_symlink(), 'requires symlink support') ++ @unittest.skipUnless(hasattr(os, 'chmod'), "missing os.chmod") ++ @unittest.mock.patch('os.chmod') ++ def test_deferred_directory_attributes_update(self, mock_chmod): ++ # Regression test for gh-127987: setting attributes on arbitrary files ++ tempdir = os.path.join(TEMPDIR, 'test127987') ++ def mock_chmod_side_effect(path, mode, **kwargs): ++ target_path = os.path.realpath(path) ++ if os.path.commonpath([target_path, tempdir]) != tempdir: ++ raise Exception("should not try to chmod anything outside the destination", target_path) ++ mock_chmod.side_effect = mock_chmod_side_effect ++ ++ outside_tree_dir = os.path.join(TEMPDIR, 'outside_tree_dir') ++ with ArchiveMaker() as arc: ++ arc.add('x', symlink_to='.') ++ arc.add('x', type=tarfile.DIRTYPE, mode='?rwsrwsrwt') ++ arc.add('x', symlink_to=outside_tree_dir) ++ ++ os.makedirs(outside_tree_dir) ++ try: ++ arc.open().extractall(path=tempdir, filter='tar') ++ finally: ++ os_helper.rmtree(outside_tree_dir) ++ os_helper.rmtree(tempdir) ++ + + class CommandLineTest(unittest.TestCase): + +@@ -3275,6 +3300,10 @@ def check_files_present(self, directory): + got_paths = set( + p.relative_to(directory) + for p in pathlib.Path(directory).glob('**/*')) ++ if self.extraction_filter in (None, 'data'): ++ # The 'data' filter is expected to reject special files ++ for path in 'ustar/fifotype', 'ustar/blktype', 'ustar/chrtype': ++ got_paths.discard(pathlib.Path(path)) + self.assertEqual(self.control_paths, got_paths) + + @contextmanager +@@ -3504,12 +3533,28 @@ def __exit__(self, *exc): + self.bio = None + + def add(self, name, *, type=None, symlink_to=None, hardlink_to=None, +- mode=None, size=None, **kwargs): +- """Add a member to the test archive. Call within `with`.""" ++ mode=None, size=None, content=None, **kwargs): ++ """Add a member to the test archive. Call within `with`. ++ ++ Provides many shortcuts: ++ - default `type` is based on symlink_to, hardlink_to, and trailing `/` ++ in name (which is stripped) ++ - size & content defaults are based on each other ++ - content can be str or bytes ++ - mode should be textual ('-rwxrwxrwx') ++ ++ (add more! this is unstable internal test-only API) ++ """ + name = str(name) + tarinfo = tarfile.TarInfo(name).replace(**kwargs) ++ if content is not None: ++ if isinstance(content, str): ++ content = content.encode() ++ size = len(content) + if size is not None: + tarinfo.size = size ++ if content is None: ++ content = bytes(tarinfo.size) + if mode: + tarinfo.mode = _filemode_to_int(mode) + if symlink_to is not None: +@@ -3523,7 +3568,7 @@ def add(self, name, *, type=None, symlink_to=None, hardlink_to=None, + if type is not None: + tarinfo.type = type + if tarinfo.isreg(): +- fileobj = io.BytesIO(bytes(tarinfo.size)) ++ fileobj = io.BytesIO(content) + else: + fileobj = None + self.tar_w.addfile(tarinfo, fileobj) +@@ -3557,7 +3602,7 @@ class TestExtractionFilters(unittest.TestCase): + destdir = outerdir / 'dest' + + @contextmanager +- def check_context(self, tar, filter): ++ def check_context(self, tar, filter, *, check_flag=True): + """Extracts `tar` to `self.destdir` and allows checking the result + + If an error occurs, it must be checked using `expect_exception` +@@ -3566,27 +3611,40 @@ def check_context(self, tar, filter): + except the destination directory itself and parent directories of + other files. + When checking directories, do so before their contents. ++ ++ A file called 'flag' is made in outerdir (i.e. outside destdir) ++ before extraction; it should not be altered nor should its contents ++ be read/copied. + """ + with os_helper.temp_dir(self.outerdir): ++ flag_path = self.outerdir / 'flag' ++ flag_path.write_text('capture me') + try: + tar.extractall(self.destdir, filter=filter) + except Exception as exc: + self.raised_exception = exc ++ self.reraise_exception = True + self.expected_paths = set() + else: + self.raised_exception = None ++ self.reraise_exception = False + self.expected_paths = set(self.outerdir.glob('**/*')) + self.expected_paths.discard(self.destdir) ++ self.expected_paths.discard(flag_path) + try: +- yield ++ yield self + finally: + tar.close() +- if self.raised_exception: ++ if self.reraise_exception: + raise self.raised_exception + self.assertEqual(self.expected_paths, set()) ++ if check_flag: ++ self.assertEqual(flag_path.read_text(), 'capture me') ++ else: ++ assert filter == 'fully_trusted' + + def expect_file(self, name, type=None, symlink_to=None, mode=None, +- size=None): ++ size=None, content=None): + """Check a single file. See check_context.""" + if self.raised_exception: + raise self.raised_exception +@@ -3605,26 +3663,45 @@ def expect_file(self, name, type=None, symlink_to=None, mode=None, + # The symlink might be the same (textually) as what we expect, + # but some systems change the link to an equivalent path, so + # we fall back to samefile(). +- if expected != got: +- self.assertTrue(got.samefile(expected)) ++ try: ++ if expected != got: ++ self.assertTrue(got.samefile(expected)) ++ except Exception as e: ++ # attach a note, so it's shown even if `samefile` fails ++ e.add_note(f'{expected=}, {got=}') ++ raise + elif type == tarfile.REGTYPE or type is None: + self.assertTrue(path.is_file()) + elif type == tarfile.DIRTYPE: + self.assertTrue(path.is_dir()) + elif type == tarfile.FIFOTYPE: + self.assertTrue(path.is_fifo()) ++ elif type == tarfile.SYMTYPE: ++ self.assertTrue(path.is_symlink()) + else: + raise NotImplementedError(type) + if size is not None: + self.assertEqual(path.stat().st_size, size) ++ if content is not None: ++ self.assertEqual(path.read_text(), content) + for parent in path.parents: + self.expected_paths.discard(parent) + ++ def expect_any_tree(self, name): ++ """Check a directory; forget about its contents.""" ++ tree_path = (self.destdir / name).resolve() ++ self.expect_file(tree_path, type=tarfile.DIRTYPE) ++ self.expected_paths = { ++ p for p in self.expected_paths ++ if tree_path not in p.parents ++ } ++ + def expect_exception(self, exc_type, message_re='.'): + with self.assertRaisesRegex(exc_type, message_re): + if self.raised_exception is not None: + raise self.raised_exception +- self.raised_exception = None ++ self.reraise_exception = False ++ return self.raised_exception + + def test_benign_file(self): + with ArchiveMaker() as arc: +@@ -3709,6 +3786,80 @@ def test_parent_symlink(self): + with self.check_context(arc.open(), 'data'): + self.expect_file('parent/evil') + ++ @symlink_test ++ @os_helper.skip_unless_symlink ++ def test_realpath_limit_attack(self): ++ # (CVE-2025-4517) ++ ++ with ArchiveMaker() as arc: ++ # populate the symlinks and dirs that expand in os.path.realpath() ++ # The component length is chosen so that in common cases, the unexpanded ++ # path fits in PATH_MAX, but it overflows when the final symlink ++ # is expanded ++ steps = "abcdefghijklmnop" ++ if sys.platform == 'win32': ++ component = 'd' * 25 ++ elif 'PC_PATH_MAX' in os.pathconf_names: ++ max_path_len = os.pathconf(self.outerdir.parent, "PC_PATH_MAX") ++ path_sep_len = 1 ++ dest_len = len(str(self.destdir)) + path_sep_len ++ component_len = (max_path_len - dest_len) // (len(steps) + path_sep_len) ++ component = 'd' * component_len ++ else: ++ raise NotImplementedError("Need to guess component length for {sys.platform}") ++ path = "" ++ step_path = "" ++ for i in steps: ++ arc.add(os.path.join(path, component), type=tarfile.DIRTYPE, ++ mode='drwxrwxrwx') ++ arc.add(os.path.join(path, i), symlink_to=component) ++ path = os.path.join(path, component) ++ step_path = os.path.join(step_path, i) ++ # create the final symlink that exceeds PATH_MAX and simply points ++ # to the top dir. ++ # this link will never be expanded by ++ # os.path.realpath(strict=False), nor anything after it. ++ linkpath = os.path.join(*steps, "l"*254) ++ parent_segments = [".."] * len(steps) ++ arc.add(linkpath, symlink_to=os.path.join(*parent_segments)) ++ # make a symlink outside to keep the tar command happy ++ arc.add("escape", symlink_to=os.path.join(linkpath, "..")) ++ # use the symlinks above, that are not checked, to create a hardlink ++ # to a file outside of the destination path ++ arc.add("flaglink", hardlink_to=os.path.join("escape", "flag")) ++ # now that we have the hardlink we can overwrite the file ++ arc.add("flaglink", content='overwrite') ++ # we can also create new files as well! ++ arc.add("escape/newfile", content='new') ++ ++ with (self.subTest('fully_trusted'), ++ self.check_context(arc.open(), filter='fully_trusted', ++ check_flag=False)): ++ if sys.platform == 'win32': ++ self.expect_exception((FileNotFoundError, FileExistsError)) ++ elif self.raised_exception: ++ # Cannot symlink/hardlink: tarfile falls back to getmember() ++ self.expect_exception(KeyError) ++ # Otherwise, this block should never enter. ++ else: ++ self.expect_any_tree(component) ++ self.expect_file('flaglink', content='overwrite') ++ self.expect_file('../newfile', content='new') ++ self.expect_file('escape', type=tarfile.SYMTYPE) ++ self.expect_file('a', symlink_to=component) ++ ++ for filter in 'tar', 'data': ++ with self.subTest(filter), self.check_context(arc.open(), filter=filter): ++ exc = self.expect_exception((OSError, KeyError)) ++ if isinstance(exc, OSError): ++ if sys.platform == 'win32': ++ # 3: ERROR_PATH_NOT_FOUND ++ # 5: ERROR_ACCESS_DENIED ++ # 206: ERROR_FILENAME_EXCED_RANGE ++ self.assertIn(exc.winerror, (3, 5, 206)) ++ else: ++ self.assertEqual(exc.errno, errno.ENAMETOOLONG) ++ + @symlink_test + def test_parent_symlink2(self): + # Test interplaying symlinks +@@ -3931,8 +4082,8 @@ def test_chains(self): + arc.add('symlink2', symlink_to=os.path.join( + 'linkdir', 'hardlink2')) + arc.add('targetdir/target', size=3) +- arc.add('linkdir/hardlink', hardlink_to='targetdir/target') +- arc.add('linkdir/hardlink2', hardlink_to='linkdir/symlink') ++ arc.add('linkdir/hardlink', hardlink_to=os.path.join('targetdir', 'target')) ++ arc.add('linkdir/hardlink2', hardlink_to=os.path.join('linkdir', 'symlink')) + + for filter in 'tar', 'data', 'fully_trusted': + with self.check_context(arc.open(), filter): +@@ -3948,6 +4099,129 @@ def test_chains(self): + self.expect_file('linkdir/symlink', size=3) + self.expect_file('symlink2', size=3) + ++ @symlink_test ++ def test_sneaky_hardlink_fallback(self): ++ # (CVE-2025-4330) ++ # Test that when hardlink extraction falls back to extracting members ++ # from the archive, the extracted member is (re-)filtered. ++ with ArchiveMaker() as arc: ++ # Create a directory structure so the c/escape symlink stays ++ # inside the path ++ arc.add("a/t/dummy") ++ # Create b/ directory ++ arc.add("b/") ++ # Point "c" to the bottom of the tree in "a" ++ arc.add("c", symlink_to=os.path.join("a", "t")) ++ # link to non-existant location under "a" ++ arc.add("c/escape", symlink_to=os.path.join("..", "..", ++ "link_here")) ++ # Move "c" to point to "b" ("c/escape" no longer exists) ++ arc.add("c", symlink_to="b") ++ # Attempt to create a hard link to "c/escape". Since it doesn't ++ # exist it will attempt to extract "cescape" but at "boom". ++ arc.add("boom", hardlink_to=os.path.join("c", "escape")) ++ ++ with self.check_context(arc.open(), 'data'): ++ if not os_helper.can_symlink(): ++ # When 'c/escape' is extracted, 'c' is a regular ++ # directory, and 'c/escape' *would* point outside ++ # the destination if symlinks were allowed. ++ self.expect_exception( ++ tarfile.LinkOutsideDestinationError) ++ elif sys.platform == "win32": ++ # On Windows, 'c/escape' points outside the destination ++ self.expect_exception(tarfile.LinkOutsideDestinationError) ++ else: ++ e = self.expect_exception( ++ tarfile.LinkFallbackError, ++ "link 'boom' would be extracted as a copy of " ++ + "'c/escape', which was rejected") ++ self.assertIsInstance(e.__cause__, ++ tarfile.LinkOutsideDestinationError) ++ for filter in 'tar', 'fully_trusted': ++ with self.subTest(filter), self.check_context(arc.open(), filter): ++ if not os_helper.can_symlink(): ++ self.expect_file("a/t/dummy") ++ self.expect_file("b/") ++ self.expect_file("c/") ++ else: ++ self.expect_file("a/t/dummy") ++ self.expect_file("b/") ++ self.expect_file("a/t/escape", symlink_to='../../link_here') ++ self.expect_file("boom", symlink_to='../../link_here') ++ self.expect_file("c", symlink_to='b') ++ ++ @symlink_test ++ def test_exfiltration_via_symlink(self): ++ # (CVE-2025-4138) ++ # Test changing symlinks that result in a symlink pointing outside ++ # the extraction directory, unless prevented by 'data' filter's ++ # normalization. ++ with ArchiveMaker() as arc: ++ arc.add("escape", symlink_to=os.path.join('link', 'link', '..', '..', 'link-here')) ++ arc.add("link", symlink_to='./') ++ ++ for filter in 'tar', 'data', 'fully_trusted': ++ with self.check_context(arc.open(), filter): ++ if os_helper.can_symlink(): ++ self.expect_file("link", symlink_to='./') ++ if filter == 'data': ++ self.expect_file("escape", symlink_to='link-here') ++ else: ++ self.expect_file("escape", ++ symlink_to='link/link/../../link-here') ++ else: ++ # Nothing is extracted. ++ pass ++ ++ @symlink_test ++ def test_chmod_outside_dir(self): ++ # (CVE-2024-12718) ++ # Test that members used for delayed updates of directory metadata ++ # are (re-)filtered. ++ with ArchiveMaker() as arc: ++ # "pwn" is a veeeery innocent symlink: ++ arc.add("a/pwn", symlink_to='.') ++ # But now "pwn" is also a directory, so it's scheduled to have its ++ # metadata updated later: ++ arc.add("a/pwn/", mode='drwxrwxrwx') ++ # Oops, "pwn" is not so innocent any more: ++ arc.add("a/pwn", symlink_to='x/../') ++ # Newly created symlink points to the dest dir, ++ # so it's OK for the "data" filter. ++ arc.add('a/x', symlink_to=('../')) ++ # But now "pwn" points outside the dest dir ++ ++ for filter in 'tar', 'data', 'fully_trusted': ++ with self.check_context(arc.open(), filter) as cc: ++ if not os_helper.can_symlink(): ++ self.expect_file("a/pwn/") ++ elif filter == 'data': ++ self.expect_file("a/x", symlink_to='../') ++ self.expect_file("a/pwn", symlink_to='.') ++ else: ++ self.expect_file("a/x", symlink_to='../') ++ self.expect_file("a/pwn", symlink_to='x/../') ++ if sys.platform != "win32": ++ st_mode = cc.outerdir.stat().st_mode ++ self.assertNotEqual(st_mode & 0o777, 0o777) ++ ++ def test_link_fallback_normalizes(self): ++ # Make sure hardlink fallbacks work for non-normalized paths for all ++ # filters ++ with ArchiveMaker() as arc: ++ arc.add("dir/") ++ arc.add("dir/../afile") ++ arc.add("link1", hardlink_to='dir/../afile') ++ arc.add("link2", hardlink_to='dir/../dir/../afile') ++ ++ for filter in 'tar', 'data', 'fully_trusted': ++ with self.check_context(arc.open(), filter) as cc: ++ self.expect_file("dir/") ++ self.expect_file("afile") ++ self.expect_file("link1") ++ self.expect_file("link2") ++ + def test_modes(self): + # Test how file modes are extracted + # (Note that the modes are ignored on platforms without working chmod) +@@ -4072,7 +4346,7 @@ def test_tar_filter(self): + # The 'tar' filter returns TarInfo objects with the same name/type. + # (It can also fail for particularly "evil" input, but we don't have + # that in the test archive.) +- with tarfile.TarFile.open(tarname) as tar: ++ with tarfile.TarFile.open(tarname, encoding="iso8859-1") as tar: + for tarinfo in tar.getmembers(): + try: + filtered = tarfile.tar_filter(tarinfo, '') +@@ -4084,7 +4358,7 @@ def test_tar_filter(self): + def test_data_filter(self): + # The 'data' filter either raises, or returns TarInfo with the same + # name/type. +- with tarfile.TarFile.open(tarname) as tar: ++ with tarfile.TarFile.open(tarname, encoding="iso8859-1") as tar: + for tarinfo in tar.getmembers(): + try: + filtered = tarfile.data_filter(tarinfo, '') +@@ -4242,13 +4516,13 @@ def valueerror_filter(tarinfo, path): + # If errorlevel is 0, errors affected by errorlevel are ignored + + with self.check_context(arc.open(errorlevel=0), extracterror_filter): +- self.expect_file('file') ++ pass + + with self.check_context(arc.open(errorlevel=0), filtererror_filter): +- self.expect_file('file') ++ pass + + with self.check_context(arc.open(errorlevel=0), oserror_filter): +- self.expect_file('file') ++ pass + + with self.check_context(arc.open(errorlevel=0), tarerror_filter): + self.expect_exception(tarfile.TarError) +@@ -4259,7 +4533,7 @@ def valueerror_filter(tarinfo, path): + # If 1, all fatal errors are raised + + with self.check_context(arc.open(errorlevel=1), extracterror_filter): +- self.expect_file('file') ++ pass + + with self.check_context(arc.open(errorlevel=1), filtererror_filter): + self.expect_exception(tarfile.FilterError) +diff --git a/Misc/NEWS.d/next/Security/2025-06-02-11-32-23.gh-issue-135034.RLGjbp.rst b/Misc/NEWS.d/next/Security/2025-06-02-11-32-23.gh-issue-135034.RLGjbp.rst +new file mode 100644 +index 00000000000000..08a0087e203671 +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2025-06-02-11-32-23.gh-issue-135034.RLGjbp.rst +@@ -0,0 +1,6 @@ ++Fixes multiple issues that allowed ``tarfile`` extraction filters ++(``filter="data"`` and ``filter="tar"``) to be bypassed using crafted ++symlinks and hard links. ++ ++Addresses :cve:`2024-12718`, :cve:`2025-4138`, :cve:`2025-4330`, and :cve:`2025-4517`. ++ diff --git a/pkgs/development/interpreters/python/cpython/default.nix b/pkgs/development/interpreters/python/cpython/default.nix index ed88658ed27f..023cc6778475 100644 --- a/pkgs/development/interpreters/python/cpython/default.nix +++ b/pkgs/development/interpreters/python/cpython/default.nix @@ -340,6 +340,9 @@ stdenv.mkDerivation (finalAttrs: { ++ optionals (pythonAtLeast "3.13") [ ./3.13/virtualenv-permissions.patch ] + ++ optionals (pythonAtLeast "3.14") [ + ./3.14/CVE-2025-4517.patch + ] ++ optionals mimetypesSupport [ # Make the mimetypes module refer to the right file ./mimetypes.patch From f2df03f8b8ffac490d56b08a0c8a0a3b1a93a02d Mon Sep 17 00:00:00 2001 From: "\"Gaetan Lepage\"" <"gaetan@glepage.com"> Date: Mon, 9 Jun 2025 13:39:26 +0200 Subject: [PATCH 60/82] vimPlugins.ts-autotag-nvim: init at 2025-01-15 --- pkgs/applications/editors/vim/plugins/generated.nix | 13 +++++++++++++ .../editors/vim/plugins/vim-plugin-names | 1 + 2 files changed, 14 insertions(+) diff --git a/pkgs/applications/editors/vim/plugins/generated.nix b/pkgs/applications/editors/vim/plugins/generated.nix index ef9b2813ab76..aa9c71ea635b 100644 --- a/pkgs/applications/editors/vim/plugins/generated.nix +++ b/pkgs/applications/editors/vim/plugins/generated.nix @@ -15120,6 +15120,19 @@ final: prev: { meta.hydraPlatforms = [ ]; }; + ts-autotag-nvim = buildVimPlugin { + pname = "ts-autotag.nvim"; + version = "2025-01-15"; + src = fetchFromGitHub { + owner = "tronikelis"; + repo = "ts-autotag.nvim"; + rev = "0f1dc38fddd99b468ef58938d7cd99ce1d6bcb0e"; + sha256 = "1m0gng9v5dn6mm026nxw0n24bvysr156xhwvf83pv9xqp28xfwar"; + }; + meta.homepage = "https://github.com/tronikelis/ts-autotag.nvim/"; + meta.hydraPlatforms = [ ]; + }; + ts-comments-nvim = buildVimPlugin { pname = "ts-comments.nvim"; version = "2025-02-27"; diff --git a/pkgs/applications/editors/vim/plugins/vim-plugin-names b/pkgs/applications/editors/vim/plugins/vim-plugin-names index d082b27c10a5..cb768334d047 100644 --- a/pkgs/applications/editors/vim/plugins/vim-plugin-names +++ b/pkgs/applications/editors/vim/plugins/vim-plugin-names @@ -1160,6 +1160,7 @@ https://github.com/simonmclean/triptych.nvim/,HEAD, https://github.com/folke/trouble.nvim/,, https://github.com/Pocco81/true-zen.nvim/,, https://github.com/tesaguri/trust.vim/,HEAD, +https://github.com/tronikelis/ts-autotag.nvim/,HEAD, https://github.com/folke/ts-comments.nvim/,HEAD, https://github.com/dmmulroy/tsc.nvim/,HEAD, https://github.com/jgdavey/tslime.vim/,, From 0cfd82e2aaf6b20d65e379d8d164eeb45a758354 Mon Sep 17 00:00:00 2001 From: "R. Ryantm" Date: Mon, 9 Jun 2025 12:35:38 +0000 Subject: [PATCH 61/82] dooit: 3.2.2 -> 3.2.3 --- pkgs/by-name/do/dooit/package.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/by-name/do/dooit/package.nix b/pkgs/by-name/do/dooit/package.nix index 361729775ae1..df0cfae3fc9d 100644 --- a/pkgs/by-name/do/dooit/package.nix +++ b/pkgs/by-name/do/dooit/package.nix @@ -9,14 +9,14 @@ }: python3.pkgs.buildPythonApplication rec { pname = "dooit"; - version = "3.2.2"; + version = "3.2.3"; pyproject = true; src = fetchFromGitHub { owner = "dooit-org"; repo = "dooit"; tag = "v${version}"; - hash = "sha256-2W3iO4AOuDdDKJDMMY8YKXlI+dQKRI3PQtkdi9J3wZo="; + hash = "sha256-bI9X+2tTLnQwxfsnBmy2vBI3lJ4UX418zOy3oniVKWc="; }; build-system = with python3.pkgs; [ poetry-core ]; From d6b530cc9c1b6463aa8f6e22201b208f72da8e6c Mon Sep 17 00:00:00 2001 From: Marcos Benevides Date: Fri, 6 Jun 2025 17:00:49 -0400 Subject: [PATCH 62/82] postgresqlPackages.omnigres: 0-unstable-2025-05-16 -> 0-unstable-2025-06-03 --------- Co-authored-by: Wolfgang Walther --- pkgs/servers/sql/postgresql/ext/omnigres.nix | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/pkgs/servers/sql/postgresql/ext/omnigres.nix b/pkgs/servers/sql/postgresql/ext/omnigres.nix index c7e967882413..c422de9becd9 100644 --- a/pkgs/servers/sql/postgresql/ext/omnigres.nix +++ b/pkgs/servers/sql/postgresql/ext/omnigres.nix @@ -12,6 +12,7 @@ postgresqlBuildExtension, postgresqlTestExtension, python3, + unstableGitUpdater, }: let @@ -19,13 +20,13 @@ let in postgresqlBuildExtension (finalAttrs: { pname = "omnigres"; - version = "0-unstable-2025-05-16"; + version = "0-unstable-2025-06-03"; src = fetchFromGitHub { owner = "omnigres"; repo = "omnigres"; - rev = "84f14792d80fb6fd60b680b7825245a8e7c5583e"; - hash = "sha256-jOlHXl7ANhMwOPizd5KH+wYZmBNNkkIa9jbXZR8Xu28="; + rev = "d347be5ae1d79645ac277d19080eacba7b229cf8"; + hash = "sha256-LKsH+aeLg7v2RfK80D3mgXdPB8jMIv5uFdf+3c5Z0vA="; }; strictDeps = true; @@ -75,6 +76,10 @@ postgresqlBuildExtension (finalAttrs: { ''; }; + passthru.updateScript = unstableGitUpdater { + hardcodeZeroVersion = true; + }; + meta = { description = "Postgres as a Business Operating System"; homepage = "https://docs.omnigres.org"; From 576032bbe3fe3f33c7e5349092a8e8fae7088026 Mon Sep 17 00:00:00 2001 From: "R. Ryantm" Date: Mon, 9 Jun 2025 13:06:54 +0000 Subject: [PATCH 63/82] frankenphp: 1.6.2 -> 1.7.0 --- pkgs/by-name/fr/frankenphp/package.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/by-name/fr/frankenphp/package.nix b/pkgs/by-name/fr/frankenphp/package.nix index 71dd976cbff0..075fd4bfa35e 100644 --- a/pkgs/by-name/fr/frankenphp/package.nix +++ b/pkgs/by-name/fr/frankenphp/package.nix @@ -31,13 +31,13 @@ let in buildGoModule rec { pname = "frankenphp"; - version = "1.6.2"; + version = "1.7.0"; src = fetchFromGitHub { owner = "dunglas"; repo = "frankenphp"; tag = "v${version}"; - hash = "sha256-YYEipvr0qqudKuLrINt5htl2oCp6wXWLpyvCPuwR9e8="; + hash = "sha256-FukxXuZwF7P5tUao0nTT7bELGIYivtoOBQQkHA7ZE3s="; }; sourceRoot = "${src.name}/caddy"; @@ -45,7 +45,7 @@ buildGoModule rec { # frankenphp requires C code that would be removed with `go mod tidy` # https://github.com/golang/go/issues/26366 proxyVendor = true; - vendorHash = "sha256-M1z9Yv+WomKA+UACOUT8xcWdw+SD1MY2jfaDO4zYUQg="; + vendorHash = "sha256-likIETO/eq1kATNbbYHxXxvIPH7q5tp3WHjz+zvNOws="; buildInputs = [ phpUnwrapped From 89e9c39e6550d1babc52096853eee41461005151 Mon Sep 17 00:00:00 2001 From: K900 Date: Mon, 9 Jun 2025 16:16:13 +0300 Subject: [PATCH 64/82] python313Packages.networkx: backport fix for Python 3.13.4 --- pkgs/development/python-modules/networkx/default.nix | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pkgs/development/python-modules/networkx/default.nix b/pkgs/development/python-modules/networkx/default.nix index eba7e30c2307..b80019907614 100644 --- a/pkgs/development/python-modules/networkx/default.nix +++ b/pkgs/development/python-modules/networkx/default.nix @@ -2,6 +2,7 @@ lib, buildPythonPackage, fetchPypi, + fetchpatch, pythonOlder, # build-system @@ -38,6 +39,16 @@ buildPythonPackage rec { hash = "sha256-MHw2aUKMU2KqsnyKEmCqj0fE6R04kfSL4BQXONjQU+E="; }; + # backport patch to fix tests with Python 3.13.4 + # FIXME: remove in next update + patches = [ + (fetchpatch { + url = "https://github.com/networkx/networkx/commit/d85b04a8b9619580d8901f35400414f612c83113.patch"; + includes = ["networkx/generators/lattice.py"]; + hash = "sha256-6y/aJBDgNkUzmQ6o52CGVVzqoQgkCEXA4iAXhv1cS0c="; + }) + ]; + nativeBuildInputs = [ setuptools ]; optional-dependencies = { From cd79fb5465fa7f6fc05be3dcaa8c98d90610dfe5 Mon Sep 17 00:00:00 2001 From: K900 Date: Mon, 9 Jun 2025 16:18:53 +0300 Subject: [PATCH 65/82] python313Packages.black: skip test broken on 3.13.4 --- pkgs/development/python-modules/black/default.nix | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkgs/development/python-modules/black/default.nix b/pkgs/development/python-modules/black/default.nix index 27f18cca5279..37c8e876fa62 100644 --- a/pkgs/development/python-modules/black/default.nix +++ b/pkgs/development/python-modules/black/default.nix @@ -95,6 +95,9 @@ buildPythonPackage rec { [ # requires network access "test_gen_check_output" + # broken on Python 3.13.4 + # FIXME: remove this when fixed upstream + "test_simple_format[pep_701]" ] ++ lib.optionals stdenv.hostPlatform.isDarwin [ # fails on darwin From bf129079bf8ea6468c2d4d25c67179f8315b1e76 Mon Sep 17 00:00:00 2001 From: K900 Date: Mon, 9 Jun 2025 16:25:48 +0300 Subject: [PATCH 66/82] python313Packages.beautifulsoup4: nixfmt --- pkgs/development/python-modules/beautifulsoup4/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/development/python-modules/beautifulsoup4/default.nix b/pkgs/development/python-modules/beautifulsoup4/default.nix index 4ca473b72b5d..72dbe6e438da 100644 --- a/pkgs/development/python-modules/beautifulsoup4/default.nix +++ b/pkgs/development/python-modules/beautifulsoup4/default.nix @@ -52,7 +52,7 @@ buildPythonPackage rec { # backport test fix for behavior changes in libxml 2.14.3 (fetchpatch { url = "https://git.launchpad.net/beautifulsoup/patch/?id=53d328406ec8c37c0edbd00ace3782be63e2e7e5"; - excludes = ["CHANGELOG"]; + excludes = [ "CHANGELOG" ]; hash = "sha256-RtavbpnfT6x0A8L3tAvCXwKUpty1ASPGJKdks7evBr8="; }) ]; From 7a90517fff28e184655d4047754e2d60b94882b2 Mon Sep 17 00:00:00 2001 From: K900 Date: Mon, 9 Jun 2025 16:25:57 +0300 Subject: [PATCH 67/82] python313Packages.networkx: nixfmt --- pkgs/development/python-modules/networkx/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/development/python-modules/networkx/default.nix b/pkgs/development/python-modules/networkx/default.nix index b80019907614..91ff6b59b531 100644 --- a/pkgs/development/python-modules/networkx/default.nix +++ b/pkgs/development/python-modules/networkx/default.nix @@ -44,7 +44,7 @@ buildPythonPackage rec { patches = [ (fetchpatch { url = "https://github.com/networkx/networkx/commit/d85b04a8b9619580d8901f35400414f612c83113.patch"; - includes = ["networkx/generators/lattice.py"]; + includes = [ "networkx/generators/lattice.py" ]; hash = "sha256-6y/aJBDgNkUzmQ6o52CGVVzqoQgkCEXA4iAXhv1cS0c="; }) ]; From 5b5fbfd9f07a1a0dc266dc47aab4d643eca2087a Mon Sep 17 00:00:00 2001 From: Sizhe Zhao Date: Mon, 9 Jun 2025 21:25:12 +0800 Subject: [PATCH 68/82] maintainers/team-list: add prince213 to ngi team --- maintainers/team-list.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/maintainers/team-list.nix b/maintainers/team-list.nix index 35aa999a58be..28f2f1007e40 100644 --- a/maintainers/team-list.nix +++ b/maintainers/team-list.nix @@ -915,6 +915,7 @@ with lib.maintainers; eljamm ethancedwards8 fricklerhandwerk + prince213 wegank ]; scope = "Maintain NGI-supported software."; From 7b94aa96ee74e3ed732dc981cd1d4f4902870bcc Mon Sep 17 00:00:00 2001 From: Marie Ramlow Date: Mon, 9 Jun 2025 11:24:54 +0200 Subject: [PATCH 69/82] vencord: remove custom esbuild override Upstream's lockfile seems to include hashes for esbuild on every platform we need now, so this is no longer required. --- pkgs/by-name/ve/vencord/package.nix | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/pkgs/by-name/ve/vencord/package.nix b/pkgs/by-name/ve/vencord/package.nix index b9aff387a8b7..3b919d9e583e 100644 --- a/pkgs/by-name/ve/vencord/package.nix +++ b/pkgs/by-name/ve/vencord/package.nix @@ -1,6 +1,5 @@ { curl, - esbuild, fetchFromGitHub, git, jq, @@ -36,20 +35,6 @@ stdenv.mkDerivation (finalAttrs: { ]; env = { - ESBUILD_BINARY_PATH = lib.getExe ( - esbuild.overrideAttrs ( - final: _: { - version = "0.25.1"; - src = fetchFromGitHub { - owner = "evanw"; - repo = "esbuild"; - rev = "v${final.version}"; - hash = "sha256-vrhtdrvrcC3dQoJM6hWq6wrGJLSiVww/CNPlL1N5kQ8="; - }; - vendorHash = "sha256-+BfxCyg0KkDQpHt/wycy/8CTG6YBA/VJvJFhhzUnSiQ="; - } - ) - ); VENCORD_REMOTE = "${finalAttrs.src.owner}/${finalAttrs.src.repo}"; VENCORD_HASH = "${finalAttrs.version}"; }; From c6c2299d94a49d9833d96b6804fce3f6d1cfe04b Mon Sep 17 00:00:00 2001 From: Grimmauld Date: Mon, 9 Jun 2025 15:37:45 +0200 Subject: [PATCH 70/82] jq: disable failing time conversion test on 32 bit jq upstream has a test right on 32 bit epoch end [1]. On i686-linux, this test is executed because it is a native build. However, the test will fail on 32 bit. The *good* solution is to build jq with 64 bit time representation. That might break with dynamic linking though, so instead we just disable this test. Note: this is a bit of a hack! [1] https://github.com/jqlang/jq/blob/859a8073ee8a21f2133154eea7c2bd5e0d60837f/tests/optional.test#L17 --- .../disable-end-of-epoch-conversion-test.patch | 16 ++++++++++++++++ pkgs/by-name/jq/jq/package.nix | 9 +++++++++ 2 files changed, 25 insertions(+) create mode 100644 pkgs/by-name/jq/jq/disable-end-of-epoch-conversion-test.patch diff --git a/pkgs/by-name/jq/jq/disable-end-of-epoch-conversion-test.patch b/pkgs/by-name/jq/jq/disable-end-of-epoch-conversion-test.patch new file mode 100644 index 000000000000..570d443db12f --- /dev/null +++ b/pkgs/by-name/jq/jq/disable-end-of-epoch-conversion-test.patch @@ -0,0 +1,16 @@ +diff --git a/tests/optional.test b/tests/optional.test +index 2623731..85bc9e9 100644 +--- a/tests/optional.test ++++ b/tests/optional.test +@@ -12,11 +12,6 @@ last(range(365 * 67)|("1970-03-01T01:02:03Z"|strptime("%Y-%m-%dT%H:%M:%SZ")|mkti + null + [2037,1,11,1,2,3,3,41] + +-# Regression test for #3276 +-fromdate +-"2038-01-19T03:14:08Z" +-2147483648 +- + # %e is not available on mingw/WIN32 + strftime("%A, %B %e, %Y") + 1435677542.822351 diff --git a/pkgs/by-name/jq/jq/package.nix b/pkgs/by-name/jq/jq/package.nix index 074e24725fc6..5d3a7c3aa975 100644 --- a/pkgs/by-name/jq/jq/package.nix +++ b/pkgs/by-name/jq/jq/package.nix @@ -30,6 +30,15 @@ stdenv.mkDerivation (finalAttrs: { "out" ]; + # tortured syntax to avoid rebuilds + # needed because epoch conversion test here is right at the end of 32 bit integer space + # See also: https://github.com/jqlang/jq/blob/859a8073ee8a21f2133154eea7c2bd5e0d60837f/tests/optional.test#L15-L18 + # "-D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64" would be preferrable, but breaks with dynamic linking, + # unless done globally in stdenv for all of 32 bit. + ${if stdenv.hostPlatform.is32bit then "patches" else null} = [ + ./disable-end-of-epoch-conversion-test.patch + ]; + # https://github.com/jqlang/jq/issues/2871 postPatch = lib.optionalString stdenv.hostPlatform.isFreeBSD '' substituteInPlace Makefile.am --replace-fail "tests/mantest" "" --replace-fail "tests/optionaltest" "" From 4512fb86b894f5e28996c88f9c6144e4042df2fa Mon Sep 17 00:00:00 2001 From: Ethan Carter Edwards Date: Fri, 30 May 2025 13:45:37 -0400 Subject: [PATCH 71/82] style50: init at 2.10.4 Signed-off-by: Ethan Carter Edwards --- pkgs/by-name/st/style50/package.nix | 68 +++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 pkgs/by-name/st/style50/package.nix diff --git a/pkgs/by-name/st/style50/package.nix b/pkgs/by-name/st/style50/package.nix new file mode 100644 index 000000000000..034f7428aa4e --- /dev/null +++ b/pkgs/by-name/st/style50/package.nix @@ -0,0 +1,68 @@ +{ + lib, + python3Packages, + fetchFromGitHub, + libclang, + versionCheckHook, +}: + +python3Packages.buildPythonApplication rec { + pname = "style50"; + version = "2.10.4"; + pyproject = true; + + src = fetchFromGitHub { + owner = "cs50"; + repo = "style50"; + tag = "v${version}"; + hash = "sha256-59V3QZMYH5edBXv1GNdoaQxerDfKmLKUZ7VL3cvDvuE="; + }; + + build-system = [ + python3Packages.setuptools + ]; + + dependencies = with python3Packages; [ + autopep8 + icdiff + jinja2 + jsbeautifier + pycodestyle + python-magic + termcolor + ]; + + preFixup = '' + makeWrapperArgs+=(--prefix PATH : ${ + lib.makeBinPath [ + libclang # clang-format + ] + }) + ''; + + pythonRelaxDeps = [ + "pycodestyle" + ]; + + pythonRemoveDeps = [ + "clang-format" + ]; + + pythonImportsCheck = [ "style50" ]; + + nativeCheckInputs = [ versionCheckHook ]; + versionCheckProgramArg = "--version"; + + # no python tests + + meta = { + description = "Tool for checking code against the CS50 style guide"; + homepage = "https://cs50.readthedocs.io/style50/"; + downloadPage = "https://github.com/cs50/style50"; + changelog = "https://github.com/cs50/style50/releases/tag/v${version}"; + license = lib.licenses.gpl3Only; + platforms = lib.platforms.unix; + maintainers = with lib.maintainers; [ ethancedwards8 ]; + mainProgram = "style50"; + }; +} From 827020f4fd71aada82ebcd42db002904931a57d1 Mon Sep 17 00:00:00 2001 From: Rouven Czerwinski Date: Mon, 9 Jun 2025 17:15:55 +0200 Subject: [PATCH 72/82] niri: generate completions Generate bash, zsh and fish completions after compilation and add them to the derivation. --- pkgs/by-name/ni/niri/package.nix | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pkgs/by-name/ni/niri/package.nix b/pkgs/by-name/ni/niri/package.nix index 338564c76338..3c473ac59cd2 100644 --- a/pkgs/by-name/ni/niri/package.nix +++ b/pkgs/by-name/ni/niri/package.nix @@ -3,6 +3,7 @@ dbus, eudev, fetchFromGitHub, + installShellFiles, libdisplay-info, libglvnd, libinput, @@ -15,6 +16,7 @@ pkg-config, rustPlatform, seatd, + stdenv, systemd, wayland, withDbus ? true, @@ -46,6 +48,7 @@ rustPlatform.buildRustPackage (finalAttrs: { strictDeps = true; nativeBuildInputs = [ + installShellFiles pkg-config rustPlatform.bindgenHook ]; @@ -88,6 +91,12 @@ rustPlatform.buildRustPackage (finalAttrs: { '' + lib.optionalString withDinit '' install -Dm0644 resources/dinit/niri{-shutdown,} -t $out/lib/dinit.d/user + '' + + lib.optionalString (stdenv.buildPlatform.canExecute stdenv.hostPlatform) '' + installShellCompletion --cmd $pname \ + --bash <($out/bin/niri completions bash) \ + --fish <($out/bin/niri completions fish) \ + --zsh <($out/bin/niri completions zsh) ''; env = { From 9ebbf272a7c58e2afb2769f8afcd341e83702d03 Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Fri, 6 Jun 2025 16:51:40 +0900 Subject: [PATCH 73/82] artichoke: init at 0-unstable-2025-06-01 --- pkgs/by-name/ar/artichoke/package.nix | 58 +++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 pkgs/by-name/ar/artichoke/package.nix diff --git a/pkgs/by-name/ar/artichoke/package.nix b/pkgs/by-name/ar/artichoke/package.nix new file mode 100644 index 000000000000..f3d93d31a96a --- /dev/null +++ b/pkgs/by-name/ar/artichoke/package.nix @@ -0,0 +1,58 @@ +{ + lib, + rustPlatform, + fetchFromGitHub, + llvmPackages, + _experimental-update-script-combinators, + unstableGitUpdater, + nix-update-script, +}: + +rustPlatform.buildRustPackage { + pname = "artichoke"; + version = "0-unstable-2025-06-01"; + + src = fetchFromGitHub { + owner = "artichoke"; + repo = "artichoke"; + rev = "7c35392d8c7622cd8ab8eccaee73d57633b2b901"; + hash = "sha256-7YPExT+5F+5MMk/yLfG4Rk8ZDwsYfVKlkvIroFB22No="; + }; + + cargoHash = "sha256-cN70yYYKhktUoswow63ZXHvfFbXDo1rUrTWm22LluCM="; + + nativeBuildInputs = [ + rustPlatform.bindgenHook + ]; + + doInstallCheck = true; + installCheckPhase = '' + runHook preInstallCheck + + stdout="$("$out/bin/artichoke" -e 'puts "Hello World!"')" + [[ "$stdout" == 'Hello World!' ]] + + runHook postInstallCheck + ''; + + passthru = { + updateScript = _experimental-update-script-combinators.sequence [ + (unstableGitUpdater { }) + (nix-update-script { + # Updating `cargoHash` + extraArgs = [ "--version=skip" ]; + }) + ]; + }; + + meta = { + description = "Ruby implementation written in Rust and Ruby"; + homepage = "https://www.artichokeruby.org/"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ + kachick + ]; + mainProgram = "artichoke"; + platforms = with lib.platforms; unix ++ windows; + }; +} From 76dd00a305dbe83e74f43848e2fe0e009de205a1 Mon Sep 17 00:00:00 2001 From: Edgar Vincent Date: Mon, 9 Jun 2025 17:24:28 +0200 Subject: [PATCH 74/82] nixos/pipewire: remove obsolete comment Since 05b4964, the pipewire-pulse system service and socket are enabled when the `systemWide' option is set to `true'. --- nixos/modules/services/desktops/pipewire/pipewire.nix | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nixos/modules/services/desktops/pipewire/pipewire.nix b/nixos/modules/services/desktops/pipewire/pipewire.nix index 5f1de7e63f3f..6e90855114e0 100644 --- a/nixos/modules/services/desktops/pipewire/pipewire.nix +++ b/nixos/modules/services/desktops/pipewire/pipewire.nix @@ -359,8 +359,7 @@ in systemd.services.pipewire.bindsTo = [ "dbus.service" ]; systemd.user.services.pipewire.bindsTo = [ "dbus.service" ]; - # Enable either system or user units. Note that for pipewire-pulse there - # are only user units, which work in both cases. + # Enable either system or user units. systemd.sockets.pipewire.enable = cfg.systemWide; systemd.services.pipewire.enable = cfg.systemWide; systemd.user.sockets.pipewire.enable = !cfg.systemWide; From 73052f6867b4d3be871f1028644a9760fba86f8c Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Sun, 25 May 2025 12:59:54 +0900 Subject: [PATCH 75/82] shaperglot-cli: init at 0-unstable-2025-05-27 Co-authored-by: Aleksana --- pkgs/by-name/sh/shaperglot-cli/package.nix | 64 ++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 pkgs/by-name/sh/shaperglot-cli/package.nix diff --git a/pkgs/by-name/sh/shaperglot-cli/package.nix b/pkgs/by-name/sh/shaperglot-cli/package.nix new file mode 100644 index 000000000000..57e63811bc50 --- /dev/null +++ b/pkgs/by-name/sh/shaperglot-cli/package.nix @@ -0,0 +1,64 @@ +{ + lib, + fetchFromGitHub, + rustPlatform, + _experimental-update-script-combinators, + unstableGitUpdater, + nix-update-script, +}: + +rustPlatform.buildRustPackage (finalAttrs: { + pname = "shaperglot-cli"; + version = "0-unstable-2025-05-27"; + + src = fetchFromGitHub { + owner = "googlefonts"; + repo = "shaperglot"; + rev = "0d934110dfdf315761255e34040f207f7d7868b5"; + hash = "sha256-5Bgvx4Yv74nQLd037L5uBj6oySqqp947LI/6yGwYSKY="; + }; + + cargoHash = "sha256-UMPoPNpyM/+1rq4U6xQ1DF4W+51p5YjQXr/8zLiPvEI="; + + cargoBuildFlags = [ + "--package=shaperglot-cli" + ]; + + cargoTestFlags = [ + "--package=shaperglot-cli" + ]; + + doInstallCheck = true; + installCheckPhase = '' + runHook preInstallCheck + + describe_output="$("$out/bin/shaperglot" describe English)" + [[ "$describe_output" == *'support'* ]] + + runHook postInstallCheck + ''; + + passthru = { + updateScript = _experimental-update-script-combinators.sequence [ + (unstableGitUpdater { + branch = "main"; + # Git tag differs from CLI version: https://github.com/googlefonts/shaperglot/issues/138 + hardcodeZeroVersion = true; + }) + (nix-update-script { + # Updating `cargoHash` + extraArgs = [ "--version=skip" ]; + }) + ]; + }; + + meta = { + description = "Test font files for language support"; + homepage = "https://github.com/googlefonts/shaperglot"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ + kachick + ]; + mainProgram = "shaperglot"; + }; +}) From c7999503b059c6cd08c642718409e337d4aee87e Mon Sep 17 00:00:00 2001 From: Michael Daniels Date: Mon, 9 Jun 2025 11:56:37 -0400 Subject: [PATCH 76/82] libast: drop Fails to build with gcc 14, unmaintained upstream for 5 years. Tracking: #388196 #356812 --- pkgs/by-name/li/libast/package.nix | 33 ------------------------------ pkgs/top-level/aliases.nix | 1 + 2 files changed, 1 insertion(+), 33 deletions(-) delete mode 100644 pkgs/by-name/li/libast/package.nix diff --git a/pkgs/by-name/li/libast/package.nix b/pkgs/by-name/li/libast/package.nix deleted file mode 100644 index 3ac848203286..000000000000 --- a/pkgs/by-name/li/libast/package.nix +++ /dev/null @@ -1,33 +0,0 @@ -{ - lib, - stdenv, - fetchFromGitHub, - autoreconfHook, - pkg-config, -}: - -stdenv.mkDerivation rec { - pname = "libast"; - version = "0.8"; - - src = fetchFromGitHub { - owner = "mej"; - repo = "libast"; - rev = version; - hash = "sha256-rnqToFi+d6D6O+JDHQxkVjTc/0RBag6Jqv4uDcE4PNc="; - }; - - nativeBuildInputs = [ - autoreconfHook - pkg-config - ]; - - meta = with lib; { - inherit (src.meta) homepage; - description = "Library of Assorted Spiffy Things"; - mainProgram = "libast-config"; - license = licenses.bsd2; - maintainers = [ ]; - platforms = platforms.unix; - }; -} diff --git a/pkgs/top-level/aliases.nix b/pkgs/top-level/aliases.nix index 1d9d50ade96b..10cbf91f4109 100644 --- a/pkgs/top-level/aliases.nix +++ b/pkgs/top-level/aliases.nix @@ -992,6 +992,7 @@ mapAliases { ledger_agent = ledger-agent; # Added 2024-01-07 lfs = dysk; # Added 2023-07-03 libAfterImage = throw "'libAfterImage' has been removed from nixpkgs, as it's no longer in development for a long time"; # Added 2024-06-01 + libast = throw "'libast' has been removed due to lack of maintenance upstream."; # Added 2025-06-09 libav = throw "libav has been removed as it was insecure and abandoned upstream for over half a decade; please use FFmpeg"; # Added 2024-08-25 libav_0_8 = libav; # Added 2024-08-25 libav_11 = libav; # Added 2024-08-25 From 82ad9c5797912083242df7dc9699b8e6b284e125 Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Wed, 4 Jun 2025 18:51:43 +0900 Subject: [PATCH 77/82] ameba-ls: init at 0.1.0 Co-authored-by: Aleksana --- pkgs/by-name/am/ameba-ls/package.nix | 60 ++++++++++++++++++++++++++++ pkgs/by-name/am/ameba-ls/shards.nix | 27 +++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 pkgs/by-name/am/ameba-ls/package.nix create mode 100644 pkgs/by-name/am/ameba-ls/shards.nix diff --git a/pkgs/by-name/am/ameba-ls/package.nix b/pkgs/by-name/am/ameba-ls/package.nix new file mode 100644 index 000000000000..3c6fbcbce3a1 --- /dev/null +++ b/pkgs/by-name/am/ameba-ls/package.nix @@ -0,0 +1,60 @@ +{ + lib, + fetchFromGitHub, + crystal_1_15, + versionCheckHook, +}: + +let + # Use the same Crystal minor version as specified in upstream + crystal = crystal_1_15; +in +crystal.buildCrystalPackage rec { + pname = "ameba-ls"; + version = "0.1.0"; + + src = fetchFromGitHub { + owner = "crystal-lang-tools"; + repo = "ameba-ls"; + tag = "v${version}"; + hash = "sha256-TEHjR+34wrq24XJNLhWZCEzcDEMDlmUHv0iiF4Z6JlI="; + }; + + shardsFile = ./shards.nix; + + crystalBinaries.ameba-ls.src = "src/ameba-ls.cr"; + + buildTargets = [ + "ameba-ls" + ]; + + # There are no actual tests + doCheck = false; + + installPhase = '' + runHook preInstall + + install -Dm555 bin/ameba-ls -t "$out/bin/" + + runHook postInstall + ''; + + nativeInstallCheckInputs = [ + versionCheckHook + ]; + doInstallCheck = true; + versionCheckProgram = "${placeholder "out"}/bin/ameba-ls"; + versionCheckProgramArg = "--version"; + + meta = { + description = "Crystal language server powered by Ameba linter"; + homepage = "https://github.com/crystal-lang-tools/ameba-ls"; + changelog = "https://github.com/crystal-lang-tools/ameba-ls/blob/v${version}/CHANGELOG.md"; + license = lib.licenses.mit; + platforms = lib.platforms.unix; + maintainers = with lib.maintainers; [ + kachick + ]; + mainProgram = "ameba-ls"; + }; +} diff --git a/pkgs/by-name/am/ameba-ls/shards.nix b/pkgs/by-name/am/ameba-ls/shards.nix new file mode 100644 index 000000000000..33ece94ac460 --- /dev/null +++ b/pkgs/by-name/am/ameba-ls/shards.nix @@ -0,0 +1,27 @@ +{ + ameba = { + url = "https://github.com/crystal-ameba/ameba.git"; + rev = "a21dea0b44642f4fc87429283f8b0dd9f1e47a9f"; + sha256 = "1kzr4ynd4r5w87y2czzrlir1dvqmv43ijm07804kgsy1g20k00fs"; + }; + larimar = { + url = "https://github.com/nobodywasishere/larimar.git"; + rev = "97d37e665f7189a7ec35f54fb65003a8438d6cf0"; + sha256 = "0s5hnfdybwbfk8sbjzrly2p6xppc5niww14h9cx00xkm8m1rlyj2"; + }; + lsprotocol = { + url = "https://github.com/nobodywasishere/lsprotocol-crystal.git"; + rev = "28986890c7657af4aefea8355ca3f3c7fc2bc9dd"; + sha256 = "0pccgq5g87mnvrhpgw3j22p3wgch8kp1svxcrbz2dha7zvgn65kj"; + }; + rwlock = { + url = "https://github.com/spider-gazelle/readers-writer.git"; + rev = "v1.0.7"; + sha256 = "1cs4ang50cza7sb5zh94rl1ppwcn9z1l8jjcsshhy4w72wkbqyny"; + }; + tree_sitter = { + url = "https://github.com/crystal-lang-tools/crystal-tree-sitter.git"; + rev = "1d46ca231a641b30b8e7fbbae7eba050f7717a9f"; + sha256 = "16g0ii3b3pmpnwmx2iz9dr1865pgfka7a724dfj62csjavqm5i1k"; + }; +} From 0e6cba69ce544efbc2d958a7c5413459aa5045c3 Mon Sep 17 00:00:00 2001 From: aleksana Date: Mon, 26 May 2025 22:40:26 +0800 Subject: [PATCH 78/82] github/PULL_REQUEST_TEMPLATE: mention other contributing doc as well --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 27635498f54d..1ed8ae285d89 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -30,7 +30,7 @@ For new packages please briefly describe the package or provide a link to its ho - [NixOS 25.11 Release Notes](https://github.com/NixOS/nixpkgs/blob/master/nixos/doc/manual/release-notes/rl-2511.section.md) (or backporting [24.11](https://github.com/NixOS/nixpkgs/blob/master/nixos/doc/manual/release-notes/rl-2411.section.md) and [25.05](https://github.com/NixOS/nixpkgs/blob/master/nixos/doc/manual/release-notes/rl-2505.section.md) NixOS Release notes) - [ ] (Module updates) Added a release notes entry if the change is significant - [ ] (Module addition) Added a release notes entry if adding a new NixOS module -- [ ] Fits [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md). +- [ ] Fits [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md), [pkgs/README.md](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md), [maintainers/README.md](https://github.com/NixOS/nixpkgs/blob/master/maintainers/README.md) and other contributing documentation in corresponding paths.