about summary refs log tree commit diff
path: root/nixpkgs/pkgs/build-support
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2023-08-08 16:04:42 +0000
committerAlyssa Ross <hi@alyssa.is>2023-08-13 06:35:37 +0000
commit12aaa58dac35800b5b7d77f81cf2a87c21ee55da (patch)
treebe0add9e5c22a85d20b5d78206aa74f956eb2a1b /nixpkgs/pkgs/build-support
parent45892a5591202f75a1c2f1ca7c62a92c7566e3c5 (diff)
parent5a8e9243812ba528000995b294292d3b5e120947 (diff)
downloadnixlib-12aaa58dac35800b5b7d77f81cf2a87c21ee55da.tar
nixlib-12aaa58dac35800b5b7d77f81cf2a87c21ee55da.tar.gz
nixlib-12aaa58dac35800b5b7d77f81cf2a87c21ee55da.tar.bz2
nixlib-12aaa58dac35800b5b7d77f81cf2a87c21ee55da.tar.lz
nixlib-12aaa58dac35800b5b7d77f81cf2a87c21ee55da.tar.xz
nixlib-12aaa58dac35800b5b7d77f81cf2a87c21ee55da.tar.zst
nixlib-12aaa58dac35800b5b7d77f81cf2a87c21ee55da.zip
Merge branch 'nixos-unstable' of https://github.com/NixOS/nixpkgs
Conflicts:
	nixpkgs/pkgs/applications/window-managers/sway/default.nix
	nixpkgs/pkgs/build-support/go/module.nix
	nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix
	nixpkgs/pkgs/development/libraries/mesa/default.nix
	nixpkgs/pkgs/servers/dict/dictd-db.nix

Link: https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/issues/391
Diffstat (limited to 'nixpkgs/pkgs/build-support')
-rw-r--r--nixpkgs/pkgs/build-support/binary-cache/default.nix4
-rw-r--r--nixpkgs/pkgs/build-support/bintools-wrapper/add-hardening.sh10
-rw-r--r--nixpkgs/pkgs/build-support/bintools-wrapper/default.nix20
-rw-r--r--nixpkgs/pkgs/build-support/build-fhsenv-bubblewrap/buildFHSEnv.nix70
-rwxr-xr-xnixpkgs/pkgs/build-support/buildenv/builder.pl2
-rw-r--r--nixpkgs/pkgs/build-support/buildenv/default.nix3
-rw-r--r--nixpkgs/pkgs/build-support/cc-wrapper/add-hardening.sh2
-rw-r--r--nixpkgs/pkgs/build-support/cc-wrapper/default.nix39
-rw-r--r--nixpkgs/pkgs/build-support/cc-wrapper/setup-hook.sh2
-rw-r--r--nixpkgs/pkgs/build-support/dart/build-dart-application/default.nix4
-rw-r--r--nixpkgs/pkgs/build-support/docker/default.nix2
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/build-dotnet-global-tool/default.nix48
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/default.nix36
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/default.nix18
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-build-hook.sh9
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-check-hook.sh6
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-configure-hook.sh31
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-fixup-hook.sh13
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-install-hook.sh29
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/make-nuget-deps/default.nix6
-rw-r--r--nixpkgs/pkgs/build-support/dotnet/make-nuget-source/default.nix10
-rwxr-xr-xnixpkgs/pkgs/build-support/dotnet/nuget-to-nix/nuget-to-nix.sh1
-rw-r--r--nixpkgs/pkgs/build-support/emacs/buffer.nix4
-rw-r--r--nixpkgs/pkgs/build-support/emacs/generic.nix17
-rw-r--r--nixpkgs/pkgs/build-support/emacs/wrapper.nix41
-rw-r--r--nixpkgs/pkgs/build-support/fetch9front/default.nix36
-rw-r--r--nixpkgs/pkgs/build-support/fetchdarcs/default.nix4
-rw-r--r--nixpkgs/pkgs/build-support/fetchfirefoxaddon/default.nix27
-rw-r--r--nixpkgs/pkgs/build-support/fetchgit/default.nix6
-rwxr-xr-xnixpkgs/pkgs/build-support/fetchgit/nix-prefetch-git23
-rw-r--r--nixpkgs/pkgs/build-support/fetchgithub/default.nix2
-rw-r--r--nixpkgs/pkgs/build-support/fetchhg/default.nix5
-rw-r--r--nixpkgs/pkgs/build-support/fetchpijul/default.nix56
-rw-r--r--nixpkgs/pkgs/build-support/fetchrepoproject/default.nix2
-rw-r--r--nixpkgs/pkgs/build-support/fetchsvn/default.nix15
-rw-r--r--nixpkgs/pkgs/build-support/fetchsvnssh/default.nix5
-rw-r--r--nixpkgs/pkgs/build-support/fetchurl/default.nix2
-rw-r--r--nixpkgs/pkgs/build-support/fetchurl/mirrors.nix6
-rw-r--r--nixpkgs/pkgs/build-support/go/module.nix10
-rw-r--r--nixpkgs/pkgs/build-support/kernel/compress-firmware-xz.nix8
-rw-r--r--nixpkgs/pkgs/build-support/kernel/make-initrd-ng.nix2
-rw-r--r--nixpkgs/pkgs/build-support/nix-gitignore/default.nix4
-rw-r--r--nixpkgs/pkgs/build-support/node/build-npm-package/default.nix8
-rw-r--r--nixpkgs/pkgs/build-support/node/build-npm-package/hooks/npm-build-hook.sh2
-rw-r--r--nixpkgs/pkgs/build-support/node/build-npm-package/hooks/npm-install-hook.sh8
-rw-r--r--nixpkgs/pkgs/build-support/node/fetch-npm-deps/Cargo.lock883
-rw-r--r--nixpkgs/pkgs/build-support/node/fetch-npm-deps/Cargo.toml24
-rw-r--r--nixpkgs/pkgs/build-support/node/fetch-npm-deps/default.nix14
-rw-r--r--nixpkgs/pkgs/build-support/node/fetch-npm-deps/src/cacache.rs5
-rw-r--r--nixpkgs/pkgs/build-support/node/fetch-npm-deps/src/main.rs15
-rw-r--r--nixpkgs/pkgs/build-support/node/fetch-npm-deps/src/parse/mod.rs12
-rw-r--r--nixpkgs/pkgs/build-support/node/fetch-npm-deps/src/util.rs45
-rw-r--r--nixpkgs/pkgs/build-support/node/fetch-yarn-deps/common.js17
-rw-r--r--nixpkgs/pkgs/build-support/node/fetch-yarn-deps/default.nix11
-rwxr-xr-xnixpkgs/pkgs/build-support/node/fetch-yarn-deps/fixup.js74
-rwxr-xr-xnixpkgs/pkgs/build-support/node/fetch-yarn-deps/index.js36
-rw-r--r--nixpkgs/pkgs/build-support/node/fetch-yarn-deps/tests/default.nix10
-rw-r--r--nixpkgs/pkgs/build-support/node/fetch-yarn-deps/tests/giturl.lock11
-rw-r--r--nixpkgs/pkgs/build-support/pkg-config-wrapper/default.nix4
-rw-r--r--nixpkgs/pkgs/build-support/release/binary-tarball.nix2
-rw-r--r--nixpkgs/pkgs/build-support/release/debian-build.nix2
-rw-r--r--nixpkgs/pkgs/build-support/release/default.nix2
-rw-r--r--nixpkgs/pkgs/build-support/release/nix-build.nix8
-rw-r--r--nixpkgs/pkgs/build-support/release/rpm-build.nix2
-rw-r--r--nixpkgs/pkgs/build-support/release/source-tarball.nix6
-rw-r--r--nixpkgs/pkgs/build-support/rust/build-rust-crate/configure-crate.nix2
-rw-r--r--nixpkgs/pkgs/build-support/rust/build-rust-crate/test/rcgen-crates.nix4
-rw-r--r--nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix3
-rw-r--r--nixpkgs/pkgs/build-support/rust/fetch-cargo-tarball/default.nix4
-rw-r--r--nixpkgs/pkgs/build-support/rust/hooks/cargo-build-hook.sh4
-rw-r--r--nixpkgs/pkgs/build-support/rust/import-cargo-lock.nix2
-rw-r--r--nixpkgs/pkgs/build-support/rust/test/import-cargo-lock/default.nix4
-rw-r--r--nixpkgs/pkgs/build-support/rust/test/import-cargo-lock/maturin/Cargo.lock682
-rw-r--r--nixpkgs/pkgs/build-support/rust/test/import-cargo-lock/maturin/default.nix43
-rw-r--r--nixpkgs/pkgs/build-support/setup-hooks/make-wrapper.sh6
-rw-r--r--nixpkgs/pkgs/build-support/src-only/default.nix3
-rw-r--r--nixpkgs/pkgs/build-support/testers/default.nix4
-rw-r--r--nixpkgs/pkgs/build-support/trivial-builders/default.nix24
-rw-r--r--nixpkgs/pkgs/build-support/trivial-builders/test/default.nix33
-rw-r--r--nixpkgs/pkgs/build-support/trivial-builders/test/write-text-file.nix99
-rw-r--r--nixpkgs/pkgs/build-support/trivial-builders/test/writeCBin.nix43
-rw-r--r--nixpkgs/pkgs/build-support/trivial-builders/test/writeScriptBin.nix39
-rw-r--r--nixpkgs/pkgs/build-support/trivial-builders/test/writeShellScriptBin.nix39
-rw-r--r--nixpkgs/pkgs/build-support/vm/default.nix10
-rw-r--r--nixpkgs/pkgs/build-support/writers/data.nix80
-rw-r--r--nixpkgs/pkgs/build-support/writers/default.nix365
-rw-r--r--nixpkgs/pkgs/build-support/writers/scripts.nix384
-rw-r--r--nixpkgs/pkgs/build-support/writers/test.nix198
88 files changed, 2165 insertions, 1751 deletions
diff --git a/nixpkgs/pkgs/build-support/binary-cache/default.nix b/nixpkgs/pkgs/build-support/binary-cache/default.nix
index 577328cad920..27f9ad962899 100644
--- a/nixpkgs/pkgs/build-support/binary-cache/default.nix
+++ b/nixpkgs/pkgs/build-support/binary-cache/default.nix
@@ -1,4 +1,4 @@
-{ stdenv, buildPackages }:
+{ lib, stdenv, buildPackages }:
 
 # This function is for creating a flat-file binary cache, i.e. the kind created by
 # nix copy --to file:///some/path and usable as a substituter (with the file:// prefix).
@@ -19,7 +19,7 @@ stdenv.mkDerivation {
 
   preferLocalBuild = true;
 
-  PATH = "${buildPackages.coreutils}/bin:${buildPackages.jq}/bin:${buildPackages.python3}/bin:${buildPackages.nix}/bin:${buildPackages.xz}/bin";
+  PATH = lib.makeBinPath (with buildPackages; [ coreutils jq python3 nix xz ]);
 
   builder = builtins.toFile "builder" ''
     . .attrs.sh
diff --git a/nixpkgs/pkgs/build-support/bintools-wrapper/add-hardening.sh b/nixpkgs/pkgs/build-support/bintools-wrapper/add-hardening.sh
index 0a2b2509a826..db9553c3fc76 100644
--- a/nixpkgs/pkgs/build-support/bintools-wrapper/add-hardening.sh
+++ b/nixpkgs/pkgs/build-support/bintools-wrapper/add-hardening.sh
@@ -37,11 +37,11 @@ fi
 for flag in "${!hardeningEnableMap[@]}"; do
   case $flag in
     pie)
-      if [[ ! (" $* " =~ " -shared " \
-            || " $* " =~ " -static " \
-            || " $* " =~ " -r " \
-            || " $* " =~ " -Ur " \
-            || " $* " =~ " -i ") ]]; then
+      if [[ ! (" ${params[*]} " =~ " -shared " \
+            || " ${params[*]} " =~ " -static " \
+            || " ${params[*]} " =~ " -r " \
+            || " ${params[*]} " =~ " -Ur " \
+            || " ${params[*]} " =~ " -i ") ]]; then
         if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling LDFlags -pie >&2; fi
         hardeningLDFlags+=('-pie')
       fi
diff --git a/nixpkgs/pkgs/build-support/bintools-wrapper/default.nix b/nixpkgs/pkgs/build-support/bintools-wrapper/default.nix
index acc433496b0e..9ed4f5886f61 100644
--- a/nixpkgs/pkgs/build-support/bintools-wrapper/default.nix
+++ b/nixpkgs/pkgs/build-support/bintools-wrapper/default.nix
@@ -59,12 +59,12 @@ let
   bintoolsVersion = lib.getVersion bintools;
   bintoolsName = lib.removePrefix targetPrefix (lib.getName bintools);
 
-  libc_bin = if libc == null then "" else getBin libc;
-  libc_dev = if libc == null then "" else getDev libc;
-  libc_lib = if libc == null then "" else getLib libc;
-  bintools_bin = if nativeTools then "" else getBin bintools;
+  libc_bin = lib.optionalString (libc != null) (getBin libc);
+  libc_dev = lib.optionalString (libc != null) (getDev libc);
+  libc_lib = lib.optionalString (libc != null) (getLib libc);
+  bintools_bin = lib.optionalString (!nativeTools) (getBin bintools);
   # The wrapper scripts use 'cat' and 'grep', so we may need coreutils.
-  coreutils_bin = if nativeTools then "" else getBin coreutils;
+  coreutils_bin = lib.optionalString (!nativeTools) (getBin coreutils);
 
   # See description in cc-wrapper.
   suffixSalt = replaceStrings ["-" "."] ["_" "_"] targetPlatform.config;
@@ -103,7 +103,7 @@ in
 stdenv.mkDerivation {
   pname = targetPrefix
     + (if name != "" then name else "${bintoolsName}-wrapper");
-  version = if bintools == null then "" else bintoolsVersion;
+  version = lib.optionalString (bintools != null) bintoolsVersion;
 
   preferLocalBuild = true;
 
@@ -265,7 +265,7 @@ stdenv.mkDerivation {
     # install the wrapper, you get tools like objdump (same for any
     # binaries of libc).
     + optionalString (!nativeTools) ''
-      printWords ${bintools_bin} ${if libc == null then "" else libc_bin} > $out/nix-support/propagated-user-env-packages
+      printWords ${bintools_bin} ${lib.optionalString (libc != null) libc_bin} > $out/nix-support/propagated-user-env-packages
     ''
 
     ##
@@ -381,15 +381,15 @@ stdenv.mkDerivation {
     # for substitution in utils.bash
     expandResponseParams = "${expand-response-params}/bin/expand-response-params";
     shell = getBin shell + shell.shellPath or "";
-    gnugrep_bin = if nativeTools then "" else gnugrep;
+    gnugrep_bin = lib.optionalString (!nativeTools) gnugrep;
     wrapperName = "BINTOOLS_WRAPPER";
     inherit dynamicLinker targetPrefix suffixSalt coreutils_bin;
     inherit bintools_bin libc_bin libc_dev libc_lib;
   };
 
   meta =
-    let bintools_ = if bintools != null then bintools else {}; in
-    (if bintools_ ? meta then removeAttrs bintools.meta ["priority"] else {}) //
+    let bintools_ = lib.optionalAttrs (bintools != null) bintools; in
+    (lib.optionalAttrs (bintools_ ? meta) (removeAttrs bintools.meta ["priority"])) //
     { description =
         lib.attrByPath ["meta" "description"] "System binary utilities" bintools_
         + " (wrapper script)";
diff --git a/nixpkgs/pkgs/build-support/build-fhsenv-bubblewrap/buildFHSEnv.nix b/nixpkgs/pkgs/build-support/build-fhsenv-bubblewrap/buildFHSEnv.nix
index 2d927c7df731..3e6fc922906f 100644
--- a/nixpkgs/pkgs/build-support/build-fhsenv-bubblewrap/buildFHSEnv.nix
+++ b/nixpkgs/pkgs/build-support/build-fhsenv-bubblewrap/buildFHSEnv.nix
@@ -12,6 +12,7 @@
 , profile ? ""
 , targetPkgs ? pkgs: []
 , multiPkgs ? pkgs: []
+, multiArch ? false # Whether to include 32bit packages
 , extraBuildCommands ? ""
 , extraBuildCommandsMulti ? ""
 , extraOutputsToInstall ? []
@@ -35,8 +36,8 @@
 let
   inherit (stdenv) is64bit;
 
-  # use of glibc_multi is only supported on x86_64-linux
-  isMultiBuild  = multiPkgs != null && stdenv.isx86_64 && stdenv.isLinux;
+  # "use of glibc_multi is only supported on x86_64-linux"
+  isMultiBuild = multiArch && stdenv.system == "x86_64-linux";
   isTargetBuild = !isMultiBuild;
 
   # list of packages (usually programs) which are only be installed for the
@@ -51,21 +52,34 @@ let
   # these match the host's architecture, glibc_multi is used for multilib
   # builds. glibcLocales must be before glibc or glibc_multi as otherwiese
   # the wrong LOCALE_ARCHIVE will be used where only C.UTF-8 is available.
-  basePkgs = with pkgs;
-    [ glibcLocales
-      (if isMultiBuild then glibc_multi else glibc)
-      (toString gcc.cc.lib) bashInteractiveFHS coreutils less shadow su
-      gawk diffutils findutils gnused gnugrep
-      gnutar gzip bzip2 xz
-    ];
-  baseMultiPkgs = with pkgsi686Linux;
-    [ (toString gcc.cc.lib)
-    ];
+  basePkgs = with pkgs; [
+    glibcLocales
+    (if isMultiBuild then glibc_multi else glibc)
+    (toString gcc.cc.lib)
+    bashInteractiveFHS
+    coreutils
+    less
+    shadow
+    su
+    gawk
+    diffutils
+    findutils
+    gnused
+    gnugrep
+    gnutar
+    gzip
+    bzip2
+    xz
+  ];
+  baseMultiPkgs = with pkgsi686Linux; [
+    (toString gcc.cc.lib)
+  ];
 
   ldconfig = writeShellScriptBin "ldconfig" ''
     # due to a glibc bug, 64-bit ldconfig complains about patchelf'd 32-bit libraries, so we're using 32-bit ldconfig
-    exec ${if stdenv.isx86_64 && stdenv.isLinux then pkgsi686Linux.glibc.bin else pkgs.glibc.bin}/bin/ldconfig -f /etc/ld.so.conf -C /etc/ld.so.cache "$@"
+    exec ${if stdenv.system == "x86_64-linux" then pkgsi686Linux.glibc.bin else pkgs.glibc.bin}/bin/ldconfig -f /etc/ld.so.conf -C /etc/ld.so.cache "$@"
   '';
+
   etcProfile = writeText "profile" ''
     export PS1='${name}-chrootenv:\u@\h:\w\$ '
     export LOCALE_ARCHIVE='/usr/lib/locale/locale-archive'
@@ -104,7 +118,7 @@ let
   # Compose /etc for the chroot environment
   etcPkg = runCommandLocal "${name}-chrootenv-etc" { } ''
     mkdir -p $out/etc
-    cd $out/etc
+    pushd $out/etc
 
     # environment variables
     ln -s ${etcProfile} profile
@@ -172,13 +186,18 @@ let
     ln -s lib64 lib
 
     # copy glibc stuff
-    cp -rsHf ${staticUsrProfileTarget}/lib/32/* lib32/ && chmod u+w -R lib32/
+    cp -rsHf ${staticUsrProfileTarget}/lib/32/* lib32/
+    chmod u+w -R lib32/
 
     # copy content of multiPaths (32bit libs)
-    [ -d ${staticUsrProfileMulti}/lib ] && cp -rsHf ${staticUsrProfileMulti}/lib/* lib32/ && chmod u+w -R lib32/
+    if [ -d ${staticUsrProfileMulti}/lib ]; then
+      cp -rsHf ${staticUsrProfileMulti}/lib/* lib32/
+      chmod u+w -R lib32/
+    fi
 
     # copy content of targetPaths (64bit libs)
-    cp -rsHf ${staticUsrProfileTarget}/lib/* lib64/ && chmod u+w -R lib64/
+    cp -rsHf ${staticUsrProfileTarget}/lib/* lib64/
+    chmod u+w -R lib64/
 
     # symlink 32-bit ld-linux.so
     ln -Ls ${staticUsrProfileTarget}/lib/32/ld-linux.so.2 lib/
@@ -191,13 +210,15 @@ let
   # the target profile is the actual profile that will be used for the chroot
   setupTargetProfile = ''
     mkdir -m0755 usr
-    cd usr
+    pushd usr
+
     ${setupLibDirs}
-    ${lib.optionalString isMultiBuild ''
+
+    '' + lib.optionalString isMultiBuild ''
     if [ -d "${staticUsrProfileMulti}/share" ]; then
       cp -rLf ${staticUsrProfileMulti}/share share
     fi
-    ''}
+    '' + ''
     if [ -d "${staticUsrProfileTarget}/share" ]; then
       if [ -d share ]; then
         chmod -R 755 share
@@ -223,18 +244,19 @@ let
         ln -s "$i"
       fi
     done
+
+    popd
   '';
 
 in runCommandLocal "${name}-fhs" {
   passthru = {
-    inherit args multiPaths targetPaths;
+    inherit args multiPaths targetPaths ldconfig;
   };
 } ''
   mkdir -p $out
-  cd $out
+  pushd $out
+
   ${setupTargetProfile}
-  cd $out
   ${extraBuildCommands}
-  cd $out
   ${lib.optionalString isMultiBuild extraBuildCommandsMulti}
 ''
diff --git a/nixpkgs/pkgs/build-support/buildenv/builder.pl b/nixpkgs/pkgs/build-support/buildenv/builder.pl
index ebd6026b2597..975e76df05c0 100755
--- a/nixpkgs/pkgs/build-support/buildenv/builder.pl
+++ b/nixpkgs/pkgs/build-support/buildenv/builder.pl
@@ -126,7 +126,7 @@ sub findFiles {
     return if
         $relName eq "/propagated-build-inputs" ||
         $relName eq "/nix-support" ||
-        $relName =~ /info\/dir/ ||
+        $relName =~ /info\/dir$/ ||
         ( $relName =~ /^\/share\/mime\// && !( $relName =~ /^\/share\/mime\/packages/ ) ) ||
         $baseName eq "perllocal.pod" ||
         $baseName eq "log" ||
diff --git a/nixpkgs/pkgs/build-support/buildenv/default.nix b/nixpkgs/pkgs/build-support/buildenv/default.nix
index 006fc2aff923..786a2ad5da02 100644
--- a/nixpkgs/pkgs/build-support/buildenv/default.nix
+++ b/nixpkgs/pkgs/build-support/buildenv/default.nix
@@ -1,6 +1,5 @@
 # buildEnv creates a tree of symlinks to the specified paths.  This is
-# a fork of the buildEnv in the Nix distribution.  Most changes should
-# eventually be merged back into the Nix distribution.
+# a fork of the hardcoded buildEnv in the Nix distribution.
 
 { buildPackages, runCommand, lib, substituteAll }:
 
diff --git a/nixpkgs/pkgs/build-support/cc-wrapper/add-hardening.sh b/nixpkgs/pkgs/build-support/cc-wrapper/add-hardening.sh
index b1aa01355b13..07ac6737f39d 100644
--- a/nixpkgs/pkgs/build-support/cc-wrapper/add-hardening.sh
+++ b/nixpkgs/pkgs/build-support/cc-wrapper/add-hardening.sh
@@ -71,7 +71,7 @@ for flag in "${!hardeningEnableMap[@]}"; do
       # NB: we do not use `+=` here, because PIE flags must occur before any PIC flags
       if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling CFlags -fPIE >&2; fi
       hardeningCFlags=('-fPIE' "${hardeningCFlags[@]}")
-      if [[ ! (" $* " =~ " -shared " || " $* " =~ " -static ") ]]; then
+      if [[ ! (" ${params[*]} " =~ " -shared " || " ${params[*]} " =~ " -static ") ]]; then
         if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling LDFlags -pie >&2; fi
         hardeningCFlags=('-pie' "${hardeningCFlags[@]}")
       fi
diff --git a/nixpkgs/pkgs/build-support/cc-wrapper/default.nix b/nixpkgs/pkgs/build-support/cc-wrapper/default.nix
index e4dcb8134669..551074e0a211 100644
--- a/nixpkgs/pkgs/build-support/cc-wrapper/default.nix
+++ b/nixpkgs/pkgs/build-support/cc-wrapper/default.nix
@@ -75,14 +75,14 @@ let
   ccVersion = lib.getVersion cc;
   ccName = lib.removePrefix targetPrefix (lib.getName cc);
 
-  libc_bin = if libc == null then "" else getBin libc;
-  libc_dev = if libc == null then "" else getDev libc;
-  libc_lib = if libc == null then "" else getLib libc;
+  libc_bin = optionalString (libc != null) (getBin libc);
+  libc_dev = optionalString (libc != null) (getDev libc);
+  libc_lib = optionalString (libc != null) (getLib libc);
   cc_solib = getLib cc
     + optionalString (targetPlatform != hostPlatform) "/${targetPlatform.config}";
 
   # The wrapper scripts use 'cat' and 'grep', so we may need coreutils.
-  coreutils_bin = if nativeTools then "" else getBin coreutils;
+  coreutils_bin = optionalString (!nativeTools) (getBin coreutils);
 
   # The "suffix salt" is a arbitrary string added in the end of env vars
   # defined by cc-wrapper's hooks so that multiple cc-wrappers can be used
@@ -106,7 +106,12 @@ let
   isGccArchSupported = arch:
     if targetPlatform.isPower then false else # powerpc does not allow -march=
     if isGNU then
-      { # Intel
+      { # Generic
+        x86-64-v2 = versionAtLeast ccVersion "11.0";
+        x86-64-v3 = versionAtLeast ccVersion "11.0";
+        x86-64-v4 = versionAtLeast ccVersion "11.0";
+
+        # Intel
         skylake        = versionAtLeast ccVersion "6.0";
         skylake-avx512 = versionAtLeast ccVersion "6.0";
         cannonlake     = versionAtLeast ccVersion "8.0";
@@ -116,20 +121,32 @@ let
         cooperlake     = versionAtLeast ccVersion "10.0";
         tigerlake      = versionAtLeast ccVersion "10.0";
         knm            = versionAtLeast ccVersion "8.0";
+        alderlake      = versionAtLeast ccVersion "12.0";
+
         # AMD
         znver1         = versionAtLeast ccVersion "6.0";
         znver2         = versionAtLeast ccVersion "9.0";
         znver3         = versionAtLeast ccVersion "11.0";
+        znver4         = versionAtLeast ccVersion "13.0";
       }.${arch} or true
     else if isClang then
-      { # Intel
+      { #Generic
+        x86-64-v2 = versionAtLeast ccVersion "12.0";
+        x86-64-v3 = versionAtLeast ccVersion "12.0";
+        x86-64-v4 = versionAtLeast ccVersion "12.0";
+
+        # Intel
         cannonlake     = versionAtLeast ccVersion "5.0";
         icelake-client = versionAtLeast ccVersion "7.0";
         icelake-server = versionAtLeast ccVersion "7.0";
         knm            = versionAtLeast ccVersion "7.0";
+        alderlake      = versionAtLeast ccVersion "16.0";
+
         # AMD
         znver1         = versionAtLeast ccVersion "4.0";
         znver2         = versionAtLeast ccVersion "9.0";
+        znver3         = versionAtLeast ccVersion "12.0";
+        znver4         = versionAtLeast ccVersion "16.0";
       }.${arch} or true
     else
       false;
@@ -159,7 +176,7 @@ assert nativePrefix == bintools.nativePrefix;
 stdenv.mkDerivation {
   pname = targetPrefix
     + (if name != "" then name else "${ccName}-wrapper");
-  version = if cc == null then "" else ccVersion;
+  version = optionalString (cc != null) ccVersion;
 
   preferLocalBuild = true;
 
@@ -595,10 +612,10 @@ stdenv.mkDerivation {
     # for substitution in utils.bash
     expandResponseParams = "${expand-response-params}/bin/expand-response-params";
     shell = getBin shell + shell.shellPath or "";
-    gnugrep_bin = if nativeTools then "" else gnugrep;
+    gnugrep_bin = optionalString (!nativeTools) gnugrep;
     # stdenv.cc.cc should not be null and we have nothing better for now.
     # if the native impure bootstrap is gotten rid of this can become `inherit cc;` again.
-    cc = if nativeTools then "" else cc;
+    cc = optionalString (!nativeTools) cc;
     wrapperName = "CC_WRAPPER";
     inherit suffixSalt coreutils_bin bintools;
     inherit libc_bin libc_dev libc_lib;
@@ -606,8 +623,8 @@ stdenv.mkDerivation {
   };
 
   meta =
-    let cc_ = if cc != null then cc else {}; in
-    (if cc_ ? meta then removeAttrs cc.meta ["priority"] else {}) //
+    let cc_ = lib.optionalAttrs (cc != null) cc; in
+    (lib.optionalAttrs (cc_ ? meta) (removeAttrs cc.meta ["priority"])) //
     { description =
         lib.attrByPath ["meta" "description"] "System C compiler" cc_
         + " (wrapper script)";
diff --git a/nixpkgs/pkgs/build-support/cc-wrapper/setup-hook.sh b/nixpkgs/pkgs/build-support/cc-wrapper/setup-hook.sh
index be01c51a71ff..9326d76e2a8f 100644
--- a/nixpkgs/pkgs/build-support/cc-wrapper/setup-hook.sh
+++ b/nixpkgs/pkgs/build-support/cc-wrapper/setup-hook.sh
@@ -111,7 +111,7 @@ export CC${role_post}=@named_cc@
 export CXX${role_post}=@named_cxx@
 
 # If unset, assume the default hardening flags.
-: ${NIX_HARDENING_ENABLE="fortify stackprotector pic strictoverflow format relro bindnow"}
+: ${NIX_HARDENING_ENABLE="fortify fortify3 stackprotector pic strictoverflow format relro bindnow"}
 export NIX_HARDENING_ENABLE
 
 # No local scope in sourced file
diff --git a/nixpkgs/pkgs/build-support/dart/build-dart-application/default.nix b/nixpkgs/pkgs/build-support/dart/build-dart-application/default.nix
index 780aefa90ef9..7e9c3f842b80 100644
--- a/nixpkgs/pkgs/build-support/dart/build-dart-application/default.nix
+++ b/nixpkgs/pkgs/build-support/dart/build-dart-application/default.nix
@@ -1,4 +1,4 @@
-{ lib, stdenv, fetchDartDeps, writeText, dartHooks, makeWrapper, dart, nodejs }:
+{ lib, stdenv, fetchDartDeps, writeText, dartHooks, makeWrapper, dart, nodejs, darwin }:
 
 { pubGetScript ? "dart pub get"
 
@@ -54,6 +54,8 @@ stdenv.mkDerivation (args // {
     dartBuildHook
     dartInstallHook
     makeWrapper
+  ] ++ lib.optionals stdenv.isDarwin [
+    darwin.sigtool
   ];
 
   # When stripping, it seems some ELF information is lost and the dart VM cli
diff --git a/nixpkgs/pkgs/build-support/docker/default.nix b/nixpkgs/pkgs/build-support/docker/default.nix
index 5f48fb9f7bdb..b74d7885d54a 100644
--- a/nixpkgs/pkgs/build-support/docker/default.nix
+++ b/nixpkgs/pkgs/build-support/docker/default.nix
@@ -594,7 +594,7 @@ rec {
           nativeBuildInputs = [ jshon pigz jq moreutils ];
           # Image name must be lowercase
           imageName = lib.toLower name;
-          imageTag = if tag == null then "" else tag;
+          imageTag = lib.optionalString (tag != null) tag;
           inherit fromImage baseJson;
           layerClosure = writeReferencesToFile layer;
           passthru.buildArgs = args;
diff --git a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-global-tool/default.nix b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-global-tool/default.nix
new file mode 100644
index 000000000000..5e63aa669c56
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-global-tool/default.nix
@@ -0,0 +1,48 @@
+{ buildDotnetModule, emptyDirectory, mkNugetDeps, dotnet-sdk }:
+
+{ pname
+, version
+  # Name of the nuget package to install, if different from pname
+, nugetName ? pname
+  # Hash of the nuget package to install, will be given on first build
+, nugetSha256 ? ""
+  # Additional nuget deps needed by the tool package
+, nugetDeps ? (_: [])
+  # Executables to wrap into `$out/bin`, same as in `buildDotnetModule`, but with
+  # a default of `pname` instead of null, to avoid auto-wrapping everything
+, executables ? pname
+  # The dotnet runtime to use, dotnet tools need a full SDK to function
+, dotnet-runtime ? dotnet-sdk
+, ...
+} @ args:
+
+buildDotnetModule (args // {
+  inherit pname version dotnet-runtime executables;
+
+  src = emptyDirectory;
+
+  nugetDeps = mkNugetDeps {
+    name = pname;
+    nugetDeps = { fetchNuGet }: [
+      (fetchNuGet { pname = nugetName; inherit version; sha256 = nugetSha256; })
+    ] ++ (nugetDeps fetchNuGet);
+  };
+
+  projectFile = "";
+
+  useDotnetFromEnv = true;
+
+  dontBuld = true;
+
+  installPhase = ''
+    runHook preInstall
+
+    dotnet tool install --tool-path $out/lib/${pname} ${nugetName}
+
+    # remove files that contain nix store paths to temp nuget sources we made
+    find $out -name 'project.assets.json' -delete
+    find $out -name '.nupkg.metadata' -delete
+
+    runHook postInstall
+  '';
+})
diff --git a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/default.nix b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/default.nix
index 07e62835956f..686d89f8c11c 100644
--- a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/default.nix
+++ b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/default.nix
@@ -12,6 +12,7 @@
 , nuget-to-nix
 , cacert
 , coreutils
+, runtimeShellPackage
 }:
 
 { name ? "${args.pname}-${args.version}"
@@ -74,7 +75,10 @@
 , buildType ? "Release"
   # If set to true, builds the application as a self-contained - removing the runtime dependency on dotnet
 , selfContainedBuild ? false
-  # Whether to explicitly enable UseAppHost when building
+  # Whether to use an alternative wrapper, that executes the application DLL using the dotnet runtime from the user environment. `dotnet-runtime` is provided as a default in case no .NET is installed
+  # This is useful for .NET tools and applications that may need to run under different .NET runtimes
+, useDotnetFromEnv ? false
+  # Whether to explicitly enable UseAppHost when building. This is redundant if useDotnetFromEnv is enabledz
 , useAppHost ? true
   # The dotnet SDK to use.
 , dotnet-sdk ? dotnetCorePackages.sdk_6_0
@@ -108,7 +112,11 @@ let
     if (nugetDeps != null) then
       if lib.isDerivation nugetDeps
       then nugetDeps
-      else mkNugetDeps { inherit name; nugetDeps = import nugetDeps; }
+      else mkNugetDeps {
+        inherit name;
+        nugetDeps = import nugetDeps;
+        sourceFile = nugetDeps;
+      }
     else throw "Defining the `nugetDeps` attribute is required, as to lock the NuGet dependencies. This file can be generated by running the `passthru.fetch-deps` script.";
 
   # contains the actual package dependencies
@@ -134,6 +142,8 @@ let
     name = "${name}-nuget-source";
     paths = [ dependenciesSource sdkSource ];
   };
+
+  nugetDepsFile = _nugetDeps.sourceFile;
 in
 stdenvNoCC.mkDerivation (args // {
   nativeBuildInputs = args.nativeBuildInputs or [ ] ++ [
@@ -158,11 +168,11 @@ stdenvNoCC.mkDerivation (args // {
   # gappsWrapperArgs gets included when wrapping for dotnet, as to avoid double wrapping
   dontWrapGApps = args.dontWrapGApps or true;
 
-  inherit selfContainedBuild useAppHost;
+  inherit selfContainedBuild useAppHost useDotnetFromEnv;
 
   passthru = {
     inherit nuget-source;
-
+  } // lib.optionalAttrs (nugetDepsFile != null) {
     fetch-deps =
       let
         flags = dotnetFlags ++ dotnetRestoreFlags;
@@ -176,14 +186,14 @@ stdenvNoCC.mkDerivation (args // {
           # Note that toString is necessary here as it results in the path at
           # eval time (i.e. to the file in your local Nixpkgs checkout) rather
           # than the Nix store path of the path after it's been imported.
-          if lib.isPath nugetDeps && !lib.hasPrefix "${builtins.storeDir}/" (toString nugetDeps)
-          then toString nugetDeps
+          if lib.isPath nugetDepsFile && !lib.hasPrefix "${builtins.storeDir}/" (toString nugetDepsFile)
+          then toString nugetDepsFile
           else ''$(mktemp -t "${pname}-deps-XXXXXX.nix")'';
       in
       writeShellScript "fetch-${pname}-deps" ''
         set -euo pipefail
 
-        export PATH="${lib.makeBinPath [ coreutils dotnet-sdk (nuget-to-nix.override { inherit dotnet-sdk; }) ]}"
+        export PATH="${lib.makeBinPath [ coreutils runtimeShellPackage dotnet-sdk (nuget-to-nix.override { inherit dotnet-sdk; }) ]}"
 
         for arg in "$@"; do
             case "$arg" in
@@ -204,7 +214,7 @@ stdenvNoCC.mkDerivation (args // {
         if [[ ''${TMPDIR:-} == /run/user/* ]]; then
            # /run/user is usually a tmpfs in RAM, which may be too small
            # to store all downloaded dotnet packages
-           TMPDIR=
+           unset TMPDIR
         fi
 
         export tmp=$(mktemp -td "deps-${pname}-XXXXXX")
@@ -262,7 +272,7 @@ stdenvNoCC.mkDerivation (args // {
         echo "Restoring project..."
 
         ${dotnet-sdk}/bin/dotnet tool restore
-        mv $HOME/.nuget/packages/* $tmp/nuget_pkgs || true
+        cp -r $HOME/.nuget/packages/* $tmp/nuget_pkgs || true
 
         for rid in "${lib.concatStringsSep "\" \"" runtimeIds}"; do
             (( ''${#projectFiles[@]} == 0 )) && dotnetRestore "" "$rid"
@@ -271,17 +281,21 @@ stdenvNoCC.mkDerivation (args // {
                 dotnetRestore "$project" "$rid"
             done
         done
+        # Second copy, makes sure packages restored by ie. paket are included
+        cp -r $HOME/.nuget/packages/* $tmp/nuget_pkgs || true
 
         echo "Succesfully restored project"
 
         echo "Writing lockfile..."
-        echo -e "# This file was automatically generated by passthru.fetch-deps.\n# Please dont edit it manually, your changes might get overwritten!\n" > "$depsFile"
 
         excluded_sources="${lib.concatStringsSep " " sdkDeps}"
         for excluded_source in ''${excluded_sources[@]}; do
           ls "$excluded_source" >> "$tmp/excluded_list"
         done
-        nuget-to-nix "$tmp/nuget_pkgs" "$tmp/excluded_list" >> "$depsFile"
+        tmpFile="$tmp"/deps.nix
+        echo -e "# This file was automatically generated by passthru.fetch-deps.\n# Please dont edit it manually, your changes might get overwritten!\n" > "$tmpFile"
+        nuget-to-nix "$tmp/nuget_pkgs" "$tmp/excluded_list" >> "$tmpFile"
+        mv "$tmpFile" "$depsFile"
         echo "Succesfully wrote lockfile to $depsFile"
       '';
   } // args.passthru or { };
diff --git a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/default.nix b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/default.nix
index a72f0291a872..8d0d27f67345 100644
--- a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/default.nix
+++ b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/default.nix
@@ -1,4 +1,9 @@
 { lib
+, stdenv
+, which
+, coreutils
+, zlib
+, openssl
 , callPackage
 , makeSetupHook
 , makeWrapper
@@ -23,6 +28,14 @@ in
       propagatedBuildInputs = [ dotnet-sdk nuget-source ];
       substitutions = {
         nugetSource = nuget-source;
+        dynamicLinker = "${stdenv.cc}/nix-support/dynamic-linker";
+        libPath = lib.makeLibraryPath [
+          stdenv.cc.cc.lib
+          stdenv.cc.libc
+          dotnet-sdk.passthru.icu
+          zlib
+          openssl
+        ];
         inherit runtimeId;
       };
     } ./dotnet-configure-hook.sh) { };
@@ -41,7 +54,7 @@ in
       name = "dotnet-check-hook";
       propagatedBuildInputs = [ dotnet-test-sdk ];
       substitutions = {
-        inherit buildType libraryPath;
+        inherit buildType runtimeId libraryPath;
         disabledTests = lib.optionalString (disabledTests != [])
           (let
             escapedNames = lib.lists.map (n: lib.replaceStrings [","] ["%2C"] n) disabledTests;
@@ -67,6 +80,9 @@ in
       substitutions = {
         dotnetRuntime = dotnet-runtime;
         runtimeDeps = libraryPath;
+        shell = stdenv.shell;
+        which = "${which}/bin/which";
+        dirname = "${coreutils}/bin/dirname";
       };
     } ./dotnet-fixup-hook.sh) { };
 }
diff --git a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-build-hook.sh b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-build-hook.sh
index 8f7f77339357..e9567b64cf2c 100644
--- a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-build-hook.sh
+++ b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-build-hook.sh
@@ -15,7 +15,7 @@ dotnetBuildHook() {
     fi
 
     if [ "${selfContainedBuild-}" ]; then
-        dotnetBuildFlags+=(--runtime "@runtimeId@" "-p:SelfContained=true")
+        dotnetBuildFlags+=("-p:SelfContained=true")
     else
         dotnetBuildFlags+=("-p:SelfContained=false")
     fi
@@ -30,6 +30,12 @@ dotnetBuildHook() {
 
     dotnetBuild() {
         local -r project="${1-}"
+
+        runtimeIdFlags=()
+        if [[ "$project" == *.csproj ]] || [ "${selfContainedBuild-}" ]; then
+            runtimeIdFlags+=("--runtime @runtimeId@")
+        fi
+
         env dotnet build ${project-} \
             -maxcpucount:$maxCpuFlag \
             -p:BuildInParallel=$parallelBuildFlag \
@@ -38,6 +44,7 @@ dotnetBuildHook() {
             --configuration "@buildType@" \
             --no-restore \
             ${versionFlag-} \
+            ${runtimeIdFlags[@]} \
             ${dotnetBuildFlags[@]}  \
             ${dotnetFlags[@]}
     }
diff --git a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-check-hook.sh b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-check-hook.sh
index fdcf8d54be46..507721ef9818 100644
--- a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-check-hook.sh
+++ b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-check-hook.sh
@@ -17,6 +17,11 @@ dotnetCheckHook() {
     fi
 
     for project in ${testProjectFile[@]-${projectFile[@]}}; do
+        runtimeIdFlags=()
+        if [[ "$project" == *.csproj ]]; then
+            runtimeIdFlags=("--runtime @runtimeId@")
+        fi
+
         env "LD_LIBRARY_PATH=@libraryPath@" \
             dotnet test "$project" \
               -maxcpucount:$maxCpuFlag \
@@ -26,6 +31,7 @@ dotnetCheckHook() {
               --no-build \
               --logger "console;verbosity=normal" \
               ${disabledTestsFlag-} \
+              ${runtimeIdFlags[@]} \
               "${dotnetTestFlags[@]}"  \
               "${dotnetFlags[@]}"
     done
diff --git a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-configure-hook.sh b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-configure-hook.sh
index 0e502fe6a14d..c046fc3c306b 100644
--- a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-configure-hook.sh
+++ b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-configure-hook.sh
@@ -25,8 +25,6 @@ dotnetConfigureHook() {
             ${dotnetFlags[@]}
     }
 
-    (( "${#projectFile[@]}" == 0 )) && dotnetRestore
-
     # Generate a NuGet.config file to make sure everything,
     # including things like <Sdk /> dependencies, is restored from the proper source
 cat <<EOF > "./NuGet.config"
@@ -39,12 +37,41 @@ cat <<EOF > "./NuGet.config"
 </configuration>
 EOF
 
+    # Patch paket.dependencies and paket.lock (if found) to use the proper source. This ensures
+    # paket restore works correctly
+    # We use + instead of / in sed to avoid problems with slashes
+    find -name paket.dependencies -exec sed -i 's+source .*+source @nugetSource@/lib+g' {} \;
+    find -name paket.lock -exec sed -i 's+remote:.*+remote: @nugetSource@/lib+g' {} \;
+
     env dotnet tool restore --add-source "@nugetSource@/lib"
 
+    (( "${#projectFile[@]}" == 0 )) && dotnetRestore
+
     for project in ${projectFile[@]} ${testProjectFile[@]-}; do
         dotnetRestore "$project"
     done
 
+    echo "Fixing up native binaries..."
+    # Find all native binaries and nuget libraries, and fix them up,
+    # by setting the proper interpreter and rpath to some commonly used libraries
+    for binary in $(find "$HOME/.nuget/packages/" -type f -executable); do
+        if patchelf --print-interpreter "$binary" >/dev/null 2>/dev/null; then
+            echo "Found binary: $binary, fixing it up..."
+            patchelf --set-interpreter "$(cat "@dynamicLinker@")" "$binary"
+
+            # This makes sure that if the binary requires some specific runtime dependencies, it can find it.
+            # This fixes dotnet-built binaries like crossgen2
+            patchelf \
+                --add-needed libicui18n.so \
+                --add-needed libicuuc.so \
+                --add-needed libz.so \
+                --add-needed libssl.so \
+                "$binary"
+
+            patchelf --set-rpath "@libPath@" "$binary"
+        fi
+    done
+
     runHook postConfigure
 
     echo "Finished dotnetConfigureHook"
diff --git a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-fixup-hook.sh b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-fixup-hook.sh
index 27885238ef7b..70728e4321ed 100644
--- a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-fixup-hook.sh
+++ b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-fixup-hook.sh
@@ -5,13 +5,22 @@ makeWrapperArgs=( "${derivationMakeWrapperArgs[@]}" )
 # First argument is the executable you want to wrap,
 # the second is the destination for the wrapper.
 wrapDotnetProgram() {
+    local dotnetRootFlags=()
+
     if [ ! "${selfContainedBuild-}" ]; then
-        local -r dotnetRootFlag=("--set" "DOTNET_ROOT" "@dotnetRuntime@")
+        if [ "${useDotnetFromEnv-}" ]; then
+            # if dotnet CLI is available, set DOTNET_ROOT based on it. Otherwise set to default .NET runtime
+            dotnetRootFlags+=("--run" 'command -v dotnet &>/dev/null && export DOTNET_ROOT="$(@dirname@ "$(@dirname@ "$(@which@ dotnet)")")" || export DOTNET_ROOT="@dotnetRuntime@"')
+            dotnetRootFlags+=("--suffix" "PATH" ":" "@dotnetRuntime@/bin")
+        else
+            dotnetRootFlags+=("--set" "DOTNET_ROOT" "@dotnetRuntime@")
+            dotnetRootFlags+=("--prefix" "PATH" ":" "@dotnetRuntime@/bin")
+        fi
     fi
 
     makeWrapper "$1" "$2" \
         --suffix "LD_LIBRARY_PATH" : "@runtimeDeps@" \
-        "${dotnetRootFlag[@]}" \
+        "${dotnetRootFlags[@]}" \
         "${gappsWrapperArgs[@]}" \
         "${makeWrapperArgs[@]}"
 
diff --git a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-install-hook.sh b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-install-hook.sh
index 831059f941ca..3f2a89c41404 100644
--- a/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-install-hook.sh
+++ b/nixpkgs/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-install-hook.sh
@@ -7,9 +7,12 @@ dotnetInstallHook() {
     runHook preInstall
 
     if [ "${selfContainedBuild-}" ]; then
-        dotnetInstallFlags+=(--runtime "@runtimeId@" "--self-contained")
+        dotnetInstallFlags+=("--self-contained")
     else
         dotnetInstallFlags+=("--no-self-contained")
+        # https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trim-self-contained
+        # Trimming is only available for self-contained build, so force disable it here
+        dotnetInstallFlags+=("-p:PublishTrimmed=false")
     fi
 
     if [ "${useAppHost-}" ]; then
@@ -18,26 +21,34 @@ dotnetInstallHook() {
 
     dotnetPublish() {
         local -r project="${1-}"
+
+        runtimeIdFlags=()
+        if [[ "$project" == *.csproj ]] || [ "${selfContainedBuild-}" ]; then
+            runtimeIdFlags+=("--runtime @runtimeId@")
+        fi
+
         env dotnet publish ${project-} \
             -p:ContinuousIntegrationBuild=true \
             -p:Deterministic=true \
             --output "$out/lib/${pname}" \
             --configuration "@buildType@" \
             --no-build \
+            ${runtimeIdFlags[@]} \
             ${dotnetInstallFlags[@]}  \
             ${dotnetFlags[@]}
     }
 
     dotnetPack() {
         local -r project="${1-}"
-         env dotnet pack ${project-} \
-             -p:ContinuousIntegrationBuild=true \
-             -p:Deterministic=true \
-             --output "$out/share" \
-             --configuration "@buildType@" \
-             --no-build \
-             ${dotnetPackFlags[@]}  \
-             ${dotnetFlags[@]}
+        env dotnet pack ${project-} \
+            -p:ContinuousIntegrationBuild=true \
+            -p:Deterministic=true \
+            --output "$out/share" \
+            --configuration "@buildType@" \
+            --no-build \
+            --runtime "@runtimeId@" \
+            ${dotnetPackFlags[@]}  \
+            ${dotnetFlags[@]}
     }
 
     if (( "${#projectFile[@]}" == 0 )); then
diff --git a/nixpkgs/pkgs/build-support/dotnet/make-nuget-deps/default.nix b/nixpkgs/pkgs/build-support/dotnet/make-nuget-deps/default.nix
index 723646c5fdca..8281976df626 100644
--- a/nixpkgs/pkgs/build-support/dotnet/make-nuget-deps/default.nix
+++ b/nixpkgs/pkgs/build-support/dotnet/make-nuget-deps/default.nix
@@ -1,5 +1,5 @@
 { linkFarmFromDrvs, fetchurl }:
-{ name, nugetDeps }:
+{ name, nugetDeps, sourceFile ? null }:
 linkFarmFromDrvs "${name}-nuget-deps" (nugetDeps {
   fetchNuGet = { pname, version, sha256
     , url ? "https://www.nuget.org/api/v2/package/${pname}/${version}" }:
@@ -7,4 +7,6 @@ linkFarmFromDrvs "${name}-nuget-deps" (nugetDeps {
       name = "${pname}.${version}.nupkg";
       inherit url sha256;
     };
-})
+}) // {
+  inherit sourceFile;
+}
diff --git a/nixpkgs/pkgs/build-support/dotnet/make-nuget-source/default.nix b/nixpkgs/pkgs/build-support/dotnet/make-nuget-source/default.nix
index 6bda65f18d58..a23a143ab246 100644
--- a/nixpkgs/pkgs/build-support/dotnet/make-nuget-source/default.nix
+++ b/nixpkgs/pkgs/build-support/dotnet/make-nuget-source/default.nix
@@ -15,12 +15,10 @@ let
     buildCommand = ''
       mkdir -p $out/{lib,share}
 
-      (
-        shopt -s nullglob
-        for nupkg in ${lib.concatMapStringsSep " " (dep: "\"${dep}\"/*.nupkg") deps}; do
-          cp --no-clobber "$nupkg" $out/lib
-        done
-      )
+      # use -L to follow symbolic links. When `projectReferences` is used in
+      # buildDotnetModule, one of the deps will be a symlink farm.
+      find -L ${lib.concatStringsSep " " deps} -type f -name '*.nupkg' -exec \
+        cp --no-clobber '{}' $out/lib ';'
 
       # Generates a list of all licenses' spdx ids, if available.
       # Note that this currently ignores any license provided in plain text (e.g. "LICENSE.txt")
diff --git a/nixpkgs/pkgs/build-support/dotnet/nuget-to-nix/nuget-to-nix.sh b/nixpkgs/pkgs/build-support/dotnet/nuget-to-nix/nuget-to-nix.sh
index ce2a7070ea31..86bc4482088b 100755
--- a/nixpkgs/pkgs/build-support/dotnet/nuget-to-nix/nuget-to-nix.sh
+++ b/nixpkgs/pkgs/build-support/dotnet/nuget-to-nix/nuget-to-nix.sh
@@ -1,6 +1,7 @@
 #!@runtimeShell@
 
 set -euo pipefail
+shopt -s nullglob
 
 export PATH="@binPath@"
 # used for glob ordering of package names
diff --git a/nixpkgs/pkgs/build-support/emacs/buffer.nix b/nixpkgs/pkgs/build-support/emacs/buffer.nix
index 8f824f4e1a57..b8bd4584e322 100644
--- a/nixpkgs/pkgs/build-support/emacs/buffer.nix
+++ b/nixpkgs/pkgs/build-support/emacs/buffer.nix
@@ -73,7 +73,5 @@ rec {
         haskell-package-env =
           builtins.head haskell-package.env.nativeBuildInputs;
     in
-      if is-haskell-package
-        then withPackages [ haskell-package-env ]
-        else {};
+      lib.optionalAttrs is-haskell-package (withPackages [ haskell-package-env ]);
 }
diff --git a/nixpkgs/pkgs/build-support/emacs/generic.nix b/nixpkgs/pkgs/build-support/emacs/generic.nix
index e3d1505dde87..add8fb5525f9 100644
--- a/nixpkgs/pkgs/build-support/emacs/generic.nix
+++ b/nixpkgs/pkgs/build-support/emacs/generic.nix
@@ -2,32 +2,25 @@
 
 { lib, stdenv, emacs, texinfo, writeText, gcc, ... }:
 
-with lib;
-
 { pname
 , version ? null
-
 , buildInputs ? []
 , packageRequires ? []
-
 , meta ? {}
-
 , ...
 }@args:
 
 let
-
   defaultMeta = {
     broken = false;
     platforms = emacs.meta.platforms;
-  } // optionalAttrs ((args.src.meta.homepage or "") != "") {
+  } // lib.optionalAttrs ((args.src.meta.homepage or "") != "") {
     homepage = args.src.meta.homepage;
   };
-
 in
 
 stdenv.mkDerivation ({
-  name = "emacs-${pname}${optionalString (version != null) "-${version}"}";
+  name = "emacs-${pname}${lib.optionalString (version != null) "-${version}"}";
 
   unpackCmd = ''
     case "$curSrc" in
@@ -68,7 +61,7 @@ stdenv.mkDerivation ({
   meta = defaultMeta // meta;
 }
 
-// lib.optionalAttrs (emacs.nativeComp or false) {
+// lib.optionalAttrs (emacs.withNativeCompilation or false) {
 
   LIBRARY_PATH = "${lib.getLib stdenv.cc.libc}/lib";
 
@@ -90,6 +83,4 @@ stdenv.mkDerivation ({
   '';
 }
 
-// removeAttrs args [ "buildInputs" "packageRequires"
-                      "meta"
-                    ])
+// removeAttrs args [ "buildInputs" "packageRequires" "meta" ])
diff --git a/nixpkgs/pkgs/build-support/emacs/wrapper.nix b/nixpkgs/pkgs/build-support/emacs/wrapper.nix
index bd7702ebb916..a3842dec6997 100644
--- a/nixpkgs/pkgs/build-support/emacs/wrapper.nix
+++ b/nixpkgs/pkgs/build-support/emacs/wrapper.nix
@@ -32,34 +32,25 @@ in customEmacsPackages.withPackages (epkgs: [ epkgs.evil epkgs.magit ])
 
 */
 
-{ lib, lndir, makeWrapper, runCommand, gcc }: self:
-
-with lib;
-
+{ lib, lndir, makeWrapper, runCommand, gcc }:
+self:
 let
-
   inherit (self) emacs;
-
-  nativeComp = emacs.nativeComp or false;
-
-  treeSitter = emacs.treeSitter or false;
-
+  withNativeCompilation = emacs.withNativeCompilation or emacs.nativeComp or false;
+  withTreeSitter = emacs.withTreeSitter or emacs.treeSitter or false;
 in
-
 packagesFun: # packages explicitly requested by the user
-
 let
   explicitRequires =
     if lib.isFunction packagesFun
-      then packagesFun self
+    then packagesFun self
     else packagesFun;
 in
-
 runCommand
-  (appendToName "with-packages" emacs).name
+  (lib.appendToName "with-packages" emacs).name
   {
-    nativeBuildInputs = [ emacs lndir makeWrapper ];
     inherit emacs explicitRequires;
+    nativeBuildInputs = [ emacs lndir makeWrapper ];
 
     preferLocalBuild = true;
     allowSubstitutes = false;
@@ -69,8 +60,8 @@ runCommand
     deps = runCommand "emacs-packages-deps"
       ({
         inherit explicitRequires lndir emacs;
-        nativeBuildInputs = lib.optional nativeComp gcc;
-      } // lib.optionalAttrs nativeComp {
+        nativeBuildInputs = lib.optional withNativeCompilation gcc;
+      } // lib.optionalAttrs withNativeCompilation {
         inherit (emacs) LIBRARY_PATH;
       })
       ''
@@ -110,10 +101,10 @@ runCommand
         }
         mkdir -p $out/bin
         mkdir -p $out/share/emacs/site-lisp
-        ${optionalString nativeComp ''
+        ${lib.optionalString withNativeCompilation ''
           mkdir -p $out/share/emacs/native-lisp
         ''}
-        ${optionalString treeSitter ''
+        ${lib.optionalString withTreeSitter ''
           mkdir -p $out/lib
         ''}
 
@@ -137,10 +128,10 @@ runCommand
         linkEmacsPackage() {
           linkPath "$1" "bin" "bin"
           linkPath "$1" "share/emacs/site-lisp" "share/emacs/site-lisp"
-          ${optionalString nativeComp ''
+          ${lib.optionalString withNativeCompilation ''
             linkPath "$1" "share/emacs/native-lisp" "share/emacs/native-lisp"
           ''}
-          ${optionalString treeSitter ''
+          ${lib.optionalString withTreeSitter ''
             linkPath "$1" "lib" "lib"
           ''}
         }
@@ -171,10 +162,10 @@ runCommand
           (load-file "$emacs/share/emacs/site-lisp/site-start.el"))
         (add-to-list 'load-path "$out/share/emacs/site-lisp")
         (add-to-list 'exec-path "$out/bin")
-        ${optionalString nativeComp ''
+        ${lib.optionalString withNativeCompilation ''
           (add-to-list 'native-comp-eln-load-path "$out/share/emacs/native-lisp/")
         ''}
-        ${optionalString treeSitter ''
+        ${lib.optionalString withTreeSitter ''
           (add-to-list 'treesit-extra-load-path "$out/lib/")
         ''}
         EOF
@@ -189,7 +180,7 @@ runCommand
         # Byte-compiling improves start-up time only slightly, but costs nothing.
         $emacs/bin/emacs --batch -f batch-byte-compile "$siteStart" "$subdirs"
 
-        ${optionalString nativeComp ''
+        ${lib.optionalString withNativeCompilation ''
           $emacs/bin/emacs --batch \
             --eval "(add-to-list 'native-comp-eln-load-path \"$out/share/emacs/native-lisp/\")" \
             -f batch-native-compile "$siteStart" "$subdirs"
diff --git a/nixpkgs/pkgs/build-support/fetch9front/default.nix b/nixpkgs/pkgs/build-support/fetch9front/default.nix
new file mode 100644
index 000000000000..677fee1decd7
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/fetch9front/default.nix
@@ -0,0 +1,36 @@
+{ fetchgit, fetchzip, lib }:
+
+lib.makeOverridable (
+  { owner
+  , repo
+  , rev
+  , domain ? "git.9front.org"
+  , name ? "source"
+  , leaveDotGit ? false
+  , deepClone ? false
+  , ... # For hash agility
+  } @ args:
+
+  let
+    passthruAttrs = removeAttrs args [ "domain" "owner" "repo" "rev" "leaveDotGit" "deepClone" ];
+
+    useFetchGit = leaveDotGit || deepClone;
+    fetcher = if useFetchGit then fetchgit else fetchzip;
+
+    gitRepoUrl = "git://${domain}/${owner}/${repo}";
+
+    fetcherArgs = (if useFetchGit then {
+      # git9 does not support shallow fetches
+      inherit rev leaveDotGit;
+      url = gitRepoUrl;
+    } else {
+      url = "https://${domain}/${owner}/${repo}/${rev}/snap.tar.gz";
+
+      passthru = {
+        inherit gitRepoUrl;
+      };
+    }) // passthruAttrs // { inherit name; };
+  in
+
+  fetcher fetcherArgs // { inherit rev; }
+)
diff --git a/nixpkgs/pkgs/build-support/fetchdarcs/default.nix b/nixpkgs/pkgs/build-support/fetchdarcs/default.nix
index 9ab57d5c05ea..6073efec2815 100644
--- a/nixpkgs/pkgs/build-support/fetchdarcs/default.nix
+++ b/nixpkgs/pkgs/build-support/fetchdarcs/default.nix
@@ -4,14 +4,10 @@ lib.makeOverridable (
 { url
 , rev ? null
 , context ? null
-, md5 ? ""
 , sha256 ? ""
 , name ? "fetchdarcs"
 }:
 
-if md5 != "" then
-  throw "fetchdarcs does not support md5 anymore, please use sha256"
-else
 stdenvNoCC.mkDerivation {
   builder = ./builder.sh;
   nativeBuildInputs = [cacert darcs];
diff --git a/nixpkgs/pkgs/build-support/fetchfirefoxaddon/default.nix b/nixpkgs/pkgs/build-support/fetchfirefoxaddon/default.nix
index fe9ff5c469ba..e07a6a1a79dd 100644
--- a/nixpkgs/pkgs/build-support/fetchfirefoxaddon/default.nix
+++ b/nixpkgs/pkgs/build-support/fetchfirefoxaddon/default.nix
@@ -1,9 +1,14 @@
-{stdenv, unzip, jq, zip, fetchurl,writeScript,  ...}:
+{ stdenv
+, fetchurl
+, jq
+, strip-nondeterminism
+, unzip
+, writeScript
+, zip
+}:
 
-{
-  name
+{ name
 , url ? null
-, md5 ? ""
 , sha1 ? ""
 , sha256 ? ""
 , sha512 ? ""
@@ -14,9 +19,10 @@
 
 let
   extid = if fixedExtid == null then "nixos@${name}" else fixedExtid;
-  source = if url == null then src else fetchurl {
+  source = if url == null then src else
+  fetchurl {
     url = url;
-    inherit md5 sha1 sha256 sha512 hash;
+    inherit sha1 sha256 sha512 hash;
   };
 in
 stdenv.mkDerivation {
@@ -38,7 +44,14 @@ stdenv.mkDerivation {
     echo "$NEW_MANIFEST" > "$out/$UUID/manifest.json"
     cd "$out/$UUID"
     zip -r -q -FS "$out/$UUID.xpi" *
+    strip-nondeterminism "$out/$UUID.xpi"
     rm -r "$out/$UUID"
   '';
-  nativeBuildInputs = [ unzip zip jq  ];
+
+  nativeBuildInputs = [
+    jq
+    strip-nondeterminism
+    unzip
+    zip
+  ];
 }
diff --git a/nixpkgs/pkgs/build-support/fetchgit/default.nix b/nixpkgs/pkgs/build-support/fetchgit/default.nix
index 3d73eae9821e..1d06ce44a91e 100644
--- a/nixpkgs/pkgs/build-support/fetchgit/default.nix
+++ b/nixpkgs/pkgs/build-support/fetchgit/default.nix
@@ -11,7 +11,7 @@
   in "${if matched == null then base else builtins.head matched}${appendShort}";
 in
 lib.makeOverridable (
-{ url, rev ? "HEAD", md5 ? "", sha256 ? "", hash ? "", leaveDotGit ? deepClone
+{ url, rev ? "HEAD", sha256 ? "", hash ? "", leaveDotGit ? deepClone
 , fetchSubmodules ? true, deepClone ? false
 , branchName ? null
 , sparseCheckout ? []
@@ -56,9 +56,7 @@ lib.makeOverridable (
 assert deepClone -> leaveDotGit;
 assert nonConeMode -> (sparseCheckout != []);
 
-if md5 != "" then
-  throw "fetchgit does not support md5 anymore, please use sha256"
-else if hash != "" && sha256 != "" then
+if hash != "" && sha256 != "" then
   throw "Only one of sha256 or hash can be set"
 else if builtins.isString sparseCheckout then
   # Changed to throw on 2023-06-04
diff --git a/nixpkgs/pkgs/build-support/fetchgit/nix-prefetch-git b/nixpkgs/pkgs/build-support/fetchgit/nix-prefetch-git
index ba2dfa2fb2c4..79ab699bcc25 100755
--- a/nixpkgs/pkgs/build-support/fetchgit/nix-prefetch-git
+++ b/nixpkgs/pkgs/build-support/fetchgit/nix-prefetch-git
@@ -206,27 +206,7 @@ checkout_ref(){
 
 # Update submodules
 init_submodules(){
-    # Add urls into .git/config file
-    clean_git submodule init
-
-    # list submodule directories and their hashes
-    git submodule status |
-    while read -r l; do
-        local hash
-        local dir
-        local name
-        local url
-
-        # checkout each submodule
-        hash=$(echo "$l" | awk '{print $1}' | tr -d '-')
-        dir=$(echo "$l" | sed -n 's/^.[0-9a-f]\+ \(.*[^)]*\)\( (.*)\)\?$/\1/p')
-        name=$(
-            git config -f .gitmodules --get-regexp submodule\..*\.path |
-            sed -n "s,^\(.*\)\.path $dir\$,\\1,p")
-        url=$(git config --get "${name}.url")
-
-        clone "$dir" "$url" "$hash" ""
-    done
+    clean_git submodule update --init --recursive -j ${NIX_BUILD_CORES:-1}
 }
 
 clone(){
@@ -410,6 +390,7 @@ print_results() {
   "date": "$(json_escape "$commitDateStrict8601")",
   "path": "$(json_escape "$finalPath")",
   "$(json_escape "$hashType")": "$(json_escape "$hash")",
+  "hash": "$(nix-hash --to-sri --type $hashType $hash)",
   "fetchLFS": $([[ -n "$fetchLFS" ]] && echo true || echo false),
   "fetchSubmodules": $([[ -n "$fetchSubmodules" ]] && echo true || echo false),
   "deepClone": $([[ -n "$deepClone" ]] && echo true || echo false),
diff --git a/nixpkgs/pkgs/build-support/fetchgithub/default.nix b/nixpkgs/pkgs/build-support/fetchgithub/default.nix
index faa338b672f0..a2498700b545 100644
--- a/nixpkgs/pkgs/build-support/fetchgithub/default.nix
+++ b/nixpkgs/pkgs/build-support/fetchgithub/default.nix
@@ -24,7 +24,7 @@ let
     position = "${position.file}:${toString position.line}";
   };
   passthruAttrs = removeAttrs args [ "owner" "repo" "rev" "fetchSubmodules" "forceFetchGit" "private" "githubBase" "varPrefix" ];
-  varBase = "NIX${if varPrefix == null then "" else "_${varPrefix}"}_GITHUB_PRIVATE_";
+  varBase = "NIX${lib.optionalString (varPrefix != null) "_${varPrefix}"}_GITHUB_PRIVATE_";
   useFetchGit = fetchSubmodules || (leaveDotGit == true) || deepClone || forceFetchGit || (sparseCheckout != []);
   # We prefer fetchzip in cases we don't need submodules as the hash
   # is more stable in that case.
diff --git a/nixpkgs/pkgs/build-support/fetchhg/default.nix b/nixpkgs/pkgs/build-support/fetchhg/default.nix
index a5817f2c3050..6af886bf0934 100644
--- a/nixpkgs/pkgs/build-support/fetchhg/default.nix
+++ b/nixpkgs/pkgs/build-support/fetchhg/default.nix
@@ -2,15 +2,12 @@
 { name ? null
 , url
 , rev ? null
-, md5 ? null
 , sha256 ? null
 , hash ? null
 , fetchSubrepos ? false
 , preferLocalBuild ? true }:
 
-if md5 != null then
-  throw "fetchhg does not support md5 anymore, please use sha256 or hash"
-else if hash != null && sha256 != null then
+if hash != null && sha256 != null then
   throw "Only one of sha256 or hash can be set"
 else
 # TODO: statically check if mercurial as the https support if the url starts woth https.
diff --git a/nixpkgs/pkgs/build-support/fetchpijul/default.nix b/nixpkgs/pkgs/build-support/fetchpijul/default.nix
new file mode 100644
index 000000000000..ca7e1a7926e8
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/fetchpijul/default.nix
@@ -0,0 +1,56 @@
+{ lib, stdenvNoCC, pijul }:
+
+lib.makeOverridable (
+{ url
+, hash ? ""
+, change ? null
+, state ? null
+, channel ? "main"
+, name ? "fetchpijul"
+, # TODO: Changes in pijul are unordered so there's many ways to end up with the same repository state.
+  # This makes leaveDotPijul unfeasible to implement until pijul CLI implements
+  # a way of reordering changes to sort them in a consistent and deterministic manner.
+  # leaveDotPijul ? false
+}:
+if change != null && state != null then
+  throw "Only one of 'change' or 'state' can be set"
+else
+  stdenvNoCC.mkDerivation {
+    inherit name;
+    nativeBuildInputs = [ pijul ];
+
+    dontUnpack = true;
+    dontConfigure = true;
+    dontBuild = true;
+
+    installPhase = ''
+      runHook preInstall
+
+      pijul clone \
+        ''${change:+--change "$change"} \
+        ''${state:+--state "$state"} \
+        --channel "$channel" \
+        "$url" \
+        "$out"
+
+      runHook postInstall
+    '';
+
+    fixupPhase = ''
+      runHook preFixup
+
+      rm -rf "$out/.pijul"
+
+      runHook postFixup
+    '';
+
+    outputHashAlgo = if hash != "" then null else "sha256";
+    outputHashMode = "recursive";
+    outputHash = if hash != "" then
+      hash
+    else
+      lib.fakeSha256;
+
+    inherit url change state channel;
+  }
+)
diff --git a/nixpkgs/pkgs/build-support/fetchrepoproject/default.nix b/nixpkgs/pkgs/build-support/fetchrepoproject/default.nix
index 69b1bd1aef74..78b8caeb8091 100644
--- a/nixpkgs/pkgs/build-support/fetchrepoproject/default.nix
+++ b/nixpkgs/pkgs/build-support/fetchrepoproject/default.nix
@@ -60,7 +60,7 @@ in stdenvNoCC.mkDerivation {
     ${optionalString (local_manifests != []) ''
       mkdir .repo/local_manifests
       for local_manifest in ${concatMapStringsSep " " toString local_manifests}; do
-        cp $local_manifest .repo/local_manifests/$(stripHash $local_manifest; echo $strippedName)
+        cp $local_manifest .repo/local_manifests/$(stripHash $local_manifest)
       done
     ''}
 
diff --git a/nixpkgs/pkgs/build-support/fetchsvn/default.nix b/nixpkgs/pkgs/build-support/fetchsvn/default.nix
index 82dececc124a..41752eb55a7a 100644
--- a/nixpkgs/pkgs/build-support/fetchsvn/default.nix
+++ b/nixpkgs/pkgs/build-support/fetchsvn/default.nix
@@ -2,7 +2,7 @@
 , subversion, glibcLocales, sshSupport ? true, openssh ? null
 }:
 
-{ url, rev ? "HEAD", md5 ? "", sha256 ? ""
+{ url, rev ? "HEAD", sha256 ? "", hash ? ""
 , ignoreExternals ? false, ignoreKeywords ? false, name ? null
 , preferLocalBuild ? true
 }:
@@ -32,8 +32,8 @@ let
   name_ = if name == null then "${repoName}-r${toString rev}" else name;
 in
 
-if md5 != "" then
-  throw "fetchsvn does not support md5 anymore, please use sha256"
+if hash != "" && sha256 != "" then
+  throw "Only one of sha256 or hash can be set"
 else
 stdenvNoCC.mkDerivation {
   name = name_;
@@ -43,9 +43,14 @@ stdenvNoCC.mkDerivation {
 
   SVN_SSH = if sshSupport then "${buildPackages.openssh}/bin/ssh" else null;
 
-  outputHashAlgo = "sha256";
+  outputHashAlgo = if hash != "" then null else "sha256";
   outputHashMode = "recursive";
-  outputHash = sha256;
+  outputHash = if hash != "" then
+    hash
+  else if sha256 != "" then
+    sha256
+  else
+    lib.fakeSha256;
 
   inherit url rev ignoreExternals ignoreKeywords;
 
diff --git a/nixpkgs/pkgs/build-support/fetchsvnssh/default.nix b/nixpkgs/pkgs/build-support/fetchsvnssh/default.nix
index fbd74efd750a..ef72de61fe21 100644
--- a/nixpkgs/pkgs/build-support/fetchsvnssh/default.nix
+++ b/nixpkgs/pkgs/build-support/fetchsvnssh/default.nix
@@ -1,10 +1,7 @@
 {stdenvNoCC, subversion, sshSupport ? true, openssh ? null, expect}:
-{username, password, url, rev ? "HEAD", md5 ? "", sha256 ? ""}:
+{username, password, url, rev ? "HEAD", sha256 ? ""}:
 
 
-if md5 != "" then
-  throw "fetchsvnssh does not support md5 anymore, please use sha256"
-else
 stdenvNoCC.mkDerivation {
   name = "svn-export-ssh";
   builder = ./builder.sh;
diff --git a/nixpkgs/pkgs/build-support/fetchurl/default.nix b/nixpkgs/pkgs/build-support/fetchurl/default.nix
index 28d2519f4232..bcab54e273dc 100644
--- a/nixpkgs/pkgs/build-support/fetchurl/default.nix
+++ b/nixpkgs/pkgs/build-support/fetchurl/default.nix
@@ -67,7 +67,6 @@ in
 , # Legacy ways of specifying the hash.
   outputHash ? ""
 , outputHashAlgo ? ""
-, md5 ? ""
 , sha1 ? ""
 , sha256 ? ""
 , sha512 ? ""
@@ -125,7 +124,6 @@ let
     if hash != "" && sha256 != "" then throw "multiple hashes passed to fetchurl" else
 
     if hash != "" then { outputHashAlgo = null; outputHash = hash; }
-    else if md5 != "" then throw "fetchurl does not support md5 anymore, please use sha256 or sha512"
     else if (outputHash != "" && outputHashAlgo != "") then { inherit outputHashAlgo outputHash; }
     else if sha512 != "" then { outputHashAlgo = "sha512"; outputHash = sha512; }
     else if sha256 != "" then { outputHashAlgo = "sha256"; outputHash = sha256; }
diff --git a/nixpkgs/pkgs/build-support/fetchurl/mirrors.nix b/nixpkgs/pkgs/build-support/fetchurl/mirrors.nix
index 2f12be0a897d..2546b8e6dc99 100644
--- a/nixpkgs/pkgs/build-support/fetchurl/mirrors.nix
+++ b/nixpkgs/pkgs/build-support/fetchurl/mirrors.nix
@@ -175,12 +175,6 @@
     "https://download.qt.io/"
   ];
 
-  # Roy marples mirrors
-  roy = [
-    "https://roy.marples.name/downloads/"
-    "https://cflags.cc/roy/"
-  ];
-
   # Sage mirrors (https://www.sagemath.org/mirrors.html)
   sageupstream = [
     # Africa (HTTPS)
diff --git a/nixpkgs/pkgs/build-support/go/module.nix b/nixpkgs/pkgs/build-support/go/module.nix
index 683c28c469fb..bb48315dc4f8 100644
--- a/nixpkgs/pkgs/build-support/go/module.nix
+++ b/nixpkgs/pkgs/build-support/go/module.nix
@@ -8,7 +8,7 @@ let
     , passthru ? { }
     , patches ? [ ]
 
-      # A function to override the go-modules derivation
+      # A function to override the goModules derivation
     , overrideModAttrs ? (_oldAttrs: { })
 
       # path to go.mod and go.sum directory
@@ -54,7 +54,7 @@ let
     let
       args = removeAttrs args' [ "overrideModAttrs" "vendorSha256" "vendorHash" ];
 
-      go-modules = if (vendorHash == null) then "" else
+      goModules = if (vendorHash == null) then "" else
       (stdenv.mkDerivation {
         name = "${name}-go-modules";
 
@@ -165,10 +165,10 @@ let
           cd "$modRoot"
         '' + lib.optionalString (vendorHash != null) ''
           ${if proxyVendor then ''
-            export GOPROXY=file://${go-modules}
+            export GOPROXY=file://${goModules}
           '' else ''
             rm -rf vendor
-            cp -r --reflink=auto ${go-modules} vendor
+            cp -r --reflink=auto ${goModules} vendor
           ''}
         '' + ''
 
@@ -290,7 +290,7 @@ let
 
         disallowedReferences = lib.optional (!allowGoReference) go;
 
-        passthru = passthru // { inherit go go-modules vendorHash; } // { inherit (args') vendorSha256; };
+        passthru = passthru // { inherit go goModules vendorHash; } // { inherit (args') vendorSha256; };
 
         meta = {
           # Add default meta information
diff --git a/nixpkgs/pkgs/build-support/kernel/compress-firmware-xz.nix b/nixpkgs/pkgs/build-support/kernel/compress-firmware-xz.nix
index 6a797226aa67..cfb06a5c0f15 100644
--- a/nixpkgs/pkgs/build-support/kernel/compress-firmware-xz.nix
+++ b/nixpkgs/pkgs/build-support/kernel/compress-firmware-xz.nix
@@ -1,8 +1,12 @@
-{ runCommand }:
+{ runCommand, lib }:
 
 firmware:
 
-runCommand "${firmware.name}-xz" {} ''
+let
+  args = lib.optionalAttrs (firmware ? meta) { inherit (firmware) meta; };
+in
+
+runCommand "${firmware.name}-xz" args ''
   mkdir -p $out/lib
   (cd ${firmware} && find lib/firmware -type d -print0) |
       (cd $out && xargs -0 mkdir -v --)
diff --git a/nixpkgs/pkgs/build-support/kernel/make-initrd-ng.nix b/nixpkgs/pkgs/build-support/kernel/make-initrd-ng.nix
index f3cf3d59f92b..2418838176ef 100644
--- a/nixpkgs/pkgs/build-support/kernel/make-initrd-ng.nix
+++ b/nixpkgs/pkgs/build-support/kernel/make-initrd-ng.nix
@@ -72,7 +72,7 @@ in
   ${if makeUInitrd then "uInitrdCompression" else null} = uInitrdCompression;
 
   passAsFile = ["contents"];
-  contents = lib.concatMapStringsSep "\n" ({ object, symlink, ... }: "${object}\n${if symlink == null then "" else symlink}") contents + "\n";
+  contents = lib.concatMapStringsSep "\n" ({ object, symlink, ... }: "${object}\n${lib.optionalString (symlink != null) symlink}") contents + "\n";
 
   nativeBuildInputs = [makeInitrdNGTool cpio] ++ lib.optional makeUInitrd ubootTools ++ lib.optional strip binutils;
 
diff --git a/nixpkgs/pkgs/build-support/nix-gitignore/default.nix b/nixpkgs/pkgs/build-support/nix-gitignore/default.nix
index d55465302e44..c047bfc7d9a2 100644
--- a/nixpkgs/pkgs/build-support/nix-gitignore/default.nix
+++ b/nixpkgs/pkgs/build-support/nix-gitignore/default.nix
@@ -45,7 +45,7 @@ in rec {
           escs = "\\*?";
           splitString =
             let recurse = str : [(substring 0 1 str)] ++
-                                 (if str == "" then [] else (recurse (substring 1 (stringLength(str)) str) ));
+                                 (lib.optionals (str != "") (recurse (substring 1 (stringLength(str)) str) ));
             in str : recurse str;
           chars = s: filter (c: c != "" && !isList c) (splitString s);
           escape = s: map (c: "\\" + c) (chars s);
@@ -66,7 +66,7 @@ in rec {
       handleSlashPrefix = l:
         let
           split = (match "^(/?)(.*)" l);
-          findSlash = l: if (match ".+/.+" l) != null then "" else l;
+          findSlash = l: lib.optionalString ((match ".+/.+" l) == null) l;
           hasSlash = mapAroundCharclass findSlash l != l;
         in
           (if (elemAt split 0) == "/" || hasSlash
diff --git a/nixpkgs/pkgs/build-support/node/build-npm-package/default.nix b/nixpkgs/pkgs/build-support/node/build-npm-package/default.nix
index 1c3fb6a74efc..0a988cbbaf3f 100644
--- a/nixpkgs/pkgs/build-support/node/build-npm-package/default.nix
+++ b/nixpkgs/pkgs/build-support/node/build-npm-package/default.nix
@@ -22,7 +22,7 @@
 , npmBuildScript ? "build"
   # Flags to pass to all npm commands.
 , npmFlags ? [ ]
-  # Flags to pass to `npm ci` and `npm prune`.
+  # Flags to pass to `npm ci`.
 , npmInstallFlags ? [ ]
   # Flags to pass to `npm rebuild`.
 , npmRebuildFlags ? [ ]
@@ -30,6 +30,10 @@
 , npmBuildFlags ? [ ]
   # Flags to pass to `npm pack`.
 , npmPackFlags ? [ ]
+  # Flags to pass to `npm prune`.
+, npmPruneFlags ? npmInstallFlags
+  # Value for npm `--workspace` flag and directory in which the files to be installed are found.
+, npmWorkspace ? null
 , ...
 } @ args:
 
@@ -53,7 +57,5 @@ stdenv.mkDerivation (args // {
   # Stripping takes way too long with the amount of files required by a typical Node.js project.
   dontStrip = args.dontStrip or true;
 
-  passthru = { inherit npmDeps; } // (args.passthru or { });
-
   meta = (args.meta or { }) // { platforms = args.meta.platforms or nodejs.meta.platforms; };
 })
diff --git a/nixpkgs/pkgs/build-support/node/build-npm-package/hooks/npm-build-hook.sh b/nixpkgs/pkgs/build-support/node/build-npm-package/hooks/npm-build-hook.sh
index b712e3a0543a..c341f672363a 100644
--- a/nixpkgs/pkgs/build-support/node/build-npm-package/hooks/npm-build-hook.sh
+++ b/nixpkgs/pkgs/build-support/node/build-npm-package/hooks/npm-build-hook.sh
@@ -14,7 +14,7 @@ npmBuildHook() {
         exit 1
     fi
 
-    if ! npm run "$npmBuildScript" $npmBuildFlags "${npmBuildFlagsArray[@]}" $npmFlags "${npmFlagsArray[@]}"; then
+    if ! npm run ${npmWorkspace+--workspace=$npmWorkspace} "$npmBuildScript" $npmBuildFlags "${npmBuildFlagsArray[@]}" $npmFlags "${npmFlagsArray[@]}"; then
         echo
         echo 'ERROR: `npm build` failed'
         echo
diff --git a/nixpkgs/pkgs/build-support/node/build-npm-package/hooks/npm-install-hook.sh b/nixpkgs/pkgs/build-support/node/build-npm-package/hooks/npm-install-hook.sh
index 4282419d5d6b..b17fb552cc6b 100644
--- a/nixpkgs/pkgs/build-support/node/build-npm-package/hooks/npm-install-hook.sh
+++ b/nixpkgs/pkgs/build-support/node/build-npm-package/hooks/npm-install-hook.sh
@@ -13,8 +13,8 @@ npmInstallHook() {
     while IFS= read -r file; do
         local dest="$packageOut/$(dirname "$file")"
         mkdir -p "$dest"
-        cp "$file" "$dest"
-    done < <(@jq@ --raw-output '.[0].files | map(.path) | join("\n")' <<< "$(npm pack --json --dry-run $npmPackFlags "${npmPackFlagsArray[@]}" $npmFlags "${npmFlagsArray[@]}")")
+        cp "${npmWorkspace-.}/$file" "$dest"
+    done < <(@jq@ --raw-output '.[0].files | map(.path) | join("\n")' <<< "$(npm pack --json --dry-run ${npmWorkspace+--workspace=$npmWorkspace} $npmPackFlags "${npmPackFlagsArray[@]}" $npmFlags "${npmFlagsArray[@]}")")
 
     while IFS=" " read -ra bin; do
         mkdir -p "$out/bin"
@@ -22,13 +22,13 @@ npmInstallHook() {
     done < <(@jq@ --raw-output '(.bin | type) as $typ | if $typ == "string" then
         .name + " " + .bin
         elif $typ == "object" then .bin | to_entries | map(.key + " " + .value) | join("\n")
-        else "invalid type " + $typ | halt_error end' package.json)
+        else "invalid type " + $typ | halt_error end' "${npmWorkspace-.}/package.json")
 
     local -r nodeModulesPath="$packageOut/node_modules"
 
     if [ ! -d "$nodeModulesPath" ]; then
         if [ -z "${dontNpmPrune-}" ]; then
-            npm prune --omit dev --no-save $npmInstallFlags "${npmInstallFlagsArray[@]}" $npmFlags "${npmFlagsArray[@]}"
+            npm prune --omit=dev --no-save ${npmWorkspace+--workspace=$npmWorkspace} $npmPruneFlags "${npmPruneFlagsArray[@]}" $npmFlags "${npmFlagsArray[@]}"
         fi
 
         find node_modules -maxdepth 1 -type d -empty -delete
diff --git a/nixpkgs/pkgs/build-support/node/fetch-npm-deps/Cargo.lock b/nixpkgs/pkgs/build-support/node/fetch-npm-deps/Cargo.lock
index ff636e7e5961..482eb6c7beab 100644
--- a/nixpkgs/pkgs/build-support/node/fetch-npm-deps/Cargo.lock
+++ b/nixpkgs/pkgs/build-support/node/fetch-npm-deps/Cargo.lock
@@ -3,16 +3,30 @@
 version = 3
 
 [[package]]
-name = "adler"
+name = "aho-corasick"
 version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41"
+dependencies = [
+ "memchr",
+]
 
 [[package]]
 name = "anyhow"
-version = "1.0.65"
+version = "1.0.71"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
+
+[[package]]
+name = "async-channel"
+version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602"
+checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833"
+dependencies = [
+ "concurrent-queue",
+ "event-listener",
+ "futures-core",
+]
 
 [[package]]
 name = "autocfg"
@@ -21,10 +35,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
 
 [[package]]
+name = "backoff"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1"
+dependencies = [
+ "getrandom",
+ "instant",
+ "rand",
+]
+
+[[package]]
 name = "base64"
-version = "0.13.0"
+version = "0.21.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
+checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d"
 
 [[package]]
 name = "bitflags"
@@ -33,25 +58,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
 [[package]]
+name = "bitflags"
+version = "2.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42"
+
+[[package]]
 name = "block-buffer"
-version = "0.10.2"
+version = "0.10.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
 dependencies = [
  "generic-array",
 ]
 
 [[package]]
-name = "bumpalo"
-version = "3.11.0"
+name = "bytes"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
+
+[[package]]
+name = "castaway"
+version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d"
+checksum = "a2698f953def977c68f935bb0dfa959375ad4638570e969e2f1e9f433cbf1af6"
 
 [[package]]
 name = "cc"
-version = "1.0.73"
+version = "1.0.79"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
+checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
 
 [[package]]
 name = "cfg-if"
@@ -60,34 +97,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
-name = "chunked_transfer"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e"
-
-[[package]]
-name = "cpufeatures"
-version = "0.2.4"
+name = "concurrent-queue"
+version = "2.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc948ebb96241bb40ab73effeb80d9f93afaad49359d159a5e61be51619fe813"
+checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c"
 dependencies = [
- "libc",
+ "crossbeam-utils",
 ]
 
 [[package]]
-name = "crc32fast"
-version = "1.3.2"
+name = "cpufeatures"
+version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
+checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c"
 dependencies = [
- "cfg-if",
+ "libc",
 ]
 
 [[package]]
 name = "crossbeam-channel"
-version = "0.5.6"
+version = "0.5.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
+checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
 dependencies = [
  "cfg-if",
  "crossbeam-utils",
@@ -95,9 +126,9 @@ dependencies = [
 
 [[package]]
 name = "crossbeam-deque"
-version = "0.8.2"
+version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
+checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
 dependencies = [
  "cfg-if",
  "crossbeam-epoch",
@@ -106,26 +137,24 @@ dependencies = [
 
 [[package]]
 name = "crossbeam-epoch"
-version = "0.9.10"
+version = "0.9.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1"
+checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7"
 dependencies = [
  "autocfg",
  "cfg-if",
  "crossbeam-utils",
  "memoffset",
- "once_cell",
  "scopeguard",
 ]
 
 [[package]]
 name = "crossbeam-utils"
-version = "0.8.11"
+version = "0.8.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc"
+checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
 dependencies = [
  "cfg-if",
- "once_cell",
 ]
 
 [[package]]
@@ -139,10 +168,40 @@ dependencies = [
 ]
 
 [[package]]
+name = "curl"
+version = "0.4.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22"
+dependencies = [
+ "curl-sys",
+ "libc",
+ "openssl-probe",
+ "openssl-sys",
+ "schannel",
+ "socket2",
+ "winapi",
+]
+
+[[package]]
+name = "curl-sys"
+version = "0.4.63+curl-8.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aeb0fef7046022a1e2ad67a004978f0e3cacb9e3123dc62ce768f92197b771dc"
+dependencies = [
+ "cc",
+ "libc",
+ "libz-sys",
+ "openssl-sys",
+ "pkg-config",
+ "vcpkg",
+ "winapi",
+]
+
+[[package]]
 name = "digest"
-version = "0.10.5"
+version = "0.10.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
 dependencies = [
  "block-buffer",
  "crypto-common",
@@ -150,62 +209,150 @@ dependencies = [
 
 [[package]]
 name = "either"
-version = "1.8.0"
+version = "1.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
+checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
 
 [[package]]
-name = "fastrand"
-version = "1.8.0"
+name = "env_logger"
+version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
+checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0"
 dependencies = [
- "instant",
+ "humantime",
+ "is-terminal",
+ "log",
+ "regex",
+ "termcolor",
 ]
 
 [[package]]
-name = "flate2"
-version = "1.0.24"
+name = "errno"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6"
+checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
 dependencies = [
- "crc32fast",
- "miniz_oxide",
+ "errno-dragonfly",
+ "libc",
+ "windows-sys",
 ]
 
 [[package]]
+name = "errno-dragonfly"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
+name = "event-listener"
+version = "2.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
+
+[[package]]
+name = "fastrand"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
+dependencies = [
+ "instant",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
 name = "form_urlencoded"
-version = "1.1.0"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
+checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
 dependencies = [
  "percent-encoding",
 ]
 
 [[package]]
+name = "futures-core"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
+
+[[package]]
+name = "futures-io"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964"
+
+[[package]]
+name = "futures-lite"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce"
+dependencies = [
+ "fastrand",
+ "futures-core",
+ "futures-io",
+ "memchr",
+ "parking",
+ "pin-project-lite",
+ "waker-fn",
+]
+
+[[package]]
 name = "generic-array"
-version = "0.14.6"
+version = "0.14.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
 dependencies = [
  "typenum",
  "version_check",
 ]
 
 [[package]]
-name = "hermit-abi"
-version = "0.1.19"
+name = "getrandom"
+version = "0.2.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
 dependencies = [
+ "cfg-if",
  "libc",
+ "wasi",
 ]
 
 [[package]]
+name = "hermit-abi"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
+
+[[package]]
+name = "http"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482"
+dependencies = [
+ "bytes",
+ "fnv",
+ "itoa",
+]
+
+[[package]]
+name = "humantime"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
+
+[[package]]
 name = "idna"
-version = "0.3.0"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
+checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
 dependencies = [
  "unicode-bidi",
  "unicode-normalization",
@@ -221,128 +368,292 @@ dependencies = [
 ]
 
 [[package]]
-name = "itoa"
-version = "1.0.3"
+name = "io-lifetimes"
+version = "1.0.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
+checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "windows-sys",
+]
 
 [[package]]
-name = "js-sys"
-version = "0.3.59"
+name = "is-terminal"
+version = "0.4.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2"
+checksum = "24fddda5af7e54bf7da53067d6e802dbcc381d0a8eef629df528e3ebf68755cb"
 dependencies = [
- "wasm-bindgen",
+ "hermit-abi",
+ "rustix 0.38.2",
+ "windows-sys",
+]
+
+[[package]]
+name = "isahc"
+version = "1.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "334e04b4d781f436dc315cb1e7515bd96826426345d498149e4bde36b67f8ee9"
+dependencies = [
+ "async-channel",
+ "castaway",
+ "crossbeam-utils",
+ "curl",
+ "curl-sys",
+ "event-listener",
+ "futures-lite",
+ "http",
+ "log",
+ "once_cell",
+ "polling",
+ "slab",
+ "sluice",
+ "tracing",
+ "tracing-futures",
+ "url",
+ "waker-fn",
 ]
 
 [[package]]
+name = "itoa"
+version = "1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a"
+
+[[package]]
 name = "libc"
-version = "0.2.132"
+version = "0.2.147"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
+checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
 
 [[package]]
-name = "log"
-version = "0.4.17"
+name = "libz-sys"
+version = "1.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+checksum = "56ee889ecc9568871456d42f603d6a0ce59ff328d291063a45cbdf0036baf6db"
 dependencies = [
- "cfg-if",
+ "cc",
+ "libc",
+ "pkg-config",
+ "vcpkg",
 ]
 
 [[package]]
+name = "linux-raw-sys"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0"
+
+[[package]]
+name = "log"
+version = "0.4.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
+
+[[package]]
+name = "memchr"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+
+[[package]]
 name = "memoffset"
-version = "0.6.5"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
+checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
 dependencies = [
  "autocfg",
 ]
 
 [[package]]
-name = "miniz_oxide"
-version = "0.5.3"
+name = "num_cpus"
+version = "1.16.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc"
+checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
 dependencies = [
- "adler",
+ "hermit-abi",
+ "libc",
 ]
 
 [[package]]
-name = "num_cpus"
-version = "1.13.1"
+name = "once_cell"
+version = "1.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
+
+[[package]]
+name = "openssl-probe"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
+
+[[package]]
+name = "openssl-sys"
+version = "0.9.90"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
+checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6"
 dependencies = [
- "hermit-abi",
+ "cc",
  "libc",
+ "pkg-config",
+ "vcpkg",
 ]
 
 [[package]]
-name = "once_cell"
-version = "1.13.1"
+name = "parking"
+version = "2.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e"
+checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e"
 
 [[package]]
 name = "percent-encoding"
-version = "2.2.0"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
+
+[[package]]
+name = "pin-project"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842"
+dependencies = [
+ "pin-project-internal",
+]
+
+[[package]]
+name = "pin-project-internal"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
+checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57"
+
+[[package]]
+name = "pkg-config"
+version = "0.3.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
+
+[[package]]
+name = "polling"
+version = "2.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce"
+dependencies = [
+ "autocfg",
+ "bitflags 1.3.2",
+ "cfg-if",
+ "concurrent-queue",
+ "libc",
+ "log",
+ "pin-project-lite",
+ "windows-sys",
+]
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
 
 [[package]]
 name = "prefetch-npm-deps"
 version = "0.1.0"
 dependencies = [
  "anyhow",
+ "backoff",
  "base64",
  "digest",
+ "env_logger",
+ "isahc",
  "rayon",
  "serde",
  "serde_json",
  "sha1",
  "sha2",
  "tempfile",
- "ureq",
  "url",
  "walkdir",
 ]
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.43"
+version = "1.0.63"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
+checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb"
 dependencies = [
  "unicode-ident",
 ]
 
 [[package]]
 name = "quote"
-version = "1.0.21"
+version = "1.0.29"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
+checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105"
 dependencies = [
  "proc-macro2",
 ]
 
 [[package]]
+name = "rand"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+dependencies = [
+ "libc",
+ "rand_chacha",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+dependencies = [
+ "getrandom",
+]
+
+[[package]]
 name = "rayon"
-version = "1.5.3"
+version = "1.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d"
+checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b"
 dependencies = [
- "autocfg",
- "crossbeam-deque",
  "either",
  "rayon-core",
 ]
 
 [[package]]
 name = "rayon-core"
-version = "1.9.3"
+version = "1.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f"
+checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d"
 dependencies = [
  "crossbeam-channel",
  "crossbeam-deque",
@@ -352,54 +663,62 @@ dependencies = [
 
 [[package]]
 name = "redox_syscall"
-version = "0.2.16"
+version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
+checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
 dependencies = [
- "bitflags",
+ "bitflags 1.3.2",
 ]
 
 [[package]]
-name = "remove_dir_all"
-version = "0.5.3"
+name = "regex"
+version = "1.8.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
+checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f"
 dependencies = [
- "winapi",
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
 ]
 
 [[package]]
-name = "ring"
-version = "0.16.20"
+name = "regex-syntax"
+version = "0.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
+checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
+
+[[package]]
+name = "rustix"
+version = "0.37.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8818fa822adcc98b18fedbb3632a6a33213c070556b5aa7c4c8cc21cff565c4c"
 dependencies = [
- "cc",
+ "bitflags 1.3.2",
+ "errno",
+ "io-lifetimes",
  "libc",
- "once_cell",
- "spin",
- "untrusted",
- "web-sys",
- "winapi",
+ "linux-raw-sys 0.3.8",
+ "windows-sys",
 ]
 
 [[package]]
-name = "rustls"
-version = "0.20.6"
+name = "rustix"
+version = "0.38.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033"
+checksum = "aabcb0461ebd01d6b79945797c27f8529082226cb630a9865a71870ff63532a4"
 dependencies = [
- "log",
- "ring",
- "sct",
- "webpki",
+ "bitflags 2.3.3",
+ "errno",
+ "libc",
+ "linux-raw-sys 0.4.3",
+ "windows-sys",
 ]
 
 [[package]]
 name = "ryu"
-version = "1.0.11"
+version = "1.0.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
+checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9"
 
 [[package]]
 name = "same-file"
@@ -411,35 +730,34 @@ dependencies = [
 ]
 
 [[package]]
-name = "scopeguard"
-version = "1.1.0"
+name = "schannel"
+version = "0.1.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88"
+dependencies = [
+ "windows-sys",
+]
 
 [[package]]
-name = "sct"
-version = "0.7.0"
+name = "scopeguard"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
-dependencies = [
- "ring",
- "untrusted",
-]
+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
 
 [[package]]
 name = "serde"
-version = "1.0.145"
+version = "1.0.166"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b"
+checksum = "d01b7404f9d441d3ad40e6a636a7782c377d2abdbe4fa2440e2edcc2f4f10db8"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.145"
+version = "1.0.166"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c"
+checksum = "5dd83d6dde2b6b2d466e14d9d1acce8816dedee94f735eac6395808b3483c6d6"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -448,9 +766,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.85"
+version = "1.0.99"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44"
+checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3"
 dependencies = [
  "itoa",
  "ryu",
@@ -470,9 +788,9 @@ dependencies = [
 
 [[package]]
 name = "sha2"
-version = "0.10.6"
+version = "0.10.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
+checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8"
 dependencies = [
  "cfg-if",
  "cpufeatures",
@@ -480,16 +798,40 @@ dependencies = [
 ]
 
 [[package]]
-name = "spin"
-version = "0.5.2"
+name = "slab"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "sluice"
+version = "0.5.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
+checksum = "6d7400c0eff44aa2fcb5e31a5f24ba9716ed90138769e4977a2ba6014ae63eb5"
+dependencies = [
+ "async-channel",
+ "futures-core",
+ "futures-io",
+]
+
+[[package]]
+name = "socket2"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
+dependencies = [
+ "libc",
+ "winapi",
+]
 
 [[package]]
 name = "syn"
-version = "1.0.99"
+version = "2.0.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
+checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -498,16 +840,25 @@ dependencies = [
 
 [[package]]
 name = "tempfile"
-version = "3.3.0"
+version = "3.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
+checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6"
 dependencies = [
+ "autocfg",
  "cfg-if",
  "fastrand",
- "libc",
  "redox_syscall",
- "remove_dir_all",
- "winapi",
+ "rustix 0.37.22",
+ "windows-sys",
+]
+
+[[package]]
+name = "termcolor"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
+dependencies = [
+ "winapi-util",
 ]
 
 [[package]]
@@ -521,65 +872,85 @@ dependencies = [
 
 [[package]]
 name = "tinyvec_macros"
-version = "0.1.0"
+version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
 
 [[package]]
-name = "typenum"
-version = "1.15.0"
+name = "tracing"
+version = "0.1.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
+checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
+dependencies = [
+ "cfg-if",
+ "log",
+ "pin-project-lite",
+ "tracing-attributes",
+ "tracing-core",
+]
 
 [[package]]
-name = "unicode-bidi"
-version = "0.3.8"
+name = "tracing-attributes"
+version = "0.1.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
+checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
 
 [[package]]
-name = "unicode-ident"
-version = "1.0.3"
+name = "tracing-core"
+version = "0.1.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf"
+checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a"
+dependencies = [
+ "once_cell",
+]
 
 [[package]]
-name = "unicode-normalization"
-version = "0.1.21"
+name = "tracing-futures"
+version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6"
+checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
 dependencies = [
- "tinyvec",
+ "pin-project",
+ "tracing",
 ]
 
 [[package]]
-name = "untrusted"
-version = "0.7.1"
+name = "typenum"
+version = "1.16.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
+checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
 
 [[package]]
-name = "ureq"
-version = "2.5.0"
+name = "unicode-bidi"
+version = "0.3.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b97acb4c28a254fd7a4aeec976c46a7fa404eac4d7c134b30c75144846d7cb8f"
+checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73"
+
+[[package]]
+name = "unicode-normalization"
+version = "0.1.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
 dependencies = [
- "base64",
- "chunked_transfer",
- "flate2",
- "log",
- "once_cell",
- "rustls",
- "url",
- "webpki",
- "webpki-roots",
+ "tinyvec",
 ]
 
 [[package]]
 name = "url"
-version = "2.3.1"
+version = "2.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
+checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"
 dependencies = [
  "form_urlencoded",
  "idna",
@@ -588,132 +959,132 @@ dependencies = [
 ]
 
 [[package]]
+name = "vcpkg"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
+
+[[package]]
 name = "version_check"
 version = "0.9.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
 
 [[package]]
+name = "waker-fn"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
+
+[[package]]
 name = "walkdir"
-version = "2.3.2"
+version = "2.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
+checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698"
 dependencies = [
  "same-file",
- "winapi",
  "winapi-util",
 ]
 
 [[package]]
-name = "wasm-bindgen"
-version = "0.2.82"
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d"
-dependencies = [
- "cfg-if",
- "wasm-bindgen-macro",
-]
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 
 [[package]]
-name = "wasm-bindgen-backend"
-version = "0.2.82"
+name = "winapi"
+version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
 dependencies = [
- "bumpalo",
- "log",
- "once_cell",
- "proc-macro2",
- "quote",
- "syn",
- "wasm-bindgen-shared",
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
 ]
 
 [[package]]
-name = "wasm-bindgen-macro"
-version = "0.2.82"
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602"
-dependencies = [
- "quote",
- "wasm-bindgen-macro-support",
-]
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
 
 [[package]]
-name = "wasm-bindgen-macro-support"
-version = "0.2.82"
+name = "winapi-util"
+version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
 dependencies = [
- "proc-macro2",
- "quote",
- "syn",
- "wasm-bindgen-backend",
- "wasm-bindgen-shared",
+ "winapi",
 ]
 
 [[package]]
-name = "wasm-bindgen-shared"
-version = "0.2.82"
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 
 [[package]]
-name = "web-sys"
-version = "0.3.59"
+name = "windows-sys"
+version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
 dependencies = [
- "js-sys",
- "wasm-bindgen",
+ "windows-targets",
 ]
 
 [[package]]
-name = "webpki"
-version = "0.22.0"
+name = "windows-targets"
+version = "0.48.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
+checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f"
 dependencies = [
- "ring",
- "untrusted",
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
 ]
 
 [[package]]
-name = "webpki-roots"
-version = "0.22.4"
+name = "windows_aarch64_gnullvm"
+version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1c760f0d366a6c24a02ed7816e23e691f5d92291f94d15e836006fd11b04daf"
-dependencies = [
- "webpki",
-]
+checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
 
 [[package]]
-name = "winapi"
-version = "0.3.9"
+name = "windows_aarch64_msvc"
+version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
-dependencies = [
- "winapi-i686-pc-windows-gnu",
- "winapi-x86_64-pc-windows-gnu",
-]
+checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
 
 [[package]]
-name = "winapi-i686-pc-windows-gnu"
-version = "0.4.0"
+name = "windows_i686_gnu"
+version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
 
 [[package]]
-name = "winapi-util"
-version = "0.1.5"
+name = "windows_i686_msvc"
+version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
-dependencies = [
- "winapi",
-]
+checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
 
 [[package]]
-name = "winapi-x86_64-pc-windows-gnu"
-version = "0.4.0"
+name = "windows_x86_64_gnu"
+version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
diff --git a/nixpkgs/pkgs/build-support/node/fetch-npm-deps/Cargo.toml b/nixpkgs/pkgs/build-support/node/fetch-npm-deps/Cargo.toml
index ebb631c0955a..41347b6c2cc3 100644
--- a/nixpkgs/pkgs/build-support/node/fetch-npm-deps/Cargo.toml
+++ b/nixpkgs/pkgs/build-support/node/fetch-npm-deps/Cargo.toml
@@ -6,15 +6,17 @@ edition = "2021"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-anyhow = "1.0.65"
-base64 = "0.13.0"
-digest = "0.10.5"
-rayon = "1.5.3"
-serde = { version = "1.0.145", features = ["derive"] }
-serde_json = "1.0.85"
+anyhow = "1.0.71"
+backoff = "0.4.0"
+base64 = "0.21.2"
+digest = "0.10.7"
+env_logger = "0.10.0"
+isahc = { version = "1.7.2", default_features = false }
+rayon = "1.7.0"
+serde = { version = "1.0.164", features = ["derive"] }
+serde_json = "1.0.99"
 sha1 = "0.10.5"
-sha2 = "0.10.6"
-tempfile = "3.3.0"
-ureq = { version = "2.5.0" }
-url = { version = "2.3.1", features = ["serde"] }
-walkdir = "2.3.2"
+sha2 = "0.10.7"
+tempfile = "3.6.0"
+url = { version = "2.4.0", features = ["serde"] }
+walkdir = "2.3.3"
diff --git a/nixpkgs/pkgs/build-support/node/fetch-npm-deps/default.nix b/nixpkgs/pkgs/build-support/node/fetch-npm-deps/default.nix
index 41cad9d12ee6..ac76758ba50e 100644
--- a/nixpkgs/pkgs/build-support/node/fetch-npm-deps/default.nix
+++ b/nixpkgs/pkgs/build-support/node/fetch-npm-deps/default.nix
@@ -1,4 +1,4 @@
-{ lib, stdenvNoCC, rustPlatform, makeWrapper, Security, gnutar, gzip, nix, testers, fetchurl, prefetch-npm-deps, fetchNpmDeps }:
+{ lib, stdenvNoCC, rustPlatform, makeWrapper, pkg-config, curl, gnutar, gzip, nix, testers, fetchurl, cacert, prefetch-npm-deps, fetchNpmDeps }:
 
 {
   prefetch-npm-deps = rustPlatform.buildRustPackage {
@@ -16,8 +16,8 @@
 
     cargoLock.lockFile = ./Cargo.lock;
 
-    nativeBuildInputs = [ makeWrapper ];
-    buildInputs = lib.optional stdenvNoCC.isDarwin Security;
+    nativeBuildInputs = [ makeWrapper pkg-config ];
+    buildInputs = [ curl ];
 
     postInstall = ''
       wrapProgram "$out/bin/prefetch-npm-deps" --prefix PATH : ${lib.makeBinPath [ gnutar gzip nix ]}
@@ -115,7 +115,7 @@
 
     meta = with lib; {
       description = "Prefetch dependencies from npm (for use with `fetchNpmDeps`)";
-      maintainers = with maintainers; [ winter ];
+      maintainers = with maintainers; [ lilyinstarlight winter ];
       license = licenses.mit;
     };
   };
@@ -165,6 +165,12 @@
 
       dontInstall = true;
 
+      impureEnvVars = lib.fetchers.proxyImpureEnvVars;
+
+      SSL_CERT_FILE = if (hash_.outputHash == "" || hash_.outputHash == lib.fakeSha256 || hash_.outputHash == lib.fakeSha512 || hash_.outputHash == lib.fakeHash)
+        then "${cacert}/etc/ssl/certs/ca-bundle.crt"
+        else "/no-cert-file.crt";
+
       outputHashMode = "recursive";
     } // hash_ // forceGitDeps_);
 }
diff --git a/nixpkgs/pkgs/build-support/node/fetch-npm-deps/src/cacache.rs b/nixpkgs/pkgs/build-support/node/fetch-npm-deps/src/cacache.rs
index 3c49ef187021..b7efedac59bd 100644
--- a/nixpkgs/pkgs/build-support/node/fetch-npm-deps/src/cacache.rs
+++ b/nixpkgs/pkgs/build-support/node/fetch-npm-deps/src/cacache.rs
@@ -1,3 +1,4 @@
+use base64::prelude::{Engine, BASE64_STANDARD};
 use digest::{Digest, Update};
 use serde::{Deserialize, Serialize};
 use sha1::Sha1;
@@ -52,14 +53,14 @@ impl Cache {
         let (algo, hash, integrity) = if let Some(integrity) = integrity {
             let (algo, hash) = integrity.split_once('-').unwrap();
 
-            (algo.to_string(), base64::decode(hash)?, integrity)
+            (algo.to_string(), BASE64_STANDARD.decode(hash)?, integrity)
         } else {
             let hash = Sha512::new().chain(data).finalize();
 
             (
                 String::from("sha512"),
                 hash.to_vec(),
-                format!("sha512-{}", base64::encode(hash)),
+                format!("sha512-{}", BASE64_STANDARD.encode(hash)),
             )
         };
 
diff --git a/nixpkgs/pkgs/build-support/node/fetch-npm-deps/src/main.rs b/nixpkgs/pkgs/build-support/node/fetch-npm-deps/src/main.rs
index e6e44fc9d92e..62e5752c74c0 100644
--- a/nixpkgs/pkgs/build-support/node/fetch-npm-deps/src/main.rs
+++ b/nixpkgs/pkgs/build-support/node/fetch-npm-deps/src/main.rs
@@ -16,6 +16,7 @@ use walkdir::WalkDir;
 
 mod cacache;
 mod parse;
+mod util;
 
 fn cache_map_path() -> Option<PathBuf> {
     env::var_os("CACHE_MAP_PATH").map(PathBuf::from)
@@ -172,6 +173,8 @@ fn map_cache() -> anyhow::Result<HashMap<Url, String>> {
 }
 
 fn main() -> anyhow::Result<()> {
+    env_logger::init();
+
     let args = env::args().collect::<Vec<_>>();
 
     if args.len() < 2 {
@@ -182,6 +185,18 @@ fn main() -> anyhow::Result<()> {
         process::exit(1);
     }
 
+    if let Ok(jobs) = env::var("NIX_BUILD_CORES") {
+        if !jobs.is_empty() {
+            rayon::ThreadPoolBuilder::new()
+                .num_threads(
+                    jobs.parse()
+                        .expect("NIX_BUILD_CORES must be a whole number"),
+                )
+                .build_global()
+                .unwrap();
+        }
+    }
+
     if args[1] == "--fixup-lockfile" {
         let lock = serde_json::from_str(&fs::read_to_string(&args[2])?)?;
 
diff --git a/nixpkgs/pkgs/build-support/node/fetch-npm-deps/src/parse/mod.rs b/nixpkgs/pkgs/build-support/node/fetch-npm-deps/src/parse/mod.rs
index 3dd6b7da4978..e1b491cccea2 100644
--- a/nixpkgs/pkgs/build-support/node/fetch-npm-deps/src/parse/mod.rs
+++ b/nixpkgs/pkgs/build-support/node/fetch-npm-deps/src/parse/mod.rs
@@ -3,12 +3,15 @@ use lock::UrlOrString;
 use rayon::prelude::*;
 use serde_json::{Map, Value};
 use std::{
-    fs, io,
+    fs,
+    io::{self, Read},
     process::{Command, Stdio},
 };
 use tempfile::{tempdir, TempDir};
 use url::Url;
 
+use crate::util;
+
 pub mod lock;
 
 pub fn lockfile(content: &str, force_git_deps: bool) -> anyhow::Result<Vec<Package>> {
@@ -103,7 +106,7 @@ impl Package {
 
         let specifics = match get_hosted_git_url(&resolved)? {
             Some(hosted) => {
-                let mut body = ureq::get(hosted.as_str()).call()?.into_reader();
+                let mut body = util::get_url_with_retry(&hosted)?;
 
                 let workdir = tempdir()?;
 
@@ -154,10 +157,7 @@ impl Package {
             Specifics::Registry { .. } => {
                 let mut body = Vec::new();
 
-                ureq::get(self.url.as_str())
-                    .call()?
-                    .into_reader()
-                    .read_to_end(&mut body)?;
+                util::get_url_with_retry(&self.url)?.read_to_end(&mut body)?;
 
                 Ok(body)
             }
diff --git a/nixpkgs/pkgs/build-support/node/fetch-npm-deps/src/util.rs b/nixpkgs/pkgs/build-support/node/fetch-npm-deps/src/util.rs
new file mode 100644
index 000000000000..a165461fa71a
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/node/fetch-npm-deps/src/util.rs
@@ -0,0 +1,45 @@
+use backoff::{retry, ExponentialBackoff};
+use isahc::{
+    config::{CaCertificate, Configurable, RedirectPolicy, SslOption},
+    Body, Request, RequestExt,
+};
+use std::{env, path::Path};
+use url::Url;
+
+pub fn get_url(url: &Url) -> Result<Body, isahc::Error> {
+    let mut request = Request::get(url.as_str()).redirect_policy(RedirectPolicy::Limit(10));
+
+    // Respect SSL_CERT_FILE if environment variable exists
+    if let Ok(ssl_cert_file) = env::var("SSL_CERT_FILE") {
+        if Path::new(&ssl_cert_file).exists() {
+            // When file exists, use it. NIX_SSL_CERT_FILE will still override.
+            request = request.ssl_ca_certificate(CaCertificate::file(ssl_cert_file));
+        } else if env::var("outputHash").is_ok() {
+            // When file does not exist, assume we are downloading in a FOD and
+            // therefore do not need to check certificates, since the output is
+            // already hashed.
+            request = request.ssl_options(SslOption::DANGER_ACCEPT_INVALID_CERTS);
+        }
+    }
+
+    Ok(request.body(())?.send()?.into_body())
+}
+
+pub fn get_url_with_retry(url: &Url) -> Result<Body, isahc::Error> {
+    retry(ExponentialBackoff::default(), || {
+        get_url(url).map_err(|err| {
+            if err.is_network() || err.is_timeout() {
+                backoff::Error::transient(err)
+            } else {
+                backoff::Error::permanent(err)
+            }
+        })
+    })
+    .map_err(|backoff_err| match backoff_err {
+        backoff::Error::Permanent(err)
+        | backoff::Error::Transient {
+            err,
+            retry_after: _,
+        } => err,
+    })
+}
diff --git a/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/common.js b/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/common.js
new file mode 100644
index 000000000000..8e0d1b0e470b
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/common.js
@@ -0,0 +1,17 @@
+const path = require('path')
+
+// This has to match the logic in pkgs/development/tools/yarn2nix-moretea/yarn2nix/lib/urlToName.js
+// so that fixup_yarn_lock produces the same paths
+const urlToName = url => {
+	const isCodeloadGitTarballUrl = url.startsWith('https://codeload.github.com/') && url.includes('/tar.gz/')
+
+	if (url.startsWith('git+') || isCodeloadGitTarballUrl) {
+		return path.basename(url)
+	} else {
+		return url
+			.replace(/https:\/\/(.)*(.com)\//g, '') // prevents having long directory names
+			.replace(/[@/%:-]/g, '_') // replace @ and : and - and % characters with underscore
+	}
+}
+
+module.exports = { urlToName };
diff --git a/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/default.nix b/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/default.nix
index 4cf2507706ae..d95b1078c162 100644
--- a/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/default.nix
+++ b/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/default.nix
@@ -6,6 +6,8 @@ let
     sha512 = "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==";
   };
 
+  tests = callPackage ./tests {};
+
 in {
   prefetch-yarn-deps = stdenv.mkDerivation {
     name = "prefetch-yarn-deps";
@@ -21,8 +23,8 @@ in {
       mkdir libexec
       tar --strip-components=1 -xf ${yarnpkg-lockfile-tar} package/index.js
       mv index.js libexec/yarnpkg-lockfile.js
-      cp ${./index.js} libexec/index.js
-      patchShebangs libexec/index.js
+      cp ${./.}/*.js libexec/
+      patchShebangs libexec
 
       runHook postBuild
     '';
@@ -34,9 +36,12 @@ in {
       cp -r libexec $out
       makeWrapper $out/libexec/index.js $out/bin/prefetch-yarn-deps \
         --prefix PATH : ${lib.makeBinPath [ coreutils nix-prefetch-git nix ]}
+      makeWrapper $out/libexec/fixup.js $out/bin/fixup-yarn-lock
 
       runHook postInstall
     '';
+
+    passthru = { inherit tests; };
   };
 
   fetchYarnDeps = let
@@ -74,6 +79,6 @@ in {
     } // hash_ // (removeAttrs args ["src" "name" "hash" "sha256"]));
 
   in lib.setFunctionArgs f (lib.functionArgs f) // {
-    tests = callPackage ./tests {};
+    inherit tests;
   };
 }
diff --git a/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/fixup.js b/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/fixup.js
new file mode 100755
index 000000000000..8b91e7efa63f
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/fixup.js
@@ -0,0 +1,74 @@
+#!/usr/bin/env node
+'use strict'
+
+const fs = require('fs')
+const process = require('process')
+const lockfile = require('./yarnpkg-lockfile.js')
+const { urlToName } = require('./common.js')
+
+const fixupYarnLock = async (lockContents, verbose) => {
+	const lockData = lockfile.parse(lockContents)
+
+	const fixedData = Object.fromEntries(
+		Object.entries(lockData.object)
+		.map(([dep, pkg]) => {
+			const [ url, hash ] = pkg.resolved.split("#", 2)
+
+			if (hash || url.startsWith("https://codeload.github.com")) {
+				if (verbose) console.log(`Removing integrity for git dependency ${dep}`)
+				delete pkg.integrity
+			}
+
+			if (verbose) console.log(`Rewriting URL ${url} for dependency ${dep}`)
+			pkg.resolved = urlToName(url)
+
+			return [dep, pkg]
+		})
+	)
+
+	if (verbose) console.log('Done')
+
+	return fixedData
+}
+
+const showUsage = async () => {
+	process.stderr.write(`
+syntax: fixup-yarn-lock [path to yarn.lock] [options]
+
+Options:
+  -h --help         Show this help
+  -v --verbose      Verbose output
+`)
+	process.exit(1)
+}
+
+const main = async () => {
+	const args = process.argv.slice(2)
+	let next, lockFile, verbose
+	while (next = args.shift()) {
+		if (next == '--verbose' || next == '-v') {
+			verbose = true
+		} else if (next == '--help' || next == '-h') {
+			showUsage()
+		} else if (!lockFile) {
+			lockFile = next
+		} else {
+			showUsage()
+		}
+	}
+	let lockContents
+	try {
+		lockContents = await fs.promises.readFile(lockFile || 'yarn.lock', 'utf-8')
+	} catch {
+		showUsage()
+	}
+
+	const fixedData = await fixupYarnLock(lockContents, verbose)
+	await fs.promises.writeFile(lockFile || 'yarn.lock', lockfile.stringify(fixedData))
+}
+
+main()
+	.catch(e => {
+		console.error(e)
+		process.exit(1)
+	})
diff --git a/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/index.js b/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/index.js
index b66e1220218d..04f47362b10d 100755
--- a/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/index.js
+++ b/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/index.js
@@ -10,6 +10,7 @@ const path = require('path')
 const lockfile = require('./yarnpkg-lockfile.js')
 const { promisify } = require('util')
 const url = require('url')
+const { urlToName } = require('./common.js')
 
 const execFile = promisify(child_process.execFile)
 
@@ -19,23 +20,16 @@ const exec = async (...args) => {
 	return res
 }
 
-// This has to match the logic in pkgs/development/tools/yarn2nix-moretea/yarn2nix/lib/urlToName.js
-// so that fixup_yarn_lock produces the same paths
-const urlToName = url => {
-	const isCodeloadGitTarballUrl = url.startsWith('https://codeload.github.com/') && url.includes('/tar.gz/')
-
-	if (url.startsWith('git+') || isCodeloadGitTarballUrl) {
-		return path.basename(url)
-	} else {
-		return url
-			.replace(/https:\/\/(.)*(.com)\//g, '') // prevents having long directory names
-			.replace(/[@/%:-]/g, '_') // replace @ and : and - and % characters with underscore
-	}
-}
-
 const downloadFileHttps = (fileName, url, expectedHash, hashType = 'sha1') => {
 	return new Promise((resolve, reject) => {
-		https.get(url, (res) => {
+		const get = (url, redirects = 0) => https.get(url, (res) => {
+			if(redirects > 10) {
+				reject('Too many redirects!');
+				return;
+			}
+			if(res.statusCode === 301 || res.statusCode === 302) {
+				return get(res.headers.location, redirects + 1)
+			}
 			const file = fs.createWriteStream(fileName)
 			const hash = crypto.createHash(hashType)
 			res.pipe(file)
@@ -48,6 +42,7 @@ const downloadFileHttps = (fileName, url, expectedHash, hashType = 'sha1') => {
 			})
                         res.on('error', e => reject(e))
 		})
+		get(url)
 	})
 }
 
@@ -91,12 +86,21 @@ const isGitUrl = pattern => {
 }
 
 const downloadPkg = (pkg, verbose) => {
+	const [ name, spec ] = pkg.key.split('@', 2);
+	if (spec.startsWith('file:')) {
+		console.info(`ignoring relative file:path dependency "${spec}"`)
+		return
+	}
+
 	const [ url, hash ] = pkg.resolved.split('#')
 	if (verbose) console.log('downloading ' + url)
 	const fileName = urlToName(url)
 	if (url.startsWith('https://codeload.github.com/') && url.includes('/tar.gz/')) {
 		const s = url.split('/')
-		downloadGit(fileName, `https://github.com/${s[3]}/${s[4]}.git`, s[6])
+		return downloadGit(fileName, `https://github.com/${s[3]}/${s[4]}.git`, s[s.length-1])
+	} else if (url.startsWith('https://github.com/') && url.endsWith('.tar.gz')) {
+		const s = url.split('/')
+		return downloadGit(fileName, `https://github.com/${s[3]}/${s[4]}.git`, s[s.length-1].replace(/.tar.gz$/, ''))
 	} else if (isGitUrl(url)) {
 		return downloadGit(fileName, url.replace(/^git\+/, ''), hash)
 	} else if (url.startsWith('https://')) {
diff --git a/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/tests/default.nix b/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/tests/default.nix
index 19451466f24f..8ffe103a9548 100644
--- a/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/tests/default.nix
+++ b/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/tests/default.nix
@@ -3,14 +3,18 @@
 {
   simple = testers.invalidateFetcherByDrvHash fetchYarnDeps {
     yarnLock = ./simple.lock;
-    sha256 = "sha256-Erdkw2E8wWT09jFNLXGkrdwKl0HuSZWnUDJUrV95vSE=";
+    sha256 = "sha256-FRrt8BixleILmFB2ZV8RgPNLqgS+dlH5nWoPgeaaNQ8=";
   };
   gitDep = testers.invalidateFetcherByDrvHash fetchYarnDeps {
     yarnLock = ./git.lock;
-    sha256 = "sha256-lAqN4LpoE+jgsQO1nDtuORwcVEO7ogEV53jCu2jFJUI=";
+    sha256 = "sha256-f90IiEzHDiBdswWewRBHcJfqqpPipaMg8N0DVLq2e8Q=";
   };
   githubDep = testers.invalidateFetcherByDrvHash fetchYarnDeps {
     yarnLock = ./github.lock;
-    sha256 = "sha256-Tsfgyjxz8x6gNmfN0xR7G/NQNoEs4svxRN/N+26vfJU=";
+    sha256 = "sha256-DIKrhDKoqm7tHZmcuh9eK9VTqp6BxeW0zqDUpY4F57A=";
+  };
+  gitUrlDep = testers.invalidateFetcherByDrvHash fetchYarnDeps {
+    yarnLock = ./giturl.lock;
+    sha256 = "sha256-VPnyqN6lePQZGXwR7VhbFnP7/0/LB621RZwT1F+KzVQ=";
   };
 }
diff --git a/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/tests/giturl.lock b/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/tests/giturl.lock
new file mode 100644
index 000000000000..154030a7e358
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/node/fetch-yarn-deps/tests/giturl.lock
@@ -0,0 +1,11 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"autocomplete-atom-api@https://codeload.github.com/atom/autocomplete-atom-api/legacy.tar.gz/refs/tags/v0.10.7":
+  version "0.10.7"
+  resolved "https://codeload.github.com/atom/autocomplete-atom-api/legacy.tar.gz/refs/tags/v0.10.7#c9d51fa721d543ccfc1b2189101155e81db6b97d"
+
+"find-and-replace@https://github.com/atom-community/find-and-replace/archive/refs/tags/v0.220.1.tar.gz":
+  version "0.220.1"
+  resolved "https://github.com/atom-community/find-and-replace/archive/refs/tags/v0.220.1.tar.gz#d7a0f56511e38ee72a89895a795bbbcab4a1a405"
diff --git a/nixpkgs/pkgs/build-support/pkg-config-wrapper/default.nix b/nixpkgs/pkgs/build-support/pkg-config-wrapper/default.nix
index f68597662608..f409ca3a7d4b 100644
--- a/nixpkgs/pkgs/build-support/pkg-config-wrapper/default.nix
+++ b/nixpkgs/pkgs/build-support/pkg-config-wrapper/default.nix
@@ -119,8 +119,8 @@ stdenv.mkDerivation {
   };
 
   meta =
-    let pkg-config_ = if pkg-config != null then pkg-config else {}; in
-    (if pkg-config_ ? meta then removeAttrs pkg-config.meta ["priority"] else {}) //
+    let pkg-config_ = lib.optionalAttrs (pkg-config != null) pkg-config; in
+    (lib.optionalAttrs (pkg-config_ ? meta) (removeAttrs pkg-config.meta ["priority"])) //
     { description =
         lib.attrByPath ["meta" "description"] "pkg-config" pkg-config_
         + " (wrapper script)";
diff --git a/nixpkgs/pkgs/build-support/release/binary-tarball.nix b/nixpkgs/pkgs/build-support/release/binary-tarball.nix
index 24d5b2e1cafc..37c5f8c7ee86 100644
--- a/nixpkgs/pkgs/build-support/release/binary-tarball.nix
+++ b/nixpkgs/pkgs/build-support/release/binary-tarball.nix
@@ -70,7 +70,7 @@ stdenv.mkDerivation (
       test -n "$releaseName" && (echo "$releaseName" >> $out/nix-support/hydra-release-name)
     '';
 
-    meta = (if args ? meta then args.meta else {}) // {
+    meta = (lib.optionalAttrs (args ? meta) args.meta) // {
       description = "Build of a generic binary distribution";
     };
 
diff --git a/nixpkgs/pkgs/build-support/release/debian-build.nix b/nixpkgs/pkgs/build-support/release/debian-build.nix
index 6e08caf0a4e5..ab84a504b54c 100644
--- a/nixpkgs/pkgs/build-support/release/debian-build.nix
+++ b/nixpkgs/pkgs/build-support/release/debian-build.nix
@@ -86,7 +86,7 @@ vmTools.runInLinuxImage (stdenv.mkDerivation (
       eval "$postInstall"
     '';
 
-    meta = (if args ? meta then args.meta else {}) // {
+    meta = (lib.optionalAttrs (args ? meta) args.meta) // {
       description = "Deb package for ${diskImage.fullName}";
     };
   }
diff --git a/nixpkgs/pkgs/build-support/release/default.nix b/nixpkgs/pkgs/build-support/release/default.nix
index ee414ea3280d..d09f6c8568be 100644
--- a/nixpkgs/pkgs/build-support/release/default.nix
+++ b/nixpkgs/pkgs/build-support/release/default.nix
@@ -5,7 +5,7 @@ with pkgs;
 rec {
 
   sourceTarball = args: import ./source-tarball.nix (
-    { inherit stdenv autoconf automake libtool;
+    { inherit lib stdenv autoconf automake libtool;
     } // args);
 
   makeSourceTarball = sourceTarball; # compatibility
diff --git a/nixpkgs/pkgs/build-support/release/nix-build.nix b/nixpkgs/pkgs/build-support/release/nix-build.nix
index 83e521bb65c7..348cd5b8345c 100644
--- a/nixpkgs/pkgs/build-support/release/nix-build.nix
+++ b/nixpkgs/pkgs/build-support/release/nix-build.nix
@@ -146,7 +146,7 @@ stdenv.mkDerivation (
 
     postPhases = postPhases ++ ["finalPhase"];
 
-    meta = (if args ? meta then args.meta else {}) // {
+    meta = (lib.optionalAttrs (args ? meta) args.meta) // {
       description = if doCoverageAnalysis then "Coverage analysis" else "Nix package for ${stdenv.hostPlatform.system}";
     };
 
@@ -154,8 +154,8 @@ stdenv.mkDerivation (
 
   //
 
-  (if buildOutOfSourceTree
-   then {
+  (lib.optionalAttrs buildOutOfSourceTree
+   {
      preConfigure =
        # Build out of source tree and make the source tree read-only.  This
        # helps catch violations of the GNU Coding Standards (info
@@ -170,5 +170,5 @@ stdenv.mkDerivation (
           ${lib.optionalString (preConfigure != null) preConfigure}
        '';
    }
-   else {})
+  )
 )
diff --git a/nixpkgs/pkgs/build-support/release/rpm-build.nix b/nixpkgs/pkgs/build-support/release/rpm-build.nix
index 8f4711470509..ccbbd57107bd 100644
--- a/nixpkgs/pkgs/build-support/release/rpm-build.nix
+++ b/nixpkgs/pkgs/build-support/release/rpm-build.nix
@@ -46,7 +46,7 @@ vmTools.buildRPM (
       done
     '';
 
-    meta = (if args ? meta then args.meta else {}) // {
+    meta = (lib.optionalAttrs (args ? meta) args.meta) // {
       description = "RPM package for ${diskImage.fullName}";
     };
   }
diff --git a/nixpkgs/pkgs/build-support/release/source-tarball.nix b/nixpkgs/pkgs/build-support/release/source-tarball.nix
index d624d071cc21..fbc8bc6b258b 100644
--- a/nixpkgs/pkgs/build-support/release/source-tarball.nix
+++ b/nixpkgs/pkgs/build-support/release/source-tarball.nix
@@ -10,7 +10,7 @@
     if officialRelease
     then ""
     else "pre${toString (src.rev or src.revCount or "")}"
-, src, stdenv, autoconf, automake, libtool
+, src, lib, stdenv, autoconf, automake, libtool
 , # By default, provide all the GNU Build System as input.
   bootstrapBuildInputs ? [ autoconf automake libtool ]
 , ... } @ args:
@@ -73,7 +73,7 @@ stdenv.mkDerivation (
   }
 
   # Then, the caller-supplied attributes.
-  // args //
+  // (builtins.removeAttrs args [ "lib" ]) //
 
   # And finally, our own stuff.
   {
@@ -117,7 +117,7 @@ stdenv.mkDerivation (
       version = version + versionSuffix;
     };
 
-    meta = (if args ? meta then args.meta else {}) // {
+    meta = (lib.optionalAttrs (args ? meta) args.meta) // {
       description = "Source distribution";
 
       # Tarball builds are generally important, so give them a high
diff --git a/nixpkgs/pkgs/build-support/rust/build-rust-crate/configure-crate.nix b/nixpkgs/pkgs/build-support/rust/build-rust-crate/configure-crate.nix
index 5168eb6ab759..60310f178747 100644
--- a/nixpkgs/pkgs/build-support/rust/build-rust-crate/configure-crate.nix
+++ b/nixpkgs/pkgs/build-support/rust/build-rust-crate/configure-crate.nix
@@ -21,7 +21,7 @@
 , verbose
 , workspace_member }:
 let version_ = lib.splitString "-" crateVersion;
-    versionPre = if lib.tail version_ == [] then "" else lib.elemAt version_ 1;
+    versionPre = lib.optionalString (lib.tail version_ != []) (lib.elemAt version_ 1);
     version = lib.splitVersion (lib.head version_);
     rustcOpts = lib.foldl' (opts: opt: opts + " " + opt)
         (if release then "-C opt-level=3" else "-C debuginfo=2")
diff --git a/nixpkgs/pkgs/build-support/rust/build-rust-crate/test/rcgen-crates.nix b/nixpkgs/pkgs/build-support/rust/build-rust-crate/test/rcgen-crates.nix
index e15390c3ffa8..ed273c01d26d 100644
--- a/nixpkgs/pkgs/build-support/rust/build-rust-crate/test/rcgen-crates.nix
+++ b/nixpkgs/pkgs/build-support/rust/build-rust-crate/test/rcgen-crates.nix
@@ -24,9 +24,7 @@
 , release ? true
   # Additional crate2nix configuration if it exists.
 , crateConfig
-  ? if builtins.pathExists ./crate-config.nix
-    then pkgs.callPackage ./crate-config.nix {}
-    else {}
+  ? lib.optionalAttrs (builtins.pathExists ./crate-config.nix) (pkgs.callPackage ./crate-config.nix {})
 }:
 
 rec {
diff --git a/nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix b/nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix
index 35eb1d2468b0..9eab4733db64 100644
--- a/nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix
+++ b/nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix
@@ -164,8 +164,7 @@ let
           # Platforms without host tools from
           # https://doc.rust-lang.org/nightly/rustc/platform-support.html
           "armv7a-darwin"
-          "armv5tel-linux" "armv6l-linux" "armv7a-linux" "m68k-linux"
-          "riscv32-linux"
+          "armv5tel-linux" "armv7a-linux" "m68k-linux" "riscv32-linux"
           "armv6l-netbsd"
           "x86_64-redox"
           "wasm32-wasi"
diff --git a/nixpkgs/pkgs/build-support/rust/fetch-cargo-tarball/default.nix b/nixpkgs/pkgs/build-support/rust/fetch-cargo-tarball/default.nix
index 8c6a97888c10..adbfe98d8103 100644
--- a/nixpkgs/pkgs/build-support/rust/fetch-cargo-tarball/default.nix
+++ b/nixpkgs/pkgs/build-support/rust/fetch-cargo-tarball/default.nix
@@ -62,10 +62,6 @@ in stdenv.mkDerivation ({
     export CARGO_HOME=$(mktemp -d cargo-home.XXX)
     CARGO_CONFIG=$(mktemp cargo-config.XXXX)
 
-    # https://blog.rust-lang.org/2023/03/09/Rust-1.68.0.html#cargos-sparse-protocol
-    # planned to become the default in 1.70
-    export CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse
-
     if [[ -n "$NIX_CRATES_INDEX" ]]; then
     cat >$CARGO_HOME/config.toml <<EOF
     [source.crates-io]
diff --git a/nixpkgs/pkgs/build-support/rust/hooks/cargo-build-hook.sh b/nixpkgs/pkgs/build-support/rust/hooks/cargo-build-hook.sh
index 7503fae4cd7f..af94e02e38ae 100644
--- a/nixpkgs/pkgs/build-support/rust/hooks/cargo-build-hook.sh
+++ b/nixpkgs/pkgs/build-support/rust/hooks/cargo-build-hook.sh
@@ -5,6 +5,10 @@ cargoBuildHook() {
 
     runHook preBuild
 
+    # Let stdenv handle stripping, for consistency and to not break
+    # separateDebugInfo.
+    export "CARGO_PROFILE_${cargoBuildType@U}_STRIP"=false
+
     if [ ! -z "${buildAndTestSubdir-}" ]; then
         # ensure the output doesn't end up in the subdirectory
         export CARGO_TARGET_DIR="$(pwd)/target"
diff --git a/nixpkgs/pkgs/build-support/rust/import-cargo-lock.nix b/nixpkgs/pkgs/build-support/rust/import-cargo-lock.nix
index f4daf3540531..c17b0e41cca8 100644
--- a/nixpkgs/pkgs/build-support/rust/import-cargo-lock.nix
+++ b/nixpkgs/pkgs/build-support/rust/import-cargo-lock.nix
@@ -201,7 +201,7 @@ let
 
         # Set up configuration for the vendor directory.
         cat > $out/.cargo-config <<EOF
-        [source."${gitParts.url}"]
+        [source."${gitParts.url}${lib.optionalString (gitParts ? type) "?${gitParts.type}=${gitParts.value}"}"]
         git = "${gitParts.url}"
         ${lib.optionalString (gitParts ? type) "${gitParts.type} = \"${gitParts.value}\""}
         replace-with = "vendored-sources"
diff --git a/nixpkgs/pkgs/build-support/rust/test/import-cargo-lock/default.nix b/nixpkgs/pkgs/build-support/rust/test/import-cargo-lock/default.nix
index 74d6c534a739..26e6487989c4 100644
--- a/nixpkgs/pkgs/build-support/rust/test/import-cargo-lock/default.nix
+++ b/nixpkgs/pkgs/build-support/rust/test/import-cargo-lock/default.nix
@@ -1,4 +1,4 @@
-{ callPackage, writers, python3Packages }:
+{ callPackage, maturin, writers, python3Packages }:
 
 # Build like this from nixpkgs root:
 # $ nix-build -A tests.importCargoLock
@@ -10,7 +10,7 @@
   gitDependencyRevNonWorkspaceNestedCrate = callPackage ./git-dependency-rev-non-workspace-nested-crate { };
   gitDependencyTag = callPackage ./git-dependency-tag { };
   gitDependencyBranch = callPackage ./git-dependency-branch { };
-  maturin = callPackage ./maturin { };
+  maturin = maturin.tests.pyo3;
   v1 = callPackage ./v1 { };
   gitDependencyWorkspaceInheritance = callPackage ./git-dependency-workspace-inheritance {
     replaceWorkspaceValues = writers.writePython3 "replace-workspace-values"
diff --git a/nixpkgs/pkgs/build-support/rust/test/import-cargo-lock/maturin/Cargo.lock b/nixpkgs/pkgs/build-support/rust/test/import-cargo-lock/maturin/Cargo.lock
deleted file mode 100644
index 5e698d4ff735..000000000000
--- a/nixpkgs/pkgs/build-support/rust/test/import-cargo-lock/maturin/Cargo.lock
+++ /dev/null
@@ -1,682 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-[[package]]
-name = "ahash"
-version = "0.4.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e"
-
-[[package]]
-name = "assert_approx_eq"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c07dab4369547dbe5114677b33fbbf724971019f3818172d59a97a61c774ffd"
-
-[[package]]
-name = "autocfg"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
-
-[[package]]
-name = "bitflags"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
-
-[[package]]
-name = "byteorder"
-version = "1.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b"
-
-[[package]]
-name = "cfg-if"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
-
-[[package]]
-name = "const_fn"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6"
-
-[[package]]
-name = "crossbeam-channel"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
-dependencies = [
- "cfg-if",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-deque"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
-dependencies = [
- "cfg-if",
- "crossbeam-epoch",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-epoch"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d"
-dependencies = [
- "cfg-if",
- "const_fn",
- "crossbeam-utils",
- "lazy_static",
- "memoffset",
- "scopeguard",
-]
-
-[[package]]
-name = "crossbeam-utils"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
-dependencies = [
- "autocfg",
- "cfg-if",
- "lazy_static",
-]
-
-[[package]]
-name = "ctor"
-version = "0.1.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8f45d9ad417bcef4817d614a501ab55cdd96a6fdb24f49aab89a54acfd66b19"
-dependencies = [
- "quote",
- "syn",
-]
-
-[[package]]
-name = "either"
-version = "1.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
-
-[[package]]
-name = "getrandom"
-version = "0.1.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
-dependencies = [
- "cfg-if",
- "libc",
- "wasi",
-]
-
-[[package]]
-name = "ghost"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a5bcf1bbeab73aa4cf2fde60a846858dc036163c7c33bec309f8d17de785479"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "glob"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
-
-[[package]]
-name = "hashbrown"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
-dependencies = [
- "ahash",
-]
-
-[[package]]
-name = "hermit-abi"
-version = "0.1.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "indoc"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47741a8bc60fb26eb8d6e0238bbb26d8575ff623fdc97b1a2c00c050b9684ed8"
-dependencies = [
- "indoc-impl",
- "proc-macro-hack",
-]
-
-[[package]]
-name = "indoc-impl"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce046d161f000fffde5f432a0d034d0341dc152643b2598ed5bfce44c4f3a8f0"
-dependencies = [
- "proc-macro-hack",
- "proc-macro2",
- "quote",
- "syn",
- "unindent",
-]
-
-[[package]]
-name = "instant"
-version = "0.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "inventory"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f0f7efb804ec95e33db9ad49e4252f049e37e8b0a4652e3cd61f7999f2eff7f"
-dependencies = [
- "ctor",
- "ghost",
- "inventory-impl",
-]
-
-[[package]]
-name = "inventory-impl"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75c094e94816723ab936484666968f5b58060492e880f3c8d00489a1e244fa51"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "itoa"
-version = "0.4.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
-
-[[package]]
-name = "lazy_static"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
-
-[[package]]
-name = "libc"
-version = "0.2.86"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c"
-
-[[package]]
-name = "lock_api"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312"
-dependencies = [
- "scopeguard",
-]
-
-[[package]]
-name = "memoffset"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "num-bigint"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e9a41747ae4633fce5adffb4d2e81ffc5e89593cb19917f8fb2cc5ff76507bf"
-dependencies = [
- "autocfg",
- "num-integer",
- "num-traits",
-]
-
-[[package]]
-name = "num-complex"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5"
-dependencies = [
- "num-traits",
-]
-
-[[package]]
-name = "num-integer"
-version = "0.1.44"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
-dependencies = [
- "autocfg",
- "num-traits",
-]
-
-[[package]]
-name = "num-traits"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "num_cpus"
-version = "1.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
-dependencies = [
- "hermit-abi",
- "libc",
-]
-
-[[package]]
-name = "parking_lot"
-version = "0.11.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb"
-dependencies = [
- "instant",
- "lock_api",
- "parking_lot_core",
-]
-
-[[package]]
-name = "parking_lot_core"
-version = "0.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018"
-dependencies = [
- "cfg-if",
- "instant",
- "libc",
- "redox_syscall",
- "smallvec",
- "winapi",
-]
-
-[[package]]
-name = "paste"
-version = "0.1.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880"
-dependencies = [
- "paste-impl",
- "proc-macro-hack",
-]
-
-[[package]]
-name = "paste-impl"
-version = "0.1.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6"
-dependencies = [
- "proc-macro-hack",
-]
-
-[[package]]
-name = "ppv-lite86"
-version = "0.2.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
-
-[[package]]
-name = "proc-macro-hack"
-version = "0.5.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
-
-[[package]]
-name = "proc-macro2"
-version = "1.0.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
-dependencies = [
- "unicode-xid",
-]
-
-[[package]]
-name = "proptest"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12e6c80c1139113c28ee4670dc50cc42915228b51f56a9e407f0ec60f966646f"
-dependencies = [
- "bitflags",
- "byteorder",
- "lazy_static",
- "num-traits",
- "quick-error",
- "rand",
- "rand_chacha",
- "rand_xorshift",
- "regex-syntax",
-]
-
-[[package]]
-name = "pyo3"
-version = "0.13.2"
-dependencies = [
- "assert_approx_eq",
- "cfg-if",
- "ctor",
- "hashbrown",
- "indoc",
- "inventory",
- "libc",
- "num-bigint",
- "num-complex",
- "parking_lot",
- "paste",
- "proptest",
- "pyo3",
- "pyo3-macros",
- "rustversion",
- "serde",
- "serde_json",
- "trybuild",
- "unindent",
-]
-
-[[package]]
-name = "pyo3-macros"
-version = "0.13.2"
-dependencies = [
- "pyo3-macros-backend",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "pyo3-macros-backend"
-version = "0.13.2"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "quick-error"
-version = "1.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
-
-[[package]]
-name = "quote"
-version = "1.0.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
-dependencies = [
- "proc-macro2",
-]
-
-[[package]]
-name = "rand"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
-dependencies = [
- "getrandom",
- "libc",
- "rand_chacha",
- "rand_core",
- "rand_hc",
-]
-
-[[package]]
-name = "rand_chacha"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
-dependencies = [
- "ppv-lite86",
- "rand_core",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
-dependencies = [
- "getrandom",
-]
-
-[[package]]
-name = "rand_hc"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
-dependencies = [
- "rand_core",
-]
-
-[[package]]
-name = "rand_xorshift"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77d416b86801d23dde1aa643023b775c3a462efc0ed96443add11546cdf1dca8"
-dependencies = [
- "rand_core",
-]
-
-[[package]]
-name = "rayon"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
-dependencies = [
- "autocfg",
- "crossbeam-deque",
- "either",
- "rayon-core",
-]
-
-[[package]]
-name = "rayon-core"
-version = "1.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
-dependencies = [
- "crossbeam-channel",
- "crossbeam-deque",
- "crossbeam-utils",
- "lazy_static",
- "num_cpus",
-]
-
-[[package]]
-name = "redox_syscall"
-version = "0.2.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9"
-dependencies = [
- "bitflags",
-]
-
-[[package]]
-name = "regex-syntax"
-version = "0.6.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
-
-[[package]]
-name = "rustapi-module"
-version = "0.1.0"
-dependencies = [
- "pyo3",
-]
-
-[[package]]
-name = "rustversion"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb5d2a036dc6d2d8fd16fde3498b04306e29bd193bf306a57427019b823d5acd"
-
-[[package]]
-name = "ryu"
-version = "1.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
-
-[[package]]
-name = "scopeguard"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
-
-[[package]]
-name = "serde"
-version = "1.0.123"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae"
-dependencies = [
- "serde_derive",
-]
-
-[[package]]
-name = "serde_derive"
-version = "1.0.123"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "serde_json"
-version = "1.0.62"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea1c6153794552ea7cf7cf63b1231a25de00ec90db326ba6264440fa08e31486"
-dependencies = [
- "itoa",
- "ryu",
- "serde",
-]
-
-[[package]]
-name = "smallvec"
-version = "1.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
-
-[[package]]
-name = "syn"
-version = "1.0.60"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-xid",
-]
-
-[[package]]
-name = "termcolor"
-version = "1.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
-dependencies = [
- "winapi-util",
-]
-
-[[package]]
-name = "toml"
-version = "0.5.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "trybuild"
-version = "1.0.41"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99471a206425fba51842a9186315f32d91c56eadc21ea4c21f847b59cf778f8b"
-dependencies = [
- "glob",
- "lazy_static",
- "serde",
- "serde_json",
- "termcolor",
- "toml",
-]
-
-[[package]]
-name = "unicode-xid"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
-
-[[package]]
-name = "unindent"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f14ee04d9415b52b3aeab06258a3f07093182b88ba0f9b8d203f211a7a7d41c7"
-
-[[package]]
-name = "wasi"
-version = "0.9.0+wasi-snapshot-preview1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
-
-[[package]]
-name = "winapi"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
-dependencies = [
- "winapi-i686-pc-windows-gnu",
- "winapi-x86_64-pc-windows-gnu",
-]
-
-[[package]]
-name = "winapi-i686-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-
-[[package]]
-name = "winapi-util"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
-dependencies = [
- "winapi",
-]
-
-[[package]]
-name = "winapi-x86_64-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
-
-[[package]]
-name = "word-count"
-version = "0.1.0"
-dependencies = [
- "pyo3",
- "rayon",
-]
diff --git a/nixpkgs/pkgs/build-support/rust/test/import-cargo-lock/maturin/default.nix b/nixpkgs/pkgs/build-support/rust/test/import-cargo-lock/maturin/default.nix
deleted file mode 100644
index f8deb4f657e0..000000000000
--- a/nixpkgs/pkgs/build-support/rust/test/import-cargo-lock/maturin/default.nix
+++ /dev/null
@@ -1,43 +0,0 @@
-{ lib
-, fetchFromGitHub
-, python3
-, rustPlatform
-}:
-
-python3.pkgs.buildPythonPackage rec {
-  pname = "word-count";
-  version = "0.13.2";
-
-  format = "pyproject";
-
-  src = fetchFromGitHub {
-    owner = "PyO3";
-    repo = "pyo3";
-    rev = "v${version}";
-    hash = "sha256-NOMrrfo8WjlPhtGxWUOPJS/UDDdbLQRCXR++Zd6JmIA=";
-  };
-
-  cargoDeps = rustPlatform.importCargoLock {
-    lockFile = ./Cargo.lock;
-  };
-
-  postPatch = ''
-    cp ${./Cargo.lock} Cargo.lock
-  '';
-
-  buildAndTestSubdir = "examples/word-count";
-
-  nativeBuildInputs = with rustPlatform; [
-    cargoSetupHook
-    maturinBuildHook
-  ];
-
-  pythonImportsCheck = [ "word_count" ];
-
-  meta = with lib; {
-    description = "PyO3 word count example";
-    homepage = "https://github.com/PyO3/pyo3";
-    license = licenses.asl20;
-    maintainers = [ ];
-  };
-}
diff --git a/nixpkgs/pkgs/build-support/setup-hooks/make-wrapper.sh b/nixpkgs/pkgs/build-support/setup-hooks/make-wrapper.sh
index 4932e934ec16..11b332bfc3eb 100644
--- a/nixpkgs/pkgs/build-support/setup-hooks/make-wrapper.sh
+++ b/nixpkgs/pkgs/build-support/setup-hooks/make-wrapper.sh
@@ -166,11 +166,11 @@ makeShellWrapper() {
         elif [[ "$p" == "--add-flags" ]]; then
             flags="${params[$((n + 1))]}"
             n=$((n + 1))
-            flagsBefore="$flagsBefore $flags"
+            flagsBefore="${flagsBefore-} $flags"
         elif [[ "$p" == "--append-flags" ]]; then
             flags="${params[$((n + 1))]}"
             n=$((n + 1))
-            flagsAfter="$flagsAfter $flags"
+            flagsAfter="${flagsAfter-} $flags"
         elif [[ "$p" == "--argv0" ]]; then
             argv0="${params[$((n + 1))]}"
             n=$((n + 1))
@@ -183,7 +183,7 @@ makeShellWrapper() {
     done
 
     echo exec ${argv0:+-a \"$argv0\"} \""$original"\" \
-         "$flagsBefore" '"$@"' "$flagsAfter" >> "$wrapper"
+         "${flagsBefore-}" '"$@"' "${flagsAfter-}" >> "$wrapper"
 
     chmod +x "$wrapper"
 }
diff --git a/nixpkgs/pkgs/build-support/src-only/default.nix b/nixpkgs/pkgs/build-support/src-only/default.nix
index 6cf5c2ad482b..2b0db0e267aa 100644
--- a/nixpkgs/pkgs/build-support/src-only/default.nix
+++ b/nixpkgs/pkgs/build-support/src-only/default.nix
@@ -1,7 +1,6 @@
 { stdenv }:
 # srcOnly is a utility builder that only fetches and unpacks the given `src`,
-# maybe pathings it in the process with the optional `patches` and
-# `buildInputs` attributes.
+# and optionally patching with `patches` or adding build inputs.
 #
 # It can be invoked directly, or be used to wrap an existing derivation. Eg:
 #
diff --git a/nixpkgs/pkgs/build-support/testers/default.nix b/nixpkgs/pkgs/build-support/testers/default.nix
index 190ce72d0e63..d380dc6f30e1 100644
--- a/nixpkgs/pkgs/build-support/testers/default.nix
+++ b/nixpkgs/pkgs/build-support/testers/default.nix
@@ -97,7 +97,9 @@
   # See doc/builders/testers.chapter.md or
   # https://nixos.org/manual/nixpkgs/unstable/#tester-runNixOSTest
   runNixOSTest =
-    let nixos = import ../../../nixos/lib {};
+    let nixos = import ../../../nixos/lib {
+      inherit lib;
+    };
     in testModule:
         nixos.runTest {
           _file = "pkgs.runNixOSTest implementation";
diff --git a/nixpkgs/pkgs/build-support/trivial-builders/default.nix b/nixpkgs/pkgs/build-support/trivial-builders/default.nix
index d3cb22a1f535..dcdac09004bb 100644
--- a/nixpkgs/pkgs/build-support/trivial-builders/default.nix
+++ b/nixpkgs/pkgs/build-support/trivial-builders/default.nix
@@ -88,6 +88,12 @@ rec {
       passAsFile = [ "buildCommand" ]
         ++ (derivationArgs.passAsFile or []);
     }
+    // lib.optionalAttrs (! derivationArgs?meta) {
+      pos = let args = builtins.attrNames derivationArgs; in
+        if builtins.length args > 0
+        then builtins.unsafeGetAttrPos (builtins.head args) derivationArgs
+        else null;
+    }
     // (lib.optionalAttrs runLocal {
           preferLocalBuild = true;
           allowSubstitutes = false;
@@ -236,7 +242,11 @@ rec {
 
 
   */
-  writeScriptBin = name: text: writeTextFile {inherit name text; executable = true; destination = "/bin/${name}";};
+  writeScriptBin = name: text: writeTextFile {
+    inherit name text;
+    executable = true;
+    destination = "/bin/${name}";
+  };
 
   /*
     Similar to writeScript. Writes a Shell script and checks its syntax.
@@ -368,6 +378,9 @@ rec {
       # Pointless to do this on a remote machine.
       preferLocalBuild = true;
       allowSubstitutes = false;
+      meta = {
+        mainProgram = name;
+      };
     }
     ''
       n=$out/bin/$name
@@ -620,6 +633,10 @@ rec {
     script:
     runCommand name
       (substitutions // {
+        # TODO(@Artturin:) substitutions should be inside the env attrset
+        # but users are likely passing non-substitution arguments through substitutions
+        # turn off __structuredAttrs to unbreak substituteAll
+        __structuredAttrs = false;
         inherit meta;
         inherit depsTargetTargetPropagated;
         propagatedBuildInputs =
@@ -807,9 +824,10 @@ rec {
         or
           nix-prefetch-url --type ${hashAlgo} file:///path/to/${name_}
       '';
-      hashAlgo = if hash != null then ""
+      hashAlgo = if hash != null then (builtins.head (lib.strings.splitString "-" hash))
             else if sha256 != null then "sha256"
             else "sha1";
+      hashAlgo_ = if hash != null then "" else hashAlgo;
       hash_ = if hash != null then hash
          else if sha256 != null then sha256
          else sha1;
@@ -818,7 +836,7 @@ rec {
     stdenvNoCC.mkDerivation {
       name = name_;
       outputHashMode = hashMode;
-      outputHashAlgo = hashAlgo;
+      outputHashAlgo = hashAlgo_;
       outputHash = hash_;
       preferLocalBuild = true;
       allowSubstitutes = false;
diff --git a/nixpkgs/pkgs/build-support/trivial-builders/test/default.nix b/nixpkgs/pkgs/build-support/trivial-builders/test/default.nix
new file mode 100644
index 000000000000..683f4b9fd04f
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/trivial-builders/test/default.nix
@@ -0,0 +1,33 @@
+/*
+  Run all tests with:
+
+      cd nixpkgs
+      nix-build -A tests.trivial-builders
+
+  or run a specific test with:
+
+      cd nixpkgs
+      nix-build -A tests.trivial-builders.foo
+
+*/
+
+{ callPackage, lib, stdenv }:
+let
+  inherit (lib) recurseIntoAttrs;
+in
+recurseIntoAttrs {
+  concat = callPackage ./concat-test.nix {};
+  linkFarm = callPackage ./link-farm.nix {};
+  overriding = callPackage ../test-overriding.nix {};
+  references =
+    # VM test not supported beyond linux yet
+    if stdenv.hostPlatform.isLinux
+    then callPackage ./references.nix {}
+    else null;
+  writeCBin = callPackage ./writeCBin.nix {};
+  writeScriptBin = callPackage ./writeScriptBin.nix {};
+  writeShellScript = callPackage ./write-shell-script.nix {};
+  writeShellScriptBin = callPackage ./writeShellScriptBin.nix {};
+  writeStringReferencesToFile = callPackage ./writeStringReferencesToFile.nix {};
+  writeTextFile = callPackage ./write-text-file.nix {};
+}
diff --git a/nixpkgs/pkgs/build-support/trivial-builders/test/write-text-file.nix b/nixpkgs/pkgs/build-support/trivial-builders/test/write-text-file.nix
index ac83a75fca4a..2e6685c1980b 100644
--- a/nixpkgs/pkgs/build-support/trivial-builders/test/write-text-file.nix
+++ b/nixpkgs/pkgs/build-support/trivial-builders/test/write-text-file.nix
@@ -1,34 +1,71 @@
-{ writeTextFile }:
+/*
+  To run:
+
+      cd nixpkgs
+      nix-build -A tests.trivial-builders.writeTextFile
+
+  or to run an individual test case
+
+      cd nixpkgs
+      nix-build -A tests.trivial-builders.writeTextFile.foo
+*/
+{ lib, runCommand, runtimeShell, writeTextFile }:
 let
   veryWeirdName = ''here's a name with some "bad" characters, like spaces and quotes'';
-in writeTextFile {
-  name = "weird-names";
-  destination = "/etc/${veryWeirdName}";
-  text = ''passed!'';
-  checkPhase = ''
-    # intentionally hardcode everything here, to make sure
-    # Nix does not mess with file paths
-
-    name="here's a name with some \"bad\" characters, like spaces and quotes"
-    fullPath="$out/etc/$name"
-
-    if [ -f "$fullPath" ]; then
-      echo "[PASS] File exists!"
-    else
-      echo "[FAIL] File was not created at expected path!"
-      exit 1
-    fi
-
-    content=$(<"$fullPath")
-    expected="passed!"
-
-    if [ "$content" = "$expected" ]; then
-      echo "[PASS] Contents match!"
-    else
-      echo "[FAIL] File contents don't match!"
-      echo "       Expected: $expected"
-      echo "       Got:      $content"
-      exit 2
-    fi
-  '';
+in
+lib.recurseIntoAttrs {
+
+  different-exe-name =
+    let
+      pkg = writeTextFile {
+        name = "bar";
+        destination = "/bin/foo";
+        executable = true;
+        text = ''
+          #!${runtimeShell}
+          echo hi
+        '';
+      };
+    in
+      assert pkg.meta.mainProgram == "foo";
+      assert baseNameOf (lib.getExe pkg) == "foo";
+      assert pkg.name == "bar";
+      runCommand "test-writeTextFile-different-exe-name" {} ''
+        PATH="${lib.makeBinPath [ pkg ]}:$PATH"
+        x=$(foo)
+        [[ "$x" == hi ]]
+        touch $out
+      '';
+
+  weird-name = writeTextFile {
+    name = "weird-names";
+    destination = "/etc/${veryWeirdName}";
+    text = ''passed!'';
+    checkPhase = ''
+      # intentionally hardcode everything here, to make sure
+      # Nix does not mess with file paths
+
+      name="here's a name with some \"bad\" characters, like spaces and quotes"
+      fullPath="$out/etc/$name"
+
+      if [ -f "$fullPath" ]; then
+        echo "[PASS] File exists!"
+      else
+        echo "[FAIL] File was not created at expected path!"
+        exit 1
+      fi
+
+      content=$(<"$fullPath")
+      expected="passed!"
+
+      if [ "$content" = "$expected" ]; then
+        echo "[PASS] Contents match!"
+      else
+        echo "[FAIL] File contents don't match!"
+        echo "       Expected: $expected"
+        echo "       Got:      $content"
+        exit 2
+      fi
+    '';
+  };
 }
diff --git a/nixpkgs/pkgs/build-support/trivial-builders/test/writeCBin.nix b/nixpkgs/pkgs/build-support/trivial-builders/test/writeCBin.nix
new file mode 100644
index 000000000000..56cab45b3801
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/trivial-builders/test/writeCBin.nix
@@ -0,0 +1,43 @@
+/*
+  Run with:
+
+      cd nixpkgs
+      nix-build -A tests.trivial-builders.writeCBin
+*/
+
+{ lib, writeCBin, runCommand }:
+let
+  output = "hello";
+  pkg = writeCBin "test-script" ''
+    #include <stdio.h>
+    int main () {
+      printf("hello\n");
+      return 0;
+    }
+  '';
+in
+  assert pkg.meta.mainProgram == "test-script";
+  runCommand "test-writeCBin" { } ''
+
+    echo Testing with getExe...
+
+    target=${lib.getExe pkg}
+    expected=${lib.escapeShellArg output}
+    got=$("$target")
+    if [[ "$got" != "$expected" ]]; then
+      echo "wrong output: expected $expected, got $got"
+      exit 1
+    fi
+
+    echo Testing with makeBinPath...
+
+    PATH="${lib.makeBinPath [ pkg ]}:$PATH"
+    got=$(test-script)
+    if [[ "$got" != "$expected" ]]; then
+      echo "wrong output: expected $expected, got $got"
+      exit 1
+    fi
+
+    touch $out
+  ''
+
diff --git a/nixpkgs/pkgs/build-support/trivial-builders/test/writeScriptBin.nix b/nixpkgs/pkgs/build-support/trivial-builders/test/writeScriptBin.nix
new file mode 100644
index 000000000000..1487443130da
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/trivial-builders/test/writeScriptBin.nix
@@ -0,0 +1,39 @@
+/*
+  Run with:
+
+      cd nixpkgs
+      nix-build -A tests.trivial-builders.writeShellScriptBin
+*/
+
+{ lib, writeScriptBin, runCommand }:
+let
+  output = "hello";
+  pkg = writeScriptBin "test-script" ''
+    echo ${lib.escapeShellArg output}
+  '';
+in
+  assert pkg.meta.mainProgram == "test-script";
+  runCommand "test-writeScriptBin" { } ''
+
+    echo Testing with getExe...
+
+    target=${lib.getExe pkg}
+    expected=${lib.escapeShellArg output}
+    got=$("$target")
+    if [[ "$got" != "$expected" ]]; then
+      echo "wrong output: expected $expected, got $got"
+      exit 1
+    fi
+
+    echo Testing with makeBinPath...
+
+    PATH="${lib.makeBinPath [ pkg ]}:$PATH"
+    got=$(test-script)
+    if [[ "$got" != "$expected" ]]; then
+      echo "wrong output: expected $expected, got $got"
+      exit 1
+    fi
+
+    touch $out
+  ''
+
diff --git a/nixpkgs/pkgs/build-support/trivial-builders/test/writeShellScriptBin.nix b/nixpkgs/pkgs/build-support/trivial-builders/test/writeShellScriptBin.nix
new file mode 100644
index 000000000000..e93410e25bcb
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/trivial-builders/test/writeShellScriptBin.nix
@@ -0,0 +1,39 @@
+/*
+  Run with:
+
+      cd nixpkgs
+      nix-build -A tests.trivial-builders.writeShellScriptBin
+*/
+
+{ lib, writeShellScriptBin, runCommand }:
+let
+  output = "hello";
+  pkg = writeShellScriptBin "test-script" ''
+    echo ${lib.escapeShellArg output}
+  '';
+in
+  assert pkg.meta.mainProgram == "test-script";
+  runCommand "test-writeShellScriptBin" { } ''
+
+    echo Testing with getExe...
+
+    target=${lib.getExe pkg}
+    expected=${lib.escapeShellArg output}
+    got=$("$target")
+    if [[ "$got" != "$expected" ]]; then
+      echo "wrong output: expected $expected, got $got"
+      exit 1
+    fi
+
+    echo Testing with makeBinPath...
+
+    PATH="${lib.makeBinPath [ pkg ]}:$PATH"
+    got=$(test-script)
+    if [[ "$got" != "$expected" ]]; then
+      echo "wrong output: expected $expected, got $got"
+      exit 1
+    fi
+
+    touch $out
+  ''
+
diff --git a/nixpkgs/pkgs/build-support/vm/default.nix b/nixpkgs/pkgs/build-support/vm/default.nix
index 403bc9b1d2da..f6baa42348ab 100644
--- a/nixpkgs/pkgs/build-support/vm/default.nix
+++ b/nixpkgs/pkgs/build-support/vm/default.nix
@@ -468,7 +468,7 @@ rec {
 
         echo "installing RPMs..."
         PATH=/usr/bin:/bin:/usr/sbin:/sbin $chroot /mnt \
-          rpm -iv --nosignature ${if runScripts then "" else "--noscripts"} $rpms
+          rpm -iv --nosignature ${lib.optionalString (!runScripts) "--noscripts"} $rpms
 
         echo "running post-install script..."
         eval "$postInstall"
@@ -1018,7 +1018,7 @@ rec {
         url = "https://snapshot.debian.org/archive/debian/20221126T084953Z/dists/buster/main/binary-i386/Packages.xz";
         hash = "sha256-n9JquhtZgxw3qr9BX0MQoY3ZTIHN0dit+iru3DC31UY=";
       };
-      urlPrefix = "mirror://debian";
+      urlPrefix = "https://snapshot.debian.org/archive/debian/20221126T084953Z";
       packages = commonDebianPackages;
     };
 
@@ -1029,7 +1029,7 @@ rec {
         url = "https://snapshot.debian.org/archive/debian/20221126T084953Z/dists/buster/main/binary-amd64/Packages.xz";
         hash = "sha256-YukIIB3u87jgp9oudwklsxyKVKjSL618wFgDSXiFmjU=";
       };
-      urlPrefix = "mirror://debian";
+      urlPrefix = "https://snapshot.debian.org/archive/debian/20221126T084953Z";
       packages = commonDebianPackages;
     };
 
@@ -1040,7 +1040,7 @@ rec {
         url = "https://snapshot.debian.org/archive/debian/20230131T034648Z/dists/bullseye/main/binary-i386/Packages.xz";
         hash = "sha256-z9eG7RlvelEnZAaeCfIO+XxTZVL3d+zTA7ShU43l/pw=";
       };
-      urlPrefix = "mirror://debian";
+      urlPrefix = "https://snapshot.debian.org/archive/debian/20230131T034648Z";
       packages = commonDebianPackages;
     };
 
@@ -1051,7 +1051,7 @@ rec {
         url = "https://snapshot.debian.org/archive/debian/20230131T034648Z/dists/bullseye/main/binary-amd64/Packages.xz";
         hash = "sha256-mz0eCWdn6uWt40OxsSPheHzEnMeLE52yR/vpb48/VF0=";
       };
-      urlPrefix = "mirror://debian";
+      urlPrefix = "https://snapshot.debian.org/archive/debian/20230131T034648Z";
       packages = commonDebianPackages;
     };
   };
diff --git a/nixpkgs/pkgs/build-support/writers/data.nix b/nixpkgs/pkgs/build-support/writers/data.nix
new file mode 100644
index 000000000000..48f9bc547ed3
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/writers/data.nix
@@ -0,0 +1,80 @@
+{ lib, runCommand, dasel }:
+let
+  daselBin = lib.getExe dasel;
+
+  inherit (lib)
+    last
+    optionalString
+    types
+    ;
+in
+rec {
+  # Creates a transformer function that writes input data to disk, transformed
+  # by both the `input` and `output` arguments.
+  #
+  # Type: makeDataWriter :: input -> output -> nameOrPath -> data -> (any -> string) -> string -> string -> any -> derivation
+  #
+  #   input :: T -> string: function that takes the nix data and returns a string
+  #   output :: string: script that takes the $inputFile and write the result into $out
+  #   nameOrPath :: string: if the name contains a / the files gets written to a sub-folder of $out. The derivation name is the basename of this argument.
+  #   data :: T: the data that will be converted.
+  #
+  # Example:
+  #   writeJSON = makeDataWriter { input = builtins.toJSON; output = "cp $inputPath $out"; };
+  #   myConfig = writeJSON "config.json" { hello = "world"; }
+  #
+  makeDataWriter = { input ? lib.id, output ? "cp $inputPath $out" }: nameOrPath: data:
+    assert lib.or (types.path.check nameOrPath) (builtins.match "([0-9A-Za-z._])[0-9A-Za-z._-]*" nameOrPath != null);
+    let
+      name = last (builtins.split "/" nameOrPath);
+    in
+    runCommand name
+      {
+        input = input data;
+        passAsFile = [ "input" ];
+      } ''
+      ${output}
+
+      ${optionalString (types.path.check nameOrPath) ''
+        mv $out tmp
+        mkdir -p $out/$(dirname "${nameOrPath}")
+        mv tmp $out/${nameOrPath}
+      ''}
+    '';
+
+  # Writes the content to text.
+  #
+  # Example:
+  #   writeText "filename.txt" "file content"
+  writeText = makeDataWriter {
+    input = toString;
+    output = "cp $inputPath $out";
+  };
+
+  # Writes the content to a JSON file.
+  #
+  # Example:
+  #   writeJSON "data.json" { hello = "world"; }
+  writeJSON = makeDataWriter {
+    input = builtins.toJSON;
+    output = "${daselBin} -f $inputPath -r json -w json > $out";
+  };
+
+  # Writes the content to a TOML file.
+  #
+  # Example:
+  #   writeTOML "data.toml" { hello = "world"; }
+  writeTOML = makeDataWriter {
+    input = builtins.toJSON;
+    output = "${daselBin} -f $inputPath -r json -w toml > $out";
+  };
+
+  # Writes the content to a YAML file.
+  #
+  # Example:
+  #   writeYAML "data.yaml" { hello = "world"; }
+  writeYAML = makeDataWriter {
+    input = builtins.toJSON;
+    output = "${daselBin} -f $inputPath -r json -w yaml > $out";
+  };
+}
diff --git a/nixpkgs/pkgs/build-support/writers/default.nix b/nixpkgs/pkgs/build-support/writers/default.nix
index 2c26f350fbd7..a161322cd35b 100644
--- a/nixpkgs/pkgs/build-support/writers/default.nix
+++ b/nixpkgs/pkgs/build-support/writers/default.nix
@@ -1,367 +1,14 @@
-{ pkgs, config, buildPackages, lib, stdenv, libiconv, mkNugetDeps, mkNugetSource, gixy }:
+{ config, lib, callPackages }:
 
 let
   aliases = if config.allowAliases then (import ./aliases.nix lib) else prev: {};
 
-  writers = with lib; rec {
-  # Base implementation for non-compiled executables.
-  # Takes an interpreter, for example `${pkgs.bash}/bin/bash`
-  #
-  # Examples:
-  #   writeBash = makeScriptWriter { interpreter = "${pkgs.bash}/bin/bash"; }
-  #   makeScriptWriter { interpreter = "${pkgs.dash}/bin/dash"; } "hello" "echo hello world"
-  makeScriptWriter = { interpreter, check ? "" }: nameOrPath: content:
-    assert lib.or (types.path.check nameOrPath) (builtins.match "([0-9A-Za-z._])[0-9A-Za-z._-]*" nameOrPath != null);
-    assert lib.or (types.path.check content) (types.str.check content);
-    let
-      name = last (builtins.split "/" nameOrPath);
-    in
+  # Writers for JSON-like data structures
+  dataWriters = callPackages ./data.nix { };
 
-    pkgs.runCommandLocal name (if (types.str.check content) then {
-      inherit content interpreter;
-      passAsFile = [ "content" ];
-    } else {
-      inherit interpreter;
-      contentPath = content;
-    }) ''
-      # On darwin a script cannot be used as an interpreter in a shebang but
-      # there doesn't seem to be a limit to the size of shebang and multiple
-      # arguments to the interpreter are allowed.
-      if [[ -n "${toString pkgs.stdenvNoCC.isDarwin}" ]] && isScript $interpreter
-      then
-        wrapperInterpreterLine=$(head -1 "$interpreter" | tail -c+3)
-        # Get first word from the line (note: xargs echo remove leading spaces)
-        wrapperInterpreter=$(echo "$wrapperInterpreterLine" | xargs echo | cut -d " " -f1)
+  # Writers for scripts
+  scriptWriters = callPackages ./scripts.nix { };
 
-        if isScript $wrapperInterpreter
-        then
-          echo "error: passed interpreter ($interpreter) is a script which has another script ($wrapperInterpreter) as an interpreter, which is not supported."
-          exit 1
-        fi
-
-        # This should work as long as wrapperInterpreter is a shell, which is
-        # the case for programs wrapped with makeWrapper, like
-        # python3.withPackages etc.
-        interpreterLine="$wrapperInterpreterLine $interpreter"
-      else
-        interpreterLine=$interpreter
-      fi
-
-      echo "#! $interpreterLine" > $out
-      cat "$contentPath" >> $out
-      ${optionalString (check != "") ''
-        ${check} $out
-      ''}
-      chmod +x $out
-      ${optionalString (types.path.check nameOrPath) ''
-        mv $out tmp
-        mkdir -p $out/$(dirname "${nameOrPath}")
-        mv tmp $out/${nameOrPath}
-      ''}
-    '';
-
-  # Base implementation for compiled executables.
-  # Takes a compile script, which in turn takes the name as an argument.
-  #
-  # Examples:
-  #   writeSimpleC = makeBinWriter { compileScript = name: "gcc -o $out $contentPath"; }
-  makeBinWriter = { compileScript, strip ? true }: nameOrPath: content:
-    assert lib.or (types.path.check nameOrPath) (builtins.match "([0-9A-Za-z._])[0-9A-Za-z._-]*" nameOrPath != null);
-    assert lib.or (types.path.check content) (types.str.check content);
-    let
-      name = last (builtins.split "/" nameOrPath);
-    in
-    pkgs.runCommand name ((if (types.str.check content) then {
-      inherit content;
-      passAsFile = [ "content" ];
-    } else {
-      contentPath = content;
-    }) // lib.optionalAttrs (stdenv.hostPlatform.isDarwin && stdenv.hostPlatform.isAarch64) {
-      # post-link-hook expects codesign_allocate to be in PATH
-      # https://github.com/NixOS/nixpkgs/issues/154203
-      # https://github.com/NixOS/nixpkgs/issues/148189
-      nativeBuildInputs = [ stdenv.cc.bintools ];
-    }) ''
-      ${compileScript}
-      ${lib.optionalString strip
-          "${lib.getBin buildPackages.bintools-unwrapped}/bin/${buildPackages.bintools-unwrapped.targetPrefix}strip -S $out"}
-      # Sometimes binaries produced for darwin (e. g. by GHC) won't be valid
-      # mach-o executables from the get-go, but need to be corrected somehow
-      # which is done by fixupPhase.
-      ${lib.optionalString pkgs.stdenvNoCC.hostPlatform.isDarwin "fixupPhase"}
-      ${optionalString (types.path.check nameOrPath) ''
-        mv $out tmp
-        mkdir -p $out/$(dirname "${nameOrPath}")
-        mv tmp $out/${nameOrPath}
-      ''}
-    '';
-
-  # Like writeScript but the first line is a shebang to bash
-  #
-  # Example:
-  #   writeBash "example" ''
-  #     echo hello world
-  #   ''
-  writeBash = makeScriptWriter {
-    interpreter = "${pkgs.bash}/bin/bash";
-  };
-
-  # Like writeScriptBin but the first line is a shebang to bash
-  writeBashBin = name:
-    writeBash "/bin/${name}";
-
-  # Like writeScript but the first line is a shebang to dash
-  #
-  # Example:
-  #   writeDash "example" ''
-  #     echo hello world
-  #   ''
-  writeDash = makeScriptWriter {
-    interpreter = "${pkgs.dash}/bin/dash";
-  };
-
-  # Like writeScriptBin but the first line is a shebang to dash
-  writeDashBin = name:
-    writeDash "/bin/${name}";
-
-  # Like writeScript but the first line is a shebang to fish
-  #
-  # Example:
-  #   writeFish "example" ''
-  #     echo hello world
-  #   ''
-  writeFish = makeScriptWriter {
-    interpreter = "${pkgs.fish}/bin/fish --no-config";
-    check = "${pkgs.fish}/bin/fish --no-config --no-execute";  # syntax check only
-  };
-
-  # Like writeScriptBin but the first line is a shebang to fish
-  writeFishBin = name:
-    writeFish "/bin/${name}";
-
-  # writeHaskell takes a name, an attrset with libraries and haskell version (both optional)
-  # and some haskell source code and returns an executable.
-  #
-  # Example:
-  #   writeHaskell "missiles" { libraries = [ pkgs.haskellPackages.acme-missiles ]; } ''
-  #     import Acme.Missiles
-  #
-  #     main = launchMissiles
-  #   '';
-  writeHaskell = name: {
-    libraries ? [],
-    ghc ? pkgs.ghc,
-    ghcArgs ? [],
-    threadedRuntime ? true,
-    strip ? true
-  }:
-    let
-      appendIfNotSet = el: list: if elem el list then list else list ++ [ el ];
-      ghcArgs' = if threadedRuntime then appendIfNotSet "-threaded" ghcArgs else ghcArgs;
-
-    in makeBinWriter {
-      compileScript = ''
-        cp $contentPath tmp.hs
-        ${ghc.withPackages (_: libraries )}/bin/ghc ${lib.escapeShellArgs ghcArgs'} tmp.hs
-        mv tmp $out
-      '';
-      inherit strip;
-    } name;
-
-  # writeHaskellBin takes the same arguments as writeHaskell but outputs a directory (like writeScriptBin)
-  writeHaskellBin = name:
-    writeHaskell "/bin/${name}";
-
-  writeRust = name: {
-      rustc ? pkgs.rustc,
-      rustcArgs ? [],
-      strip ? true
-  }:
-  let
-    darwinArgs = lib.optionals stdenv.isDarwin [ "-L${lib.getLib libiconv}/lib" ];
-  in
-    makeBinWriter {
-      compileScript = ''
-        cp "$contentPath" tmp.rs
-        PATH=${makeBinPath [pkgs.gcc]} ${lib.getBin rustc}/bin/rustc ${lib.escapeShellArgs rustcArgs} ${lib.escapeShellArgs darwinArgs} -o "$out" tmp.rs
-      '';
-      inherit strip;
-    } name;
-
-  writeRustBin = name:
-    writeRust "/bin/${name}";
-
-  # writeJS takes a name an attributeset with libraries and some JavaScript sourcecode and
-  # returns an executable
-  #
-  # Example:
-  #   writeJS "example" { libraries = [ pkgs.nodePackages.uglify-js ]; } ''
-  #     var UglifyJS = require("uglify-js");
-  #     var code = "function add(first, second) { return first + second; }";
-  #     var result = UglifyJS.minify(code);
-  #     console.log(result.code);
-  #   ''
-  writeJS = name: { libraries ? [] }: content:
-  let
-    node-env = pkgs.buildEnv {
-      name = "node";
-      paths = libraries;
-      pathsToLink = [
-        "/lib/node_modules"
-      ];
-    };
-  in writeDash name ''
-    export NODE_PATH=${node-env}/lib/node_modules
-    exec ${pkgs.nodejs}/bin/node ${pkgs.writeText "js" content} "$@"
-  '';
-
-  # writeJSBin takes the same arguments as writeJS but outputs a directory (like writeScriptBin)
-  writeJSBin = name:
-    writeJS "/bin/${name}";
-
-  awkFormatNginx = builtins.toFile "awkFormat-nginx.awk" ''
-    awk -f
-    {sub(/^[ \t]+/,"");idx=0}
-    /\{/{ctx++;idx=1}
-    /\}/{ctx--}
-    {id="";for(i=idx;i<ctx;i++)id=sprintf("%s%s", id, "\t");printf "%s%s\n", id, $0}
-   '';
-
-  writeNginxConfig = name: text: pkgs.runCommandLocal name {
-    inherit text;
-    passAsFile = [ "text" ];
-    nativeBuildInputs = [ gixy ];
-  } /* sh */ ''
-    # nginx-config-formatter has an error - https://github.com/1connect/nginx-config-formatter/issues/16
-    awk -f ${awkFormatNginx} "$textPath" | sed '/^\s*$/d' > $out
-    gixy $out
-  '';
-
-  # writePerl takes a name an attributeset with libraries and some perl sourcecode and
-  # returns an executable
-  #
-  # Example:
-  #   writePerl "example" { libraries = [ pkgs.perlPackages.boolean ]; } ''
-  #     use boolean;
-  #     print "Howdy!\n" if true;
-  #   ''
-  writePerl = name: { libraries ? [] }:
-    makeScriptWriter {
-      interpreter = "${pkgs.perl.withPackages (p: libraries)}/bin/perl";
-    } name;
-
-  # writePerlBin takes the same arguments as writePerl but outputs a directory (like writeScriptBin)
-  writePerlBin = name:
-    writePerl "/bin/${name}";
-
-  # makePythonWriter takes python and compatible pythonPackages and produces python script writer,
-  # which validates the script with flake8 at build time. If any libraries are specified,
-  # python.withPackages is used as interpreter, otherwise the "bare" python is used.
-  makePythonWriter = python: pythonPackages: buildPythonPackages: name: { libraries ? [], flakeIgnore ? [] }:
-  let
-    ignoreAttribute = optionalString (flakeIgnore != []) "--ignore ${concatMapStringsSep "," escapeShellArg flakeIgnore}";
-  in
-  makeScriptWriter {
-    interpreter =
-      if libraries == []
-      then "${python}/bin/python"
-      else "${python.withPackages (ps: libraries)}/bin/python"
-    ;
-    check = optionalString python.isPy3k (writeDash "pythoncheck.sh" ''
-      exec ${buildPythonPackages.flake8}/bin/flake8 --show-source ${ignoreAttribute} "$1"
-    '');
-  } name;
-
-  # writePyPy2 takes a name an attributeset with libraries and some pypy2 sourcecode and
-  # returns an executable
-  #
-  # Example:
-  # writePyPy2 "test_pypy2" { libraries = [ pkgs.pypy2Packages.enum ]; } ''
-  #   from enum import Enum
-  #
-  #   class Test(Enum):
-  #       a = "success"
-  #
-  #   print Test.a
-  # ''
-  writePyPy2 = makePythonWriter pkgs.pypy2 pkgs.pypy2Packages buildPackages.pypy2Packages;
-
-  # writePyPy2Bin takes the same arguments as writePyPy2 but outputs a directory (like writeScriptBin)
-  writePyPy2Bin = name:
-    writePyPy2 "/bin/${name}";
-
-  # writePython3 takes a name an attributeset with libraries and some python3 sourcecode and
-  # returns an executable
-  #
-  # Example:
-  # writePython3 "test_python3" { libraries = [ pkgs.python3Packages.pyyaml ]; } ''
-  #   import yaml
-  #
-  #   y = yaml.load("""
-  #     - test: success
-  #   """)
-  #   print(y[0]['test'])
-  # ''
-  writePython3 = makePythonWriter pkgs.python3 pkgs.python3Packages buildPackages.python3Packages;
-
-  # writePython3Bin takes the same arguments as writePython3 but outputs a directory (like writeScriptBin)
-  writePython3Bin = name:
-    writePython3 "/bin/${name}";
-
-  # writePyPy3 takes a name an attributeset with libraries and some pypy3 sourcecode and
-  # returns an executable
-  #
-  # Example:
-  # writePyPy3 "test_pypy3" { libraries = [ pkgs.pypy3Packages.pyyaml ]; } ''
-  #   import yaml
-  #
-  #   y = yaml.load("""
-  #     - test: success
-  #   """)
-  #   print(y[0]['test'])
-  # ''
-  writePyPy3 = makePythonWriter pkgs.pypy3 pkgs.pypy3Packages buildPackages.pypy3Packages;
-
-  # writePyPy3Bin takes the same arguments as writePyPy3 but outputs a directory (like writeScriptBin)
-  writePyPy3Bin = name:
-    writePyPy3 "/bin/${name}";
-
-
-  makeFSharpWriter = { dotnet-sdk ? pkgs.dotnet-sdk, fsi-flags ? "", libraries ? _: [] }: nameOrPath:
-  let
-    fname = last (builtins.split "/" nameOrPath);
-    path = if strings.hasSuffix ".fsx" nameOrPath then nameOrPath else "${nameOrPath}.fsx";
-    _nugetDeps = mkNugetDeps { name = "${fname}-nuget-deps"; nugetDeps = libraries; };
-
-    nuget-source = mkNugetSource {
-      name = "${fname}-nuget-source";
-      description = "A Nuget source with the dependencies for ${fname}";
-      deps = [ _nugetDeps ];
-    };
-
-    fsi = writeBash "fsi" ''
-      export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
-      export DOTNET_CLI_TELEMETRY_OPTOUT=1
-      export DOTNET_NOLOGO=1
-      script="$1"; shift
-      ${dotnet-sdk}/bin/dotnet fsi --quiet --nologo --readline- ${fsi-flags} "$@" < "$script"
-    '';
-
-  in content: writers.makeScriptWriter {
-    interpreter = fsi;
-  } path
-  ''
-    #i "nuget: ${nuget-source}/lib"
-    ${ content }
-    exit 0
-  '';
-
-  writeFSharp =
-    makeFSharpWriter {};
-
-  writeFSharpBin = name:
-    writeFSharp "/bin/${name}";
-
-};
+  writers = scriptWriters // dataWriters;
 in
 writers // (aliases writers)
diff --git a/nixpkgs/pkgs/build-support/writers/scripts.nix b/nixpkgs/pkgs/build-support/writers/scripts.nix
new file mode 100644
index 000000000000..c43f10f0a2ec
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/writers/scripts.nix
@@ -0,0 +1,384 @@
+{ pkgs, buildPackages, lib, stdenv, libiconv, mkNugetDeps, mkNugetSource, gixy }:
+let
+  inherit (lib)
+    concatMapStringsSep
+    elem
+    escapeShellArg
+    last
+    optionalString
+    stringLength
+    strings
+    types
+    ;
+in
+rec {
+  # Base implementation for non-compiled executables.
+  # Takes an interpreter, for example `${pkgs.bash}/bin/bash`
+  #
+  # Examples:
+  #   writeBash = makeScriptWriter { interpreter = "${pkgs.bash}/bin/bash"; }
+  #   makeScriptWriter { interpreter = "${pkgs.dash}/bin/dash"; } "hello" "echo hello world"
+  makeScriptWriter = { interpreter, check ? "" }: nameOrPath: content:
+    assert lib.or (types.path.check nameOrPath) (builtins.match "([0-9A-Za-z._])[0-9A-Za-z._-]*" nameOrPath != null);
+    assert lib.or (types.path.check content) (types.str.check content);
+    let
+      name = last (builtins.split "/" nameOrPath);
+    in
+
+    pkgs.runCommandLocal name (
+      lib.optionalAttrs (nameOrPath == "/bin/${name}") {
+        meta.mainProgram = name;
+      }
+      // (
+        if (types.str.check content) then {
+          inherit content interpreter;
+          passAsFile = [ "content" ];
+        } else {
+          inherit interpreter;
+          contentPath = content;
+        }
+      )
+    )
+    ''
+      # On darwin a script cannot be used as an interpreter in a shebang but
+      # there doesn't seem to be a limit to the size of shebang and multiple
+      # arguments to the interpreter are allowed.
+      if [[ -n "${toString pkgs.stdenvNoCC.isDarwin}" ]] && isScript $interpreter
+      then
+        wrapperInterpreterLine=$(head -1 "$interpreter" | tail -c+3)
+        # Get first word from the line (note: xargs echo remove leading spaces)
+        wrapperInterpreter=$(echo "$wrapperInterpreterLine" | xargs echo | cut -d " " -f1)
+
+        if isScript $wrapperInterpreter
+        then
+          echo "error: passed interpreter ($interpreter) is a script which has another script ($wrapperInterpreter) as an interpreter, which is not supported."
+          exit 1
+        fi
+
+        # This should work as long as wrapperInterpreter is a shell, which is
+        # the case for programs wrapped with makeWrapper, like
+        # python3.withPackages etc.
+        interpreterLine="$wrapperInterpreterLine $interpreter"
+      else
+        interpreterLine=$interpreter
+      fi
+
+      echo "#! $interpreterLine" > $out
+      cat "$contentPath" >> $out
+      ${optionalString (check != "") ''
+        ${check} $out
+      ''}
+      chmod +x $out
+      ${optionalString (types.path.check nameOrPath) ''
+        mv $out tmp
+        mkdir -p $out/$(dirname "${nameOrPath}")
+        mv tmp $out/${nameOrPath}
+      ''}
+    '';
+
+  # Base implementation for compiled executables.
+  # Takes a compile script, which in turn takes the name as an argument.
+  #
+  # Examples:
+  #   writeSimpleC = makeBinWriter { compileScript = name: "gcc -o $out $contentPath"; }
+  makeBinWriter = { compileScript, strip ? true }: nameOrPath: content:
+    assert lib.or (types.path.check nameOrPath) (builtins.match "([0-9A-Za-z._])[0-9A-Za-z._-]*" nameOrPath != null);
+    assert lib.or (types.path.check content) (types.str.check content);
+    let
+      name = last (builtins.split "/" nameOrPath);
+    in
+    pkgs.runCommand name ((if (types.str.check content) then {
+      inherit content;
+      passAsFile = [ "content" ];
+    } else {
+      contentPath = content;
+    }) // lib.optionalAttrs (stdenv.hostPlatform.isDarwin && stdenv.hostPlatform.isAarch64) {
+      # post-link-hook expects codesign_allocate to be in PATH
+      # https://github.com/NixOS/nixpkgs/issues/154203
+      # https://github.com/NixOS/nixpkgs/issues/148189
+      nativeBuildInputs = [ stdenv.cc.bintools ];
+    } // lib.optionalAttrs (nameOrPath == "/bin/${name}") {
+      meta.mainProgram = name;
+    }) ''
+      ${compileScript}
+      ${lib.optionalString strip
+          "${lib.getBin buildPackages.bintools-unwrapped}/bin/${buildPackages.bintools-unwrapped.targetPrefix}strip -S $out"}
+      # Sometimes binaries produced for darwin (e. g. by GHC) won't be valid
+      # mach-o executables from the get-go, but need to be corrected somehow
+      # which is done by fixupPhase.
+      ${lib.optionalString pkgs.stdenvNoCC.hostPlatform.isDarwin "fixupPhase"}
+      ${optionalString (types.path.check nameOrPath) ''
+        mv $out tmp
+        mkdir -p $out/$(dirname "${nameOrPath}")
+        mv tmp $out/${nameOrPath}
+      ''}
+    '';
+
+  # Like writeScript but the first line is a shebang to bash
+  #
+  # Example:
+  #   writeBash "example" ''
+  #     echo hello world
+  #   ''
+  writeBash = makeScriptWriter {
+    interpreter = "${pkgs.bash}/bin/bash";
+  };
+
+  # Like writeScriptBin but the first line is a shebang to bash
+  writeBashBin = name:
+    writeBash "/bin/${name}";
+
+  # Like writeScript but the first line is a shebang to dash
+  #
+  # Example:
+  #   writeDash "example" ''
+  #     echo hello world
+  #   ''
+  writeDash = makeScriptWriter {
+    interpreter = "${pkgs.dash}/bin/dash";
+  };
+
+  # Like writeScriptBin but the first line is a shebang to dash
+  writeDashBin = name:
+    writeDash "/bin/${name}";
+
+  # Like writeScript but the first line is a shebang to fish
+  #
+  # Example:
+  #   writeFish "example" ''
+  #     echo hello world
+  #   ''
+  writeFish = makeScriptWriter {
+    interpreter = "${pkgs.fish}/bin/fish --no-config";
+    check = "${pkgs.fish}/bin/fish --no-config --no-execute";  # syntax check only
+  };
+
+  # Like writeScriptBin but the first line is a shebang to fish
+  writeFishBin = name:
+    writeFish "/bin/${name}";
+
+  # writeHaskell takes a name, an attrset with libraries and haskell version (both optional)
+  # and some haskell source code and returns an executable.
+  #
+  # Example:
+  #   writeHaskell "missiles" { libraries = [ pkgs.haskellPackages.acme-missiles ]; } ''
+  #     import Acme.Missiles
+  #
+  #     main = launchMissiles
+  #   '';
+  writeHaskell = name: {
+    libraries ? [],
+    ghc ? pkgs.ghc,
+    ghcArgs ? [],
+    threadedRuntime ? true,
+    strip ? true
+  }:
+    let
+      appendIfNotSet = el: list: if elem el list then list else list ++ [ el ];
+      ghcArgs' = if threadedRuntime then appendIfNotSet "-threaded" ghcArgs else ghcArgs;
+
+    in makeBinWriter {
+      compileScript = ''
+        cp $contentPath tmp.hs
+        ${ghc.withPackages (_: libraries )}/bin/ghc ${lib.escapeShellArgs ghcArgs'} tmp.hs
+        mv tmp $out
+      '';
+      inherit strip;
+    } name;
+
+  # writeHaskellBin takes the same arguments as writeHaskell but outputs a directory (like writeScriptBin)
+  writeHaskellBin = name:
+    writeHaskell "/bin/${name}";
+
+  writeRust = name: {
+      rustc ? pkgs.rustc,
+      rustcArgs ? [],
+      strip ? true
+  }:
+  let
+    darwinArgs = lib.optionals stdenv.isDarwin [ "-L${lib.getLib libiconv}/lib" ];
+  in
+    makeBinWriter {
+      compileScript = ''
+        cp "$contentPath" tmp.rs
+        PATH=${lib.makeBinPath [pkgs.gcc]} ${lib.getBin rustc}/bin/rustc ${lib.escapeShellArgs rustcArgs} ${lib.escapeShellArgs darwinArgs} -o "$out" tmp.rs
+      '';
+      inherit strip;
+    } name;
+
+  writeRustBin = name:
+    writeRust "/bin/${name}";
+
+  # writeJS takes a name an attributeset with libraries and some JavaScript sourcecode and
+  # returns an executable
+  #
+  # Example:
+  #   writeJS "example" { libraries = [ pkgs.nodePackages.uglify-js ]; } ''
+  #     var UglifyJS = require("uglify-js");
+  #     var code = "function add(first, second) { return first + second; }";
+  #     var result = UglifyJS.minify(code);
+  #     console.log(result.code);
+  #   ''
+  writeJS = name: { libraries ? [] }: content:
+  let
+    node-env = pkgs.buildEnv {
+      name = "node";
+      paths = libraries;
+      pathsToLink = [
+        "/lib/node_modules"
+      ];
+    };
+  in writeDash name ''
+    export NODE_PATH=${node-env}/lib/node_modules
+    exec ${pkgs.nodejs}/bin/node ${pkgs.writeText "js" content} "$@"
+  '';
+
+  # writeJSBin takes the same arguments as writeJS but outputs a directory (like writeScriptBin)
+  writeJSBin = name:
+    writeJS "/bin/${name}";
+
+  awkFormatNginx = builtins.toFile "awkFormat-nginx.awk" ''
+    awk -f
+    {sub(/^[ \t]+/,"");idx=0}
+    /\{/{ctx++;idx=1}
+    /\}/{ctx--}
+    {id="";for(i=idx;i<ctx;i++)id=sprintf("%s%s", id, "\t");printf "%s%s\n", id, $0}
+   '';
+
+  writeNginxConfig = name: text: pkgs.runCommandLocal name {
+    inherit text;
+    passAsFile = [ "text" ];
+    nativeBuildInputs = [ gixy ];
+  } /* sh */ ''
+    # nginx-config-formatter has an error - https://github.com/1connect/nginx-config-formatter/issues/16
+    awk -f ${awkFormatNginx} "$textPath" | sed '/^\s*$/d' > $out
+    gixy $out
+  '';
+
+  # writePerl takes a name an attributeset with libraries and some perl sourcecode and
+  # returns an executable
+  #
+  # Example:
+  #   writePerl "example" { libraries = [ pkgs.perlPackages.boolean ]; } ''
+  #     use boolean;
+  #     print "Howdy!\n" if true;
+  #   ''
+  writePerl = name: { libraries ? [] }:
+    makeScriptWriter {
+      interpreter = "${pkgs.perl.withPackages (p: libraries)}/bin/perl";
+    } name;
+
+  # writePerlBin takes the same arguments as writePerl but outputs a directory (like writeScriptBin)
+  writePerlBin = name:
+    writePerl "/bin/${name}";
+
+  # makePythonWriter takes python and compatible pythonPackages and produces python script writer,
+  # which validates the script with flake8 at build time. If any libraries are specified,
+  # python.withPackages is used as interpreter, otherwise the "bare" python is used.
+  makePythonWriter = python: pythonPackages: buildPythonPackages: name: { libraries ? [], flakeIgnore ? [] }:
+  let
+    ignoreAttribute = optionalString (flakeIgnore != []) "--ignore ${concatMapStringsSep "," escapeShellArg flakeIgnore}";
+  in
+  makeScriptWriter {
+    interpreter =
+      if libraries == []
+      then python.interpreter
+      else (python.withPackages (ps: libraries)).interpreter
+    ;
+    check = optionalString python.isPy3k (writeDash "pythoncheck.sh" ''
+      exec ${buildPythonPackages.flake8}/bin/flake8 --show-source ${ignoreAttribute} "$1"
+    '');
+  } name;
+
+  # writePyPy2 takes a name an attributeset with libraries and some pypy2 sourcecode and
+  # returns an executable
+  #
+  # Example:
+  # writePyPy2 "test_pypy2" { libraries = [ pkgs.pypy2Packages.enum ]; } ''
+  #   from enum import Enum
+  #
+  #   class Test(Enum):
+  #       a = "success"
+  #
+  #   print Test.a
+  # ''
+  writePyPy2 = makePythonWriter pkgs.pypy2 pkgs.pypy2Packages buildPackages.pypy2Packages;
+
+  # writePyPy2Bin takes the same arguments as writePyPy2 but outputs a directory (like writeScriptBin)
+  writePyPy2Bin = name:
+    writePyPy2 "/bin/${name}";
+
+  # writePython3 takes a name an attributeset with libraries and some python3 sourcecode and
+  # returns an executable
+  #
+  # Example:
+  # writePython3 "test_python3" { libraries = [ pkgs.python3Packages.pyyaml ]; } ''
+  #   import yaml
+  #
+  #   y = yaml.load("""
+  #     - test: success
+  #   """)
+  #   print(y[0]['test'])
+  # ''
+  writePython3 = makePythonWriter pkgs.python3 pkgs.python3Packages buildPackages.python3Packages;
+
+  # writePython3Bin takes the same arguments as writePython3 but outputs a directory (like writeScriptBin)
+  writePython3Bin = name:
+    writePython3 "/bin/${name}";
+
+  # writePyPy3 takes a name an attributeset with libraries and some pypy3 sourcecode and
+  # returns an executable
+  #
+  # Example:
+  # writePyPy3 "test_pypy3" { libraries = [ pkgs.pypy3Packages.pyyaml ]; } ''
+  #   import yaml
+  #
+  #   y = yaml.load("""
+  #     - test: success
+  #   """)
+  #   print(y[0]['test'])
+  # ''
+  writePyPy3 = makePythonWriter pkgs.pypy3 pkgs.pypy3Packages buildPackages.pypy3Packages;
+
+  # writePyPy3Bin takes the same arguments as writePyPy3 but outputs a directory (like writeScriptBin)
+  writePyPy3Bin = name:
+    writePyPy3 "/bin/${name}";
+
+
+  makeFSharpWriter = { dotnet-sdk ? pkgs.dotnet-sdk, fsi-flags ? "", libraries ? _: [] }: nameOrPath:
+  let
+    fname = last (builtins.split "/" nameOrPath);
+    path = if strings.hasSuffix ".fsx" nameOrPath then nameOrPath else "${nameOrPath}.fsx";
+    _nugetDeps = mkNugetDeps { name = "${fname}-nuget-deps"; nugetDeps = libraries; };
+
+    nuget-source = mkNugetSource {
+      name = "${fname}-nuget-source";
+      description = "A Nuget source with the dependencies for ${fname}";
+      deps = [ _nugetDeps ];
+    };
+
+    fsi = writeBash "fsi" ''
+      export HOME=$NIX_BUILD_TOP/.home
+      export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
+      export DOTNET_CLI_TELEMETRY_OPTOUT=1
+      export DOTNET_NOLOGO=1
+      script="$1"; shift
+      ${dotnet-sdk}/bin/dotnet fsi --quiet --nologo --readline- ${fsi-flags} "$@" < "$script"
+    '';
+
+  in content: makeScriptWriter {
+    interpreter = fsi;
+  } path
+  ''
+    #i "nuget: ${nuget-source}/lib"
+    ${ content }
+    exit 0
+  '';
+
+  writeFSharp =
+    makeFSharpWriter {};
+
+  writeFSharpBin = name:
+    writeFSharp "/bin/${name}";
+
+}
diff --git a/nixpkgs/pkgs/build-support/writers/test.nix b/nixpkgs/pkgs/build-support/writers/test.nix
index 561c3e4ab002..2411f8c03a70 100644
--- a/nixpkgs/pkgs/build-support/writers/test.nix
+++ b/nixpkgs/pkgs/build-support/writers/test.nix
@@ -12,29 +12,62 @@
 }:
 with writers;
 let
+  expectSuccess = test:
+    runCommand "run-${test.name}" {} ''
+      if [[ "$(${test})" != success ]]; then
+        echo 'test ${test.name} failed'
+        exit 1
+      fi
 
-  bin = {
-    bash = writeBashBin "test-writers-bash-bin" ''
-     if [[ "test" == "test" ]]; then echo "success"; fi
+      touch $out
     '';
 
-    dash = writeDashBin "test-writers-dash-bin" ''
-     test '~' = '~' && echo 'success'
+  expectSuccessBin = test:
+    runCommand "run-${test.name}" {} ''
+      if [[ "$(${lib.getExe test})" != success ]]; then
+        echo 'test ${test.name} failed'
+        exit 1
+      fi
+
+      touch $out
     '';
 
-    fish = writeFishBin "test-writers-fish-bin" ''
+  expectDataEqual = { file, expected }:
+    let
+      expectedFile = writeText "${file.name}-expected" expected;
+    in
+    runCommand "run-${file.name}" {} ''
+      if ! diff -u ${file} ${expectedFile}; then
+        echo 'test ${file.name} failed'
+        exit 1
+      fi
+
+      touch $out
+    '';
+in
+lib.recurseIntoAttrs {
+  bin = lib.recurseIntoAttrs {
+    bash = expectSuccessBin (writeBashBin "test-writers-bash-bin" ''
+     if [[ "test" == "test" ]]; then echo "success"; fi
+    '');
+
+    dash = expectSuccessBin (writeDashBin "test-writers-dash-bin" ''
+     test '~' = '~' && echo 'success'
+    '');
+
+    fish = expectSuccessBin (writeFishBin "test-writers-fish-bin" ''
       if test "test" = "test"
         echo "success"
       end
-    '';
+    '');
 
-    rust = writeRustBin "test-writers-rust-bin" {} ''
+    rust = expectSuccessBin (writeRustBin "test-writers-rust-bin" {} ''
       fn main(){
         println!("success")
       }
-    '';
+    '');
 
-    haskell = writeHaskellBin "test-writers-haskell-bin" { libraries = [ haskellPackages.acme-default ]; } ''
+    haskell = expectSuccessBin (writeHaskellBin "test-writers-haskell-bin" { libraries = [ haskellPackages.acme-default ]; } ''
       import Data.Default
 
       int :: Int
@@ -44,9 +77,9 @@ let
       main = case int of
         18871 -> putStrLn $ id "success"
         _ -> print "fail"
-    '';
+    '');
 
-    js = writeJSBin "test-writers-js-bin" { libraries = [ nodePackages.semver ]; } ''
+    js = expectSuccessBin (writeJSBin "test-writers-js-bin" { libraries = [ nodePackages.semver ]; } ''
       var semver = require('semver');
 
       if (semver.valid('1.2.3')) {
@@ -54,59 +87,57 @@ let
       } else {
         console.log('fail')
       }
-    '';
+    '');
 
-    perl = writePerlBin "test-writers-perl-bin" { libraries = [ perlPackages.boolean ]; } ''
+    perl = expectSuccessBin (writePerlBin "test-writers-perl-bin" { libraries = [ perlPackages.boolean ]; } ''
       use boolean;
       print "success\n" if true;
-    '';
+    '');
 
-    pypy2 = writePyPy2Bin "test-writers-pypy2-bin" { libraries = [ pypy2Packages.enum ]; } ''
+    pypy2 = expectSuccessBin (writePyPy2Bin "test-writers-pypy2-bin" { libraries = [ pypy2Packages.enum ]; } ''
       from enum import Enum
 
-
       class Test(Enum):
           a = "success"
 
-
       print Test.a
-    '';
+    '');
 
-    python3 = writePython3Bin "test-writers-python3-bin" { libraries = [ python3Packages.pyyaml ]; } ''
+    python3 = expectSuccessBin (writePython3Bin "test-writers-python3-bin" { libraries = [ python3Packages.pyyaml ]; } ''
       import yaml
 
-      y = yaml.load("""
+      y = yaml.safe_load("""
         - test: success
       """)
       print(y[0]['test'])
-    '';
+    '');
 
-    pypy3 = writePyPy3Bin "test-writers-pypy3-bin" { libraries = [ pypy3Packages.pyyaml ]; } ''
+    pypy3 = expectSuccessBin (writePyPy3Bin "test-writers-pypy3-bin" { libraries = [ pypy3Packages.pyyaml ]; } ''
       import yaml
 
-      y = yaml.load("""
+      y = yaml.safe_load("""
         - test: success
       """)
       print(y[0]['test'])
-    '';
+    '');
   };
 
-  simple = {
-    bash = writeBash "test-writers-bash" ''
+  simple = lib.recurseIntoAttrs {
+    bash = expectSuccess (writeBash "test-writers-bash" ''
      if [[ "test" == "test" ]]; then echo "success"; fi
-    '';
+    '');
 
-    dash = writeDash "test-writers-dash" ''
+    dash = expectSuccess (writeDash "test-writers-dash" ''
      test '~' = '~' && echo 'success'
-    '';
+    '');
 
-    fish = writeFish "test-writers-fish" ''
+    fish = expectSuccess (writeFish "test-writers-fish" ''
       if test "test" = "test"
         echo "success"
       end
-    '';
+    '');
 
-    haskell = writeHaskell "test-writers-haskell" { libraries = [ haskellPackages.acme-default ]; } ''
+    haskell = expectSuccess (writeHaskell "test-writers-haskell" { libraries = [ haskellPackages.acme-default ]; } ''
       import Data.Default
 
       int :: Int
@@ -116,9 +147,9 @@ let
       main = case int of
         18871 -> putStrLn $ id "success"
         _ -> print "fail"
-    '';
+    '');
 
-    js = writeJS "test-writers-js" { libraries = [ nodePackages.semver ]; } ''
+    js = expectSuccess (writeJS "test-writers-js" { libraries = [ nodePackages.semver ]; } ''
       var semver = require('semver');
 
       if (semver.valid('1.2.3')) {
@@ -126,43 +157,41 @@ let
       } else {
         console.log('fail')
       }
-    '';
+    '');
 
-    perl = writePerl "test-writers-perl" { libraries = [ perlPackages.boolean ]; } ''
+    perl = expectSuccess (writePerl "test-writers-perl" { libraries = [ perlPackages.boolean ]; } ''
       use boolean;
       print "success\n" if true;
-    '';
+    '');
 
-    pypy2 = writePyPy2 "test-writers-pypy2" { libraries = [ pypy2Packages.enum ]; } ''
+    pypy2 = expectSuccess (writePyPy2 "test-writers-pypy2" { libraries = [ pypy2Packages.enum ]; } ''
       from enum import Enum
 
-
       class Test(Enum):
           a = "success"
 
-
       print Test.a
-    '';
+    '');
 
-    python3 = writePython3 "test-writers-python3" { libraries = [ python3Packages.pyyaml ]; } ''
+    python3 = expectSuccess (writePython3 "test-writers-python3" { libraries = [ python3Packages.pyyaml ]; } ''
       import yaml
 
-      y = yaml.load("""
+      y = yaml.safe_load("""
         - test: success
       """)
       print(y[0]['test'])
-    '';
+    '');
 
-    pypy3 = writePyPy3 "test-writers-pypy3" { libraries = [ pypy3Packages.pyyaml ]; } ''
+    pypy3 = expectSuccess (writePyPy3 "test-writers-pypy3" { libraries = [ pypy3Packages.pyyaml ]; } ''
       import yaml
 
-      y = yaml.load("""
+      y = yaml.safe_load("""
         - test: success
       """)
       print(y[0]['test'])
-    '';
+    '');
 
-    fsharp = makeFSharpWriter {
+    fsharp = expectSuccess (makeFSharpWriter {
       libraries = { fetchNuGet }: [
         (fetchNuGet { pname = "FSharp.SystemTextJson"; version = "0.17.4"; sha256 = "1bplzc9ybdqspii4q28l8gmfvzpkmgq5l1hlsiyg2h46w881lwg2"; })
       ];
@@ -183,31 +212,31 @@ let
       then "success"
       else "failed"
       |> printfn "%s"
-    '';
+    '');
 
-    pypy2NoLibs = writePyPy2 "test-writers-pypy2-no-libs" {} ''
+    pypy2NoLibs = expectSuccess (writePyPy2 "test-writers-pypy2-no-libs" {} ''
       print("success")
-    '';
+    '');
 
-    python3NoLibs = writePython3 "test-writers-python3-no-libs" {} ''
+    python3NoLibs = expectSuccess (writePython3 "test-writers-python3-no-libs" {} ''
       print("success")
-    '';
+    '');
 
-    pypy3NoLibs = writePyPy3 "test-writers-pypy3-no-libs" {} ''
+    pypy3NoLibs = expectSuccess (writePyPy3 "test-writers-pypy3-no-libs" {} ''
       print("success")
-    '';
+    '');
 
-    fsharpNoNugetDeps = writeFSharp "test-writers-fsharp-no-nuget-deps" ''
+    fsharpNoNugetDeps = expectSuccess (writeFSharp "test-writers-fsharp-no-nuget-deps" ''
       printfn "success"
-    '';
+    '');
   };
 
-
-  path = {
-    bash = writeBash "test-writers-bash-path" (writeText "test" ''
+  path = lib.recurseIntoAttrs {
+    bash = expectSuccess (writeBash "test-writers-bash-path" (writeText "test" ''
       if [[ "test" == "test" ]]; then echo "success"; fi
-    '');
-    haskell = writeHaskell "test-writers-haskell-path" { libraries = [ haskellPackages.acme-default ]; } (writeText "test" ''
+    ''));
+
+    haskell = expectSuccess (writeHaskell "test-writers-haskell-path" { libraries = [ haskellPackages.acme-default ]; } (writeText "test" ''
       import Data.Default
 
       int :: Int
@@ -217,26 +246,27 @@ let
       main = case int of
         18871 -> putStrLn $ id "success"
         _ -> print "fail"
-    '');
+    ''));
   };
 
-  writeTest = expectedValue: name: test:
-    writeDash "run-${name}" ''
-      if test "$(${test})" != "${expectedValue}"; then
-        echo 'test ${test} failed'
-        exit 1
-      fi
-    '';
-
-in runCommand "test-writers" {
-  passthru = { inherit writeTest bin simple path; };
-  meta.platforms = lib.platforms.all;
-} ''
-  ${lib.concatMapStringsSep "\n" (test: writeTest "success" test.name "${test}/bin/${test.name}") (lib.attrValues bin)}
-  ${lib.concatMapStringsSep "\n" (test: writeTest "success" test.name test) (lib.attrValues simple)}
-  ${lib.concatMapStringsSep "\n" (test: writeTest "success" test.name test) (lib.attrValues path)}
-
-  echo 'nix-writers successfully tested' >&2
-  touch $out
-''
-
+  data = {
+    json = expectDataEqual {
+      file = writeJSON "data.json" { hello = "world"; };
+      expected = ''
+        {
+          "hello": "world"
+        }
+      '';
+    };
+
+    toml = expectDataEqual {
+      file = writeTOML "data.toml" { hello = "world"; };
+      expected = "hello = 'world'\n";
+    };
+
+    yaml = expectDataEqual {
+      file = writeYAML "data.yaml" { hello = "world"; };
+      expected = "hello: world\n";
+    };
+  };
+}