From b644e5750e9a590e7ea64cc0c4dbda9afaf5643f Mon Sep 17 00:00:00 2001 From: Brian McKenna Date: Fri, 15 Nov 2024 10:45:29 +1100 Subject: [PATCH 01/60] Remove broken stack size logic from Windows The API only changes the stack size once there's already a stack overflow exception. Pretty useless. --- src/libutil/current-process.cc | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/src/libutil/current-process.cc b/src/libutil/current-process.cc index ac01f441e6b..46e72b63ad1 100644 --- a/src/libutil/current-process.cc +++ b/src/libutil/current-process.cc @@ -19,10 +19,6 @@ # include "namespaces.hh" #endif -#ifndef _WIN32 -# include -#endif - namespace nix { unsigned int getMaxCPU() @@ -77,29 +73,6 @@ void setStackSize(size_t stackSize) ); } } - #else - ULONG_PTR stackLow, stackHigh; - GetCurrentThreadStackLimits(&stackLow, &stackHigh); - ULONG maxStackSize = stackHigh - stackLow; - ULONG currStackSize = 0; - // This retrieves the current promised stack size - SetThreadStackGuarantee(&currStackSize); - if (currStackSize < stackSize) { - savedStackSize = currStackSize; - ULONG newStackSize = std::min(static_cast(stackSize), maxStackSize); - if (SetThreadStackGuarantee(&newStackSize) == 0) { - logger->log( - lvlError, - HintFmt( - "Failed to increase stack size from %1% to %2% (maximum allowed stack size: %3%): %4%", - savedStackSize, - stackSize, - maxStackSize, - std::to_string(GetLastError()) - ).str() - ); - } - } #endif } From 3bd7fa3bb4e950dcb256fff3c923dbea7d1fb349 Mon Sep 17 00:00:00 2001 From: Brian McKenna Date: Tue, 12 Nov 2024 20:47:31 +1100 Subject: [PATCH 02/60] local-store: fix infinite loop on Windows Also switch to std::filesystem. --- src/libstore/local-store.cc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index eafdac0cd33..f9529178697 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -212,16 +212,15 @@ LocalStore::LocalStore( /* Ensure that the store and its parents are not symlinks. */ if (!settings.allowSymlinkedStore) { - Path path = realStoreDir; - struct stat st; - while (path != "/") { - st = lstat(path); - if (S_ISLNK(st.st_mode)) + std::filesystem::path path = realStoreDir.get(); + std::filesystem::path root = path.root_path(); + while (path != root) { + if (std::filesystem::is_symlink(path)) throw Error( "the path '%1%' is a symlink; " "this is not allowed for the Nix store and its parent directories", path); - path = dirOf(path); + path = path.parent_path(); } } From 69fde530a6d9e935a24a0a06d763e5f6c72d1fb9 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Mon, 4 Nov 2024 09:46:51 -0500 Subject: [PATCH 03/60] Clean up packaging a bit - Multiple choices of stdenv are handled more consistently, especially for the dev shells which were previously not done correctly. - Some stray nix code was moving into the `packaging` directory --- flake.nix | 72 ++++++++----------- {scripts => packaging}/binary-tarball.nix | 10 +-- packaging/hydra.nix | 19 ++--- .../installer/default.nix | 0 {scripts => packaging/installer}/install.in | 0 tests/nixos/default.nix | 4 +- 6 files changed, 48 insertions(+), 57 deletions(-) rename {scripts => packaging}/binary-tarball.nix (85%) rename scripts/installer.nix => packaging/installer/default.nix (100%) rename {scripts => packaging/installer}/install.in (100%) diff --git a/flake.nix b/flake.nix index 8edc2266f08..64391efa40b 100644 --- a/flake.nix +++ b/flake.nix @@ -66,14 +66,7 @@ forAllCrossSystems = lib.genAttrs crossSystems; - forAllStdenvs = f: - lib.listToAttrs - (map - (stdenvName: { - name = "${stdenvName}Packages"; - value = f stdenvName; - }) - stdenvs); + forAllStdenvs = lib.genAttrs stdenvs; # We don't apply flake-parts to the whole flake so that non-development attributes @@ -89,32 +82,29 @@ # Memoize nixpkgs for different platforms for efficiency. nixpkgsFor = forAllSystems (system: let - make-pkgs = crossSystem: stdenv: import nixpkgs { - localSystem = { - inherit system; - }; - crossSystem = if crossSystem == null then null else { - config = crossSystem; - } // lib.optionalAttrs (crossSystem == "x86_64-unknown-freebsd13") { - useLLVM = true; - }; - overlays = [ - (overlayFor (p: p.${stdenv})) - ]; - }; - stdenvs = forAllStdenvs (make-pkgs null); - native = stdenvs.stdenvPackages; - in { - inherit stdenvs native; - static = native.pkgsStatic; - llvm = native.pkgsLLVM; - cross = forAllCrossSystems (crossSystem: make-pkgs crossSystem "stdenv"); + make-pkgs = crossSystem: + forAllStdenvs (stdenv: import nixpkgs { + localSystem = { + inherit system; + }; + crossSystem = if crossSystem == null then null else { + config = crossSystem; + } // lib.optionalAttrs (crossSystem == "x86_64-unknown-freebsd13") { + useLLVM = true; + }; + overlays = [ + (overlayFor (pkgs: pkgs.${stdenv})) + ]; + }); + in rec { + nativeForStdenv = make-pkgs null; + crossForStdenv = forAllCrossSystems make-pkgs; + # Alias for convenience + native = nativeForStdenv.stdenv; + cross = forAllCrossSystems (crossSystem: + crossForStdenv.${crossSystem}.stdenv); }); - binaryTarball = nix: pkgs: pkgs.callPackage ./scripts/binary-tarball.nix { - inherit nix; - }; - overlayFor = getStdenv: final: prev: let stdenv = getStdenv final; @@ -175,7 +165,6 @@ hydraJobs = import ./packaging/hydra.nix { inherit inputs - binaryTarball forAllCrossSystems forAllSystems lib @@ -211,7 +200,7 @@ # TODO: enable static builds for darwin, blocked on: # https://github.com/NixOS/nixpkgs/issues/320448 # TODO: disabled to speed up GHA CI. - #"static-" = nixpkgsFor.${system}.static; + #"static-" = nixpkgsFor.${system}.native.pkgsStatic; }) (nixpkgsPrefix: nixpkgs: flatMapAttrs nixpkgs.nixComponents @@ -282,8 +271,8 @@ (pkgName: { supportsCross ? true }: { # These attributes go right into `packages.`. "${pkgName}" = nixpkgsFor.${system}.native.nixComponents.${pkgName}; - "${pkgName}-static" = nixpkgsFor.${system}.static.nixComponents.${pkgName}; - "${pkgName}-llvm" = nixpkgsFor.${system}.llvm.nixComponents.${pkgName}; + "${pkgName}-static" = nixpkgsFor.${system}.native.pkgsStatic.nixComponents.${pkgName}; + "${pkgName}-llvm" = nixpkgsFor.${system}.native.pkgsLLVM.nixComponents.${pkgName}; } // lib.optionalAttrs supportsCross (flatMapAttrs (lib.genAttrs crossSystems (_: { })) (crossSystem: {}: { # These attributes go right into `packages.`. @@ -291,7 +280,7 @@ })) // flatMapAttrs (lib.genAttrs stdenvs (_: { })) (stdenvName: {}: { # These attributes go right into `packages.`. - "${pkgName}-${stdenvName}" = nixpkgsFor.${system}.stdenvs."${stdenvName}Packages".nixComponents.${pkgName}; + "${pkgName}-${stdenvName}" = nixpkgsFor.${system}.nativeForStdenv.${stdenvName}.nixComponents.${pkgName}; }) ) // lib.optionalAttrs (builtins.elem system linux64BitSystems) { @@ -317,21 +306,22 @@ in forAllSystems (system: prefixAttrs "native" (forAllStdenvs (stdenvName: makeShell { - pkgs = nixpkgsFor.${system}.stdenvs."${stdenvName}Packages"; + pkgs = nixpkgsFor.${system}.nativeForStdenv.${stdenvName}; })) // lib.optionalAttrs (!nixpkgsFor.${system}.native.stdenv.isDarwin) ( prefixAttrs "static" (forAllStdenvs (stdenvName: makeShell { - pkgs = nixpkgsFor.${system}.stdenvs."${stdenvName}Packages".pkgsStatic; + pkgs = nixpkgsFor.${system}.nativeForStdenv.${stdenvName}.pkgsStatic; })) // prefixAttrs "llvm" (forAllStdenvs (stdenvName: makeShell { - pkgs = nixpkgsFor.${system}.stdenvs."${stdenvName}Packages".pkgsLLVM; + pkgs = nixpkgsFor.${system}.nativeForStdenv.${stdenvName}.pkgsLLVM; })) // prefixAttrs "cross" (forAllCrossSystems (crossSystem: makeShell { pkgs = nixpkgsFor.${system}.cross.${crossSystem}; })) ) // { - default = self.devShells.${system}.native-stdenvPackages; + native = self.devShells.${system}.native-stdenv; + default = self.devShells.${system}.native; } ); }; diff --git a/scripts/binary-tarball.nix b/packaging/binary-tarball.nix similarity index 85% rename from scripts/binary-tarball.nix rename to packaging/binary-tarball.nix index 9de90b7fb56..59e11c77dfd 100644 --- a/scripts/binary-tarball.nix +++ b/packaging/binary-tarball.nix @@ -22,18 +22,18 @@ in runCommand "nix-binary-tarball-${version}" env '' cp ${installerClosureInfo}/registration $TMPDIR/reginfo - cp ${./create-darwin-volume.sh} $TMPDIR/create-darwin-volume.sh - substitute ${./install-nix-from-tarball.sh} $TMPDIR/install \ + cp ${../scripts/create-darwin-volume.sh} $TMPDIR/create-darwin-volume.sh + substitute ${../scripts/install-nix-from-tarball.sh} $TMPDIR/install \ --subst-var-by nix ${nix} \ --subst-var-by cacert ${cacert} - substitute ${./install-darwin-multi-user.sh} $TMPDIR/install-darwin-multi-user.sh \ + substitute ${../scripts/install-darwin-multi-user.sh} $TMPDIR/install-darwin-multi-user.sh \ --subst-var-by nix ${nix} \ --subst-var-by cacert ${cacert} - substitute ${./install-systemd-multi-user.sh} $TMPDIR/install-systemd-multi-user.sh \ + substitute ${../scripts/install-systemd-multi-user.sh} $TMPDIR/install-systemd-multi-user.sh \ --subst-var-by nix ${nix} \ --subst-var-by cacert ${cacert} - substitute ${./install-multi-user.sh} $TMPDIR/install-multi-user \ + substitute ${../scripts/install-multi-user.sh} $TMPDIR/install-multi-user \ --subst-var-by nix ${nix} \ --subst-var-by cacert ${cacert} diff --git a/packaging/hydra.nix b/packaging/hydra.nix index 5b1e4755948..77fe93dc330 100644 --- a/packaging/hydra.nix +++ b/packaging/hydra.nix @@ -1,5 +1,4 @@ { inputs -, binaryTarball , forAllCrossSystems , forAllSystems , lib @@ -12,7 +11,7 @@ let inherit (inputs) nixpkgs nixpkgs-regression; installScriptFor = tarballs: - nixpkgsFor.x86_64-linux.native.callPackage ../scripts/installer.nix { + nixpkgsFor.x86_64-linux.native.callPackage ./installer { inherit tarballs; }; @@ -62,7 +61,7 @@ in [ "i686-linux" ]; buildStatic = forAllPackages (pkgName: - lib.genAttrs linux64BitSystems (system: nixpkgsFor.${system}.static.nixComponents.${pkgName})); + lib.genAttrs linux64BitSystems (system: nixpkgsFor.${system}.native.pkgsStatic.nixComponents.${pkgName})); buildCross = forAllPackages (pkgName: # Hack to avoid non-evaling package @@ -99,13 +98,12 @@ in # Binary tarball for various platforms, containing a Nix store # with the closure of 'nix' package, and the second half of # the installation script. - binaryTarball = forAllSystems (system: binaryTarball nixpkgsFor.${system}.native.nix nixpkgsFor.${system}.native); + binaryTarball = forAllSystems (system: + nixpkgsFor.${system}.native.callPackage ./binary-tarball.nix {}); binaryTarballCross = lib.genAttrs [ "x86_64-linux" ] (system: forAllCrossSystems (crossSystem: - binaryTarball - nixpkgsFor.${system}.cross.${crossSystem}.nix - nixpkgsFor.${system}.cross.${crossSystem})); + nixpkgsFor.${system}.cross.${crossSystem}.callPackage ./binary-tarball.nix {})); # The first half of the installation script. This is uploaded # to https://nixos.org/nix/install. It downloads the binary @@ -124,7 +122,7 @@ in self.hydraJobs.binaryTarballCross."x86_64-linux"."riscv64-unknown-linux-gnu" ]; - installerScriptForGHA = forAllSystems (system: nixpkgsFor.${system}.native.callPackage ../scripts/installer.nix { + installerScriptForGHA = forAllSystems (system: nixpkgsFor.${system}.native.callPackage ./installer { tarballs = [ self.hydraJobs.binaryTarball.${system} ]; }); @@ -147,7 +145,10 @@ in external-api-docs = nixpkgsFor.x86_64-linux.native.nixComponents.nix-external-api-docs; # System tests. - tests = import ../tests/nixos { inherit lib nixpkgs nixpkgsFor self; } // { + tests = import ../tests/nixos { + inherit lib nixpkgs nixpkgsFor; + inherit (self.inputs) nixpkgs-23-11; + } // { # Make sure that nix-env still produces the exact same result # on a particular version of Nixpkgs. diff --git a/scripts/installer.nix b/packaging/installer/default.nix similarity index 100% rename from scripts/installer.nix rename to packaging/installer/default.nix diff --git a/scripts/install.in b/packaging/installer/install.in similarity index 100% rename from scripts/install.in rename to packaging/installer/install.in diff --git a/tests/nixos/default.nix b/tests/nixos/default.nix index 8e0cb1b225b..1c207fba55b 100644 --- a/tests/nixos/default.nix +++ b/tests/nixos/default.nix @@ -1,4 +1,4 @@ -{ lib, nixpkgs, nixpkgsFor, self }: +{ lib, nixpkgs, nixpkgsFor, nixpkgs-23-11 }: let @@ -64,7 +64,7 @@ let otherNixes.nix_2_13.setNixPackage = { lib, pkgs, ... }: { imports = [ checkOverrideNixVersion ]; nix.package = lib.mkForce ( - self.inputs.nixpkgs-23-11.legacyPackages.${pkgs.stdenv.hostPlatform.system}.nixVersions.nix_2_13.overrideAttrs (o: { + nixpkgs-23-11.legacyPackages.${pkgs.stdenv.hostPlatform.system}.nixVersions.nix_2_13.overrideAttrs (o: { meta = o.meta // { knownVulnerabilities = []; }; }) ); From 666d656593e135dbe2f84a7db0309e479ecadaa5 Mon Sep 17 00:00:00 2001 From: Illia Bobyr Date: Thu, 16 Jan 2025 00:58:29 -0800 Subject: [PATCH 04/60] nix-profile-daemon.fish: fmt `nix-profile.fish` and part of `nix-profile-daemon.fish` use 4 space indentation. Which is also the indentation that the fish shell documentation is using. Reformatting a chunk of `nix-profile-daemon.fish` from 2 space indentation to 4 space indentation for consistency. --- scripts/nix-profile-daemon.fish.in | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/scripts/nix-profile-daemon.fish.in b/scripts/nix-profile-daemon.fish.in index 346dce5ddcf..ac2ecdeee90 100644 --- a/scripts/nix-profile-daemon.fish.in +++ b/scripts/nix-profile-daemon.fish.in @@ -12,7 +12,7 @@ end # Only execute this file once per shell. if test -n "$__ETC_PROFILE_NIX_SOURCED" - exit + exit end set __ETC_PROFILE_NIX_SOURCED 1 @@ -29,26 +29,26 @@ end # Set $NIX_SSL_CERT_FILE so that Nixpkgs applications like curl work. if test -n "$NIX_SSL_CERT_FILE" - : # Allow users to override the NIX_SSL_CERT_FILE + : # Allow users to override the NIX_SSL_CERT_FILE else if test -e /etc/ssl/certs/ca-certificates.crt # NixOS, Ubuntu, Debian, Gentoo, Arch - set --export NIX_SSL_CERT_FILE /etc/ssl/certs/ca-certificates.crt + set --export NIX_SSL_CERT_FILE /etc/ssl/certs/ca-certificates.crt else if test -e /etc/ssl/ca-bundle.pem # openSUSE Tumbleweed - set --export NIX_SSL_CERT_FILE /etc/ssl/ca-bundle.pem + set --export NIX_SSL_CERT_FILE /etc/ssl/ca-bundle.pem else if test -e /etc/ssl/certs/ca-bundle.crt # Old NixOS - set --export NIX_SSL_CERT_FILE /etc/ssl/certs/ca-bundle.crt + set --export NIX_SSL_CERT_FILE /etc/ssl/certs/ca-bundle.crt else if test -e /etc/pki/tls/certs/ca-bundle.crt # Fedora, CentOS - set --export NIX_SSL_CERT_FILE /etc/pki/tls/certs/ca-bundle.crt + set --export NIX_SSL_CERT_FILE /etc/pki/tls/certs/ca-bundle.crt else if test -e "$NIX_LINK/etc/ssl/certs/ca-bundle.crt" # fall back to cacert in Nix profile - set --export NIX_SSL_CERT_FILE "$NIX_LINK/etc/ssl/certs/ca-bundle.crt" + set --export NIX_SSL_CERT_FILE "$NIX_LINK/etc/ssl/certs/ca-bundle.crt" else if test -e "$NIX_LINK/etc/ca-bundle.crt" # old cacert in Nix profile - set --export NIX_SSL_CERT_FILE "$NIX_LINK/etc/ca-bundle.crt" + set --export NIX_SSL_CERT_FILE "$NIX_LINK/etc/ca-bundle.crt" else - # Fall back to what is in the nix profiles, favouring whatever is defined last. - for i in (string split ' ' $NIX_PROFILES) - if test -e "$i/etc/ssl/certs/ca-bundle.crt" - set --export NIX_SSL_CERT_FILE "$i/etc/ssl/certs/ca-bundle.crt" + # Fall back to what is in the nix profiles, favouring whatever is defined last. + for i in (string split ' ' $NIX_PROFILES) + if test -e "$i/etc/ssl/certs/ca-bundle.crt" + set --export NIX_SSL_CERT_FILE "$i/etc/ssl/certs/ca-bundle.crt" + end end - end end add_path "@localstatedir@/nix/profiles/default/bin" From b36637c8f7ab7a2b93c6eae1139ea1c672700186 Mon Sep 17 00:00:00 2001 From: Illia Bobyr Date: Mon, 13 Jan 2025 18:08:41 -0800 Subject: [PATCH 05/60] nix-profile{,-daemon}.fish: Do not source twice In order for the script not be sourced multiple times by the same shell instance, `__ETC_PROFILE_NIX_SOURCED` needs to be set with a `--global` flag. Both files are almost identical. And style differences make it harder to see what is actually different and keep them in sync, when it is required. --- scripts/nix-profile-daemon.fish.in | 20 ++++--- scripts/nix-profile.fish.in | 87 +++++++++++++++++------------- 2 files changed, 62 insertions(+), 45 deletions(-) diff --git a/scripts/nix-profile-daemon.fish.in b/scripts/nix-profile-daemon.fish.in index ac2ecdeee90..3d193412a3c 100644 --- a/scripts/nix-profile-daemon.fish.in +++ b/scripts/nix-profile-daemon.fish.in @@ -1,3 +1,13 @@ +# Only execute this file once per shell. +if test -z "$HOME" || \ + test -n "$__ETC_PROFILE_NIX_SOURCED" + exit +end + +set --global __ETC_PROFILE_NIX_SOURCED 1 + +# Local helpers + function add_path --argument-names new_path if type -q fish_add_path # fish 3.2.0 or newer @@ -10,13 +20,7 @@ function add_path --argument-names new_path end end -# Only execute this file once per shell. -if test -n "$__ETC_PROFILE_NIX_SOURCED" - exit -end - -set __ETC_PROFILE_NIX_SOURCED 1 - +# Main configuration set --export NIX_PROFILES "@localstatedir@/nix/profiles/default $HOME/.nix-profile" # Populate bash completions, .desktop files, etc @@ -54,4 +58,6 @@ end add_path "@localstatedir@/nix/profiles/default/bin" add_path "$HOME/.nix-profile/bin" +# Cleanup + functions -e add_path diff --git a/scripts/nix-profile.fish.in b/scripts/nix-profile.fish.in index 619df52b895..dd2fbe2090f 100644 --- a/scripts/nix-profile.fish.in +++ b/scripts/nix-profile.fish.in @@ -1,3 +1,13 @@ +# Only execute this file once per shell. +if test -z "$HOME" || test -z "$USER" || \ + test -n "$__ETC_PROFILE_NIX_SOURCED" + exit +end + +set --global __ETC_PROFILE_NIX_SOURCED 1 + +# Local helpers + function add_path --argument-names new_path if type -q fish_add_path # fish 3.2.0 or newer @@ -10,50 +20,51 @@ function add_path --argument-names new_path end end -if test -n "$HOME" && test -n "$USER" +# Main configuration - # Set up the per-user profile. +# Set up the per-user profile. - set NIX_LINK $HOME/.nix-profile +set NIX_LINK $HOME/.nix-profile - # Set up environment. - # This part should be kept in sync with nixpkgs:nixos/modules/programs/environment.nix - set --export NIX_PROFILES "@localstatedir@/nix/profiles/default $HOME/.nix-profile" - - # Populate bash completions, .desktop files, etc - if test -z "$XDG_DATA_DIRS" - # According to XDG spec the default is /usr/local/share:/usr/share, don't set something that prevents that default - set --export XDG_DATA_DIRS "/usr/local/share:/usr/share:$NIX_LINK/share:/nix/var/nix/profiles/default/share" - else - set --export XDG_DATA_DIRS "$XDG_DATA_DIRS:$NIX_LINK/share:/nix/var/nix/profiles/default/share" - end +# Set up environment. +# This part should be kept in sync with nixpkgs:nixos/modules/programs/environment.nix +set --export NIX_PROFILES "@localstatedir@/nix/profiles/default $HOME/.nix-profile" - # Set $NIX_SSL_CERT_FILE so that Nixpkgs applications like curl work. - if test -n "$NIX_SSH_CERT_FILE" - : # Allow users to override the NIX_SSL_CERT_FILE - else if test -e /etc/ssl/certs/ca-certificates.crt # NixOS, Ubuntu, Debian, Gentoo, Arch - set --export NIX_SSL_CERT_FILE /etc/ssl/certs/ca-certificates.crt - else if test -e /etc/ssl/ca-bundle.pem # openSUSE Tumbleweed - set --export NIX_SSL_CERT_FILE /etc/ssl/ca-bundle.pem - else if test -e /etc/ssl/certs/ca-bundle.crt # Old NixOS - set --export NIX_SSL_CERT_FILE /etc/ssl/certs/ca-bundle.crt - else if test -e /etc/pki/tls/certs/ca-bundle.crt # Fedora, CentOS - set --export NIX_SSL_CERT_FILE /etc/pki/tls/certs/ca-bundle.crt - else if test -e "$NIX_LINK/etc/ssl/certs/ca-bundle.crt" # fall back to cacert in Nix profile - set --export NIX_SSL_CERT_FILE "$NIX_LINK/etc/ssl/certs/ca-bundle.crt" - else if test -e "$NIX_LINK/etc/ca-bundle.crt" # old cacert in Nix profile - set --export NIX_SSL_CERT_FILE "$NIX_LINK/etc/ca-bundle.crt" - end +# Populate bash completions, .desktop files, etc +if test -z "$XDG_DATA_DIRS" + # According to XDG spec the default is /usr/local/share:/usr/share, don't set something that prevents that default + set --export XDG_DATA_DIRS "/usr/local/share:/usr/share:$NIX_LINK/share:/nix/var/nix/profiles/default/share" +else + set --export XDG_DATA_DIRS "$XDG_DATA_DIRS:$NIX_LINK/share:/nix/var/nix/profiles/default/share" +end - # Only use MANPATH if it is already set. In general `man` will just simply - # pick up `.nix-profile/share/man` because is it close to `.nix-profile/bin` - # which is in the $PATH. For more info, run `manpath -d`. - if set --query MANPATH - set --export --prepend --path MANPATH "$NIX_LINK/share/man" - end +# Set $NIX_SSL_CERT_FILE so that Nixpkgs applications like curl work. +if test -n "$NIX_SSH_CERT_FILE" + : # Allow users to override the NIX_SSL_CERT_FILE +else if test -e /etc/ssl/certs/ca-certificates.crt # NixOS, Ubuntu, Debian, Gentoo, Arch + set --export NIX_SSL_CERT_FILE /etc/ssl/certs/ca-certificates.crt +else if test -e /etc/ssl/ca-bundle.pem # openSUSE Tumbleweed + set --export NIX_SSL_CERT_FILE /etc/ssl/ca-bundle.pem +else if test -e /etc/ssl/certs/ca-bundle.crt # Old NixOS + set --export NIX_SSL_CERT_FILE /etc/ssl/certs/ca-bundle.crt +else if test -e /etc/pki/tls/certs/ca-bundle.crt # Fedora, CentOS + set --export NIX_SSL_CERT_FILE /etc/pki/tls/certs/ca-bundle.crt +else if test -e "$NIX_LINK/etc/ssl/certs/ca-bundle.crt" # fall back to cacert in Nix profile + set --export NIX_SSL_CERT_FILE "$NIX_LINK/etc/ssl/certs/ca-bundle.crt" +else if test -e "$NIX_LINK/etc/ca-bundle.crt" # old cacert in Nix profile + set --export NIX_SSL_CERT_FILE "$NIX_LINK/etc/ca-bundle.crt" +end - add_path "$NIX_LINK/bin" - set --erase NIX_LINK +# Only use MANPATH if it is already set. In general `man` will just simply +# pick up `.nix-profile/share/man` because is it close to `.nix-profile/bin` +# which is in the $PATH. For more info, run `manpath -d`. +if set --query MANPATH + set --export --prepend --path MANPATH "$NIX_LINK/share/man" end +add_path "$NIX_LINK/bin" +set --erase NIX_LINK + +# Cleanup + functions -e add_path From bd10b859f71751e349af59349385af27aea40a13 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 22 Jan 2025 17:42:52 +0100 Subject: [PATCH 06/60] GitRepo::fetch(): Cleanup --- src/libfetchers/git-utils.cc | 14 ++++++-------- src/libutil/util.hh | 11 +++++++++++ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/libfetchers/git-utils.cc b/src/libfetchers/git-utils.cc index b54416b1062..3b15a85ceaf 100644 --- a/src/libfetchers/git-utils.cc +++ b/src/libfetchers/git-utils.cc @@ -206,7 +206,8 @@ static git_packbuilder_progress PACKBUILDER_PROGRESS_CHECK_INTERRUPT = &packBuil } // extern "C" -static void initRepoAtomically(std::filesystem::path &path, bool bare) { +static void initRepoAtomically(std::filesystem::path &path, bool bare) +{ if (pathExists(path.string())) return; Path tmpDir = createTempDir(os_string_to_string(PathViewNG { std::filesystem::path(path).parent_path() })); @@ -544,13 +545,10 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this // then use code that was removed in this commit (see blame) auto dir = this->path; - Strings gitArgs; - if (shallow) { - gitArgs = { "-C", dir.string(), "fetch", "--quiet", "--force", "--depth", "1", "--", url, refspec }; - } - else { - gitArgs = { "-C", dir.string(), "fetch", "--quiet", "--force", "--", url, refspec }; - } + Strings gitArgs{"-C", dir.string(), "fetch", "--quiet", "--force"}; + if (shallow) + append(gitArgs, {"--depth", "1"}); + append(gitArgs, {std::string("--"), url, refspec}); runProgram(RunOptions { .program = "git", diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 4d5683e2bda..0d55cf93bed 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -274,6 +274,17 @@ std::optional pop(T & c) } +/** + * Append items to a container. TODO: remove this once we can use + * C++23's `append_range()`. + */ +template +void append(C & c, std::initializer_list l) +{ + c.insert(c.end(), l.begin(), l.end()); +} + + template class Callback; From 41983dba8febc89a506d407ee9c597347bdd91b5 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 22 Jan 2025 17:54:19 +0100 Subject: [PATCH 07/60] GitRepo::fetch(): Ignore $GIT_DIR Fixes #12325. --- src/libfetchers/git-utils.cc | 2 +- tests/functional/common/vars.sh | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libfetchers/git-utils.cc b/src/libfetchers/git-utils.cc index 3b15a85ceaf..6a75daf6124 100644 --- a/src/libfetchers/git-utils.cc +++ b/src/libfetchers/git-utils.cc @@ -545,7 +545,7 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this // then use code that was removed in this commit (see blame) auto dir = this->path; - Strings gitArgs{"-C", dir.string(), "fetch", "--quiet", "--force"}; + Strings gitArgs{"-C", dir.string(), "--git-dir", ".", "fetch", "--quiet", "--force"}; if (shallow) append(gitArgs, {"--depth", "1"}); append(gitArgs, {std::string("--"), url, refspec}); diff --git a/tests/functional/common/vars.sh b/tests/functional/common/vars.sh index 4b88e852618..ed4b477278f 100644 --- a/tests/functional/common/vars.sh +++ b/tests/functional/common/vars.sh @@ -60,6 +60,7 @@ unset XDG_DATA_HOME unset XDG_CONFIG_HOME unset XDG_CONFIG_DIRS unset XDG_CACHE_HOME +unset GIT_DIR export IMPURE_VAR1=foo export IMPURE_VAR2=bar From e0c6ed1c8370d1dbfd60a294666c50929fe1c8fc Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 18 Nov 2024 16:07:35 +0100 Subject: [PATCH 08/60] Fix help test in dev shell Not sure what the intent was expecting help.sh to fail in the main suite, but it caused `meson test` to fail inside a `nix develop` shell: $ meson test help --print-errorlogs ninja: Entering directory `/home/eelco/Dev/nix-master/build' 1/1 nix-functional-tests:main / help UNEXPECTEDPASS 4.02s --- tests/functional/help.sh | 2 ++ tests/functional/meson.build | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/functional/help.sh b/tests/functional/help.sh index 127cc455b62..e195e10ebd2 100755 --- a/tests/functional/help.sh +++ b/tests/functional/help.sh @@ -2,6 +2,8 @@ source common.sh +[[ $(type -p man) ]] || skipTest "'man' not installed" + # test help output nix-build --help diff --git a/tests/functional/meson.build b/tests/functional/meson.build index 83e08c4f5ad..dee003e426d 100644 --- a/tests/functional/meson.build +++ b/tests/functional/meson.build @@ -242,8 +242,6 @@ foreach suite : suites # Used for target dependency/ordering tracking, not adding compiler flags or anything. depends : suite['deps'], workdir : workdir, - # Won't pass until man pages are generated - should_fail : suite['name'] == 'main' and script == 'help.sh' ) endforeach endforeach From 7f7ca3810b61c796fea6a9526ffc607ec1a00643 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Wed, 22 Jan 2025 16:15:49 -0500 Subject: [PATCH 09/60] Fix #12295 We were simply passing in the wrong path. This went uncaught because the TODO about deduplication hasn't happened yet. --- src/libstore/unix/build/local-derivation-goal.cc | 2 +- tests/functional/fixed.nix | 3 +++ tests/functional/git-hashing/fixed.sh | 6 ++++++ tests/functional/git-hashing/meson.build | 1 + 4 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 tests/functional/git-hashing/fixed.sh diff --git a/src/libstore/unix/build/local-derivation-goal.cc b/src/libstore/unix/build/local-derivation-goal.cc index 06a2f85be84..ceb0b353927 100644 --- a/src/libstore/unix/build/local-derivation-goal.cc +++ b/src/libstore/unix/build/local-derivation-goal.cc @@ -2565,7 +2565,7 @@ SingleDrvOutputs LocalDerivationGoal::registerOutputs() case FileIngestionMethod::Git: { return git::dumpHash( outputHash.hashAlgo, - {getFSSourceAccessor(), CanonPath(tmpDir + "/tmp")}).hash; + {getFSSourceAccessor(), CanonPath(actualPath)}).hash; } } assert(false); diff --git a/tests/functional/fixed.nix b/tests/functional/fixed.nix index a920a21671f..9f1ef3b61fe 100644 --- a/tests/functional/fixed.nix +++ b/tests/functional/fixed.nix @@ -66,4 +66,7 @@ rec { # Can use "nar" instead of "recursive" now. nar-not-recursive = f2 "foo" ./fixed.builder2.sh "nar" "md5" "3670af73070fa14077ad74e0f5ea4e42"; + + # Experimental feature + git = f2 "foo" ./fixed.builder2.sh "git" "sha1" "cd44baf36915d5dec8374232ea7e2057f3b4494e"; } diff --git a/tests/functional/git-hashing/fixed.sh b/tests/functional/git-hashing/fixed.sh new file mode 100644 index 00000000000..1962472a876 --- /dev/null +++ b/tests/functional/git-hashing/fixed.sh @@ -0,0 +1,6 @@ +source common.sh + +# Store layer needs bugfix +requireDaemonNewerThan "2.27pre20250122" + +nix-build ../fixed.nix -A git --no-out-link diff --git a/tests/functional/git-hashing/meson.build b/tests/functional/git-hashing/meson.build index 470c53fc5bb..d6a782cdccf 100644 --- a/tests/functional/git-hashing/meson.build +++ b/tests/functional/git-hashing/meson.build @@ -3,6 +3,7 @@ suites += { 'deps': [], 'tests': [ 'simple.sh', + 'fixed.sh', ], 'workdir': meson.current_source_dir(), } From be97dc1efc4276e41ced2014c0a909a27f1fb848 Mon Sep 17 00:00:00 2001 From: Philipp Otterbein Date: Thu, 23 Jan 2025 02:18:27 +0100 Subject: [PATCH 10/60] libstore: fix progress bars --- src/libstore/remote-store.cc | 12 +++++++++++- src/libstore/store-api.cc | 14 ++++++-------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 6781e4743f6..b230079eb27 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -539,11 +539,21 @@ void RemoteStore::addMultipleToStore( RepairFlag repair, CheckSigsFlag checkSigs) { + // `addMultipleToStore` is single threaded + size_t bytesExpected = 0; + for (auto & [pathInfo, _] : pathsToCopy) { + bytesExpected += pathInfo.narSize; + } + act.setExpected(actCopyPath, bytesExpected); + auto source = sinkToSource([&](Sink & sink) { - sink << pathsToCopy.size(); + size_t nrTotal = pathsToCopy.size(); + sink << nrTotal; // Reverse, so we can release memory at the original start std::reverse(pathsToCopy.begin(), pathsToCopy.end()); while (!pathsToCopy.empty()) { + act.progress(nrTotal - pathsToCopy.size(), nrTotal, size_t(1), size_t(0)); + auto & [pathInfo, pathSource] = pathsToCopy.back(); WorkerProto::Serialise::write(*this, WorkerProto::WriteConn { diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 6cd8e47f0ab..236622eae37 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -242,8 +242,8 @@ void Store::addMultipleToStore( storePathsToAdd.insert(thingToAdd.first.path); } - auto showProgress = [&]() { - act.progress(nrDone, pathsToCopy.size(), nrRunning, nrFailed); + auto showProgress = [&, nrTotal = pathsToCopy.size()]() { + act.progress(nrDone, nrTotal, nrRunning, nrFailed); }; processGraph( @@ -1104,9 +1104,6 @@ std::map copyPaths( return storePathForDst; }; - // total is accessed by each copy, which are each handled in separate threads - std::atomic total = 0; - for (auto & missingPath : sortedMissing) { auto info = srcStore.queryPathInfo(missingPath); @@ -1116,9 +1113,10 @@ std::map copyPaths( ValidPathInfo infoForDst = *info; infoForDst.path = storePathForDst; - auto source = sinkToSource([&](Sink & sink) { + auto source = sinkToSource([&, narSize = info->narSize](Sink & sink) { // We can reasonably assume that the copy will happen whenever we // read the path, so log something about that at that point + uint64_t total = 0; auto srcUri = srcStore.getUri(); auto dstUri = dstStore.getUri(); auto storePathS = srcStore.printStorePath(missingPath); @@ -1129,13 +1127,13 @@ std::map copyPaths( LambdaSink progressSink([&](std::string_view data) { total += data.size(); - act.progress(total, info->narSize); + act.progress(total, narSize); }); TeeSink tee { sink, progressSink }; srcStore.narFromPath(missingPath, tee); }); - pathsToCopy.push_back(std::pair{infoForDst, std::move(source)}); + pathsToCopy.emplace_back(std::move(infoForDst), std::move(source)); } dstStore.addMultipleToStore(std::move(pathsToCopy), act, repair, checkSigs); From 2dae5acf8613169aabe729e8318ca08376d24754 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 22 Jan 2025 21:36:33 +0100 Subject: [PATCH 11/60] Run the 'nix --help' tests early These don't depend on 'man' so we don't need to skip them. --- tests/functional/help.sh | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/functional/help.sh b/tests/functional/help.sh index e195e10ebd2..88d3c0a4b47 100755 --- a/tests/functional/help.sh +++ b/tests/functional/help.sh @@ -2,6 +2,25 @@ source common.sh +function subcommands() { + jq -r ' +def recurse($prefix): + to_entries[] | + ($prefix + [.key]) as $newPrefix | + (if .value | has("commands") then + ($newPrefix, (.value.commands | recurse($newPrefix))) + else + $newPrefix + end); +.args.commands | recurse([]) | join(" ") +' +} + +nix __dump-cli | subcommands | while IFS= read -r cmd; do + # shellcheck disable=SC2086 # word splitting of cmd is intended + nix $cmd --help +done + [[ $(type -p man) ]] || skipTest "'man' not installed" # test help output @@ -51,22 +70,3 @@ nix-daemon --help nix-hash --help nix-instantiate --help nix-prefetch-url --help - -function subcommands() { - jq -r ' -def recurse($prefix): - to_entries[] | - ($prefix + [.key]) as $newPrefix | - (if .value | has("commands") then - ($newPrefix, (.value.commands | recurse($newPrefix))) - else - $newPrefix - end); -.args.commands | recurse([]) | join(" ") -' -} - -nix __dump-cli | subcommands | while IFS= read -r cmd; do - # shellcheck disable=SC2086 # word splitting of cmd is intended - nix $cmd --help -done From 5b43163c6dc911fa1aad52199f6a053696266593 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 23 Jan 2025 14:54:05 +0100 Subject: [PATCH 12/60] Disable 'man' tests --- tests/functional/help.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/functional/help.sh b/tests/functional/help.sh index 88d3c0a4b47..2d64c465db0 100755 --- a/tests/functional/help.sh +++ b/tests/functional/help.sh @@ -23,6 +23,10 @@ done [[ $(type -p man) ]] || skipTest "'man' not installed" +# FIXME: we don't know whether we built the manpages, so we can't +# reliably test them here. +exit 0 + # test help output nix-build --help From 9060d0fe46f081ce63441cedc5e16c47f31f4590 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 23 Jan 2025 16:21:30 +0100 Subject: [PATCH 13/60] Fix missing format argument --- src/nix/flake.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nix/flake.cc b/src/nix/flake.cc index 4d5cad1a8b7..384c23d8c97 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -103,7 +103,7 @@ struct CmdFlakeUpdate : FlakeCommand throw e; } if (lockFlags.inputUpdates.contains(inputPath)) - warn("Input '%s' was specified multiple times. You may have done this by accident."); + warn("Input '%s' was specified multiple times. You may have done this by accident.", printInputPath(inputPath)); lockFlags.inputUpdates.insert(inputPath); } }}, From 7dfff58292475d0aed3dc3e98236ba495c45f261 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 23 Jan 2025 16:34:35 +0100 Subject: [PATCH 14/60] Rename InputPath -> InputAttrPath Fixes #12098. --- src/libcmd/command.hh | 2 +- src/libcmd/installables.cc | 12 ++-- src/libexpr/call-flake.nix | 2 +- src/libflake/flake/flake.cc | 126 ++++++++++++++++----------------- src/libflake/flake/flake.hh | 6 +- src/libflake/flake/lockfile.cc | 56 +++++++-------- src/libflake/flake/lockfile.hh | 22 +++--- src/nix/flake.cc | 14 ++-- 8 files changed, 120 insertions(+), 120 deletions(-) diff --git a/src/libcmd/command.hh b/src/libcmd/command.hh index 23529848f6b..9570ce3e7ac 100644 --- a/src/libcmd/command.hh +++ b/src/libcmd/command.hh @@ -347,7 +347,7 @@ struct MixEnvironment : virtual Args void setEnviron(); }; -void completeFlakeInputPath( +void completeFlakeInputAttrPath( AddCompletions & completions, ref evalState, const std::vector & flakeRefs, diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index ab3ab31045c..81eb883daba 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -33,7 +33,7 @@ namespace nix { namespace fs { using namespace std::filesystem; } -void completeFlakeInputPath( +void completeFlakeInputAttrPath( AddCompletions & completions, ref evalState, const std::vector & flakeRefs, @@ -117,10 +117,10 @@ MixFlakeOptions::MixFlakeOptions() .labels = {"input-path"}, .handler = {[&](std::string s) { warn("'--update-input' is a deprecated alias for 'flake update' and will be removed in a future version."); - lockFlags.inputUpdates.insert(flake::parseInputPath(s)); + lockFlags.inputUpdates.insert(flake::parseInputAttrPath(s)); }}, .completer = {[&](AddCompletions & completions, size_t, std::string_view prefix) { - completeFlakeInputPath(completions, getEvalState(), getFlakeRefsForCompletion(), prefix); + completeFlakeInputAttrPath(completions, getEvalState(), getFlakeRefsForCompletion(), prefix); }} }); @@ -129,15 +129,15 @@ MixFlakeOptions::MixFlakeOptions() .description = "Override a specific flake input (e.g. `dwarffs/nixpkgs`). This implies `--no-write-lock-file`.", .category = category, .labels = {"input-path", "flake-url"}, - .handler = {[&](std::string inputPath, std::string flakeRef) { + .handler = {[&](std::string inputAttrPath, std::string flakeRef) { lockFlags.writeLockFile = false; lockFlags.inputOverrides.insert_or_assign( - flake::parseInputPath(inputPath), + flake::parseInputAttrPath(inputAttrPath), parseFlakeRef(fetchSettings, flakeRef, absPath(getCommandBaseDir()), true)); }}, .completer = {[&](AddCompletions & completions, size_t n, std::string_view prefix) { if (n == 0) { - completeFlakeInputPath(completions, getEvalState(), getFlakeRefsForCompletion(), prefix); + completeFlakeInputAttrPath(completions, getEvalState(), getFlakeRefsForCompletion(), prefix); } else if (n == 1) { completeFlakeRef(completions, getEvalState()->store, prefix); } diff --git a/src/libexpr/call-flake.nix b/src/libexpr/call-flake.nix index 964ba25219e..3a7a249c673 100644 --- a/src/libexpr/call-flake.nix +++ b/src/libexpr/call-flake.nix @@ -25,7 +25,7 @@ let then getInputByPath lockFile.root inputSpec else inputSpec; - # Follow an input path (e.g. ["dwarffs" "nixpkgs"]) from the + # Follow an input attrpath (e.g. ["dwarffs" "nixpkgs"]) from the # root node, returning the final node. getInputByPath = nodeName: path: if path == [] diff --git a/src/libflake/flake/flake.cc b/src/libflake/flake/flake.cc index 06260c67a5d..9dc73d053d6 100644 --- a/src/libflake/flake/flake.cc +++ b/src/libflake/flake/flake.cc @@ -105,7 +105,7 @@ static std::map parseFlakeInputs( EvalState & state, Value * value, const PosIdx pos, - const InputPath & lockRootPath, + const InputAttrPath & lockRootAttrPath, const SourcePath & flakeDir); static FlakeInput parseFlakeInput( @@ -113,7 +113,7 @@ static FlakeInput parseFlakeInput( std::string_view inputName, Value * value, const PosIdx pos, - const InputPath & lockRootPath, + const InputAttrPath & lockRootAttrPath, const SourcePath & flakeDir) { expectType(state, nAttrs, *value, pos); @@ -137,7 +137,7 @@ static FlakeInput parseFlakeInput( else if (attr.value->type() == nPath) { auto path = attr.value->path(); if (path.accessor != flakeDir.accessor) - throw Error("input path '%s' at %s must be in the same source tree as %s", + throw Error("input attribute path '%s' at %s must be in the same source tree as %s", path, state.positions[attr.pos], flakeDir); url = "path:" + flakeDir.path.makeRelative(path.path); } @@ -149,11 +149,11 @@ static FlakeInput parseFlakeInput( expectType(state, nBool, *attr.value, attr.pos); input.isFlake = attr.value->boolean(); } else if (attr.name == sInputs) { - input.overrides = parseFlakeInputs(state, attr.value, attr.pos, lockRootPath, flakeDir); + input.overrides = parseFlakeInputs(state, attr.value, attr.pos, lockRootAttrPath, flakeDir); } else if (attr.name == sFollows) { expectType(state, nString, *attr.value, attr.pos); - auto follows(parseInputPath(attr.value->c_str())); - follows.insert(follows.begin(), lockRootPath.begin(), lockRootPath.end()); + auto follows(parseInputAttrPath(attr.value->c_str())); + follows.insert(follows.begin(), lockRootAttrPath.begin(), lockRootAttrPath.end()); input.follows = follows; } else { // Allow selecting a subset of enum values @@ -220,7 +220,7 @@ static std::map parseFlakeInputs( EvalState & state, Value * value, const PosIdx pos, - const InputPath & lockRootPath, + const InputAttrPath & lockRootAttrPath, const SourcePath & flakeDir) { std::map inputs; @@ -233,7 +233,7 @@ static std::map parseFlakeInputs( state.symbols[inputAttr.name], inputAttr.value, inputAttr.pos, - lockRootPath, + lockRootAttrPath, flakeDir)); } @@ -246,7 +246,7 @@ static Flake readFlake( const FlakeRef & resolvedRef, const FlakeRef & lockedRef, const SourcePath & rootDir, - const InputPath & lockRootPath) + const InputAttrPath & lockRootAttrPath) { auto flakeDir = rootDir / CanonPath(resolvedRef.subdir); auto flakePath = flakeDir / "flake.nix"; @@ -270,7 +270,7 @@ static Flake readFlake( auto sInputs = state.symbols.create("inputs"); if (auto inputs = vInfo.attrs()->get(sInputs)) - flake.inputs = parseFlakeInputs(state, inputs->value, inputs->pos, lockRootPath, flakeDir); + flake.inputs = parseFlakeInputs(state, inputs->value, inputs->pos, lockRootAttrPath, flakeDir); auto sOutputs = state.symbols.create("outputs"); @@ -347,12 +347,12 @@ static Flake getFlake( const FlakeRef & originalRef, bool useRegistries, FlakeCache & flakeCache, - const InputPath & lockRootPath) + const InputAttrPath & lockRootAttrPath) { auto [storePath, resolvedRef, lockedRef] = fetchOrSubstituteTree( state, originalRef, useRegistries, flakeCache); - return readFlake(state, originalRef, resolvedRef, lockedRef, state.rootPath(state.store->toRealPath(storePath)), lockRootPath); + return readFlake(state, originalRef, resolvedRef, lockedRef, state.rootPath(state.store->toRealPath(storePath)), lockRootAttrPath); } Flake getFlake(EvalState & state, const FlakeRef & originalRef, bool useRegistries) @@ -407,12 +407,12 @@ LockedFlake lockFlake( { FlakeInput input; SourcePath sourcePath; - std::optional parentInputPath; // FIXME: rename to inputPathPrefix? + std::optional parentInputAttrPath; // FIXME: rename to inputAttrPathPrefix? }; - std::map overrides; - std::set explicitCliOverrides; - std::set overridesUsed, updatesUsed; + std::map overrides; + std::set explicitCliOverrides; + std::set overridesUsed, updatesUsed; std::map, SourcePath> nodePaths; for (auto & i : lockFlags.inputOverrides) { @@ -436,9 +436,9 @@ LockedFlake lockFlake( std::function node, - const InputPath & inputPathPrefix, + const InputAttrPath & inputAttrPathPrefix, std::shared_ptr oldNode, - const InputPath & followsPrefix, + const InputAttrPath & followsPrefix, const SourcePath & sourcePath, bool trustLock)> computeLocks; @@ -450,7 +450,7 @@ LockedFlake lockFlake( /* The node whose locks are to be updated.*/ ref node, /* The path to this node in the lock file graph. */ - const InputPath & inputPathPrefix, + const InputAttrPath & inputAttrPathPrefix, /* The old node, if any, from which locks can be copied. */ std::shared_ptr oldNode, @@ -458,59 +458,59 @@ LockedFlake lockFlake( interpreted. When a node is initially locked, it's relative to the node's flake; when it's already locked, it's relative to the root of the lock file. */ - const InputPath & followsPrefix, + const InputAttrPath & followsPrefix, /* The source path of this node's flake. */ const SourcePath & sourcePath, bool trustLock) { - debug("computing lock file node '%s'", printInputPath(inputPathPrefix)); + debug("computing lock file node '%s'", printInputAttrPath(inputAttrPathPrefix)); /* Get the overrides (i.e. attributes of the form 'inputs.nixops.inputs.nixpkgs.url = ...'). */ for (auto & [id, input] : flakeInputs) { for (auto & [idOverride, inputOverride] : input.overrides) { - auto inputPath(inputPathPrefix); - inputPath.push_back(id); - inputPath.push_back(idOverride); - overrides.emplace(inputPath, + auto inputAttrPath(inputAttrPathPrefix); + inputAttrPath.push_back(id); + inputAttrPath.push_back(idOverride); + overrides.emplace(inputAttrPath, OverrideTarget { .input = inputOverride, .sourcePath = sourcePath, - .parentInputPath = inputPathPrefix + .parentInputAttrPath = inputAttrPathPrefix }); } } /* Check whether this input has overrides for a non-existent input. */ - for (auto [inputPath, inputOverride] : overrides) { - auto inputPath2(inputPath); - auto follow = inputPath2.back(); - inputPath2.pop_back(); - if (inputPath2 == inputPathPrefix && !flakeInputs.count(follow)) + for (auto [inputAttrPath, inputOverride] : overrides) { + auto inputAttrPath2(inputAttrPath); + auto follow = inputAttrPath2.back(); + inputAttrPath2.pop_back(); + if (inputAttrPath2 == inputAttrPathPrefix && !flakeInputs.count(follow)) warn( "input '%s' has an override for a non-existent input '%s'", - printInputPath(inputPathPrefix), follow); + printInputAttrPath(inputAttrPathPrefix), follow); } /* Go over the flake inputs, resolve/fetch them if necessary (i.e. if they're new or the flakeref changed from what's in the lock file). */ for (auto & [id, input2] : flakeInputs) { - auto inputPath(inputPathPrefix); - inputPath.push_back(id); - auto inputPathS = printInputPath(inputPath); - debug("computing input '%s'", inputPathS); + auto inputAttrPath(inputAttrPathPrefix); + inputAttrPath.push_back(id); + auto inputAttrPathS = printInputAttrPath(inputAttrPath); + debug("computing input '%s'", inputAttrPathS); try { /* Do we have an override for this input from one of the ancestors? */ - auto i = overrides.find(inputPath); + auto i = overrides.find(inputAttrPath); bool hasOverride = i != overrides.end(); - bool hasCliOverride = explicitCliOverrides.contains(inputPath); + bool hasCliOverride = explicitCliOverrides.contains(inputAttrPath); if (hasOverride) - overridesUsed.insert(inputPath); + overridesUsed.insert(inputAttrPath); auto input = hasOverride ? i->second.input : input2; /* Resolve relative 'path:' inputs relative to @@ -525,11 +525,11 @@ LockedFlake lockFlake( /* Resolve 'follows' later (since it may refer to an input path we haven't processed yet. */ if (input.follows) { - InputPath target; + InputAttrPath target; target.insert(target.end(), input.follows->begin(), input.follows->end()); - debug("input '%s' follows '%s'", inputPathS, printInputPath(target)); + debug("input '%s' follows '%s'", inputAttrPathS, printInputAttrPath(target)); node->inputs.insert_or_assign(id, target); continue; } @@ -538,7 +538,7 @@ LockedFlake lockFlake( auto overridenParentPath = input.ref->input.isRelative() - ? std::optional(hasOverride ? i->second.parentInputPath : inputPathPrefix) + ? std::optional(hasOverride ? i->second.parentInputAttrPath : inputAttrPathPrefix) : std::nullopt; auto resolveRelativePath = [&]() -> std::optional @@ -557,9 +557,9 @@ LockedFlake lockFlake( auto getInputFlake = [&]() { if (auto resolvedPath = resolveRelativePath()) { - return readFlake(state, *input.ref, *input.ref, *input.ref, *resolvedPath, inputPath); + return readFlake(state, *input.ref, *input.ref, *input.ref, *resolvedPath, inputAttrPath); } else { - return getFlake(state, *input.ref, useRegistries, flakeCache, inputPath); + return getFlake(state, *input.ref, useRegistries, flakeCache, inputAttrPath); } }; @@ -567,19 +567,19 @@ LockedFlake lockFlake( And the input is not in updateInputs? */ std::shared_ptr oldLock; - updatesUsed.insert(inputPath); + updatesUsed.insert(inputAttrPath); - if (oldNode && !lockFlags.inputUpdates.count(inputPath)) + if (oldNode && !lockFlags.inputUpdates.count(inputAttrPath)) if (auto oldLock2 = get(oldNode->inputs, id)) if (auto oldLock3 = std::get_if<0>(&*oldLock2)) oldLock = *oldLock3; if (oldLock && oldLock->originalRef == *input.ref - && oldLock->parentPath == overridenParentPath + && oldLock->parentInputAttrPath == overridenParentPath && !hasCliOverride) { - debug("keeping existing input '%s'", inputPathS); + debug("keeping existing input '%s'", inputAttrPathS); /* Copy the input from the old lock since its flakeref didn't change and there is no override from a @@ -588,18 +588,18 @@ LockedFlake lockFlake( oldLock->lockedRef, oldLock->originalRef, oldLock->isFlake, - oldLock->parentPath); + oldLock->parentInputAttrPath); node->inputs.insert_or_assign(id, childNode); /* If we have this input in updateInputs, then we must fetch the flake to update it. */ - auto lb = lockFlags.inputUpdates.lower_bound(inputPath); + auto lb = lockFlags.inputUpdates.lower_bound(inputAttrPath); auto mustRefetch = lb != lockFlags.inputUpdates.end() - && lb->size() > inputPath.size() - && std::equal(inputPath.begin(), inputPath.end(), lb->begin()); + && lb->size() > inputAttrPath.size() + && std::equal(inputAttrPath.begin(), inputAttrPath.end(), lb->begin()); FlakeInputs fakeInputs; @@ -618,7 +618,7 @@ LockedFlake lockFlake( if (!trustLock) { // It is possible that the flake has changed, // so we must confirm all the follows that are in the lock file are also in the flake. - auto overridePath(inputPath); + auto overridePath(inputAttrPath); overridePath.push_back(i.first); auto o = overrides.find(overridePath); // If the override disappeared, we have to refetch the flake, @@ -642,21 +642,21 @@ LockedFlake lockFlake( if (mustRefetch) { auto inputFlake = getInputFlake(); nodePaths.emplace(childNode, inputFlake.path.parent()); - computeLocks(inputFlake.inputs, childNode, inputPath, oldLock, followsPrefix, + computeLocks(inputFlake.inputs, childNode, inputAttrPath, oldLock, followsPrefix, inputFlake.path, false); } else { - computeLocks(fakeInputs, childNode, inputPath, oldLock, followsPrefix, sourcePath, true); + computeLocks(fakeInputs, childNode, inputAttrPath, oldLock, followsPrefix, sourcePath, true); } } else { /* We need to create a new lock file entry. So fetch this input. */ - debug("creating new input '%s'", inputPathS); + debug("creating new input '%s'", inputAttrPathS); if (!lockFlags.allowUnlocked && !input.ref->input.isLocked() && !input.ref->input.isRelative()) - throw Error("cannot update unlocked flake input '%s' in pure mode", inputPathS); + throw Error("cannot update unlocked flake input '%s' in pure mode", inputAttrPathS); /* Note: in case of an --override-input, we use the *original* ref (input2.ref) for the @@ -665,7 +665,7 @@ LockedFlake lockFlake( nuked the next time we update the lock file. That is, overrides are sticky unless you use --no-write-lock-file. */ - auto ref = (input2.ref && explicitCliOverrides.contains(inputPath)) ? *input2.ref : *input.ref; + auto ref = (input2.ref && explicitCliOverrides.contains(inputAttrPath)) ? *input2.ref : *input.ref; if (input.isFlake) { auto inputFlake = getInputFlake(); @@ -691,11 +691,11 @@ LockedFlake lockFlake( own lock file. */ nodePaths.emplace(childNode, inputFlake.path.parent()); computeLocks( - inputFlake.inputs, childNode, inputPath, + inputFlake.inputs, childNode, inputAttrPath, oldLock ? std::dynamic_pointer_cast(oldLock) : readLockFile(state.fetchSettings, inputFlake.lockFilePath()).root.get_ptr(), - oldLock ? followsPrefix : inputPath, + oldLock ? followsPrefix : inputAttrPath, inputFlake.path, false); } @@ -722,7 +722,7 @@ LockedFlake lockFlake( } } catch (Error & e) { - e.addTrace({}, "while updating the flake input '%s'", inputPathS); + e.addTrace({}, "while updating the flake input '%s'", inputAttrPathS); throw; } } @@ -742,11 +742,11 @@ LockedFlake lockFlake( for (auto & i : lockFlags.inputOverrides) if (!overridesUsed.count(i.first)) warn("the flag '--override-input %s %s' does not match any input", - printInputPath(i.first), i.second); + printInputAttrPath(i.first), i.second); for (auto & i : lockFlags.inputUpdates) if (!updatesUsed.count(i)) - warn("'%s' does not match any input of this flake", printInputPath(i)); + warn("'%s' does not match any input of this flake", printInputAttrPath(i)); /* Check 'follows' inputs. */ newLockFile.check(); diff --git a/src/libflake/flake/flake.hh b/src/libflake/flake/flake.hh index 9ab661fcee7..835d0ee0694 100644 --- a/src/libflake/flake/flake.hh +++ b/src/libflake/flake/flake.hh @@ -57,7 +57,7 @@ struct FlakeInput * false = (fetched) static source path */ bool isFlake = true; - std::optional follows; + std::optional follows; FlakeInputs overrides; }; @@ -201,13 +201,13 @@ struct LockFlags /** * Flake inputs to be overridden. */ - std::map inputOverrides; + std::map inputOverrides; /** * Flake inputs to be updated. This means that any existing lock * for those inputs will be ignored. */ - std::set inputUpdates; + std::set inputUpdates; }; LockedFlake lockFlake( diff --git a/src/libflake/flake/lockfile.cc b/src/libflake/flake/lockfile.cc index 67af108b833..25e7299f0a0 100644 --- a/src/libflake/flake/lockfile.cc +++ b/src/libflake/flake/lockfile.cc @@ -43,7 +43,7 @@ LockedNode::LockedNode( : lockedRef(getFlakeRef(fetchSettings, json, "locked", "info")) // FIXME: remove "info" , originalRef(getFlakeRef(fetchSettings, json, "original", nullptr)) , isFlake(json.find("flake") != json.end() ? (bool) json["flake"] : true) - , parentPath(json.find("parent") != json.end() ? (std::optional) json["parent"] : std::nullopt) + , parentInputAttrPath(json.find("parent") != json.end() ? (std::optional) json["parent"] : std::nullopt) { if (!lockedRef.input.isConsideredLocked(fetchSettings) && !lockedRef.input.isRelative()) throw Error("Lock file contains unlocked input '%s'. Use '--allow-dirty-locks' to accept this lock file.", @@ -59,7 +59,7 @@ StorePath LockedNode::computeStorePath(Store & store) const return lockedRef.input.computeStorePath(store); } -static std::shared_ptr doFind(const ref & root, const InputPath & path, std::vector & visited) +static std::shared_ptr doFind(const ref & root, const InputAttrPath & path, std::vector & visited) { auto pos = root; @@ -67,8 +67,8 @@ static std::shared_ptr doFind(const ref & root, const InputPath & pa if (found != visited.end()) { std::vector cycle; - std::transform(found, visited.cend(), std::back_inserter(cycle), printInputPath); - cycle.push_back(printInputPath(path)); + std::transform(found, visited.cend(), std::back_inserter(cycle), printInputAttrPath); + cycle.push_back(printInputAttrPath(path)); throw Error("follow cycle detected: [%s]", concatStringsSep(" -> ", cycle)); } visited.push_back(path); @@ -90,9 +90,9 @@ static std::shared_ptr doFind(const ref & root, const InputPath & pa return pos; } -std::shared_ptr LockFile::findInput(const InputPath & path) +std::shared_ptr LockFile::findInput(const InputAttrPath & path) { - std::vector visited; + std::vector visited; return doFind(root, path, visited); } @@ -115,7 +115,7 @@ LockFile::LockFile( if (jsonNode.find("inputs") == jsonNode.end()) return; for (auto & i : jsonNode["inputs"].items()) { if (i.value().is_array()) { // FIXME: remove, obsolete - InputPath path; + InputAttrPath path; for (auto & j : i.value()) path.push_back(j); node.inputs.insert_or_assign(i.key(), path); @@ -203,8 +203,8 @@ std::pair LockFile::toJSON() const n["locked"].erase("__final"); if (!lockedNode->isFlake) n["flake"] = false; - if (lockedNode->parentPath) - n["parent"] = *lockedNode->parentPath; + if (lockedNode->parentInputAttrPath) + n["parent"] = *lockedNode->parentInputAttrPath; } nodes[key] = std::move(n); @@ -267,36 +267,36 @@ bool LockFile::operator ==(const LockFile & other) const return toJSON().first == other.toJSON().first; } -InputPath parseInputPath(std::string_view s) +InputAttrPath parseInputAttrPath(std::string_view s) { - InputPath path; + InputAttrPath path; for (auto & elem : tokenizeString>(s, "/")) { if (!std::regex_match(elem, flakeIdRegex)) - throw UsageError("invalid flake input path element '%s'", elem); + throw UsageError("invalid flake input attribute path element '%s'", elem); path.push_back(elem); } return path; } -std::map LockFile::getAllInputs() const +std::map LockFile::getAllInputs() const { std::set> done; - std::map res; + std::map res; - std::function node)> recurse; + std::function node)> recurse; - recurse = [&](const InputPath & prefix, ref node) + recurse = [&](const InputAttrPath & prefix, ref node) { if (!done.insert(node).second) return; for (auto &[id, input] : node->inputs) { - auto inputPath(prefix); - inputPath.push_back(id); - res.emplace(inputPath, input); + auto inputAttrPath(prefix); + inputAttrPath.push_back(id); + res.emplace(inputAttrPath, input); if (auto child = std::get_if<0>(&input)) - recurse(inputPath, *child); + recurse(inputAttrPath, *child); } }; @@ -320,7 +320,7 @@ std::ostream & operator <<(std::ostream & stream, const Node::Edge & edge) if (auto node = std::get_if<0>(&edge)) stream << describe((*node)->lockedRef); else if (auto follows = std::get_if<1>(&edge)) - stream << fmt("follows '%s'", printInputPath(*follows)); + stream << fmt("follows '%s'", printInputAttrPath(*follows)); return stream; } @@ -347,15 +347,15 @@ std::string LockFile::diff(const LockFile & oldLocks, const LockFile & newLocks) while (i != oldFlat.end() || j != newFlat.end()) { if (j != newFlat.end() && (i == oldFlat.end() || i->first > j->first)) { res += fmt("• " ANSI_GREEN "Added input '%s':" ANSI_NORMAL "\n %s\n", - printInputPath(j->first), j->second); + printInputAttrPath(j->first), j->second); ++j; } else if (i != oldFlat.end() && (j == newFlat.end() || i->first < j->first)) { - res += fmt("• " ANSI_RED "Removed input '%s'" ANSI_NORMAL "\n", printInputPath(i->first)); + res += fmt("• " ANSI_RED "Removed input '%s'" ANSI_NORMAL "\n", printInputAttrPath(i->first)); ++i; } else { if (!equals(i->second, j->second)) { res += fmt("• " ANSI_BOLD "Updated input '%s':" ANSI_NORMAL "\n %s\n → %s\n", - printInputPath(i->first), + printInputAttrPath(i->first), i->second, j->second); } @@ -371,19 +371,19 @@ void LockFile::check() { auto inputs = getAllInputs(); - for (auto & [inputPath, input] : inputs) { + for (auto & [inputAttrPath, input] : inputs) { if (auto follows = std::get_if<1>(&input)) { if (!follows->empty() && !findInput(*follows)) throw Error("input '%s' follows a non-existent input '%s'", - printInputPath(inputPath), - printInputPath(*follows)); + printInputAttrPath(inputAttrPath), + printInputAttrPath(*follows)); } } } void check(); -std::string printInputPath(const InputPath & path) +std::string printInputAttrPath(const InputAttrPath & path) { return concatStringsSep("/", path); } diff --git a/src/libflake/flake/lockfile.hh b/src/libflake/flake/lockfile.hh index cb7c8da5ada..cbc6d01ebce 100644 --- a/src/libflake/flake/lockfile.hh +++ b/src/libflake/flake/lockfile.hh @@ -12,7 +12,7 @@ class StorePath; namespace nix::flake { -typedef std::vector InputPath; +typedef std::vector InputAttrPath; struct LockedNode; @@ -23,7 +23,7 @@ struct LockedNode; */ struct Node : std::enable_shared_from_this { - typedef std::variant, InputPath> Edge; + typedef std::variant, InputAttrPath> Edge; std::map inputs; @@ -40,17 +40,17 @@ struct LockedNode : Node /* The node relative to which relative source paths (e.g. 'path:../foo') are interpreted. */ - std::optional parentPath; + std::optional parentInputAttrPath; LockedNode( const FlakeRef & lockedRef, const FlakeRef & originalRef, bool isFlake = true, - std::optional parentPath = {}) - : lockedRef(lockedRef) - , originalRef(originalRef) + std::optional parentInputAttrPath = {}) + : lockedRef(std::move(lockedRef)) + , originalRef(std::move(originalRef)) , isFlake(isFlake) - , parentPath(parentPath) + , parentInputAttrPath(std::move(parentInputAttrPath)) { } LockedNode( @@ -83,9 +83,9 @@ struct LockFile bool operator ==(const LockFile & other) const; - std::shared_ptr findInput(const InputPath & path); + std::shared_ptr findInput(const InputAttrPath & path); - std::map getAllInputs() const; + std::map getAllInputs() const; static std::string diff(const LockFile & oldLocks, const LockFile & newLocks); @@ -97,8 +97,8 @@ struct LockFile std::ostream & operator <<(std::ostream & stream, const LockFile & lockFile); -InputPath parseInputPath(std::string_view s); +InputAttrPath parseInputAttrPath(std::string_view s); -std::string printInputPath(const InputPath & path); +std::string printInputAttrPath(const InputAttrPath & path); } diff --git a/src/nix/flake.cc b/src/nix/flake.cc index 384c23d8c97..adf391b97be 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -95,20 +95,20 @@ struct CmdFlakeUpdate : FlakeCommand .optional=true, .handler={[&](std::vector inputsToUpdate){ for (const auto & inputToUpdate : inputsToUpdate) { - InputPath inputPath; + InputAttrPath inputAttrPath; try { - inputPath = flake::parseInputPath(inputToUpdate); + inputAttrPath = flake::parseInputAttrPath(inputToUpdate); } catch (Error & e) { warn("Invalid flake input '%s'. To update a specific flake, use 'nix flake update --flake %s' instead.", inputToUpdate, inputToUpdate); throw e; } - if (lockFlags.inputUpdates.contains(inputPath)) - warn("Input '%s' was specified multiple times. You may have done this by accident.", printInputPath(inputPath)); - lockFlags.inputUpdates.insert(inputPath); + if (lockFlags.inputUpdates.contains(inputAttrPath)) + warn("Input '%s' was specified multiple times. You may have done this by accident.", printInputAttrPath(inputAttrPath)); + lockFlags.inputUpdates.insert(inputAttrPath); } }}, .completer = {[&](AddCompletions & completions, size_t, std::string_view prefix) { - completeFlakeInputPath(completions, getEvalState(), getFlakeRefsForCompletion(), prefix); + completeFlakeInputAttrPath(completions, getEvalState(), getFlakeRefsForCompletion(), prefix); }} }); @@ -304,7 +304,7 @@ struct CmdFlakeMetadata : FlakeCommand, MixJSON } else if (auto follows = std::get_if<1>(&input.second)) { logger->cout("%s" ANSI_BOLD "%s" ANSI_NORMAL " follows input '%s'", prefix + (last ? treeLast : treeConn), input.first, - printInputPath(*follows)); + printInputAttrPath(*follows)); } } }; From 00d9e7e1f43e3051b793ce1c21f6e902386b93fe Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 24 Jan 2025 12:15:07 +0100 Subject: [PATCH 15/60] EvalState::resolveLookupPathPath(): Call resolveSymlinks() before pathExists() Fixes #12339. --- src/libexpr/eval.cc | 2 +- tests/functional/restricted.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 345c09e7e9c..19ca1a3591e 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -3114,7 +3114,7 @@ std::optional EvalState::resolveLookupPathPath(const LookupPath::Pat } } - if (path.pathExists()) + if (path.resolveSymlinks().pathExists()) return finish(std::move(path)); else { logWarning({ diff --git a/tests/functional/restricted.sh b/tests/functional/restricted.sh index a92a9b8a3a2..00ee4ddc8c2 100755 --- a/tests/functional/restricted.sh +++ b/tests/functional/restricted.sh @@ -23,7 +23,7 @@ nix-instantiate --restrict-eval ./simple.nix -I src1=./simple.nix -I src2=./conf (! nix-instantiate --restrict-eval --eval -E 'builtins.readFile ./simple.nix') nix-instantiate --restrict-eval --eval -E 'builtins.readFile ./simple.nix' -I src=../.. -expectStderr 1 nix-instantiate --restrict-eval --eval -E 'let __nixPath = [ { prefix = "foo"; path = ./.; } ]; in builtins.readFile ' | grepQuiet "was not found in the Nix search path" +expectStderr 1 nix-instantiate --restrict-eval --eval -E 'let __nixPath = [ { prefix = "foo"; path = ./.; } ]; in builtins.readFile ' | grepQuiet "forbidden in restricted mode" nix-instantiate --restrict-eval --eval -E 'let __nixPath = [ { prefix = "foo"; path = ./.; } ]; in builtins.readFile ' -I src=. p=$(nix eval --raw --expr "builtins.fetchurl file://${_NIX_TEST_SOURCE_DIR}/restricted.sh" --impure --restrict-eval --allowed-uris "file://${_NIX_TEST_SOURCE_DIR}") From ace52b10c98fd76df2b14bdc44c1b97ed79b8b8f Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Fri, 24 Jan 2025 12:41:26 +0100 Subject: [PATCH 16/60] doc/building: Update for #11799 Reflect the shorter attribute name, changed in f168a6e739185c19f39350af985ed6de08519195 https://github.com/NixOS/nix/pull/11799 --- doc/manual/source/development/building.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/manual/source/development/building.md b/doc/manual/source/development/building.md index 409294682e9..9a8ed83468f 100644 --- a/doc/manual/source/development/building.md +++ b/doc/manual/source/development/building.md @@ -79,7 +79,7 @@ This shell also adds `./outputs/bin/nix` to your `$PATH` so you can run `nix` im To get a shell with one of the other [supported compilation environments](#compilation-environments): ```console -$ nix develop .#native-clangStdenvPackages +$ nix develop .#native-clangStdenv ``` > **Note** @@ -261,7 +261,8 @@ See [supported compilation environments](#compilation-environments) and instruct To use the LSP with your editor, you will want a `compile_commands.json` file telling `clangd` how we are compiling the code. Meson's configure always produces this inside the build directory. -Configure your editor to use the `clangd` from the `.#native-clangStdenvPackages` shell. You can do that either by running it inside the development shell, or by using [nix-direnv](https://github.com/nix-community/nix-direnv) and [the appropriate editor plugin](https://github.com/direnv/direnv/wiki#editor-integration). +Configure your editor to use the `clangd` from the `.#native-clangStdenv` shell. +You can do that either by running it inside the development shell, or by using [nix-direnv](https://github.com/nix-community/nix-direnv) and [the appropriate editor plugin](https://github.com/direnv/direnv/wiki#editor-integration). > **Note** > From d48d464c8b864e0149fb8cff2634aa2d61e7e109 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 24 Jan 2025 15:03:46 +0100 Subject: [PATCH 17/60] Add a test for #12339 --- tests/functional/nix-channel.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/functional/nix-channel.sh b/tests/functional/nix-channel.sh index 16d6a135568..d0b772850dd 100755 --- a/tests/functional/nix-channel.sh +++ b/tests/functional/nix-channel.sh @@ -68,4 +68,14 @@ nix-env -i dependencies-top [ -e $TEST_HOME/.nix-profile/foobar ] # Test evaluation through a channel symlink (#9882). -nix-instantiate '' +drvPath=$(nix-instantiate '') + +# Add a test for the special case behaviour of 'nixpkgs' in the +# channels for root (see EvalSettings::getDefaultNixPath()). +if ! isTestOnNixOS; then + nix-channel --add file://$TEST_ROOT/foo nixpkgs + nix-channel --update + mv $TEST_HOME/.local/state/nix/profiles $TEST_ROOT/var/nix/profiles/per-user/root + drvPath2=$(nix-instantiate '') + [[ "$drvPath" = "$drvPath2" ]] +fi From ba6425a7d0dad99f4fd03e17db3d4c29df62dd70 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Fri, 24 Jan 2025 13:16:36 +0100 Subject: [PATCH 18/60] dev: Configure nixfmt (rfc style) --- doc/manual/source/development/building.md | 29 +++++++++++++ flake.lock | 52 +++++++++++++++++++++++ flake.nix | 3 +- maintainers/flake-module.nix | 30 ++++++++++++- packaging/dev-shell.nix | 3 +- 5 files changed, 114 insertions(+), 3 deletions(-) diff --git a/doc/manual/source/development/building.md b/doc/manual/source/development/building.md index 9a8ed83468f..a60543f4de2 100644 --- a/doc/manual/source/development/building.md +++ b/doc/manual/source/development/building.md @@ -278,6 +278,8 @@ You may run the formatters as a one-off using: ./maintainers/format.sh ``` +### Pre-commit hooks + If you'd like to run the formatters before every commit, install the hooks: ``` @@ -292,3 +294,30 @@ If it fails, run `git add --patch` to approve the suggestions _and commit again_ To refresh pre-commit hook's config file, do the following: 1. Exit the development shell and start it again by running `nix develop`. 2. If you also use the pre-commit hook, also run `pre-commit-hooks-install` again. + +### VSCode + +Insert the following json into your `.vscode/settings.json` file to configure `nixfmt`. +This will be picked up by the _Format Document_ command, `"editor.formatOnSave"`, etc. + +```json +{ + "nix.formatterPath": "nixfmt", + "nix.serverSettings": { + "nixd": { + "formatting": { + "command": [ + "nixfmt" + ], + }, + }, + "nil": { + "formatting": { + "command": [ + "nixfmt" + ], + }, + }, + }, +} +``` diff --git a/flake.lock b/flake.lock index ce484a67a2a..e45f0fb9849 100644 --- a/flake.lock +++ b/flake.lock @@ -36,6 +36,24 @@ "type": "github" } }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, "git-hooks-nix": { "inputs": { "flake-compat": [], @@ -61,6 +79,24 @@ "type": "github" } }, + "nixfmt": { + "inputs": { + "flake-utils": "flake-utils" + }, + "locked": { + "lastModified": 1736283758, + "narHash": "sha256-hrKhUp2V2fk/dvzTTHFqvtOg000G1e+jyIam+D4XqhA=", + "owner": "NixOS", + "repo": "nixfmt", + "rev": "8d4bd690c247004d90d8554f0b746b1231fe2436", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixfmt", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1734359947, @@ -114,10 +150,26 @@ "flake-compat": "flake-compat", "flake-parts": "flake-parts", "git-hooks-nix": "git-hooks-nix", + "nixfmt": "nixfmt", "nixpkgs": "nixpkgs", "nixpkgs-23-11": "nixpkgs-23-11", "nixpkgs-regression": "nixpkgs-regression" } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 64391efa40b..c6df63c5eb2 100644 --- a/flake.nix +++ b/flake.nix @@ -17,6 +17,7 @@ # work around 7730 and https://github.com/NixOS/nix/issues/7807 inputs.git-hooks-nix.inputs.flake-compat.follows = ""; inputs.git-hooks-nix.inputs.gitignore.follows = ""; + inputs.nixfmt.url = "github:NixOS/nixfmt"; outputs = inputs@{ self, nixpkgs, nixpkgs-regression, ... }: @@ -301,7 +302,7 @@ }); devShells = let - makeShell = import ./packaging/dev-shell.nix { inherit lib devFlake; }; + makeShell = import ./packaging/dev-shell.nix { inherit inputs lib devFlake; }; prefixAttrs = prefix: lib.concatMapAttrs (k: v: { "${prefix}-${k}" = v; }); in forAllSystems (system: diff --git a/maintainers/flake-module.nix b/maintainers/flake-module.nix index fcf370b7145..93fd3675ebd 100644 --- a/maintainers/flake-module.nix +++ b/maintainers/flake-module.nix @@ -31,6 +31,35 @@ touch $out ''}"; }; + nixfmt-rfc-style = { + enable = true; + package = inputs.nixfmt.packages.${pkgs.hostPlatform.system}.default; + excludes = [ + # Invalid + ''^tests/functional/lang/parse-.*\.nix$'' + + # Formatting-sensitive + ''^tests/functional/lang/eval-okay-curpos\.nix$'' + ''^tests/functional/lang/.*comment.*\.nix$'' + ''^tests/functional/lang/.*newline.*\.nix$'' + ''^tests/functional/lang/.*eol.*\.nix$'' + + # Syntax tests + ''^tests/functional/shell.shebang\.nix$'' + ''^tests/functional/lang/eval-okay-ind-string\.nix$'' + + # Not supported by nixfmt + ''^tests/functional/lang/eval-okay-deprecate-cursed-or\.nix$'' + ''^tests/functional/lang/eval-okay-attrs5\.nix$'' + + # More syntax tests + # These tests, or parts of them, should have been parse-* test cases. + ''^tests/functional/lang/eval-fail-eol-2\.nix$'' + ''^tests/functional/lang/eval-fail-path-slash\.nix$'' + ''^tests/functional/lang/eval-fail-toJSON-non-utf-8\.nix$'' + ''^tests/functional/lang/eval-fail-set\.nix$'' + ]; + }; clang-format = { enable = true; # https://github.com/cachix/git-hooks.nix/pull/532 @@ -660,7 +689,6 @@ ''^src/libutil-tests/data/git/check-data\.sh$'' ]; }; - # TODO: nixfmt, https://github.com/NixOS/nixfmt/issues/153 }; }; }; diff --git a/packaging/dev-shell.nix b/packaging/dev-shell.nix index 30ac518d5f7..b35a48f65b0 100644 --- a/packaging/dev-shell.nix +++ b/packaging/dev-shell.nix @@ -1,4 +1,4 @@ -{ lib, devFlake }: +{ lib, inputs, devFlake }: { pkgs }: @@ -108,6 +108,7 @@ in { modular.pre-commit.settings.package (pkgs.writeScriptBin "pre-commit-hooks-install" modular.pre-commit.settings.installationScript) + inputs.nixfmt.packages.${pkgs.hostPlatform.system}.default ] # TODO: Remove the darwin check once # https://github.com/NixOS/nixpkgs/pull/291814 is available From 96e550efc5a8694dae915c41416a9f6485d4cc40 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Fri, 24 Jan 2025 13:37:47 +0100 Subject: [PATCH 19/60] Format .nix files ... with nixfmt (rfc style) --- default.nix | 19 +- doc/manual/generate-builtins.nix | 10 +- doc/manual/generate-manpage.nix | 152 +- doc/manual/generate-settings.nix | 116 +- doc/manual/generate-store-info.nix | 55 +- doc/manual/generate-store-types.nix | 28 +- doc/manual/generate-xp-features-shortlist.nix | 10 +- doc/manual/generate-xp-features.nix | 3 +- doc/manual/package.nix | 60 +- doc/manual/utils.nix | 44 +- docker.nix | 438 +++--- flake.nix | 405 +++-- maintainers/flake-module.nix | 1359 +++++++++-------- packaging/binary-tarball.nix | 16 +- packaging/components.nix | 12 +- packaging/dependencies.nix | 239 +-- packaging/dev-shell.nix | 262 ++-- packaging/everything.nix | 201 +-- packaging/hydra.nix | 211 +-- packaging/installer/default.nix | 68 +- src/external-api-docs/package.nix | 20 +- src/internal-api-docs/package.nix | 44 +- src/libcmd/package.nix | 49 +- src/libexpr-c/package.nix | 13 +- src/libexpr-test-support/package.nix | 17 +- src/libexpr-tests/package.nix | 53 +- src/libexpr/call-flake.nix | 130 +- src/libexpr/fetchurl.nix | 96 +- src/libexpr/imported-drv-to-derivation.nix | 36 +- src/libexpr/package.nix | 66 +- src/libexpr/primops/derivation.nix | 31 +- src/libfetchers-tests/package.nix | 51 +- src/libfetchers/package.nix | 17 +- src/libflake-c/package.nix | 15 +- src/libflake-tests/package.nix | 55 +- src/libflake/package.nix | 19 +- src/libmain-c/package.nix | 17 +- src/libmain/package.nix | 15 +- src/libstore-c/package.nix | 13 +- src/libstore-test-support/package.nix | 17 +- src/libstore-tests/package.nix | 76 +- src/libstore/package.nix | 68 +- src/libutil-c/package.nix | 11 +- src/libutil-test-support/package.nix | 15 +- src/libutil-tests/package.nix | 51 +- src/libutil/package.nix | 28 +- src/nix-channel/unpack-channel.nix | 6 +- src/nix-env/buildenv.nix | 16 +- src/nix/package.nix | 126 +- src/perl/package.nix | 126 +- tests/functional/big-derivation-attr.nix | 21 +- tests/functional/build-hook-ca-fixed.nix | 68 +- tests/functional/build-hook.nix | 85 +- tests/functional/ca-shell.nix | 6 +- tests/functional/ca/content-addressed.nix | 26 +- tests/functional/ca/flake.nix | 2 +- tests/functional/ca/nondeterministic.nix | 33 +- tests/functional/ca/racy.nix | 1 - tests/functional/check-refs.nix | 29 +- tests/functional/check-reqs.nix | 42 +- tests/functional/check.nix | 51 +- tests/functional/dependencies.nix | 4 +- .../advanced-attributes-defaults.nix | 5 +- ...d-attributes-structured-attrs-defaults.nix | 10 +- .../advanced-attributes-structured-attrs.nix | 38 +- .../derivation/advanced-attributes.nix | 32 +- .../functional/dyn-drv/recursive-mod-json.nix | 4 +- tests/functional/export-graph.nix | 31 +- tests/functional/failing.nix | 33 +- tests/functional/filter-source.nix | 13 +- tests/functional/fixed.nix | 26 +- tests/functional/fod-failing.nix | 30 +- tests/functional/gc-concurrent.nix | 4 +- tests/functional/hash-check.nix | 20 +- tests/functional/hermetic.nix | 85 +- tests/functional/ifd.nix | 12 +- tests/functional/import-from-derivation.nix | 21 +- tests/functional/impure-derivations.nix | 64 +- .../lang-gc/issue-11141-gc-coroutine-test.nix | 94 +- ...vOutputDependencies-multi-elem-context.nix | 13 +- ...vOutputDependencies-wrong-element-kind.nix | 8 +- .../eval-fail-addErrorContext-example.nix | 14 +- .../eval-fail-assert-equal-attrs-names-2.nix | 8 +- .../eval-fail-assert-equal-attrs-names.nix | 8 +- ...al-fail-assert-equal-derivations-extra.nix | 17 +- .../eval-fail-assert-equal-derivations.nix | 18 +- ...eval-fail-assert-equal-function-direct.nix | 7 +- .../eval-fail-assert-equal-list-length.nix | 8 +- .../lang/eval-fail-assert-equal-paths.nix | 2 +- .../lang/eval-fail-assert-nested-bool.nix | 7 +- tests/functional/lang/eval-fail-assert.nix | 7 +- .../lang/eval-fail-attr-name-type.nix | 4 +- ...val-fail-attrset-merge-drops-later-rec.nix | 9 +- .../eval-fail-bad-string-interpolation-4.nix | 12 +- .../lang/eval-fail-dup-dynamic-attrs.nix | 8 +- .../lang/eval-fail-duplicate-traces.nix | 7 +- ...eval-fail-fetchurl-baseName-attrs-name.nix | 5 +- ...l-flake-ref-to-string-negative-integer.nix | 19 +- ...fail-foldlStrict-strict-op-application.nix | 8 +- .../lang/eval-fail-hashfile-missing.nix | 17 +- tests/functional/lang/eval-fail-list.nix | 2 +- .../functional/lang/eval-fail-missing-arg.nix | 13 +- .../lang/eval-fail-mutual-recursion.nix | 30 +- .../lang/eval-fail-nested-list-items.nix | 25 +- .../functional/lang/eval-fail-not-throws.nix | 2 +- .../lang/eval-fail-overflowing-add.nix | 3 +- .../lang/eval-fail-overflowing-div.nix | 3 +- .../lang/eval-fail-overflowing-mul.nix | 3 +- .../lang/eval-fail-overflowing-sub.nix | 3 +- tests/functional/lang/eval-fail-recursion.nix | 5 +- tests/functional/lang/eval-fail-remove.nix | 9 +- tests/functional/lang/eval-fail-scope-5.nix | 11 +- .../lang/eval-fail-undeclared-arg.nix | 6 +- .../lang/eval-fail-using-set-as-attr-name.nix | 8 +- tests/functional/lang/eval-okay-any-all.nix | 39 +- .../functional/lang/eval-okay-arithmetic.nix | 91 +- tests/functional/lang/eval-okay-attrnames.nix | 15 +- tests/functional/lang/eval-okay-attrs.nix | 19 +- tests/functional/lang/eval-okay-attrs2.nix | 21 +- tests/functional/lang/eval-okay-attrs3.nix | 34 +- tests/functional/lang/eval-okay-attrs4.nix | 17 +- tests/functional/lang/eval-okay-attrs6.nix | 4 +- tests/functional/lang/eval-okay-autoargs.nix | 15 +- .../lang/eval-okay-builtins-add.nix | 12 +- tests/functional/lang/eval-okay-builtins.nix | 2 +- .../lang/eval-okay-callable-attrs.nix | 11 +- tests/functional/lang/eval-okay-catattrs.nix | 6 +- tests/functional/lang/eval-okay-closure.nix | 24 +- tests/functional/lang/eval-okay-concat.nix | 16 +- tests/functional/lang/eval-okay-concatmap.nix | 8 +- .../lang/eval-okay-concatstringssep.nix | 19 +- .../lang/eval-okay-context-introspection.nix | 39 +- tests/functional/lang/eval-okay-context.nix | 11 +- .../functional/lang/eval-okay-convertHash.nix | 130 +- tests/functional/lang/eval-okay-deepseq.nix | 10 +- .../lang/eval-okay-delayed-with-inherit.nix | 13 +- .../lang/eval-okay-delayed-with.nix | 20 +- .../lang/eval-okay-dynamic-attrs-2.nix | 6 +- .../lang/eval-okay-dynamic-attrs-bare.nix | 17 +- .../lang/eval-okay-dynamic-attrs.nix | 17 +- tests/functional/lang/eval-okay-elem.nix | 11 +- .../functional/lang/eval-okay-empty-args.nix | 5 +- .../lang/eval-okay-eq-derivations.nix | 44 +- tests/functional/lang/eval-okay-eq.nix | 16 +- tests/functional/lang/eval-okay-filter.nix | 9 +- .../lang/eval-okay-flake-ref-to-string.nix | 8 +- tests/functional/lang/eval-okay-flatten.nix | 14 +- .../functional/lang/eval-okay-floor-ceil.nix | 9 +- .../eval-okay-foldlStrict-lazy-elements.nix | 5 +- ...y-foldlStrict-lazy-initial-accumulator.nix | 8 +- .../lang/eval-okay-fromjson-escapes.nix | 3 +- tests/functional/lang/eval-okay-fromjson.nix | 94 +- .../lang/eval-okay-functionargs.nix | 140 +- .../eval-okay-getattrpos-functionargs.nix | 8 +- .../functional/lang/eval-okay-getattrpos.nix | 6 +- tests/functional/lang/eval-okay-groupBy.nix | 6 +- tests/functional/lang/eval-okay-hashfile.nix | 14 +- .../functional/lang/eval-okay-hashstring.nix | 15 +- tests/functional/lang/eval-okay-if.nix | 7 +- tests/functional/lang/eval-okay-import.nix | 3 +- .../lang/eval-okay-inherit-attr-pos.nix | 12 +- .../lang/eval-okay-inherit-from.nix | 21 +- .../lang/eval-okay-intersectAttrs.nix | 45 +- tests/functional/lang/eval-okay-list.nix | 11 +- .../functional/lang/eval-okay-listtoattrs.nix | 27 +- tests/functional/lang/eval-okay-logic.nix | 3 +- tests/functional/lang/eval-okay-map.nix | 8 +- tests/functional/lang/eval-okay-mapattrs.nix | 5 +- .../lang/eval-okay-merge-dynamic-attrs.nix | 16 +- .../functional/lang/eval-okay-nested-with.nix | 4 +- tests/functional/lang/eval-okay-new-let.nix | 8 +- .../lang/eval-okay-null-dynamic-attrs.nix | 2 +- tests/functional/lang/eval-okay-overrides.nix | 8 +- .../lang/eval-okay-parse-flake-ref.nix | 2 +- tests/functional/lang/eval-okay-partition.nix | 9 +- tests/functional/lang/eval-okay-path.nix | 26 +- tests/functional/lang/eval-okay-patterns.nix | 61 +- tests/functional/lang/eval-okay-print.nix | 16 +- .../lang/eval-okay-readFileType.nix | 6 +- .../lang/eval-okay-redefine-builtin.nix | 3 +- .../functional/lang/eval-okay-regex-match.nix | 30 +- .../functional/lang/eval-okay-regex-split.nix | 213 ++- .../lang/eval-okay-regression-20220125.nix | 1 - ...val-okay-regrettable-rec-attrset-merge.nix | 9 +- tests/functional/lang/eval-okay-remove.nix | 9 +- .../lang/eval-okay-repeated-empty-attrs.nix | 5 +- .../lang/eval-okay-repeated-empty-list.nix | 5 +- .../lang/eval-okay-replacestrings.nix | 19 +- tests/functional/lang/eval-okay-scope-1.nix | 17 +- tests/functional/lang/eval-okay-scope-2.nix | 18 +- tests/functional/lang/eval-okay-scope-3.nix | 19 +- tests/functional/lang/eval-okay-scope-4.nix | 11 +- tests/functional/lang/eval-okay-scope-6.nix | 9 +- tests/functional/lang/eval-okay-scope-7.nix | 3 +- .../functional/lang/eval-okay-search-path.nix | 15 +- tests/functional/lang/eval-okay-sort.nix | 62 +- tests/functional/lang/eval-okay-string.nix | 21 +- .../lang/eval-okay-strings-as-attrs-names.nix | 6 +- .../lang/eval-okay-substring-context.nix | 13 +- .../functional/lang/eval-okay-tail-call-1.nix | 3 +- tests/functional/lang/eval-okay-tojson.nix | 39 +- tests/functional/lang/eval-okay-toxml2.nix | 9 +- tests/functional/lang/eval-okay-tryeval.nix | 5 +- tests/functional/lang/eval-okay-types.nix | 9 +- tests/functional/lang/eval-okay-versions.nix | 14 +- tests/functional/lang/eval-okay-xml.nix | 27 +- .../lang/eval-okay-zipAttrsWith.nix | 7 +- tests/functional/lang/lib.nix | 84 +- tests/functional/linux-sandbox-cert-test.nix | 11 +- tests/functional/multiple-outputs.nix | 153 +- tests/functional/nar-access.nix | 35 +- tests/functional/nested-sandboxing/runner.nix | 41 +- tests/functional/package.nix | 181 +-- tests/functional/parallel.nix | 38 +- tests/functional/path.nix | 16 +- tests/functional/readfile-context.nix | 3 +- tests/functional/recursive.nix | 8 +- .../functional/repl/doc-comment-function.nix | 7 +- tests/functional/repl/doc-comments.nix | 97 +- tests/functional/repl/doc-functor.nix | 45 +- tests/functional/secure-drv-outputs.nix | 18 +- tests/functional/shell-hello.nix | 90 +- tests/functional/shell.nix | 192 ++- tests/functional/simple-failing.nix | 9 +- tests/functional/structured-attrs-shell.nix | 11 +- tests/functional/structured-attrs.nix | 21 +- tests/functional/undefined-variable.nix | 5 +- tests/functional/user-envs.nix | 57 +- tests/installer/default.nix | 63 +- tests/nixos/authorization.nix | 145 +- tests/nixos/ca-fd-leak/default.nix | 90 +- tests/nixos/cgroups/default.nix | 67 +- tests/nixos/cgroups/hang.nix | 5 +- tests/nixos/chroot-store.nix | 52 +- tests/nixos/containers/containers.nix | 117 +- tests/nixos/containers/id-test.nix | 14 +- tests/nixos/containers/systemd-nspawn.nix | 16 +- tests/nixos/default.nix | 137 +- tests/nixos/fetch-git/default.nix | 31 +- .../test-cases/http-auth/default.nix | 3 +- .../test-cases/http-simple/default.nix | 3 +- .../test-cases/ssh-simple/default.nix | 3 +- .../fetch-git/testsupport/gitea-repo.nix | 34 +- tests/nixos/fetch-git/testsupport/gitea.nix | 72 +- tests/nixos/fetch-git/testsupport/setup.nix | 77 +- tests/nixos/fetchurl.nix | 85 +- tests/nixos/fsync.nix | 60 +- tests/nixos/functional/as-trusted-user.nix | 6 +- tests/nixos/functional/as-user.nix | 4 +- tests/nixos/functional/common.nix | 98 +- tests/nixos/functional/symlinked-home.nix | 4 +- tests/nixos/git-submodules.nix | 114 +- tests/nixos/github-flakes.nix | 350 +++-- tests/nixos/gzip-content-encoding.nix | 59 +- tests/nixos/nix-copy-closure.nix | 159 +- tests/nixos/nix-copy.nix | 210 +-- tests/nixos/nix-docker.nix | 86 +- tests/nixos/nss-preload.nix | 181 ++- tests/nixos/remote-builds-ssh-ng.nix | 183 +-- tests/nixos/remote-builds.nix | 221 +-- tests/nixos/s3-binary-cache-store.nix | 119 +- tests/nixos/setuid.nix | 234 +-- tests/nixos/sourcehut-flakes.nix | 167 +- tests/nixos/tarball-flakes.nix | 156 +- tests/nixos/user-sandboxing/default.nix | 152 +- tests/repl-completion.nix | 73 +- 266 files changed, 7625 insertions(+), 5303 deletions(-) diff --git a/default.nix b/default.nix index 2cccff28d51..6466507b714 100644 --- a/default.nix +++ b/default.nix @@ -1,10 +1,9 @@ -(import - ( - let lock = builtins.fromJSON (builtins.readFile ./flake.lock); in - fetchTarball { - url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; - sha256 = lock.nodes.flake-compat.locked.narHash; - } - ) - { src = ./.; } -).defaultNix +(import ( + let + lock = builtins.fromJSON (builtins.readFile ./flake.lock); + in + fetchTarball { + url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; + sha256 = lock.nodes.flake-compat.locked.narHash; + } +) { src = ./.; }).defaultNix diff --git a/doc/manual/generate-builtins.nix b/doc/manual/generate-builtins.nix index 37ed12a4330..3649560f7c6 100644 --- a/doc/manual/generate-builtins.nix +++ b/doc/manual/generate-builtins.nix @@ -5,7 +5,15 @@ in builtinsInfo: let - showBuiltin = name: { doc, type ? null, args ? [ ], experimental-feature ? null, impure-only ? false }: + showBuiltin = + name: + { + doc, + type ? null, + args ? [ ], + experimental-feature ? null, + impure-only ? false, + }: let type' = optionalString (type != null) " (${type})"; diff --git a/doc/manual/generate-manpage.nix b/doc/manual/generate-manpage.nix index 791bfd2c756..31e74e17d26 100644 --- a/doc/manual/generate-manpage.nix +++ b/doc/manual/generate-manpage.nix @@ -32,7 +32,13 @@ let commandInfo = fromJSON commandDump; - showCommand = { command, details, filename, toplevel }: + showCommand = + { + command, + details, + filename, + toplevel, + }: let result = '' @@ -56,26 +62,27 @@ let ${maybeOptions} ''; - showSynopsis = command: args: + showSynopsis = + command: args: let - showArgument = arg: "*${arg.label}*" + optionalString (! arg ? arity) "..."; + showArgument = arg: "*${arg.label}*" + optionalString (!arg ? arity) "..."; arguments = concatStringsSep " " (map showArgument args); - in '' + in + '' `${command}` [*option*...] ${arguments} ''; - maybeSubcommands = optionalString (details ? commands && details.commands != {}) - '' - where *subcommand* is one of the following: + maybeSubcommands = optionalString (details ? commands && details.commands != { }) '' + where *subcommand* is one of the following: - ${subcommands} - ''; + ${subcommands} + ''; - subcommands = if length categories > 1 - then listCategories - else listSubcommands details.commands; + subcommands = if length categories > 1 then listCategories else listSubcommands details.commands; - categories = sort (x: y: x.id < y.id) (unique (map (cmd: cmd.category) (attrValues details.commands))); + categories = sort (x: y: x.id < y.id) ( + unique (map (cmd: cmd.category) (attrValues details.commands)) + ); listCategories = concatStrings (map showCategory categories); @@ -99,38 +106,39 @@ let ${allStores} ''; - index = replaceStrings - [ "@store-types@" "./local-store.md" "./local-daemon-store.md" ] - [ storesOverview "#local-store" "#local-daemon-store" ] - details.doc; + index = + replaceStrings + [ "@store-types@" "./local-store.md" "./local-daemon-store.md" ] + [ storesOverview "#local-store" "#local-daemon-store" ] + details.doc; storesOverview = let - showEntry = store: - "- [${store.name}](#${store.slug})"; + showEntry = store: "- [${store.name}](#${store.slug})"; in concatStringsSep "\n" (map showEntry storesList) + "\n"; allStores = concatStringsSep "\n" (attrValues storePages); - storePages = listToAttrs - (map (s: { name = s.filename; value = s.page; }) storesList); + storePages = listToAttrs ( + map (s: { + name = s.filename; + value = s.page; + }) storesList + ); storesList = showStoreDocs { storeInfo = commandInfo.stores; inherit inlineHTML; }; - hasInfix = infix: content: + hasInfix = + infix: content: builtins.stringLength content != builtins.stringLength (replaceStrings [ infix ] [ "" ] content); in optionalString (details ? doc) ( # An alternate implementation with builtins.match stack overflowed on some systems. - if hasInfix "@store-types@" details.doc - then help-stores - else details.doc + if hasInfix "@store-types@" details.doc then help-stores else details.doc ); maybeOptions = let - allVisibleOptions = filterAttrs - (_: o: ! o.hiddenCategory) - (details.flags // toplevel.flags); + allVisibleOptions = filterAttrs (_: o: !o.hiddenCategory) (details.flags // toplevel.flags); in optionalString (allVisibleOptions != { }) '' # Options @@ -142,55 +150,73 @@ let > See [`man nix.conf`](@docroot@/command-ref/conf-file.md#command-line-flags) for overriding configuration settings with command line flags. ''; - showOptions = inlineHTML: allOptions: + showOptions = + inlineHTML: allOptions: let showCategory = cat: opts: '' ${optionalString (cat != "") "## ${cat}"} ${concatStringsSep "\n" (attrValues (mapAttrs showOption opts))} ''; - showOption = name: option: + showOption = + name: option: let result = trim '' - ${item} ${option.description} ''; - item = if inlineHTML - then ''[`--${name}`](#opt-${name}) ${shortName} ${labels}'' - else "`--${name}` ${shortName} ${labels}"; - shortName = optionalString - (option ? shortName) - ("/ `-${option.shortName}`"); - labels = optionalString - (option ? labels) - (concatStringsSep " " (map (s: "*${s}*") option.labels)); - in result; - categories = mapAttrs - # Convert each group from a list of key-value pairs back to an attrset - (_: listToAttrs) - (groupBy - (cmd: cmd.value.category) - (attrsToList allOptions)); - in concatStrings (attrValues (mapAttrs showCategory categories)); - in squash result; + item = + if inlineHTML then + ''[`--${name}`](#opt-${name}) ${shortName} ${labels}'' + else + "`--${name}` ${shortName} ${labels}"; + shortName = optionalString (option ? shortName) ("/ `-${option.shortName}`"); + labels = optionalString (option ? labels) (concatStringsSep " " (map (s: "*${s}*") option.labels)); + in + result; + categories = + mapAttrs + # Convert each group from a list of key-value pairs back to an attrset + (_: listToAttrs) + (groupBy (cmd: cmd.value.category) (attrsToList allOptions)); + in + concatStrings (attrValues (mapAttrs showCategory categories)); + in + squash result; appendName = filename: name: (if filename == "nix" then "nix3" else filename) + "-" + name; - processCommand = { command, details, filename, toplevel }: + processCommand = + { + command, + details, + filename, + toplevel, + }: let cmd = { inherit command; name = filename + ".md"; - value = showCommand { inherit command details filename toplevel; }; - }; - subcommand = subCmd: processCommand { - command = command + " " + subCmd; - details = details.commands.${subCmd}; - filename = appendName filename subCmd; - inherit toplevel; + value = showCommand { + inherit + command + details + filename + toplevel + ; + }; }; - in [ cmd ] ++ concatMap subcommand (attrNames details.commands or {}); + subcommand = + subCmd: + processCommand { + command = command + " " + subCmd; + details = details.commands.${subCmd}; + filename = appendName filename subCmd; + inherit toplevel; + }; + in + [ cmd ] ++ concatMap subcommand (attrNames details.commands or { }); manpages = processCommand { command = "nix"; @@ -199,9 +225,11 @@ let toplevel = commandInfo.args; }; - tableOfContents = let - showEntry = page: - " - [${page.command}](command-ref/new-cli/${page.name})"; - in concatStringsSep "\n" (map showEntry manpages) + "\n"; + tableOfContents = + let + showEntry = page: " - [${page.command}](command-ref/new-cli/${page.name})"; + in + concatStringsSep "\n" (map showEntry manpages) + "\n"; -in (listToAttrs manpages) // { "SUMMARY.md" = tableOfContents; } +in +(listToAttrs manpages) // { "SUMMARY.md" = tableOfContents; } diff --git a/doc/manual/generate-settings.nix b/doc/manual/generate-settings.nix index 93a8e093e48..35ae73e5d1f 100644 --- a/doc/manual/generate-settings.nix +++ b/doc/manual/generate-settings.nix @@ -1,67 +1,99 @@ let - inherit (builtins) attrValues concatStringsSep isAttrs isBool mapAttrs; - inherit (import ) concatStrings indent optionalString squash; + inherit (builtins) + attrValues + concatStringsSep + isAttrs + isBool + mapAttrs + ; + inherit (import ) + concatStrings + indent + optionalString + squash + ; in # `inlineHTML` is a hack to accommodate inconsistent output from `lowdown` -{ prefix, inlineHTML ? true }: settingsInfo: +{ + prefix, + inlineHTML ? true, +}: +settingsInfo: let - showSetting = prefix: setting: { description, documentDefault, defaultValue, aliases, value, experimentalFeature }: + showSetting = + prefix: setting: + { + description, + documentDefault, + defaultValue, + aliases, + value, + experimentalFeature, + }: let result = squash '' - - ${item} + - ${item} - ${indent " " body} - ''; - item = if inlineHTML - then ''[`${setting}`](#${prefix}-${setting})'' - else "`${setting}`"; + ${indent " " body} + ''; + item = + if inlineHTML then + ''[`${setting}`](#${prefix}-${setting})'' + else + "`${setting}`"; # separate body to cleanly handle indentation body = '' - ${experimentalFeatureNote} + ${experimentalFeatureNote} - ${description} + ${description} - **Default:** ${showDefault documentDefault defaultValue} + **Default:** ${showDefault documentDefault defaultValue} - ${showAliases aliases} - ''; + ${showAliases aliases} + ''; experimentalFeatureNote = optionalString (experimentalFeature != null) '' - > **Warning** - > - > This setting is part of an - > [experimental feature](@docroot@/development/experimental-features.md). - > - > To change this setting, make sure the - > [`${experimentalFeature}` experimental feature](@docroot@/development/experimental-features.md#xp-feature-${experimentalFeature}) - > is enabled. - > For example, include the following in [`nix.conf`](@docroot@/command-ref/conf-file.md): - > - > ``` - > extra-experimental-features = ${experimentalFeature} - > ${setting} = ... - > ``` - ''; + > **Warning** + > + > This setting is part of an + > [experimental feature](@docroot@/development/experimental-features.md). + > + > To change this setting, make sure the + > [`${experimentalFeature}` experimental feature](@docroot@/development/experimental-features.md#xp-feature-${experimentalFeature}) + > is enabled. + > For example, include the following in [`nix.conf`](@docroot@/command-ref/conf-file.md): + > + > ``` + > extra-experimental-features = ${experimentalFeature} + > ${setting} = ... + > ``` + ''; - showDefault = documentDefault: defaultValue: + showDefault = + documentDefault: defaultValue: if documentDefault then # a StringMap value type is specified as a string, but # this shows the value type. The empty stringmap is `null` in # JSON, but that converts to `{ }` here. - if defaultValue == "" || defaultValue == [] || isAttrs defaultValue - then "*empty*" - else if isBool defaultValue then - if defaultValue then "`true`" else "`false`" - else "`${toString defaultValue}`" - else "*machine-specific*"; + if defaultValue == "" || defaultValue == [ ] || isAttrs defaultValue then + "*empty*" + else if isBool defaultValue then + if defaultValue then "`true`" else "`false`" + else + "`${toString defaultValue}`" + else + "*machine-specific*"; - showAliases = aliases: - optionalString (aliases != []) - "**Deprecated alias:** ${(concatStringsSep ", " (map (s: "`${s}`") aliases))}"; + showAliases = + aliases: + optionalString (aliases != [ ]) + "**Deprecated alias:** ${(concatStringsSep ", " (map (s: "`${s}`") aliases))}"; - in result; + in + result; -in concatStrings (attrValues (mapAttrs (showSetting prefix) settingsInfo)) +in +concatStrings (attrValues (mapAttrs (showSetting prefix) settingsInfo)) diff --git a/doc/manual/generate-store-info.nix b/doc/manual/generate-store-info.nix index cc370412414..e8b7377dafd 100644 --- a/doc/manual/generate-store-info.nix +++ b/doc/manual/generate-store-info.nix @@ -1,6 +1,20 @@ let - inherit (builtins) attrNames listToAttrs concatStringsSep readFile replaceStrings; - inherit (import ) optionalString filterAttrs trim squash toLower unique indent; + inherit (builtins) + attrNames + listToAttrs + concatStringsSep + readFile + replaceStrings + ; + inherit (import ) + optionalString + filterAttrs + trim + squash + toLower + unique + indent + ; showSettings = import ; in @@ -14,7 +28,13 @@ in let - showStore = { name, slug }: { settings, doc, experimentalFeature }: + showStore = + { name, slug }: + { + settings, + doc, + experimentalFeature, + }: let result = squash '' # ${name} @@ -25,7 +45,10 @@ let ## Settings - ${showSettings { prefix = "store-${slug}"; inherit inlineHTML; } settings} + ${showSettings { + prefix = "store-${slug}"; + inherit inlineHTML; + } settings} ''; experimentalFeatureNote = optionalString (experimentalFeature != null) '' @@ -43,15 +66,15 @@ let > extra-experimental-features = ${experimentalFeature} > ``` ''; - in result; - - storesList = map - (name: rec { - inherit name; - slug = replaceStrings [ " " ] [ "-" ] (toLower name); - filename = "${slug}.md"; - page = showStore { inherit name slug; } storeInfo.${name}; - }) - (attrNames storeInfo); - -in storesList + in + result; + + storesList = map (name: rec { + inherit name; + slug = replaceStrings [ " " ] [ "-" ] (toLower name); + filename = "${slug}.md"; + page = showStore { inherit name slug; } storeInfo.${name}; + }) (attrNames storeInfo); + +in +storesList diff --git a/doc/manual/generate-store-types.nix b/doc/manual/generate-store-types.nix index 46179abc5bf..a03d3d6216e 100644 --- a/doc/manual/generate-store-types.nix +++ b/doc/manual/generate-store-types.nix @@ -1,5 +1,11 @@ let - inherit (builtins) attrNames listToAttrs concatStringsSep readFile replaceStrings; + inherit (builtins) + attrNames + listToAttrs + concatStringsSep + readFile + replaceStrings + ; showSettings = import ; showStoreDocs = import ; in @@ -14,26 +20,28 @@ let index = let - showEntry = store: - "- [${store.name}](./${store.filename})"; + showEntry = store: "- [${store.name}](./${store.filename})"; in concatStringsSep "\n" (map showEntry storesList); - "index.md" = replaceStrings - [ "@store-types@" ] [ index ] - (readFile ./source/store/types/index.md.in); + "index.md" = + replaceStrings [ "@store-types@" ] [ index ] + (readFile ./source/store/types/index.md.in); tableOfContents = let - showEntry = store: - " - [${store.name}](store/types/${store.filename})"; + showEntry = store: " - [${store.name}](store/types/${store.filename})"; in concatStringsSep "\n" (map showEntry storesList) + "\n"; "SUMMARY.md" = tableOfContents; - storePages = listToAttrs - (map (s: { name = s.filename; value = s.page; }) storesList); + storePages = listToAttrs ( + map (s: { + name = s.filename; + value = s.page; + }) storesList + ); in storePages // { inherit "index.md" "SUMMARY.md"; } diff --git a/doc/manual/generate-xp-features-shortlist.nix b/doc/manual/generate-xp-features-shortlist.nix index eb735ba5f7a..1520fc2f815 100644 --- a/doc/manual/generate-xp-features-shortlist.nix +++ b/doc/manual/generate-xp-features-shortlist.nix @@ -2,8 +2,8 @@ with builtins; with import ; let - showExperimentalFeature = name: doc: - '' - - [`${name}`](@docroot@/development/experimental-features.md#xp-feature-${name}) - ''; -in xps: indent " " (concatStrings (attrValues (mapAttrs showExperimentalFeature xps))) + showExperimentalFeature = name: doc: '' + - [`${name}`](@docroot@/development/experimental-features.md#xp-feature-${name}) + ''; +in +xps: indent " " (concatStrings (attrValues (mapAttrs showExperimentalFeature xps))) diff --git a/doc/manual/generate-xp-features.nix b/doc/manual/generate-xp-features.nix index 0eec0e1da23..468d253bafd 100644 --- a/doc/manual/generate-xp-features.nix +++ b/doc/manual/generate-xp-features.nix @@ -2,7 +2,8 @@ with builtins; with import ; let - showExperimentalFeature = name: doc: + showExperimentalFeature = + name: doc: squash '' ## [`${name}`]{#xp-feature-${name}} diff --git a/doc/manual/package.nix b/doc/manual/package.nix index f8133f2e1dd..8f5d0dfe137 100644 --- a/doc/manual/package.nix +++ b/doc/manual/package.nix @@ -1,19 +1,20 @@ -{ lib -, mkMesonDerivation +{ + lib, + mkMesonDerivation, -, meson -, ninja -, lowdown-unsandboxed -, mdbook -, mdbook-linkcheck -, jq -, python3 -, rsync -, nix-cli + meson, + ninja, + lowdown-unsandboxed, + mdbook, + mdbook-linkcheck, + jq, + python3, + rsync, + nix-cli, -# Configuration Options + # Configuration Options -, version + version, }: let @@ -25,18 +26,22 @@ mkMesonDerivation (finalAttrs: { inherit version; workDir = ./.; - fileset = fileset.difference - (fileset.unions [ - ../../.version - # Too many different types of files to filter for now - ../../doc/manual - ./. - ]) - # Do a blacklist instead - ../../doc/manual/package.nix; + fileset = + fileset.difference + (fileset.unions [ + ../../.version + # Too many different types of files to filter for now + ../../doc/manual + ./. + ]) + # Do a blacklist instead + ../../doc/manual/package.nix; # TODO the man pages should probably be separate - outputs = [ "out" "man" ]; + outputs = [ + "out" + "man" + ]; # Hack for sake of the dev shell passthru.externalNativeBuildInputs = [ @@ -54,11 +59,10 @@ mkMesonDerivation (finalAttrs: { nix-cli ]; - preConfigure = - '' - chmod u+w ./.version - echo ${finalAttrs.version} > ./.version - ''; + preConfigure = '' + chmod u+w ./.version + echo ${finalAttrs.version} > ./.version + ''; postInstall = '' mkdir -p ''$out/nix-support diff --git a/doc/manual/utils.nix b/doc/manual/utils.nix index 19ff49b64d9..db3a0e67a83 100644 --- a/doc/manual/utils.nix +++ b/doc/manual/utils.nix @@ -11,10 +11,15 @@ rec { concatStrings = concatStringsSep ""; - attrsToList = a: - map (name: { inherit name; value = a.${name}; }) (builtins.attrNames a); + attrsToList = + a: + map (name: { + inherit name; + value = a.${name}; + }) (builtins.attrNames a); - replaceStringsRec = from: to: string: + replaceStringsRec = + from: to: string: # recursively replace occurrences of `from` with `to` within `string` # example: # replaceStringRec "--" "-" "hello-----world" @@ -22,16 +27,18 @@ rec { let replaced = replaceStrings [ from ] [ to ] string; in - if replaced == string then string else replaceStringsRec from to replaced; + if replaced == string then string else replaceStringsRec from to replaced; toLower = replaceStrings upperChars lowerChars; squash = replaceStringsRec "\n\n\n" "\n\n"; - trim = string: + trim = + string: # trim trailing spaces and squash non-leading spaces let - trimLine = line: + trimLine = + line: let # separate leading spaces from the rest parts = split "(^ *)" line; @@ -39,19 +46,30 @@ rec { rest = elemAt parts 2; # drop trailing spaces body = head (split " *$" rest); - in spaces + replaceStringsRec " " " " body; - in concatStringsSep "\n" (map trimLine (splitLines string)); + in + spaces + replaceStringsRec " " " " body; + in + concatStringsSep "\n" (map trimLine (splitLines string)); # FIXME: O(n^2) - unique = foldl' (acc: e: if elem e acc then acc else acc ++ [ e ]) []; + unique = foldl' (acc: e: if elem e acc then acc else acc ++ [ e ]) [ ]; nameValuePair = name: value: { inherit name value; }; - filterAttrs = pred: set: - listToAttrs (concatMap (name: let v = set.${name}; in if pred name v then [(nameValuePair name v)] else []) (attrNames set)); + filterAttrs = + pred: set: + listToAttrs ( + concatMap ( + name: + let + v = set.${name}; + in + if pred name v then [ (nameValuePair name v) ] else [ ] + ) (attrNames set) + ); optionalString = cond: string: if cond then string else ""; - indent = prefix: s: - concatStringsSep "\n" (map (x: if x == "" then x else "${prefix}${x}") (splitLines s)); + indent = + prefix: s: concatStringsSep "\n" (map (x: if x == "" then x else "${prefix}${x}") (splitLines s)); } diff --git a/docker.nix b/docker.nix index e2e9da72831..d52c317d6b1 100644 --- a/docker.nix +++ b/docker.nix @@ -1,112 +1,113 @@ -{ pkgs ? import { } -, lib ? pkgs.lib -, name ? "nix" -, tag ? "latest" -, bundleNixpkgs ? true -, channelName ? "nixpkgs" -, channelURL ? "https://nixos.org/channels/nixpkgs-unstable" -, extraPkgs ? [] -, maxLayers ? 100 -, nixConf ? {} -, flake-registry ? null -, uid ? 0 -, gid ? 0 -, uname ? "root" -, gname ? "root" +{ + pkgs ? import { }, + lib ? pkgs.lib, + name ? "nix", + tag ? "latest", + bundleNixpkgs ? true, + channelName ? "nixpkgs", + channelURL ? "https://nixos.org/channels/nixpkgs-unstable", + extraPkgs ? [ ], + maxLayers ? 100, + nixConf ? { }, + flake-registry ? null, + uid ? 0, + gid ? 0, + uname ? "root", + gname ? "root", }: let - defaultPkgs = with pkgs; [ - nix - bashInteractive - coreutils-full - gnutar - gzip - gnugrep - which - curl - less - wget - man - cacert.out - findutils - iana-etc - git - openssh - ] ++ extraPkgs; - - users = { - - root = { - uid = 0; - shell = "${pkgs.bashInteractive}/bin/bash"; - home = "/root"; - gid = 0; - groups = [ "root" ]; - description = "System administrator"; - }; + defaultPkgs = + with pkgs; + [ + nix + bashInteractive + coreutils-full + gnutar + gzip + gnugrep + which + curl + less + wget + man + cacert.out + findutils + iana-etc + git + openssh + ] + ++ extraPkgs; + + users = + { + + root = { + uid = 0; + shell = "${pkgs.bashInteractive}/bin/bash"; + home = "/root"; + gid = 0; + groups = [ "root" ]; + description = "System administrator"; + }; - nobody = { - uid = 65534; - shell = "${pkgs.shadow}/bin/nologin"; - home = "/var/empty"; - gid = 65534; - groups = [ "nobody" ]; - description = "Unprivileged account (don't use!)"; - }; + nobody = { + uid = 65534; + shell = "${pkgs.shadow}/bin/nologin"; + home = "/var/empty"; + gid = 65534; + groups = [ "nobody" ]; + description = "Unprivileged account (don't use!)"; + }; - } // lib.optionalAttrs (uid != 0) { - "${uname}" = { - uid = uid; - shell = "${pkgs.bashInteractive}/bin/bash"; - home = "/home/${uname}"; - gid = gid; - groups = [ "${gname}" ]; - description = "Nix user"; + } + // lib.optionalAttrs (uid != 0) { + "${uname}" = { + uid = uid; + shell = "${pkgs.bashInteractive}/bin/bash"; + home = "/home/${uname}"; + gid = gid; + groups = [ "${gname}" ]; + description = "Nix user"; + }; + } + // lib.listToAttrs ( + map (n: { + name = "nixbld${toString n}"; + value = { + uid = 30000 + n; + gid = 30000; + groups = [ "nixbld" ]; + description = "Nix build user ${toString n}"; + }; + }) (lib.lists.range 1 32) + ); + + groups = + { + root.gid = 0; + nixbld.gid = 30000; + nobody.gid = 65534; + } + // lib.optionalAttrs (gid != 0) { + "${gname}".gid = gid; }; - } // lib.listToAttrs ( - map - ( - n: { - name = "nixbld${toString n}"; - value = { - uid = 30000 + n; - gid = 30000; - groups = [ "nixbld" ]; - description = "Nix build user ${toString n}"; - }; - } - ) - (lib.lists.range 1 32) - ); - - groups = { - root.gid = 0; - nixbld.gid = 30000; - nobody.gid = 65534; - } // lib.optionalAttrs (gid != 0) { - "${gname}".gid = gid; - }; userToPasswd = ( k: - { uid - , gid ? 65534 - , home ? "/var/empty" - , description ? "" - , shell ? "/bin/false" - , groups ? [ ] - }: "${k}:x:${toString uid}:${toString gid}:${description}:${home}:${shell}" - ); - passwdContents = ( - lib.concatStringsSep "\n" - (lib.attrValues (lib.mapAttrs userToPasswd users)) + { + uid, + gid ? 65534, + home ? "/var/empty", + description ? "", + shell ? "/bin/false", + groups ? [ ], + }: + "${k}:x:${toString uid}:${toString gid}:${description}:${home}:${shell}" ); + passwdContents = (lib.concatStringsSep "\n" (lib.attrValues (lib.mapAttrs userToPasswd users))); userToShadow = k: { ... }: "${k}:!:1::::::"; - shadowContents = ( - lib.concatStringsSep "\n" - (lib.attrValues (lib.mapAttrs userToShadow users)) - ); + shadowContents = (lib.concatStringsSep "\n" (lib.attrValues (lib.mapAttrs userToShadow users))); # Map groups to members # { @@ -116,42 +117,35 @@ let let # Create a flat list of user/group mappings mappings = ( - builtins.foldl' - ( - acc: user: - let - groups = users.${user}.groups or [ ]; - in - acc ++ map - (group: { - inherit user group; - }) - groups - ) - [ ] - (lib.attrNames users) + builtins.foldl' ( + acc: user: + let + groups = users.${user}.groups or [ ]; + in + acc + ++ map (group: { + inherit user group; + }) groups + ) [ ] (lib.attrNames users) ); in - ( - builtins.foldl' - ( - acc: v: acc // { - ${v.group} = acc.${v.group} or [ ] ++ [ v.user ]; - } - ) - { } - mappings) + (builtins.foldl' ( + acc: v: + acc + // { + ${v.group} = acc.${v.group} or [ ] ++ [ v.user ]; + } + ) { } mappings) ); - groupToGroup = k: { gid }: + groupToGroup = + k: + { gid }: let members = groupMemberMap.${k} or [ ]; in "${k}:x:${toString gid}:${lib.concatStringsSep "," members}"; - groupContents = ( - lib.concatStringsSep "\n" - (lib.attrValues (lib.mapAttrs groupToGroup groups)) - ); + groupContents = (lib.concatStringsSep "\n" (lib.attrValues (lib.mapAttrs groupToGroup groups))); defaultNixConf = { sandbox = "false"; @@ -159,11 +153,17 @@ let trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ]; }; - nixConfContents = (lib.concatStringsSep "\n" (lib.mapAttrsFlatten (n: v: - let - vStr = if builtins.isList v then lib.concatStringsSep " " v else v; - in - "${n} = ${vStr}") (defaultNixConf // nixConf))) + "\n"; + nixConfContents = + (lib.concatStringsSep "\n" ( + lib.mapAttrsFlatten ( + n: v: + let + vStr = if builtins.isList v then lib.concatStringsSep " " v else v; + in + "${n} = ${vStr}" + ) (defaultNixConf // nixConf) + )) + + "\n"; userHome = if uid == 0 then "/root" else "/home/${uname}"; @@ -184,21 +184,29 @@ let manifest = pkgs.buildPackages.runCommand "manifest.nix" { } '' cat > $out < $out/etc/passwd - echo "" >> $out/etc/passwd + cat $passwdContentsPath > $out/etc/passwd + echo "" >> $out/etc/passwd - cat $groupContentsPath > $out/etc/group - echo "" >> $out/etc/group + cat $groupContentsPath > $out/etc/group + echo "" >> $out/etc/group - cat $shadowContentsPath > $out/etc/shadow - echo "" >> $out/etc/shadow + cat $shadowContentsPath > $out/etc/shadow + echo "" >> $out/etc/shadow - mkdir -p $out/usr - ln -s /nix/var/nix/profiles/share $out/usr/ + mkdir -p $out/usr + ln -s /nix/var/nix/profiles/share $out/usr/ - mkdir -p $out/nix/var/nix/gcroots + mkdir -p $out/nix/var/nix/gcroots - mkdir $out/tmp + mkdir $out/tmp - mkdir -p $out/var/tmp + mkdir -p $out/var/tmp - mkdir -p $out/etc/nix - cat $nixConfContentsPath > $out/etc/nix/nix.conf + mkdir -p $out/etc/nix + cat $nixConfContentsPath > $out/etc/nix/nix.conf - mkdir -p $out${userHome} - mkdir -p $out/nix/var/nix/profiles/per-user/${uname} + mkdir -p $out${userHome} + mkdir -p $out/nix/var/nix/profiles/per-user/${uname} - ln -s ${profile} $out/nix/var/nix/profiles/default-1-link - ln -s /nix/var/nix/profiles/default-1-link $out/nix/var/nix/profiles/default - ln -s /nix/var/nix/profiles/default $out${userHome}/.nix-profile + ln -s ${profile} $out/nix/var/nix/profiles/default-1-link + ln -s /nix/var/nix/profiles/default-1-link $out/nix/var/nix/profiles/default + ln -s /nix/var/nix/profiles/default $out${userHome}/.nix-profile - ln -s ${channel} $out/nix/var/nix/profiles/per-user/${uname}/channels-1-link - ln -s /nix/var/nix/profiles/per-user/${uname}/channels-1-link $out/nix/var/nix/profiles/per-user/${uname}/channels + ln -s ${channel} $out/nix/var/nix/profiles/per-user/${uname}/channels-1-link + ln -s /nix/var/nix/profiles/per-user/${uname}/channels-1-link $out/nix/var/nix/profiles/per-user/${uname}/channels - mkdir -p $out${userHome}/.nix-defexpr - ln -s /nix/var/nix/profiles/per-user/${uname}/channels $out${userHome}/.nix-defexpr/channels - echo "${channelURL} ${channelName}" > $out${userHome}/.nix-channels + mkdir -p $out${userHome}/.nix-defexpr + ln -s /nix/var/nix/profiles/per-user/${uname}/channels $out${userHome}/.nix-defexpr/channels + echo "${channelURL} ${channelName}" > $out${userHome}/.nix-channels - mkdir -p $out/bin $out/usr/bin - ln -s ${pkgs.coreutils}/bin/env $out/usr/bin/env - ln -s ${pkgs.bashInteractive}/bin/bash $out/bin/sh + mkdir -p $out/bin $out/usr/bin + ln -s ${pkgs.coreutils}/bin/env $out/usr/bin/env + ln -s ${pkgs.bashInteractive}/bin/bash $out/bin/sh - '' + (lib.optionalString (flake-registry-path != null) '' - nixCacheDir="${userHome}/.cache/nix" - mkdir -p $out$nixCacheDir - globalFlakeRegistryPath="$nixCacheDir/flake-registry.json" - ln -s ${flake-registry-path} $out$globalFlakeRegistryPath - mkdir -p $out/nix/var/nix/gcroots/auto - rootName=$(${pkgs.nix}/bin/nix --extra-experimental-features nix-command hash file --type sha1 --base32 <(echo -n $globalFlakeRegistryPath)) - ln -s $globalFlakeRegistryPath $out/nix/var/nix/gcroots/auto/$rootName - '')); + '' + + (lib.optionalString (flake-registry-path != null) '' + nixCacheDir="${userHome}/.cache/nix" + mkdir -p $out$nixCacheDir + globalFlakeRegistryPath="$nixCacheDir/flake-registry.json" + ln -s ${flake-registry-path} $out$globalFlakeRegistryPath + mkdir -p $out/nix/var/nix/gcroots/auto + rootName=$(${pkgs.nix}/bin/nix --extra-experimental-features nix-command hash file --type sha1 --base32 <(echo -n $globalFlakeRegistryPath)) + ln -s $globalFlakeRegistryPath $out/nix/var/nix/gcroots/auto/$rootName + '') + ); in pkgs.dockerTools.buildLayeredImageWithNixDb { - inherit name tag maxLayers uid gid uname gname; + inherit + name + tag + maxLayers + uid + gid + uname + gname + ; contents = [ baseSystem ]; @@ -305,15 +331,19 @@ pkgs.dockerTools.buildLayeredImageWithNixDb { User = "${toString uid}:${toString gid}"; Env = [ "USER=${uname}" - "PATH=${lib.concatStringsSep ":" [ - "${userHome}/.nix-profile/bin" - "/nix/var/nix/profiles/default/bin" - "/nix/var/nix/profiles/default/sbin" - ]}" - "MANPATH=${lib.concatStringsSep ":" [ - "${userHome}/.nix-profile/share/man" - "/nix/var/nix/profiles/default/share/man" - ]}" + "PATH=${ + lib.concatStringsSep ":" [ + "${userHome}/.nix-profile/bin" + "/nix/var/nix/profiles/default/bin" + "/nix/var/nix/profiles/default/sbin" + ] + }" + "MANPATH=${ + lib.concatStringsSep ":" [ + "${userHome}/.nix-profile/share/man" + "/nix/var/nix/profiles/default/share/man" + ] + }" "SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt" "GIT_SSL_CAINFO=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt" "NIX_SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt" diff --git a/flake.nix b/flake.nix index c6df63c5eb2..2f70dffbeab 100644 --- a/flake.nix +++ b/flake.nix @@ -5,7 +5,10 @@ inputs.nixpkgs-regression.url = "github:NixOS/nixpkgs/215d4d0fd80ca5163643b03a33fde804a29cc1e2"; inputs.nixpkgs-23-11.url = "github:NixOS/nixpkgs/a62e6edd6d5e1fa0329b8653c801147986f8d446"; - inputs.flake-compat = { url = "github:edolstra/flake-compat"; flake = false; }; + inputs.flake-compat = { + url = "github:edolstra/flake-compat"; + flake = false; + }; # dev tooling inputs.flake-parts.url = "github:hercules-ci/flake-parts"; @@ -19,8 +22,13 @@ inputs.git-hooks-nix.inputs.gitignore.follows = ""; inputs.nixfmt.url = "github:NixOS/nixfmt"; - outputs = inputs@{ self, nixpkgs, nixpkgs-regression, ... }: - + outputs = + inputs@{ + self, + nixpkgs, + nixpkgs-regression, + ... + }: let inherit (nixpkgs) lib; @@ -28,9 +36,15 @@ officialRelease = false; linux32BitSystems = [ "i686-linux" ]; - linux64BitSystems = [ "x86_64-linux" "aarch64-linux" ]; + linux64BitSystems = [ + "x86_64-linux" + "aarch64-linux" + ]; linuxSystems = linux32BitSystems ++ linux64BitSystems; - darwinSystems = [ "x86_64-darwin" "aarch64-darwin" ]; + darwinSystems = [ + "x86_64-darwin" + "aarch64-darwin" + ]; systems = linuxSystems ++ darwinSystems; crossSystems = [ @@ -60,7 +74,7 @@ (Provided that the names are unique.) See https://nixos.org/manual/nixpkgs/stable/index.html#function-library-lib.attrsets.concatMapAttrs - */ + */ flatMapAttrs = attrs: f: lib.concatMapAttrs f attrs; forAllSystems = lib.genAttrs systems; @@ -69,44 +83,57 @@ forAllStdenvs = lib.genAttrs stdenvs; - # We don't apply flake-parts to the whole flake so that non-development attributes # load without fetching any development inputs. devFlake = inputs.flake-parts.lib.mkFlake { inherit inputs; } { imports = [ ./maintainers/flake-module.nix ]; systems = lib.subtractLists crossSystems systems; - perSystem = { system, ... }: { - _module.args.pkgs = nixpkgsFor.${system}.native; - }; + perSystem = + { system, ... }: + { + _module.args.pkgs = nixpkgsFor.${system}.native; + }; }; # Memoize nixpkgs for different platforms for efficiency. - nixpkgsFor = forAllSystems - (system: let - make-pkgs = crossSystem: - forAllStdenvs (stdenv: import nixpkgs { - localSystem = { - inherit system; - }; - crossSystem = if crossSystem == null then null else { - config = crossSystem; - } // lib.optionalAttrs (crossSystem == "x86_64-unknown-freebsd13") { - useLLVM = true; - }; - overlays = [ - (overlayFor (pkgs: pkgs.${stdenv})) - ]; - }); - in rec { + nixpkgsFor = forAllSystems ( + system: + let + make-pkgs = + crossSystem: + forAllStdenvs ( + stdenv: + import nixpkgs { + localSystem = { + inherit system; + }; + crossSystem = + if crossSystem == null then + null + else + { + config = crossSystem; + } + // lib.optionalAttrs (crossSystem == "x86_64-unknown-freebsd13") { + useLLVM = true; + }; + overlays = [ + (overlayFor (pkgs: pkgs.${stdenv})) + ]; + } + ); + in + rec { nativeForStdenv = make-pkgs null; crossForStdenv = forAllCrossSystems make-pkgs; # Alias for convenience native = nativeForStdenv.stdenv; - cross = forAllCrossSystems (crossSystem: - crossForStdenv.${crossSystem}.stdenv); - }); + cross = forAllCrossSystems (crossSystem: crossForStdenv.${crossSystem}.stdenv); + } + ); - overlayFor = getStdenv: final: prev: + overlayFor = + getStdenv: final: prev: let stdenv = getStdenv final; in @@ -153,12 +180,19 @@ # See https://github.com/NixOS/nixpkgs/pull/214409 # Remove when fixed in this flake's nixpkgs pre-commit = - if prev.stdenv.hostPlatform.system == "i686-linux" - then (prev.pre-commit.override (o: { dotnet-sdk = ""; })).overridePythonAttrs (o: { doCheck = false; }) - else prev.pre-commit; + if prev.stdenv.hostPlatform.system == "i686-linux" then + (prev.pre-commit.override (o: { + dotnet-sdk = ""; + })).overridePythonAttrs + (o: { + doCheck = false; + }) + else + prev.pre-commit; }; - in { + in + { # A Nixpkgs overlay that overrides the 'nix' and # 'nix-perl-bindings' packages. overlays.default = overlayFor (p: p.stdenv); @@ -176,53 +210,69 @@ ; }; - checks = forAllSystems (system: { - installerScriptForGHA = self.hydraJobs.installerScriptForGHA.${system}; - installTests = self.hydraJobs.installTests.${system}; - nixpkgsLibTests = self.hydraJobs.tests.nixpkgsLibTests.${system}; - rl-next = - let pkgs = nixpkgsFor.${system}.native; - in pkgs.buildPackages.runCommand "test-rl-next-release-notes" { } '' - LANG=C.UTF-8 ${pkgs.changelog-d}/bin/changelog-d ${./doc/manual/rl-next} >$out - ''; - repl-completion = nixpkgsFor.${system}.native.callPackage ./tests/repl-completion.nix { }; - } // (lib.optionalAttrs (builtins.elem system linux64BitSystems)) { - dockerImage = self.hydraJobs.dockerImage.${system}; - } // (lib.optionalAttrs (!(builtins.elem system linux32BitSystems))) { - # Some perl dependencies are broken on i686-linux. - # Since the support is only best-effort there, disable the perl - # bindings - perlBindings = self.hydraJobs.perlBindings.${system}; - } - # Add "passthru" tests - // flatMapAttrs ({ - "" = nixpkgsFor.${system}.native; - } // lib.optionalAttrs (! nixpkgsFor.${system}.native.stdenv.hostPlatform.isDarwin) { - # TODO: enable static builds for darwin, blocked on: - # https://github.com/NixOS/nixpkgs/issues/320448 - # TODO: disabled to speed up GHA CI. - #"static-" = nixpkgsFor.${system}.native.pkgsStatic; - }) - (nixpkgsPrefix: nixpkgs: - flatMapAttrs nixpkgs.nixComponents - (pkgName: pkg: - flatMapAttrs pkg.tests or {} - (testName: test: { - "${nixpkgsPrefix}${pkgName}-${testName}" = test; - }) + checks = forAllSystems ( + system: + { + installerScriptForGHA = self.hydraJobs.installerScriptForGHA.${system}; + installTests = self.hydraJobs.installTests.${system}; + nixpkgsLibTests = self.hydraJobs.tests.nixpkgsLibTests.${system}; + rl-next = + let + pkgs = nixpkgsFor.${system}.native; + in + pkgs.buildPackages.runCommand "test-rl-next-release-notes" { } '' + LANG=C.UTF-8 ${pkgs.changelog-d}/bin/changelog-d ${./doc/manual/rl-next} >$out + ''; + repl-completion = nixpkgsFor.${system}.native.callPackage ./tests/repl-completion.nix { }; + } + // (lib.optionalAttrs (builtins.elem system linux64BitSystems)) { + dockerImage = self.hydraJobs.dockerImage.${system}; + } + // (lib.optionalAttrs (!(builtins.elem system linux32BitSystems))) { + # Some perl dependencies are broken on i686-linux. + # Since the support is only best-effort there, disable the perl + # bindings + perlBindings = self.hydraJobs.perlBindings.${system}; + } + # Add "passthru" tests + // + flatMapAttrs + ( + { + "" = nixpkgsFor.${system}.native; + } + // lib.optionalAttrs (!nixpkgsFor.${system}.native.stdenv.hostPlatform.isDarwin) { + # TODO: enable static builds for darwin, blocked on: + # https://github.com/NixOS/nixpkgs/issues/320448 + # TODO: disabled to speed up GHA CI. + #"static-" = nixpkgsFor.${system}.native.pkgsStatic; + } ) - // lib.optionalAttrs (nixpkgs.stdenv.hostPlatform == nixpkgs.stdenv.buildPlatform) { - "${nixpkgsPrefix}nix-functional-tests" = nixpkgs.nixComponents.nix-functional-tests; - } - ) - // devFlake.checks.${system} or {} + ( + nixpkgsPrefix: nixpkgs: + flatMapAttrs nixpkgs.nixComponents ( + pkgName: pkg: + flatMapAttrs pkg.tests or { } ( + testName: test: { + "${nixpkgsPrefix}${pkgName}-${testName}" = test; + } + ) + ) + // lib.optionalAttrs (nixpkgs.stdenv.hostPlatform == nixpkgs.stdenv.buildPlatform) { + "${nixpkgsPrefix}nix-functional-tests" = nixpkgs.nixComponents.nix-functional-tests; + } + ) + // devFlake.checks.${system} or { } ); - packages = forAllSystems (system: - { # Here we put attributes that map 1:1 into packages., ie + packages = forAllSystems ( + system: + { + # Here we put attributes that map 1:1 into packages., ie # for which we don't apply the full build matrix such as cross or static. inherit (nixpkgsFor.${system}.native) - changelog-d; + changelog-d + ; default = self.packages.${system}.nix; installerScriptForGHA = self.hydraJobs.installerScriptForGHA.${system}; binaryTarball = self.hydraJobs.binaryTarball.${system}; @@ -233,97 +283,144 @@ nix-external-api-docs = nixpkgsFor.${system}.native.nixComponents.nix-external-api-docs; } # We need to flatten recursive attribute sets of derivations to pass `flake check`. - // flatMapAttrs - { # Components we'll iterate over in the upcoming lambda - "nix-util" = { }; - "nix-util-c" = { }; - "nix-util-test-support" = { }; - "nix-util-tests" = { }; + // + flatMapAttrs + { + # Components we'll iterate over in the upcoming lambda + "nix-util" = { }; + "nix-util-c" = { }; + "nix-util-test-support" = { }; + "nix-util-tests" = { }; - "nix-store" = { }; - "nix-store-c" = { }; - "nix-store-test-support" = { }; - "nix-store-tests" = { }; + "nix-store" = { }; + "nix-store-c" = { }; + "nix-store-test-support" = { }; + "nix-store-tests" = { }; - "nix-fetchers" = { }; - "nix-fetchers-tests" = { }; + "nix-fetchers" = { }; + "nix-fetchers-tests" = { }; - "nix-expr" = { }; - "nix-expr-c" = { }; - "nix-expr-test-support" = { }; - "nix-expr-tests" = { }; + "nix-expr" = { }; + "nix-expr-c" = { }; + "nix-expr-test-support" = { }; + "nix-expr-tests" = { }; - "nix-flake" = { }; - "nix-flake-tests" = { }; + "nix-flake" = { }; + "nix-flake-tests" = { }; - "nix-main" = { }; - "nix-main-c" = { }; + "nix-main" = { }; + "nix-main-c" = { }; - "nix-cmd" = { }; + "nix-cmd" = { }; - "nix-cli" = { }; + "nix-cli" = { }; - "nix-everything" = { }; + "nix-everything" = { }; - "nix-functional-tests" = { supportsCross = false; }; + "nix-functional-tests" = { + supportsCross = false; + }; - "nix-perl-bindings" = { supportsCross = false; }; - } - (pkgName: { supportsCross ? true }: { - # These attributes go right into `packages.`. - "${pkgName}" = nixpkgsFor.${system}.native.nixComponents.${pkgName}; - "${pkgName}-static" = nixpkgsFor.${system}.native.pkgsStatic.nixComponents.${pkgName}; - "${pkgName}-llvm" = nixpkgsFor.${system}.native.pkgsLLVM.nixComponents.${pkgName}; + "nix-perl-bindings" = { + supportsCross = false; + }; } - // lib.optionalAttrs supportsCross (flatMapAttrs (lib.genAttrs crossSystems (_: { })) (crossSystem: {}: { - # These attributes go right into `packages.`. - "${pkgName}-${crossSystem}" = nixpkgsFor.${system}.cross.${crossSystem}.nixComponents.${pkgName}; - })) - // flatMapAttrs (lib.genAttrs stdenvs (_: { })) (stdenvName: {}: { - # These attributes go right into `packages.`. - "${pkgName}-${stdenvName}" = nixpkgsFor.${system}.nativeForStdenv.${stdenvName}.nixComponents.${pkgName}; - }) - ) + ( + pkgName: + { + supportsCross ? true, + }: + { + # These attributes go right into `packages.`. + "${pkgName}" = nixpkgsFor.${system}.native.nixComponents.${pkgName}; + "${pkgName}-static" = nixpkgsFor.${system}.native.pkgsStatic.nixComponents.${pkgName}; + "${pkgName}-llvm" = nixpkgsFor.${system}.native.pkgsLLVM.nixComponents.${pkgName}; + } + // lib.optionalAttrs supportsCross ( + flatMapAttrs (lib.genAttrs crossSystems (_: { })) ( + crossSystem: + { }: + { + # These attributes go right into `packages.`. + "${pkgName}-${crossSystem}" = nixpkgsFor.${system}.cross.${crossSystem}.nixComponents.${pkgName}; + } + ) + ) + // flatMapAttrs (lib.genAttrs stdenvs (_: { })) ( + stdenvName: + { }: + { + # These attributes go right into `packages.`. + "${pkgName}-${stdenvName}" = + nixpkgsFor.${system}.nativeForStdenv.${stdenvName}.nixComponents.${pkgName}; + } + ) + ) // lib.optionalAttrs (builtins.elem system linux64BitSystems) { - dockerImage = - let - pkgs = nixpkgsFor.${system}.native; - image = import ./docker.nix { inherit pkgs; tag = pkgs.nix.version; }; - in - pkgs.runCommand - "docker-image-tarball-${pkgs.nix.version}" - { meta.description = "Docker image with Nix for ${system}"; } - '' - mkdir -p $out/nix-support - image=$out/image.tar.gz - ln -s ${image} $image - echo "file binary-dist $image" >> $out/nix-support/hydra-build-products - ''; - }); - - devShells = let - makeShell = import ./packaging/dev-shell.nix { inherit inputs lib devFlake; }; - prefixAttrs = prefix: lib.concatMapAttrs (k: v: { "${prefix}-${k}" = v; }); - in - forAllSystems (system: - prefixAttrs "native" (forAllStdenvs (stdenvName: makeShell { - pkgs = nixpkgsFor.${system}.nativeForStdenv.${stdenvName}; - })) // - lib.optionalAttrs (!nixpkgsFor.${system}.native.stdenv.isDarwin) ( - prefixAttrs "static" (forAllStdenvs (stdenvName: makeShell { - pkgs = nixpkgsFor.${system}.nativeForStdenv.${stdenvName}.pkgsStatic; - })) // - prefixAttrs "llvm" (forAllStdenvs (stdenvName: makeShell { - pkgs = nixpkgsFor.${system}.nativeForStdenv.${stdenvName}.pkgsLLVM; - })) // - prefixAttrs "cross" (forAllCrossSystems (crossSystem: makeShell { - pkgs = nixpkgsFor.${system}.cross.${crossSystem}; - })) - ) // - { + dockerImage = + let + pkgs = nixpkgsFor.${system}.native; + image = import ./docker.nix { + inherit pkgs; + tag = pkgs.nix.version; + }; + in + pkgs.runCommand "docker-image-tarball-${pkgs.nix.version}" + { meta.description = "Docker image with Nix for ${system}"; } + '' + mkdir -p $out/nix-support + image=$out/image.tar.gz + ln -s ${image} $image + echo "file binary-dist $image" >> $out/nix-support/hydra-build-products + ''; + } + ); + + devShells = + let + makeShell = import ./packaging/dev-shell.nix { inherit inputs lib devFlake; }; + prefixAttrs = prefix: lib.concatMapAttrs (k: v: { "${prefix}-${k}" = v; }); + in + forAllSystems ( + system: + prefixAttrs "native" ( + forAllStdenvs ( + stdenvName: + makeShell { + pkgs = nixpkgsFor.${system}.nativeForStdenv.${stdenvName}; + } + ) + ) + // lib.optionalAttrs (!nixpkgsFor.${system}.native.stdenv.isDarwin) ( + prefixAttrs "static" ( + forAllStdenvs ( + stdenvName: + makeShell { + pkgs = nixpkgsFor.${system}.nativeForStdenv.${stdenvName}.pkgsStatic; + } + ) + ) + // prefixAttrs "llvm" ( + forAllStdenvs ( + stdenvName: + makeShell { + pkgs = nixpkgsFor.${system}.nativeForStdenv.${stdenvName}.pkgsLLVM; + } + ) + ) + // prefixAttrs "cross" ( + forAllCrossSystems ( + crossSystem: + makeShell { + pkgs = nixpkgsFor.${system}.cross.${crossSystem}; + } + ) + ) + ) + // { native = self.devShells.${system}.native-stdenv; default = self.devShells.${system}.native; } ); - }; + }; } diff --git a/maintainers/flake-module.nix b/maintainers/flake-module.nix index 93fd3675ebd..c44e5134c8a 100644 --- a/maintainers/flake-module.nix +++ b/maintainers/flake-module.nix @@ -1,697 +1,704 @@ -{ lib, getSystem, inputs, ... }: +{ + lib, + getSystem, + inputs, + ... +}: { imports = [ inputs.git-hooks-nix.flakeModule ]; - perSystem = { config, pkgs, ... }: { + perSystem = + { config, pkgs, ... }: + { - # https://flake.parts/options/git-hooks-nix#options - pre-commit.settings = { - hooks = { - # Conflicts are usually found by other checks, but not those in docs, - # and potentially other places. - check-merge-conflicts.enable = true; - # built-in check-merge-conflicts seems ineffective against those produced by mergify backports - check-merge-conflicts-2 = { - enable = true; - entry = "${pkgs.writeScript "check-merge-conflicts" '' - #!${pkgs.runtimeShell} - conflicts=false - for file in "$@"; do - if grep --with-filename --line-number -E '^>>>>>>> ' -- "$file"; then - conflicts=true + # https://flake.parts/options/git-hooks-nix#options + pre-commit.settings = { + hooks = { + # Conflicts are usually found by other checks, but not those in docs, + # and potentially other places. + check-merge-conflicts.enable = true; + # built-in check-merge-conflicts seems ineffective against those produced by mergify backports + check-merge-conflicts-2 = { + enable = true; + entry = "${pkgs.writeScript "check-merge-conflicts" '' + #!${pkgs.runtimeShell} + conflicts=false + for file in "$@"; do + if grep --with-filename --line-number -E '^>>>>>>> ' -- "$file"; then + conflicts=true + fi + done + if $conflicts; then + echo "ERROR: found merge/patch conflicts in files" + exit 1 fi - done - if $conflicts; then - echo "ERROR: found merge/patch conflicts in files" - exit 1 - fi - touch $out - ''}"; - }; - nixfmt-rfc-style = { - enable = true; - package = inputs.nixfmt.packages.${pkgs.hostPlatform.system}.default; - excludes = [ - # Invalid - ''^tests/functional/lang/parse-.*\.nix$'' + touch $out + ''}"; + }; + nixfmt-rfc-style = { + enable = true; + package = inputs.nixfmt.packages.${pkgs.hostPlatform.system}.default; + excludes = [ + # Invalid + ''^tests/functional/lang/parse-.*\.nix$'' - # Formatting-sensitive - ''^tests/functional/lang/eval-okay-curpos\.nix$'' - ''^tests/functional/lang/.*comment.*\.nix$'' - ''^tests/functional/lang/.*newline.*\.nix$'' - ''^tests/functional/lang/.*eol.*\.nix$'' + # Formatting-sensitive + ''^tests/functional/lang/eval-okay-curpos\.nix$'' + ''^tests/functional/lang/.*comment.*\.nix$'' + ''^tests/functional/lang/.*newline.*\.nix$'' + ''^tests/functional/lang/.*eol.*\.nix$'' - # Syntax tests - ''^tests/functional/shell.shebang\.nix$'' - ''^tests/functional/lang/eval-okay-ind-string\.nix$'' + # Syntax tests + ''^tests/functional/shell.shebang\.nix$'' + ''^tests/functional/lang/eval-okay-ind-string\.nix$'' - # Not supported by nixfmt - ''^tests/functional/lang/eval-okay-deprecate-cursed-or\.nix$'' - ''^tests/functional/lang/eval-okay-attrs5\.nix$'' + # Not supported by nixfmt + ''^tests/functional/lang/eval-okay-deprecate-cursed-or\.nix$'' + ''^tests/functional/lang/eval-okay-attrs5\.nix$'' - # More syntax tests - # These tests, or parts of them, should have been parse-* test cases. - ''^tests/functional/lang/eval-fail-eol-2\.nix$'' - ''^tests/functional/lang/eval-fail-path-slash\.nix$'' - ''^tests/functional/lang/eval-fail-toJSON-non-utf-8\.nix$'' - ''^tests/functional/lang/eval-fail-set\.nix$'' - ]; - }; - clang-format = { - enable = true; - # https://github.com/cachix/git-hooks.nix/pull/532 - package = pkgs.llvmPackages_latest.clang-tools; - excludes = [ - # We don't want to format test data - # ''tests/(?!nixos/).*\.nix'' - ''^src/[^/]*-tests/data/.*$'' + # More syntax tests + # These tests, or parts of them, should have been parse-* test cases. + ''^tests/functional/lang/eval-fail-eol-2\.nix$'' + ''^tests/functional/lang/eval-fail-path-slash\.nix$'' + ''^tests/functional/lang/eval-fail-toJSON-non-utf-8\.nix$'' + ''^tests/functional/lang/eval-fail-set\.nix$'' + ]; + }; + clang-format = { + enable = true; + # https://github.com/cachix/git-hooks.nix/pull/532 + package = pkgs.llvmPackages_latest.clang-tools; + excludes = [ + # We don't want to format test data + # ''tests/(?!nixos/).*\.nix'' + ''^src/[^/]*-tests/data/.*$'' - # Don't format vendored code - ''^doc/manual/redirects\.js$'' - ''^doc/manual/theme/highlight\.js$'' + # Don't format vendored code + ''^doc/manual/redirects\.js$'' + ''^doc/manual/theme/highlight\.js$'' - # We haven't applied formatting to these files yet - ''^doc/manual/redirects\.js$'' - ''^doc/manual/theme/highlight\.js$'' - ''^precompiled-headers\.h$'' - ''^src/build-remote/build-remote\.cc$'' - ''^src/libcmd/built-path\.cc$'' - ''^src/libcmd/built-path\.hh$'' - ''^src/libcmd/common-eval-args\.cc$'' - ''^src/libcmd/common-eval-args\.hh$'' - ''^src/libcmd/editor-for\.cc$'' - ''^src/libcmd/installable-attr-path\.cc$'' - ''^src/libcmd/installable-attr-path\.hh$'' - ''^src/libcmd/installable-derived-path\.cc$'' - ''^src/libcmd/installable-derived-path\.hh$'' - ''^src/libcmd/installable-flake\.cc$'' - ''^src/libcmd/installable-flake\.hh$'' - ''^src/libcmd/installable-value\.cc$'' - ''^src/libcmd/installable-value\.hh$'' - ''^src/libcmd/installables\.cc$'' - ''^src/libcmd/installables\.hh$'' - ''^src/libcmd/legacy\.hh$'' - ''^src/libcmd/markdown\.cc$'' - ''^src/libcmd/misc-store-flags\.cc$'' - ''^src/libcmd/repl-interacter\.cc$'' - ''^src/libcmd/repl-interacter\.hh$'' - ''^src/libcmd/repl\.cc$'' - ''^src/libcmd/repl\.hh$'' - ''^src/libexpr-c/nix_api_expr\.cc$'' - ''^src/libexpr-c/nix_api_external\.cc$'' - ''^src/libexpr/attr-path\.cc$'' - ''^src/libexpr/attr-path\.hh$'' - ''^src/libexpr/attr-set\.cc$'' - ''^src/libexpr/attr-set\.hh$'' - ''^src/libexpr/eval-cache\.cc$'' - ''^src/libexpr/eval-cache\.hh$'' - ''^src/libexpr/eval-error\.cc$'' - ''^src/libexpr/eval-inline\.hh$'' - ''^src/libexpr/eval-settings\.cc$'' - ''^src/libexpr/eval-settings\.hh$'' - ''^src/libexpr/eval\.cc$'' - ''^src/libexpr/eval\.hh$'' - ''^src/libexpr/function-trace\.cc$'' - ''^src/libexpr/gc-small-vector\.hh$'' - ''^src/libexpr/get-drvs\.cc$'' - ''^src/libexpr/get-drvs\.hh$'' - ''^src/libexpr/json-to-value\.cc$'' - ''^src/libexpr/nixexpr\.cc$'' - ''^src/libexpr/nixexpr\.hh$'' - ''^src/libexpr/parser-state\.hh$'' - ''^src/libexpr/pos-table\.hh$'' - ''^src/libexpr/primops\.cc$'' - ''^src/libexpr/primops\.hh$'' - ''^src/libexpr/primops/context\.cc$'' - ''^src/libexpr/primops/fetchClosure\.cc$'' - ''^src/libexpr/primops/fetchMercurial\.cc$'' - ''^src/libexpr/primops/fetchTree\.cc$'' - ''^src/libexpr/primops/fromTOML\.cc$'' - ''^src/libexpr/print-ambiguous\.cc$'' - ''^src/libexpr/print-ambiguous\.hh$'' - ''^src/libexpr/print-options\.hh$'' - ''^src/libexpr/print\.cc$'' - ''^src/libexpr/print\.hh$'' - ''^src/libexpr/search-path\.cc$'' - ''^src/libexpr/symbol-table\.hh$'' - ''^src/libexpr/value-to-json\.cc$'' - ''^src/libexpr/value-to-json\.hh$'' - ''^src/libexpr/value-to-xml\.cc$'' - ''^src/libexpr/value-to-xml\.hh$'' - ''^src/libexpr/value\.hh$'' - ''^src/libexpr/value/context\.cc$'' - ''^src/libexpr/value/context\.hh$'' - ''^src/libfetchers/attrs\.cc$'' - ''^src/libfetchers/cache\.cc$'' - ''^src/libfetchers/cache\.hh$'' - ''^src/libfetchers/fetch-settings\.cc$'' - ''^src/libfetchers/fetch-settings\.hh$'' - ''^src/libfetchers/fetch-to-store\.cc$'' - ''^src/libfetchers/fetchers\.cc$'' - ''^src/libfetchers/fetchers\.hh$'' - ''^src/libfetchers/filtering-source-accessor\.cc$'' - ''^src/libfetchers/filtering-source-accessor\.hh$'' - ''^src/libfetchers/fs-source-accessor\.cc$'' - ''^src/libfetchers/fs-source-accessor\.hh$'' - ''^src/libfetchers/git-utils\.cc$'' - ''^src/libfetchers/git-utils\.hh$'' - ''^src/libfetchers/github\.cc$'' - ''^src/libfetchers/indirect\.cc$'' - ''^src/libfetchers/memory-source-accessor\.cc$'' - ''^src/libfetchers/path\.cc$'' - ''^src/libfetchers/registry\.cc$'' - ''^src/libfetchers/registry\.hh$'' - ''^src/libfetchers/tarball\.cc$'' - ''^src/libfetchers/tarball\.hh$'' - ''^src/libfetchers/git\.cc$'' - ''^src/libfetchers/mercurial\.cc$'' - ''^src/libflake/flake/config\.cc$'' - ''^src/libflake/flake/flake\.cc$'' - ''^src/libflake/flake/flake\.hh$'' - ''^src/libflake/flake/flakeref\.cc$'' - ''^src/libflake/flake/flakeref\.hh$'' - ''^src/libflake/flake/lockfile\.cc$'' - ''^src/libflake/flake/lockfile\.hh$'' - ''^src/libflake/flake/url-name\.cc$'' - ''^src/libmain/common-args\.cc$'' - ''^src/libmain/common-args\.hh$'' - ''^src/libmain/loggers\.cc$'' - ''^src/libmain/loggers\.hh$'' - ''^src/libmain/progress-bar\.cc$'' - ''^src/libmain/shared\.cc$'' - ''^src/libmain/shared\.hh$'' - ''^src/libmain/unix/stack\.cc$'' - ''^src/libstore/binary-cache-store\.cc$'' - ''^src/libstore/binary-cache-store\.hh$'' - ''^src/libstore/build-result\.hh$'' - ''^src/libstore/builtins\.hh$'' - ''^src/libstore/builtins/buildenv\.cc$'' - ''^src/libstore/builtins/buildenv\.hh$'' - ''^src/libstore/common-protocol-impl\.hh$'' - ''^src/libstore/common-protocol\.cc$'' - ''^src/libstore/common-protocol\.hh$'' - ''^src/libstore/common-ssh-store-config\.hh$'' - ''^src/libstore/content-address\.cc$'' - ''^src/libstore/content-address\.hh$'' - ''^src/libstore/daemon\.cc$'' - ''^src/libstore/daemon\.hh$'' - ''^src/libstore/derivations\.cc$'' - ''^src/libstore/derivations\.hh$'' - ''^src/libstore/derived-path-map\.cc$'' - ''^src/libstore/derived-path-map\.hh$'' - ''^src/libstore/derived-path\.cc$'' - ''^src/libstore/derived-path\.hh$'' - ''^src/libstore/downstream-placeholder\.cc$'' - ''^src/libstore/downstream-placeholder\.hh$'' - ''^src/libstore/dummy-store\.cc$'' - ''^src/libstore/export-import\.cc$'' - ''^src/libstore/filetransfer\.cc$'' - ''^src/libstore/filetransfer\.hh$'' - ''^src/libstore/gc-store\.hh$'' - ''^src/libstore/globals\.cc$'' - ''^src/libstore/globals\.hh$'' - ''^src/libstore/http-binary-cache-store\.cc$'' - ''^src/libstore/legacy-ssh-store\.cc$'' - ''^src/libstore/legacy-ssh-store\.hh$'' - ''^src/libstore/length-prefixed-protocol-helper\.hh$'' - ''^src/libstore/linux/personality\.cc$'' - ''^src/libstore/linux/personality\.hh$'' - ''^src/libstore/local-binary-cache-store\.cc$'' - ''^src/libstore/local-fs-store\.cc$'' - ''^src/libstore/local-fs-store\.hh$'' - ''^src/libstore/log-store\.cc$'' - ''^src/libstore/log-store\.hh$'' - ''^src/libstore/machines\.cc$'' - ''^src/libstore/machines\.hh$'' - ''^src/libstore/make-content-addressed\.cc$'' - ''^src/libstore/make-content-addressed\.hh$'' - ''^src/libstore/misc\.cc$'' - ''^src/libstore/names\.cc$'' - ''^src/libstore/names\.hh$'' - ''^src/libstore/nar-accessor\.cc$'' - ''^src/libstore/nar-accessor\.hh$'' - ''^src/libstore/nar-info-disk-cache\.cc$'' - ''^src/libstore/nar-info-disk-cache\.hh$'' - ''^src/libstore/nar-info\.cc$'' - ''^src/libstore/nar-info\.hh$'' - ''^src/libstore/outputs-spec\.cc$'' - ''^src/libstore/outputs-spec\.hh$'' - ''^src/libstore/parsed-derivations\.cc$'' - ''^src/libstore/path-info\.cc$'' - ''^src/libstore/path-info\.hh$'' - ''^src/libstore/path-references\.cc$'' - ''^src/libstore/path-regex\.hh$'' - ''^src/libstore/path-with-outputs\.cc$'' - ''^src/libstore/path\.cc$'' - ''^src/libstore/path\.hh$'' - ''^src/libstore/pathlocks\.cc$'' - ''^src/libstore/pathlocks\.hh$'' - ''^src/libstore/profiles\.cc$'' - ''^src/libstore/profiles\.hh$'' - ''^src/libstore/realisation\.cc$'' - ''^src/libstore/realisation\.hh$'' - ''^src/libstore/remote-fs-accessor\.cc$'' - ''^src/libstore/remote-fs-accessor\.hh$'' - ''^src/libstore/remote-store-connection\.hh$'' - ''^src/libstore/remote-store\.cc$'' - ''^src/libstore/remote-store\.hh$'' - ''^src/libstore/s3-binary-cache-store\.cc$'' - ''^src/libstore/s3\.hh$'' - ''^src/libstore/serve-protocol-impl\.cc$'' - ''^src/libstore/serve-protocol-impl\.hh$'' - ''^src/libstore/serve-protocol\.cc$'' - ''^src/libstore/serve-protocol\.hh$'' - ''^src/libstore/sqlite\.cc$'' - ''^src/libstore/sqlite\.hh$'' - ''^src/libstore/ssh-store\.cc$'' - ''^src/libstore/ssh\.cc$'' - ''^src/libstore/ssh\.hh$'' - ''^src/libstore/store-api\.cc$'' - ''^src/libstore/store-api\.hh$'' - ''^src/libstore/store-dir-config\.hh$'' - ''^src/libstore/build/derivation-goal\.cc$'' - ''^src/libstore/build/derivation-goal\.hh$'' - ''^src/libstore/build/drv-output-substitution-goal\.cc$'' - ''^src/libstore/build/drv-output-substitution-goal\.hh$'' - ''^src/libstore/build/entry-points\.cc$'' - ''^src/libstore/build/goal\.cc$'' - ''^src/libstore/build/goal\.hh$'' - ''^src/libstore/unix/build/hook-instance\.cc$'' - ''^src/libstore/unix/build/local-derivation-goal\.cc$'' - ''^src/libstore/unix/build/local-derivation-goal\.hh$'' - ''^src/libstore/build/substitution-goal\.cc$'' - ''^src/libstore/build/substitution-goal\.hh$'' - ''^src/libstore/build/worker\.cc$'' - ''^src/libstore/build/worker\.hh$'' - ''^src/libstore/builtins/fetchurl\.cc$'' - ''^src/libstore/builtins/unpack-channel\.cc$'' - ''^src/libstore/gc\.cc$'' - ''^src/libstore/local-overlay-store\.cc$'' - ''^src/libstore/local-overlay-store\.hh$'' - ''^src/libstore/local-store\.cc$'' - ''^src/libstore/local-store\.hh$'' - ''^src/libstore/unix/user-lock\.cc$'' - ''^src/libstore/unix/user-lock\.hh$'' - ''^src/libstore/optimise-store\.cc$'' - ''^src/libstore/unix/pathlocks\.cc$'' - ''^src/libstore/posix-fs-canonicalise\.cc$'' - ''^src/libstore/posix-fs-canonicalise\.hh$'' - ''^src/libstore/uds-remote-store\.cc$'' - ''^src/libstore/uds-remote-store\.hh$'' - ''^src/libstore/windows/build\.cc$'' - ''^src/libstore/worker-protocol-impl\.hh$'' - ''^src/libstore/worker-protocol\.cc$'' - ''^src/libstore/worker-protocol\.hh$'' - ''^src/libutil-c/nix_api_util_internal\.h$'' - ''^src/libutil/archive\.cc$'' - ''^src/libutil/archive\.hh$'' - ''^src/libutil/args\.cc$'' - ''^src/libutil/args\.hh$'' - ''^src/libutil/args/root\.hh$'' - ''^src/libutil/callback\.hh$'' - ''^src/libutil/canon-path\.cc$'' - ''^src/libutil/canon-path\.hh$'' - ''^src/libutil/chunked-vector\.hh$'' - ''^src/libutil/closure\.hh$'' - ''^src/libutil/comparator\.hh$'' - ''^src/libutil/compute-levels\.cc$'' - ''^src/libutil/config-impl\.hh$'' - ''^src/libutil/config\.cc$'' - ''^src/libutil/config\.hh$'' - ''^src/libutil/current-process\.cc$'' - ''^src/libutil/current-process\.hh$'' - ''^src/libutil/english\.cc$'' - ''^src/libutil/english\.hh$'' - ''^src/libutil/error\.cc$'' - ''^src/libutil/error\.hh$'' - ''^src/libutil/exit\.hh$'' - ''^src/libutil/experimental-features\.cc$'' - ''^src/libutil/experimental-features\.hh$'' - ''^src/libutil/file-content-address\.cc$'' - ''^src/libutil/file-content-address\.hh$'' - ''^src/libutil/file-descriptor\.cc$'' - ''^src/libutil/file-descriptor\.hh$'' - ''^src/libutil/file-path-impl\.hh$'' - ''^src/libutil/file-path\.hh$'' - ''^src/libutil/file-system\.cc$'' - ''^src/libutil/file-system\.hh$'' - ''^src/libutil/finally\.hh$'' - ''^src/libutil/fmt\.hh$'' - ''^src/libutil/fs-sink\.cc$'' - ''^src/libutil/fs-sink\.hh$'' - ''^src/libutil/git\.cc$'' - ''^src/libutil/git\.hh$'' - ''^src/libutil/hash\.cc$'' - ''^src/libutil/hash\.hh$'' - ''^src/libutil/hilite\.cc$'' - ''^src/libutil/hilite\.hh$'' - ''^src/libutil/source-accessor\.hh$'' - ''^src/libutil/json-impls\.hh$'' - ''^src/libutil/json-utils\.cc$'' - ''^src/libutil/json-utils\.hh$'' - ''^src/libutil/linux/cgroup\.cc$'' - ''^src/libutil/linux/namespaces\.cc$'' - ''^src/libutil/logging\.cc$'' - ''^src/libutil/logging\.hh$'' - ''^src/libutil/lru-cache\.hh$'' - ''^src/libutil/memory-source-accessor\.cc$'' - ''^src/libutil/memory-source-accessor\.hh$'' - ''^src/libutil/pool\.hh$'' - ''^src/libutil/position\.cc$'' - ''^src/libutil/position\.hh$'' - ''^src/libutil/posix-source-accessor\.cc$'' - ''^src/libutil/posix-source-accessor\.hh$'' - ''^src/libutil/processes\.hh$'' - ''^src/libutil/ref\.hh$'' - ''^src/libutil/references\.cc$'' - ''^src/libutil/references\.hh$'' - ''^src/libutil/regex-combinators\.hh$'' - ''^src/libutil/serialise\.cc$'' - ''^src/libutil/serialise\.hh$'' - ''^src/libutil/signals\.hh$'' - ''^src/libutil/signature/local-keys\.cc$'' - ''^src/libutil/signature/local-keys\.hh$'' - ''^src/libutil/signature/signer\.cc$'' - ''^src/libutil/signature/signer\.hh$'' - ''^src/libutil/source-accessor\.cc$'' - ''^src/libutil/source-accessor\.hh$'' - ''^src/libutil/source-path\.cc$'' - ''^src/libutil/source-path\.hh$'' - ''^src/libutil/split\.hh$'' - ''^src/libutil/suggestions\.cc$'' - ''^src/libutil/suggestions\.hh$'' - ''^src/libutil/sync\.hh$'' - ''^src/libutil/terminal\.cc$'' - ''^src/libutil/terminal\.hh$'' - ''^src/libutil/thread-pool\.cc$'' - ''^src/libutil/thread-pool\.hh$'' - ''^src/libutil/topo-sort\.hh$'' - ''^src/libutil/types\.hh$'' - ''^src/libutil/unix/file-descriptor\.cc$'' - ''^src/libutil/unix/file-path\.cc$'' - ''^src/libutil/unix/monitor-fd\.hh$'' - ''^src/libutil/unix/processes\.cc$'' - ''^src/libutil/unix/signals-impl\.hh$'' - ''^src/libutil/unix/signals\.cc$'' - ''^src/libutil/unix-domain-socket\.cc$'' - ''^src/libutil/unix/users\.cc$'' - ''^src/libutil/url-parts\.hh$'' - ''^src/libutil/url\.cc$'' - ''^src/libutil/url\.hh$'' - ''^src/libutil/users\.cc$'' - ''^src/libutil/users\.hh$'' - ''^src/libutil/util\.cc$'' - ''^src/libutil/util\.hh$'' - ''^src/libutil/variant-wrapper\.hh$'' - ''^src/libutil/widecharwidth/widechar_width\.h$'' # vendored source - ''^src/libutil/windows/file-descriptor\.cc$'' - ''^src/libutil/windows/file-path\.cc$'' - ''^src/libutil/windows/processes\.cc$'' - ''^src/libutil/windows/users\.cc$'' - ''^src/libutil/windows/windows-error\.cc$'' - ''^src/libutil/windows/windows-error\.hh$'' - ''^src/libutil/xml-writer\.cc$'' - ''^src/libutil/xml-writer\.hh$'' - ''^src/nix-build/nix-build\.cc$'' - ''^src/nix-channel/nix-channel\.cc$'' - ''^src/nix-collect-garbage/nix-collect-garbage\.cc$'' - ''^src/nix-env/buildenv.nix$'' - ''^src/nix-env/nix-env\.cc$'' - ''^src/nix-env/user-env\.cc$'' - ''^src/nix-env/user-env\.hh$'' - ''^src/nix-instantiate/nix-instantiate\.cc$'' - ''^src/nix-store/dotgraph\.cc$'' - ''^src/nix-store/graphml\.cc$'' - ''^src/nix-store/nix-store\.cc$'' - ''^src/nix/add-to-store\.cc$'' - ''^src/nix/app\.cc$'' - ''^src/nix/build\.cc$'' - ''^src/nix/bundle\.cc$'' - ''^src/nix/cat\.cc$'' - ''^src/nix/config-check\.cc$'' - ''^src/nix/config\.cc$'' - ''^src/nix/copy\.cc$'' - ''^src/nix/derivation-add\.cc$'' - ''^src/nix/derivation-show\.cc$'' - ''^src/nix/derivation\.cc$'' - ''^src/nix/develop\.cc$'' - ''^src/nix/diff-closures\.cc$'' - ''^src/nix/dump-path\.cc$'' - ''^src/nix/edit\.cc$'' - ''^src/nix/eval\.cc$'' - ''^src/nix/flake\.cc$'' - ''^src/nix/fmt\.cc$'' - ''^src/nix/hash\.cc$'' - ''^src/nix/log\.cc$'' - ''^src/nix/ls\.cc$'' - ''^src/nix/main\.cc$'' - ''^src/nix/make-content-addressed\.cc$'' - ''^src/nix/nar\.cc$'' - ''^src/nix/optimise-store\.cc$'' - ''^src/nix/path-from-hash-part\.cc$'' - ''^src/nix/path-info\.cc$'' - ''^src/nix/prefetch\.cc$'' - ''^src/nix/profile\.cc$'' - ''^src/nix/realisation\.cc$'' - ''^src/nix/registry\.cc$'' - ''^src/nix/repl\.cc$'' - ''^src/nix/run\.cc$'' - ''^src/nix/run\.hh$'' - ''^src/nix/search\.cc$'' - ''^src/nix/sigs\.cc$'' - ''^src/nix/store-copy-log\.cc$'' - ''^src/nix/store-delete\.cc$'' - ''^src/nix/store-gc\.cc$'' - ''^src/nix/store-info\.cc$'' - ''^src/nix/store-repair\.cc$'' - ''^src/nix/store\.cc$'' - ''^src/nix/unix/daemon\.cc$'' - ''^src/nix/upgrade-nix\.cc$'' - ''^src/nix/verify\.cc$'' - ''^src/nix/why-depends\.cc$'' + # We haven't applied formatting to these files yet + ''^doc/manual/redirects\.js$'' + ''^doc/manual/theme/highlight\.js$'' + ''^precompiled-headers\.h$'' + ''^src/build-remote/build-remote\.cc$'' + ''^src/libcmd/built-path\.cc$'' + ''^src/libcmd/built-path\.hh$'' + ''^src/libcmd/common-eval-args\.cc$'' + ''^src/libcmd/common-eval-args\.hh$'' + ''^src/libcmd/editor-for\.cc$'' + ''^src/libcmd/installable-attr-path\.cc$'' + ''^src/libcmd/installable-attr-path\.hh$'' + ''^src/libcmd/installable-derived-path\.cc$'' + ''^src/libcmd/installable-derived-path\.hh$'' + ''^src/libcmd/installable-flake\.cc$'' + ''^src/libcmd/installable-flake\.hh$'' + ''^src/libcmd/installable-value\.cc$'' + ''^src/libcmd/installable-value\.hh$'' + ''^src/libcmd/installables\.cc$'' + ''^src/libcmd/installables\.hh$'' + ''^src/libcmd/legacy\.hh$'' + ''^src/libcmd/markdown\.cc$'' + ''^src/libcmd/misc-store-flags\.cc$'' + ''^src/libcmd/repl-interacter\.cc$'' + ''^src/libcmd/repl-interacter\.hh$'' + ''^src/libcmd/repl\.cc$'' + ''^src/libcmd/repl\.hh$'' + ''^src/libexpr-c/nix_api_expr\.cc$'' + ''^src/libexpr-c/nix_api_external\.cc$'' + ''^src/libexpr/attr-path\.cc$'' + ''^src/libexpr/attr-path\.hh$'' + ''^src/libexpr/attr-set\.cc$'' + ''^src/libexpr/attr-set\.hh$'' + ''^src/libexpr/eval-cache\.cc$'' + ''^src/libexpr/eval-cache\.hh$'' + ''^src/libexpr/eval-error\.cc$'' + ''^src/libexpr/eval-inline\.hh$'' + ''^src/libexpr/eval-settings\.cc$'' + ''^src/libexpr/eval-settings\.hh$'' + ''^src/libexpr/eval\.cc$'' + ''^src/libexpr/eval\.hh$'' + ''^src/libexpr/function-trace\.cc$'' + ''^src/libexpr/gc-small-vector\.hh$'' + ''^src/libexpr/get-drvs\.cc$'' + ''^src/libexpr/get-drvs\.hh$'' + ''^src/libexpr/json-to-value\.cc$'' + ''^src/libexpr/nixexpr\.cc$'' + ''^src/libexpr/nixexpr\.hh$'' + ''^src/libexpr/parser-state\.hh$'' + ''^src/libexpr/pos-table\.hh$'' + ''^src/libexpr/primops\.cc$'' + ''^src/libexpr/primops\.hh$'' + ''^src/libexpr/primops/context\.cc$'' + ''^src/libexpr/primops/fetchClosure\.cc$'' + ''^src/libexpr/primops/fetchMercurial\.cc$'' + ''^src/libexpr/primops/fetchTree\.cc$'' + ''^src/libexpr/primops/fromTOML\.cc$'' + ''^src/libexpr/print-ambiguous\.cc$'' + ''^src/libexpr/print-ambiguous\.hh$'' + ''^src/libexpr/print-options\.hh$'' + ''^src/libexpr/print\.cc$'' + ''^src/libexpr/print\.hh$'' + ''^src/libexpr/search-path\.cc$'' + ''^src/libexpr/symbol-table\.hh$'' + ''^src/libexpr/value-to-json\.cc$'' + ''^src/libexpr/value-to-json\.hh$'' + ''^src/libexpr/value-to-xml\.cc$'' + ''^src/libexpr/value-to-xml\.hh$'' + ''^src/libexpr/value\.hh$'' + ''^src/libexpr/value/context\.cc$'' + ''^src/libexpr/value/context\.hh$'' + ''^src/libfetchers/attrs\.cc$'' + ''^src/libfetchers/cache\.cc$'' + ''^src/libfetchers/cache\.hh$'' + ''^src/libfetchers/fetch-settings\.cc$'' + ''^src/libfetchers/fetch-settings\.hh$'' + ''^src/libfetchers/fetch-to-store\.cc$'' + ''^src/libfetchers/fetchers\.cc$'' + ''^src/libfetchers/fetchers\.hh$'' + ''^src/libfetchers/filtering-source-accessor\.cc$'' + ''^src/libfetchers/filtering-source-accessor\.hh$'' + ''^src/libfetchers/fs-source-accessor\.cc$'' + ''^src/libfetchers/fs-source-accessor\.hh$'' + ''^src/libfetchers/git-utils\.cc$'' + ''^src/libfetchers/git-utils\.hh$'' + ''^src/libfetchers/github\.cc$'' + ''^src/libfetchers/indirect\.cc$'' + ''^src/libfetchers/memory-source-accessor\.cc$'' + ''^src/libfetchers/path\.cc$'' + ''^src/libfetchers/registry\.cc$'' + ''^src/libfetchers/registry\.hh$'' + ''^src/libfetchers/tarball\.cc$'' + ''^src/libfetchers/tarball\.hh$'' + ''^src/libfetchers/git\.cc$'' + ''^src/libfetchers/mercurial\.cc$'' + ''^src/libflake/flake/config\.cc$'' + ''^src/libflake/flake/flake\.cc$'' + ''^src/libflake/flake/flake\.hh$'' + ''^src/libflake/flake/flakeref\.cc$'' + ''^src/libflake/flake/flakeref\.hh$'' + ''^src/libflake/flake/lockfile\.cc$'' + ''^src/libflake/flake/lockfile\.hh$'' + ''^src/libflake/flake/url-name\.cc$'' + ''^src/libmain/common-args\.cc$'' + ''^src/libmain/common-args\.hh$'' + ''^src/libmain/loggers\.cc$'' + ''^src/libmain/loggers\.hh$'' + ''^src/libmain/progress-bar\.cc$'' + ''^src/libmain/shared\.cc$'' + ''^src/libmain/shared\.hh$'' + ''^src/libmain/unix/stack\.cc$'' + ''^src/libstore/binary-cache-store\.cc$'' + ''^src/libstore/binary-cache-store\.hh$'' + ''^src/libstore/build-result\.hh$'' + ''^src/libstore/builtins\.hh$'' + ''^src/libstore/builtins/buildenv\.cc$'' + ''^src/libstore/builtins/buildenv\.hh$'' + ''^src/libstore/common-protocol-impl\.hh$'' + ''^src/libstore/common-protocol\.cc$'' + ''^src/libstore/common-protocol\.hh$'' + ''^src/libstore/common-ssh-store-config\.hh$'' + ''^src/libstore/content-address\.cc$'' + ''^src/libstore/content-address\.hh$'' + ''^src/libstore/daemon\.cc$'' + ''^src/libstore/daemon\.hh$'' + ''^src/libstore/derivations\.cc$'' + ''^src/libstore/derivations\.hh$'' + ''^src/libstore/derived-path-map\.cc$'' + ''^src/libstore/derived-path-map\.hh$'' + ''^src/libstore/derived-path\.cc$'' + ''^src/libstore/derived-path\.hh$'' + ''^src/libstore/downstream-placeholder\.cc$'' + ''^src/libstore/downstream-placeholder\.hh$'' + ''^src/libstore/dummy-store\.cc$'' + ''^src/libstore/export-import\.cc$'' + ''^src/libstore/filetransfer\.cc$'' + ''^src/libstore/filetransfer\.hh$'' + ''^src/libstore/gc-store\.hh$'' + ''^src/libstore/globals\.cc$'' + ''^src/libstore/globals\.hh$'' + ''^src/libstore/http-binary-cache-store\.cc$'' + ''^src/libstore/legacy-ssh-store\.cc$'' + ''^src/libstore/legacy-ssh-store\.hh$'' + ''^src/libstore/length-prefixed-protocol-helper\.hh$'' + ''^src/libstore/linux/personality\.cc$'' + ''^src/libstore/linux/personality\.hh$'' + ''^src/libstore/local-binary-cache-store\.cc$'' + ''^src/libstore/local-fs-store\.cc$'' + ''^src/libstore/local-fs-store\.hh$'' + ''^src/libstore/log-store\.cc$'' + ''^src/libstore/log-store\.hh$'' + ''^src/libstore/machines\.cc$'' + ''^src/libstore/machines\.hh$'' + ''^src/libstore/make-content-addressed\.cc$'' + ''^src/libstore/make-content-addressed\.hh$'' + ''^src/libstore/misc\.cc$'' + ''^src/libstore/names\.cc$'' + ''^src/libstore/names\.hh$'' + ''^src/libstore/nar-accessor\.cc$'' + ''^src/libstore/nar-accessor\.hh$'' + ''^src/libstore/nar-info-disk-cache\.cc$'' + ''^src/libstore/nar-info-disk-cache\.hh$'' + ''^src/libstore/nar-info\.cc$'' + ''^src/libstore/nar-info\.hh$'' + ''^src/libstore/outputs-spec\.cc$'' + ''^src/libstore/outputs-spec\.hh$'' + ''^src/libstore/parsed-derivations\.cc$'' + ''^src/libstore/path-info\.cc$'' + ''^src/libstore/path-info\.hh$'' + ''^src/libstore/path-references\.cc$'' + ''^src/libstore/path-regex\.hh$'' + ''^src/libstore/path-with-outputs\.cc$'' + ''^src/libstore/path\.cc$'' + ''^src/libstore/path\.hh$'' + ''^src/libstore/pathlocks\.cc$'' + ''^src/libstore/pathlocks\.hh$'' + ''^src/libstore/profiles\.cc$'' + ''^src/libstore/profiles\.hh$'' + ''^src/libstore/realisation\.cc$'' + ''^src/libstore/realisation\.hh$'' + ''^src/libstore/remote-fs-accessor\.cc$'' + ''^src/libstore/remote-fs-accessor\.hh$'' + ''^src/libstore/remote-store-connection\.hh$'' + ''^src/libstore/remote-store\.cc$'' + ''^src/libstore/remote-store\.hh$'' + ''^src/libstore/s3-binary-cache-store\.cc$'' + ''^src/libstore/s3\.hh$'' + ''^src/libstore/serve-protocol-impl\.cc$'' + ''^src/libstore/serve-protocol-impl\.hh$'' + ''^src/libstore/serve-protocol\.cc$'' + ''^src/libstore/serve-protocol\.hh$'' + ''^src/libstore/sqlite\.cc$'' + ''^src/libstore/sqlite\.hh$'' + ''^src/libstore/ssh-store\.cc$'' + ''^src/libstore/ssh\.cc$'' + ''^src/libstore/ssh\.hh$'' + ''^src/libstore/store-api\.cc$'' + ''^src/libstore/store-api\.hh$'' + ''^src/libstore/store-dir-config\.hh$'' + ''^src/libstore/build/derivation-goal\.cc$'' + ''^src/libstore/build/derivation-goal\.hh$'' + ''^src/libstore/build/drv-output-substitution-goal\.cc$'' + ''^src/libstore/build/drv-output-substitution-goal\.hh$'' + ''^src/libstore/build/entry-points\.cc$'' + ''^src/libstore/build/goal\.cc$'' + ''^src/libstore/build/goal\.hh$'' + ''^src/libstore/unix/build/hook-instance\.cc$'' + ''^src/libstore/unix/build/local-derivation-goal\.cc$'' + ''^src/libstore/unix/build/local-derivation-goal\.hh$'' + ''^src/libstore/build/substitution-goal\.cc$'' + ''^src/libstore/build/substitution-goal\.hh$'' + ''^src/libstore/build/worker\.cc$'' + ''^src/libstore/build/worker\.hh$'' + ''^src/libstore/builtins/fetchurl\.cc$'' + ''^src/libstore/builtins/unpack-channel\.cc$'' + ''^src/libstore/gc\.cc$'' + ''^src/libstore/local-overlay-store\.cc$'' + ''^src/libstore/local-overlay-store\.hh$'' + ''^src/libstore/local-store\.cc$'' + ''^src/libstore/local-store\.hh$'' + ''^src/libstore/unix/user-lock\.cc$'' + ''^src/libstore/unix/user-lock\.hh$'' + ''^src/libstore/optimise-store\.cc$'' + ''^src/libstore/unix/pathlocks\.cc$'' + ''^src/libstore/posix-fs-canonicalise\.cc$'' + ''^src/libstore/posix-fs-canonicalise\.hh$'' + ''^src/libstore/uds-remote-store\.cc$'' + ''^src/libstore/uds-remote-store\.hh$'' + ''^src/libstore/windows/build\.cc$'' + ''^src/libstore/worker-protocol-impl\.hh$'' + ''^src/libstore/worker-protocol\.cc$'' + ''^src/libstore/worker-protocol\.hh$'' + ''^src/libutil-c/nix_api_util_internal\.h$'' + ''^src/libutil/archive\.cc$'' + ''^src/libutil/archive\.hh$'' + ''^src/libutil/args\.cc$'' + ''^src/libutil/args\.hh$'' + ''^src/libutil/args/root\.hh$'' + ''^src/libutil/callback\.hh$'' + ''^src/libutil/canon-path\.cc$'' + ''^src/libutil/canon-path\.hh$'' + ''^src/libutil/chunked-vector\.hh$'' + ''^src/libutil/closure\.hh$'' + ''^src/libutil/comparator\.hh$'' + ''^src/libutil/compute-levels\.cc$'' + ''^src/libutil/config-impl\.hh$'' + ''^src/libutil/config\.cc$'' + ''^src/libutil/config\.hh$'' + ''^src/libutil/current-process\.cc$'' + ''^src/libutil/current-process\.hh$'' + ''^src/libutil/english\.cc$'' + ''^src/libutil/english\.hh$'' + ''^src/libutil/error\.cc$'' + ''^src/libutil/error\.hh$'' + ''^src/libutil/exit\.hh$'' + ''^src/libutil/experimental-features\.cc$'' + ''^src/libutil/experimental-features\.hh$'' + ''^src/libutil/file-content-address\.cc$'' + ''^src/libutil/file-content-address\.hh$'' + ''^src/libutil/file-descriptor\.cc$'' + ''^src/libutil/file-descriptor\.hh$'' + ''^src/libutil/file-path-impl\.hh$'' + ''^src/libutil/file-path\.hh$'' + ''^src/libutil/file-system\.cc$'' + ''^src/libutil/file-system\.hh$'' + ''^src/libutil/finally\.hh$'' + ''^src/libutil/fmt\.hh$'' + ''^src/libutil/fs-sink\.cc$'' + ''^src/libutil/fs-sink\.hh$'' + ''^src/libutil/git\.cc$'' + ''^src/libutil/git\.hh$'' + ''^src/libutil/hash\.cc$'' + ''^src/libutil/hash\.hh$'' + ''^src/libutil/hilite\.cc$'' + ''^src/libutil/hilite\.hh$'' + ''^src/libutil/source-accessor\.hh$'' + ''^src/libutil/json-impls\.hh$'' + ''^src/libutil/json-utils\.cc$'' + ''^src/libutil/json-utils\.hh$'' + ''^src/libutil/linux/cgroup\.cc$'' + ''^src/libutil/linux/namespaces\.cc$'' + ''^src/libutil/logging\.cc$'' + ''^src/libutil/logging\.hh$'' + ''^src/libutil/lru-cache\.hh$'' + ''^src/libutil/memory-source-accessor\.cc$'' + ''^src/libutil/memory-source-accessor\.hh$'' + ''^src/libutil/pool\.hh$'' + ''^src/libutil/position\.cc$'' + ''^src/libutil/position\.hh$'' + ''^src/libutil/posix-source-accessor\.cc$'' + ''^src/libutil/posix-source-accessor\.hh$'' + ''^src/libutil/processes\.hh$'' + ''^src/libutil/ref\.hh$'' + ''^src/libutil/references\.cc$'' + ''^src/libutil/references\.hh$'' + ''^src/libutil/regex-combinators\.hh$'' + ''^src/libutil/serialise\.cc$'' + ''^src/libutil/serialise\.hh$'' + ''^src/libutil/signals\.hh$'' + ''^src/libutil/signature/local-keys\.cc$'' + ''^src/libutil/signature/local-keys\.hh$'' + ''^src/libutil/signature/signer\.cc$'' + ''^src/libutil/signature/signer\.hh$'' + ''^src/libutil/source-accessor\.cc$'' + ''^src/libutil/source-accessor\.hh$'' + ''^src/libutil/source-path\.cc$'' + ''^src/libutil/source-path\.hh$'' + ''^src/libutil/split\.hh$'' + ''^src/libutil/suggestions\.cc$'' + ''^src/libutil/suggestions\.hh$'' + ''^src/libutil/sync\.hh$'' + ''^src/libutil/terminal\.cc$'' + ''^src/libutil/terminal\.hh$'' + ''^src/libutil/thread-pool\.cc$'' + ''^src/libutil/thread-pool\.hh$'' + ''^src/libutil/topo-sort\.hh$'' + ''^src/libutil/types\.hh$'' + ''^src/libutil/unix/file-descriptor\.cc$'' + ''^src/libutil/unix/file-path\.cc$'' + ''^src/libutil/unix/monitor-fd\.hh$'' + ''^src/libutil/unix/processes\.cc$'' + ''^src/libutil/unix/signals-impl\.hh$'' + ''^src/libutil/unix/signals\.cc$'' + ''^src/libutil/unix-domain-socket\.cc$'' + ''^src/libutil/unix/users\.cc$'' + ''^src/libutil/url-parts\.hh$'' + ''^src/libutil/url\.cc$'' + ''^src/libutil/url\.hh$'' + ''^src/libutil/users\.cc$'' + ''^src/libutil/users\.hh$'' + ''^src/libutil/util\.cc$'' + ''^src/libutil/util\.hh$'' + ''^src/libutil/variant-wrapper\.hh$'' + ''^src/libutil/widecharwidth/widechar_width\.h$'' # vendored source + ''^src/libutil/windows/file-descriptor\.cc$'' + ''^src/libutil/windows/file-path\.cc$'' + ''^src/libutil/windows/processes\.cc$'' + ''^src/libutil/windows/users\.cc$'' + ''^src/libutil/windows/windows-error\.cc$'' + ''^src/libutil/windows/windows-error\.hh$'' + ''^src/libutil/xml-writer\.cc$'' + ''^src/libutil/xml-writer\.hh$'' + ''^src/nix-build/nix-build\.cc$'' + ''^src/nix-channel/nix-channel\.cc$'' + ''^src/nix-collect-garbage/nix-collect-garbage\.cc$'' + ''^src/nix-env/buildenv.nix$'' + ''^src/nix-env/nix-env\.cc$'' + ''^src/nix-env/user-env\.cc$'' + ''^src/nix-env/user-env\.hh$'' + ''^src/nix-instantiate/nix-instantiate\.cc$'' + ''^src/nix-store/dotgraph\.cc$'' + ''^src/nix-store/graphml\.cc$'' + ''^src/nix-store/nix-store\.cc$'' + ''^src/nix/add-to-store\.cc$'' + ''^src/nix/app\.cc$'' + ''^src/nix/build\.cc$'' + ''^src/nix/bundle\.cc$'' + ''^src/nix/cat\.cc$'' + ''^src/nix/config-check\.cc$'' + ''^src/nix/config\.cc$'' + ''^src/nix/copy\.cc$'' + ''^src/nix/derivation-add\.cc$'' + ''^src/nix/derivation-show\.cc$'' + ''^src/nix/derivation\.cc$'' + ''^src/nix/develop\.cc$'' + ''^src/nix/diff-closures\.cc$'' + ''^src/nix/dump-path\.cc$'' + ''^src/nix/edit\.cc$'' + ''^src/nix/eval\.cc$'' + ''^src/nix/flake\.cc$'' + ''^src/nix/fmt\.cc$'' + ''^src/nix/hash\.cc$'' + ''^src/nix/log\.cc$'' + ''^src/nix/ls\.cc$'' + ''^src/nix/main\.cc$'' + ''^src/nix/make-content-addressed\.cc$'' + ''^src/nix/nar\.cc$'' + ''^src/nix/optimise-store\.cc$'' + ''^src/nix/path-from-hash-part\.cc$'' + ''^src/nix/path-info\.cc$'' + ''^src/nix/prefetch\.cc$'' + ''^src/nix/profile\.cc$'' + ''^src/nix/realisation\.cc$'' + ''^src/nix/registry\.cc$'' + ''^src/nix/repl\.cc$'' + ''^src/nix/run\.cc$'' + ''^src/nix/run\.hh$'' + ''^src/nix/search\.cc$'' + ''^src/nix/sigs\.cc$'' + ''^src/nix/store-copy-log\.cc$'' + ''^src/nix/store-delete\.cc$'' + ''^src/nix/store-gc\.cc$'' + ''^src/nix/store-info\.cc$'' + ''^src/nix/store-repair\.cc$'' + ''^src/nix/store\.cc$'' + ''^src/nix/unix/daemon\.cc$'' + ''^src/nix/upgrade-nix\.cc$'' + ''^src/nix/verify\.cc$'' + ''^src/nix/why-depends\.cc$'' - ''^tests/functional/plugins/plugintest\.cc'' - ''^tests/functional/test-libstoreconsumer/main\.cc'' - ''^tests/nixos/ca-fd-leak/sender\.c'' - ''^tests/nixos/ca-fd-leak/smuggler\.c'' - ''^tests/nixos/user-sandboxing/attacker\.c'' - ''^src/libexpr-test-support/tests/libexpr\.hh'' - ''^src/libexpr-test-support/tests/value/context\.cc'' - ''^src/libexpr-test-support/tests/value/context\.hh'' - ''^src/libexpr-tests/derived-path\.cc'' - ''^src/libexpr-tests/error_traces\.cc'' - ''^src/libexpr-tests/eval\.cc'' - ''^src/libexpr-tests/json\.cc'' - ''^src/libexpr-tests/main\.cc'' - ''^src/libexpr-tests/primops\.cc'' - ''^src/libexpr-tests/search-path\.cc'' - ''^src/libexpr-tests/trivial\.cc'' - ''^src/libexpr-tests/value/context\.cc'' - ''^src/libexpr-tests/value/print\.cc'' - ''^src/libfetchers-tests/public-key\.cc'' - ''^src/libflake-tests/flakeref\.cc'' - ''^src/libflake-tests/url-name\.cc'' - ''^src/libstore-test-support/tests/derived-path\.cc'' - ''^src/libstore-test-support/tests/derived-path\.hh'' - ''^src/libstore-test-support/tests/nix_api_store\.hh'' - ''^src/libstore-test-support/tests/outputs-spec\.cc'' - ''^src/libstore-test-support/tests/outputs-spec\.hh'' - ''^src/libstore-test-support/tests/path\.cc'' - ''^src/libstore-test-support/tests/path\.hh'' - ''^src/libstore-test-support/tests/protocol\.hh'' - ''^src/libstore-tests/common-protocol\.cc'' - ''^src/libstore-tests/content-address\.cc'' - ''^src/libstore-tests/derivation\.cc'' - ''^src/libstore-tests/derived-path\.cc'' - ''^src/libstore-tests/downstream-placeholder\.cc'' - ''^src/libstore-tests/machines\.cc'' - ''^src/libstore-tests/nar-info-disk-cache\.cc'' - ''^src/libstore-tests/nar-info\.cc'' - ''^src/libstore-tests/outputs-spec\.cc'' - ''^src/libstore-tests/path-info\.cc'' - ''^src/libstore-tests/path\.cc'' - ''^src/libstore-tests/serve-protocol\.cc'' - ''^src/libstore-tests/worker-protocol\.cc'' - ''^src/libutil-test-support/tests/characterization\.hh'' - ''^src/libutil-test-support/tests/hash\.cc'' - ''^src/libutil-test-support/tests/hash\.hh'' - ''^src/libutil-tests/args\.cc'' - ''^src/libutil-tests/canon-path\.cc'' - ''^src/libutil-tests/chunked-vector\.cc'' - ''^src/libutil-tests/closure\.cc'' - ''^src/libutil-tests/compression\.cc'' - ''^src/libutil-tests/config\.cc'' - ''^src/libutil-tests/file-content-address\.cc'' - ''^src/libutil-tests/git\.cc'' - ''^src/libutil-tests/hash\.cc'' - ''^src/libutil-tests/hilite\.cc'' - ''^src/libutil-tests/json-utils\.cc'' - ''^src/libutil-tests/logging\.cc'' - ''^src/libutil-tests/lru-cache\.cc'' - ''^src/libutil-tests/pool\.cc'' - ''^src/libutil-tests/references\.cc'' - ''^src/libutil-tests/suggestions\.cc'' - ''^src/libutil-tests/url\.cc'' - ''^src/libutil-tests/xml-writer\.cc'' - ]; - }; - shellcheck = { - enable = true; - excludes = [ - # We haven't linted these files yet - ''^config/install-sh$'' - ''^misc/bash/completion\.sh$'' - ''^misc/fish/completion\.fish$'' - ''^misc/zsh/completion\.zsh$'' - ''^scripts/create-darwin-volume\.sh$'' - ''^scripts/install-darwin-multi-user\.sh$'' - ''^scripts/install-multi-user\.sh$'' - ''^scripts/install-systemd-multi-user\.sh$'' - ''^src/nix/get-env\.sh$'' - ''^tests/functional/ca/build-dry\.sh$'' - ''^tests/functional/ca/build-with-garbage-path\.sh$'' - ''^tests/functional/ca/common\.sh$'' - ''^tests/functional/ca/concurrent-builds\.sh$'' - ''^tests/functional/ca/eval-store\.sh$'' - ''^tests/functional/ca/gc\.sh$'' - ''^tests/functional/ca/import-from-derivation\.sh$'' - ''^tests/functional/ca/new-build-cmd\.sh$'' - ''^tests/functional/ca/nix-shell\.sh$'' - ''^tests/functional/ca/post-hook\.sh$'' - ''^tests/functional/ca/recursive\.sh$'' - ''^tests/functional/ca/repl\.sh$'' - ''^tests/functional/ca/selfref-gc\.sh$'' - ''^tests/functional/ca/why-depends\.sh$'' - ''^tests/functional/characterisation-test-infra\.sh$'' - ''^tests/functional/common/vars-and-functions\.sh$'' - ''^tests/functional/completions\.sh$'' - ''^tests/functional/compute-levels\.sh$'' - ''^tests/functional/config\.sh$'' - ''^tests/functional/db-migration\.sh$'' - ''^tests/functional/debugger\.sh$'' - ''^tests/functional/dependencies\.builder0\.sh$'' - ''^tests/functional/dependencies\.sh$'' - ''^tests/functional/dump-db\.sh$'' - ''^tests/functional/dyn-drv/build-built-drv\.sh$'' - ''^tests/functional/dyn-drv/common\.sh$'' - ''^tests/functional/dyn-drv/dep-built-drv\.sh$'' - ''^tests/functional/dyn-drv/eval-outputOf\.sh$'' - ''^tests/functional/dyn-drv/old-daemon-error-hack\.sh$'' - ''^tests/functional/dyn-drv/recursive-mod-json\.sh$'' - ''^tests/functional/eval-store\.sh$'' - ''^tests/functional/export-graph\.sh$'' - ''^tests/functional/export\.sh$'' - ''^tests/functional/extra-sandbox-profile\.sh$'' - ''^tests/functional/fetchClosure\.sh$'' - ''^tests/functional/fetchGit\.sh$'' - ''^tests/functional/fetchGitRefs\.sh$'' - ''^tests/functional/fetchGitSubmodules\.sh$'' - ''^tests/functional/fetchGitVerification\.sh$'' - ''^tests/functional/fetchMercurial\.sh$'' - ''^tests/functional/fixed\.builder1\.sh$'' - ''^tests/functional/fixed\.builder2\.sh$'' - ''^tests/functional/fixed\.sh$'' - ''^tests/functional/flakes/absolute-paths\.sh$'' - ''^tests/functional/flakes/check\.sh$'' - ''^tests/functional/flakes/config\.sh$'' - ''^tests/functional/flakes/flakes\.sh$'' - ''^tests/functional/flakes/follow-paths\.sh$'' - ''^tests/functional/flakes/prefetch\.sh$'' - ''^tests/functional/flakes/run\.sh$'' - ''^tests/functional/flakes/show\.sh$'' - ''^tests/functional/fmt\.sh$'' - ''^tests/functional/fmt\.simple\.sh$'' - ''^tests/functional/gc-auto\.sh$'' - ''^tests/functional/gc-concurrent\.builder\.sh$'' - ''^tests/functional/gc-concurrent\.sh$'' - ''^tests/functional/gc-concurrent2\.builder\.sh$'' - ''^tests/functional/gc-non-blocking\.sh$'' - ''^tests/functional/git-hashing/common\.sh$'' - ''^tests/functional/git-hashing/simple\.sh$'' - ''^tests/functional/hash-convert\.sh$'' - ''^tests/functional/impure-derivations\.sh$'' - ''^tests/functional/impure-eval\.sh$'' - ''^tests/functional/install-darwin\.sh$'' - ''^tests/functional/legacy-ssh-store\.sh$'' - ''^tests/functional/linux-sandbox\.sh$'' - ''^tests/functional/local-overlay-store/add-lower-inner\.sh$'' - ''^tests/functional/local-overlay-store/add-lower\.sh$'' - ''^tests/functional/local-overlay-store/bad-uris\.sh$'' - ''^tests/functional/local-overlay-store/build-inner\.sh$'' - ''^tests/functional/local-overlay-store/build\.sh$'' - ''^tests/functional/local-overlay-store/check-post-init-inner\.sh$'' - ''^tests/functional/local-overlay-store/check-post-init\.sh$'' - ''^tests/functional/local-overlay-store/common\.sh$'' - ''^tests/functional/local-overlay-store/delete-duplicate-inner\.sh$'' - ''^tests/functional/local-overlay-store/delete-duplicate\.sh$'' - ''^tests/functional/local-overlay-store/delete-refs-inner\.sh$'' - ''^tests/functional/local-overlay-store/delete-refs\.sh$'' - ''^tests/functional/local-overlay-store/gc-inner\.sh$'' - ''^tests/functional/local-overlay-store/gc\.sh$'' - ''^tests/functional/local-overlay-store/optimise-inner\.sh$'' - ''^tests/functional/local-overlay-store/optimise\.sh$'' - ''^tests/functional/local-overlay-store/redundant-add-inner\.sh$'' - ''^tests/functional/local-overlay-store/redundant-add\.sh$'' - ''^tests/functional/local-overlay-store/remount\.sh$'' - ''^tests/functional/local-overlay-store/stale-file-handle-inner\.sh$'' - ''^tests/functional/local-overlay-store/stale-file-handle\.sh$'' - ''^tests/functional/local-overlay-store/verify-inner\.sh$'' - ''^tests/functional/local-overlay-store/verify\.sh$'' - ''^tests/functional/logging\.sh$'' - ''^tests/functional/misc\.sh$'' - ''^tests/functional/multiple-outputs\.sh$'' - ''^tests/functional/nested-sandboxing\.sh$'' - ''^tests/functional/nested-sandboxing/command\.sh$'' - ''^tests/functional/nix-build\.sh$'' - ''^tests/functional/nix-channel\.sh$'' - ''^tests/functional/nix-collect-garbage-d\.sh$'' - ''^tests/functional/nix-copy-ssh-common\.sh$'' - ''^tests/functional/nix-copy-ssh-ng\.sh$'' - ''^tests/functional/nix-copy-ssh\.sh$'' - ''^tests/functional/nix-daemon-untrusting\.sh$'' - ''^tests/functional/nix-profile\.sh$'' - ''^tests/functional/nix-shell\.sh$'' - ''^tests/functional/nix_path\.sh$'' - ''^tests/functional/optimise-store\.sh$'' - ''^tests/functional/output-normalization\.sh$'' - ''^tests/functional/parallel\.builder\.sh$'' - ''^tests/functional/parallel\.sh$'' - ''^tests/functional/pass-as-file\.sh$'' - ''^tests/functional/path-from-hash-part\.sh$'' - ''^tests/functional/path-info\.sh$'' - ''^tests/functional/placeholders\.sh$'' - ''^tests/functional/post-hook\.sh$'' - ''^tests/functional/pure-eval\.sh$'' - ''^tests/functional/push-to-store-old\.sh$'' - ''^tests/functional/push-to-store\.sh$'' - ''^tests/functional/read-only-store\.sh$'' - ''^tests/functional/readfile-context\.sh$'' - ''^tests/functional/recursive\.sh$'' - ''^tests/functional/referrers\.sh$'' - ''^tests/functional/remote-store\.sh$'' - ''^tests/functional/repair\.sh$'' - ''^tests/functional/restricted\.sh$'' - ''^tests/functional/search\.sh$'' - ''^tests/functional/secure-drv-outputs\.sh$'' - ''^tests/functional/selfref-gc\.sh$'' - ''^tests/functional/shell\.shebang\.sh$'' - ''^tests/functional/simple\.builder\.sh$'' - ''^tests/functional/supplementary-groups\.sh$'' - ''^tests/functional/toString-path\.sh$'' - ''^tests/functional/user-envs-migration\.sh$'' - ''^tests/functional/user-envs-test-case\.sh$'' - ''^tests/functional/user-envs\.builder\.sh$'' - ''^tests/functional/user-envs\.sh$'' - ''^tests/functional/why-depends\.sh$'' - ''^src/libutil-tests/data/git/check-data\.sh$'' - ]; + ''^tests/functional/plugins/plugintest\.cc'' + ''^tests/functional/test-libstoreconsumer/main\.cc'' + ''^tests/nixos/ca-fd-leak/sender\.c'' + ''^tests/nixos/ca-fd-leak/smuggler\.c'' + ''^tests/nixos/user-sandboxing/attacker\.c'' + ''^src/libexpr-test-support/tests/libexpr\.hh'' + ''^src/libexpr-test-support/tests/value/context\.cc'' + ''^src/libexpr-test-support/tests/value/context\.hh'' + ''^src/libexpr-tests/derived-path\.cc'' + ''^src/libexpr-tests/error_traces\.cc'' + ''^src/libexpr-tests/eval\.cc'' + ''^src/libexpr-tests/json\.cc'' + ''^src/libexpr-tests/main\.cc'' + ''^src/libexpr-tests/primops\.cc'' + ''^src/libexpr-tests/search-path\.cc'' + ''^src/libexpr-tests/trivial\.cc'' + ''^src/libexpr-tests/value/context\.cc'' + ''^src/libexpr-tests/value/print\.cc'' + ''^src/libfetchers-tests/public-key\.cc'' + ''^src/libflake-tests/flakeref\.cc'' + ''^src/libflake-tests/url-name\.cc'' + ''^src/libstore-test-support/tests/derived-path\.cc'' + ''^src/libstore-test-support/tests/derived-path\.hh'' + ''^src/libstore-test-support/tests/nix_api_store\.hh'' + ''^src/libstore-test-support/tests/outputs-spec\.cc'' + ''^src/libstore-test-support/tests/outputs-spec\.hh'' + ''^src/libstore-test-support/tests/path\.cc'' + ''^src/libstore-test-support/tests/path\.hh'' + ''^src/libstore-test-support/tests/protocol\.hh'' + ''^src/libstore-tests/common-protocol\.cc'' + ''^src/libstore-tests/content-address\.cc'' + ''^src/libstore-tests/derivation\.cc'' + ''^src/libstore-tests/derived-path\.cc'' + ''^src/libstore-tests/downstream-placeholder\.cc'' + ''^src/libstore-tests/machines\.cc'' + ''^src/libstore-tests/nar-info-disk-cache\.cc'' + ''^src/libstore-tests/nar-info\.cc'' + ''^src/libstore-tests/outputs-spec\.cc'' + ''^src/libstore-tests/path-info\.cc'' + ''^src/libstore-tests/path\.cc'' + ''^src/libstore-tests/serve-protocol\.cc'' + ''^src/libstore-tests/worker-protocol\.cc'' + ''^src/libutil-test-support/tests/characterization\.hh'' + ''^src/libutil-test-support/tests/hash\.cc'' + ''^src/libutil-test-support/tests/hash\.hh'' + ''^src/libutil-tests/args\.cc'' + ''^src/libutil-tests/canon-path\.cc'' + ''^src/libutil-tests/chunked-vector\.cc'' + ''^src/libutil-tests/closure\.cc'' + ''^src/libutil-tests/compression\.cc'' + ''^src/libutil-tests/config\.cc'' + ''^src/libutil-tests/file-content-address\.cc'' + ''^src/libutil-tests/git\.cc'' + ''^src/libutil-tests/hash\.cc'' + ''^src/libutil-tests/hilite\.cc'' + ''^src/libutil-tests/json-utils\.cc'' + ''^src/libutil-tests/logging\.cc'' + ''^src/libutil-tests/lru-cache\.cc'' + ''^src/libutil-tests/pool\.cc'' + ''^src/libutil-tests/references\.cc'' + ''^src/libutil-tests/suggestions\.cc'' + ''^src/libutil-tests/url\.cc'' + ''^src/libutil-tests/xml-writer\.cc'' + ]; + }; + shellcheck = { + enable = true; + excludes = [ + # We haven't linted these files yet + ''^config/install-sh$'' + ''^misc/bash/completion\.sh$'' + ''^misc/fish/completion\.fish$'' + ''^misc/zsh/completion\.zsh$'' + ''^scripts/create-darwin-volume\.sh$'' + ''^scripts/install-darwin-multi-user\.sh$'' + ''^scripts/install-multi-user\.sh$'' + ''^scripts/install-systemd-multi-user\.sh$'' + ''^src/nix/get-env\.sh$'' + ''^tests/functional/ca/build-dry\.sh$'' + ''^tests/functional/ca/build-with-garbage-path\.sh$'' + ''^tests/functional/ca/common\.sh$'' + ''^tests/functional/ca/concurrent-builds\.sh$'' + ''^tests/functional/ca/eval-store\.sh$'' + ''^tests/functional/ca/gc\.sh$'' + ''^tests/functional/ca/import-from-derivation\.sh$'' + ''^tests/functional/ca/new-build-cmd\.sh$'' + ''^tests/functional/ca/nix-shell\.sh$'' + ''^tests/functional/ca/post-hook\.sh$'' + ''^tests/functional/ca/recursive\.sh$'' + ''^tests/functional/ca/repl\.sh$'' + ''^tests/functional/ca/selfref-gc\.sh$'' + ''^tests/functional/ca/why-depends\.sh$'' + ''^tests/functional/characterisation-test-infra\.sh$'' + ''^tests/functional/common/vars-and-functions\.sh$'' + ''^tests/functional/completions\.sh$'' + ''^tests/functional/compute-levels\.sh$'' + ''^tests/functional/config\.sh$'' + ''^tests/functional/db-migration\.sh$'' + ''^tests/functional/debugger\.sh$'' + ''^tests/functional/dependencies\.builder0\.sh$'' + ''^tests/functional/dependencies\.sh$'' + ''^tests/functional/dump-db\.sh$'' + ''^tests/functional/dyn-drv/build-built-drv\.sh$'' + ''^tests/functional/dyn-drv/common\.sh$'' + ''^tests/functional/dyn-drv/dep-built-drv\.sh$'' + ''^tests/functional/dyn-drv/eval-outputOf\.sh$'' + ''^tests/functional/dyn-drv/old-daemon-error-hack\.sh$'' + ''^tests/functional/dyn-drv/recursive-mod-json\.sh$'' + ''^tests/functional/eval-store\.sh$'' + ''^tests/functional/export-graph\.sh$'' + ''^tests/functional/export\.sh$'' + ''^tests/functional/extra-sandbox-profile\.sh$'' + ''^tests/functional/fetchClosure\.sh$'' + ''^tests/functional/fetchGit\.sh$'' + ''^tests/functional/fetchGitRefs\.sh$'' + ''^tests/functional/fetchGitSubmodules\.sh$'' + ''^tests/functional/fetchGitVerification\.sh$'' + ''^tests/functional/fetchMercurial\.sh$'' + ''^tests/functional/fixed\.builder1\.sh$'' + ''^tests/functional/fixed\.builder2\.sh$'' + ''^tests/functional/fixed\.sh$'' + ''^tests/functional/flakes/absolute-paths\.sh$'' + ''^tests/functional/flakes/check\.sh$'' + ''^tests/functional/flakes/config\.sh$'' + ''^tests/functional/flakes/flakes\.sh$'' + ''^tests/functional/flakes/follow-paths\.sh$'' + ''^tests/functional/flakes/prefetch\.sh$'' + ''^tests/functional/flakes/run\.sh$'' + ''^tests/functional/flakes/show\.sh$'' + ''^tests/functional/fmt\.sh$'' + ''^tests/functional/fmt\.simple\.sh$'' + ''^tests/functional/gc-auto\.sh$'' + ''^tests/functional/gc-concurrent\.builder\.sh$'' + ''^tests/functional/gc-concurrent\.sh$'' + ''^tests/functional/gc-concurrent2\.builder\.sh$'' + ''^tests/functional/gc-non-blocking\.sh$'' + ''^tests/functional/git-hashing/common\.sh$'' + ''^tests/functional/git-hashing/simple\.sh$'' + ''^tests/functional/hash-convert\.sh$'' + ''^tests/functional/impure-derivations\.sh$'' + ''^tests/functional/impure-eval\.sh$'' + ''^tests/functional/install-darwin\.sh$'' + ''^tests/functional/legacy-ssh-store\.sh$'' + ''^tests/functional/linux-sandbox\.sh$'' + ''^tests/functional/local-overlay-store/add-lower-inner\.sh$'' + ''^tests/functional/local-overlay-store/add-lower\.sh$'' + ''^tests/functional/local-overlay-store/bad-uris\.sh$'' + ''^tests/functional/local-overlay-store/build-inner\.sh$'' + ''^tests/functional/local-overlay-store/build\.sh$'' + ''^tests/functional/local-overlay-store/check-post-init-inner\.sh$'' + ''^tests/functional/local-overlay-store/check-post-init\.sh$'' + ''^tests/functional/local-overlay-store/common\.sh$'' + ''^tests/functional/local-overlay-store/delete-duplicate-inner\.sh$'' + ''^tests/functional/local-overlay-store/delete-duplicate\.sh$'' + ''^tests/functional/local-overlay-store/delete-refs-inner\.sh$'' + ''^tests/functional/local-overlay-store/delete-refs\.sh$'' + ''^tests/functional/local-overlay-store/gc-inner\.sh$'' + ''^tests/functional/local-overlay-store/gc\.sh$'' + ''^tests/functional/local-overlay-store/optimise-inner\.sh$'' + ''^tests/functional/local-overlay-store/optimise\.sh$'' + ''^tests/functional/local-overlay-store/redundant-add-inner\.sh$'' + ''^tests/functional/local-overlay-store/redundant-add\.sh$'' + ''^tests/functional/local-overlay-store/remount\.sh$'' + ''^tests/functional/local-overlay-store/stale-file-handle-inner\.sh$'' + ''^tests/functional/local-overlay-store/stale-file-handle\.sh$'' + ''^tests/functional/local-overlay-store/verify-inner\.sh$'' + ''^tests/functional/local-overlay-store/verify\.sh$'' + ''^tests/functional/logging\.sh$'' + ''^tests/functional/misc\.sh$'' + ''^tests/functional/multiple-outputs\.sh$'' + ''^tests/functional/nested-sandboxing\.sh$'' + ''^tests/functional/nested-sandboxing/command\.sh$'' + ''^tests/functional/nix-build\.sh$'' + ''^tests/functional/nix-channel\.sh$'' + ''^tests/functional/nix-collect-garbage-d\.sh$'' + ''^tests/functional/nix-copy-ssh-common\.sh$'' + ''^tests/functional/nix-copy-ssh-ng\.sh$'' + ''^tests/functional/nix-copy-ssh\.sh$'' + ''^tests/functional/nix-daemon-untrusting\.sh$'' + ''^tests/functional/nix-profile\.sh$'' + ''^tests/functional/nix-shell\.sh$'' + ''^tests/functional/nix_path\.sh$'' + ''^tests/functional/optimise-store\.sh$'' + ''^tests/functional/output-normalization\.sh$'' + ''^tests/functional/parallel\.builder\.sh$'' + ''^tests/functional/parallel\.sh$'' + ''^tests/functional/pass-as-file\.sh$'' + ''^tests/functional/path-from-hash-part\.sh$'' + ''^tests/functional/path-info\.sh$'' + ''^tests/functional/placeholders\.sh$'' + ''^tests/functional/post-hook\.sh$'' + ''^tests/functional/pure-eval\.sh$'' + ''^tests/functional/push-to-store-old\.sh$'' + ''^tests/functional/push-to-store\.sh$'' + ''^tests/functional/read-only-store\.sh$'' + ''^tests/functional/readfile-context\.sh$'' + ''^tests/functional/recursive\.sh$'' + ''^tests/functional/referrers\.sh$'' + ''^tests/functional/remote-store\.sh$'' + ''^tests/functional/repair\.sh$'' + ''^tests/functional/restricted\.sh$'' + ''^tests/functional/search\.sh$'' + ''^tests/functional/secure-drv-outputs\.sh$'' + ''^tests/functional/selfref-gc\.sh$'' + ''^tests/functional/shell\.shebang\.sh$'' + ''^tests/functional/simple\.builder\.sh$'' + ''^tests/functional/supplementary-groups\.sh$'' + ''^tests/functional/toString-path\.sh$'' + ''^tests/functional/user-envs-migration\.sh$'' + ''^tests/functional/user-envs-test-case\.sh$'' + ''^tests/functional/user-envs\.builder\.sh$'' + ''^tests/functional/user-envs\.sh$'' + ''^tests/functional/why-depends\.sh$'' + ''^src/libutil-tests/data/git/check-data\.sh$'' + ]; + }; }; }; }; - }; # We'll be pulling from this in the main flake flake.getSystem = getSystem; diff --git a/packaging/binary-tarball.nix b/packaging/binary-tarball.nix index 59e11c77dfd..2050384b03f 100644 --- a/packaging/binary-tarball.nix +++ b/packaging/binary-tarball.nix @@ -1,14 +1,18 @@ -{ runCommand -, system -, buildPackages -, cacert -, nix +{ + runCommand, + system, + buildPackages, + cacert, + nix, }: let installerClosureInfo = buildPackages.closureInfo { - rootPaths = [ nix cacert ]; + rootPaths = [ + nix + cacert + ]; }; inherit (nix) version; diff --git a/packaging/components.nix b/packaging/components.nix index e1f661be8fb..d1bfe83bf0e 100644 --- a/packaging/components.nix +++ b/packaging/components.nix @@ -13,9 +13,11 @@ let versionSuffix = lib.optionalString (!officialRelease) "pre"; - fineVersionSuffix = lib.optionalString - (!officialRelease) - "pre${builtins.substring 0 8 (src.lastModifiedDate or src.lastModified or "19700101")}_${src.shortRev or "dirty"}"; + fineVersionSuffix = + lib.optionalString (!officialRelease) + "pre${ + builtins.substring 0 8 (src.lastModifiedDate or src.lastModified or "19700101") + }_${src.shortRev or "dirty"}"; fineVersion = baseVersion + fineVersionSuffix; in @@ -54,7 +56,9 @@ in nix-cli = callPackage ../src/nix/package.nix { version = fineVersion; }; - nix-functional-tests = callPackage ../src/nix-functional-tests/package.nix { version = fineVersion; }; + nix-functional-tests = callPackage ../src/nix-functional-tests/package.nix { + version = fineVersion; + }; nix-manual = callPackage ../doc/manual/package.nix { version = fineVersion; }; nix-internal-api-docs = callPackage ../src/internal-api-docs/package.nix { version = fineVersion; }; diff --git a/packaging/dependencies.nix b/packaging/dependencies.nix index acdbc9cfc79..afbc31fc6df 100644 --- a/packaging/dependencies.nix +++ b/packaging/dependencies.nix @@ -19,9 +19,7 @@ let root = ../.; - stdenv = if prevStdenv.isDarwin && prevStdenv.isx86_64 - then darwinStdenv - else prevStdenv; + stdenv = if prevStdenv.isDarwin && prevStdenv.isx86_64 then darwinStdenv else prevStdenv; # Fix the following error with the default x86_64-darwin SDK: # @@ -38,11 +36,14 @@ let # Indirection for Nixpkgs to override when package.nix files are vendored filesetToSource = lib.fileset.toSource; - /** Given a set of layers, create a mkDerivation-like function */ - mkPackageBuilder = exts: userFn: - stdenv.mkDerivation (lib.extends (lib.composeManyExtensions exts) userFn); + /** + Given a set of layers, create a mkDerivation-like function + */ + mkPackageBuilder = + exts: userFn: stdenv.mkDerivation (lib.extends (lib.composeManyExtensions exts) userFn); - localSourceLayer = finalAttrs: prevAttrs: + localSourceLayer = + finalAttrs: prevAttrs: let workDirPath = # Ideally we'd pick finalAttrs.workDir, but for now `mkDerivation` has @@ -51,8 +52,13 @@ let prevAttrs.workDir; workDirSubpath = lib.path.removePrefix root workDirPath; - sources = assert prevAttrs.fileset._type == "fileset"; prevAttrs.fileset; - src = lib.fileset.toSource { fileset = sources; inherit root; }; + sources = + assert prevAttrs.fileset._type == "fileset"; + prevAttrs.fileset; + src = lib.fileset.toSource { + fileset = sources; + inherit root; + }; in { @@ -64,117 +70,129 @@ let workDir = null; }; - mesonLayer = finalAttrs: prevAttrs: - { - # NOTE: - # As of https://github.com/NixOS/nixpkgs/blob/8baf8241cea0c7b30e0b8ae73474cb3de83c1a30/pkgs/by-name/me/meson/setup-hook.sh#L26, - # `mesonBuildType` defaults to `plain` if not specified. We want our Nix-built binaries to be optimized by default. - # More on build types here: https://mesonbuild.com/Builtin-options.html#details-for-buildtype. - mesonBuildType = "release"; - # NOTE: - # Users who are debugging Nix builds are expected to set the environment variable `mesonBuildType`, per the - # guidance in https://github.com/NixOS/nix/blob/8a3fc27f1b63a08ac983ee46435a56cf49ebaf4a/doc/manual/source/development/debugging.md?plain=1#L10. - # For this reason, we don't want to refer to `finalAttrs.mesonBuildType` here, but rather use the environment variable. - preConfigure = prevAttrs.preConfigure or "" + lib.optionalString ( - !stdenv.hostPlatform.isWindows - # build failure - && !stdenv.hostPlatform.isStatic - # LTO breaks exception handling on x86-64-darwin. - && stdenv.system != "x86_64-darwin" - ) '' - case "$mesonBuildType" in - release|minsize) appendToVar mesonFlags "-Db_lto=true" ;; - *) appendToVar mesonFlags "-Db_lto=false" ;; - esac - ''; - nativeBuildInputs = [ - pkgs.buildPackages.meson - pkgs.buildPackages.ninja - ] ++ prevAttrs.nativeBuildInputs or []; - mesonCheckFlags = prevAttrs.mesonCheckFlags or [] ++ [ - "--print-errorlogs" - ]; - }; + mesonLayer = finalAttrs: prevAttrs: { + # NOTE: + # As of https://github.com/NixOS/nixpkgs/blob/8baf8241cea0c7b30e0b8ae73474cb3de83c1a30/pkgs/by-name/me/meson/setup-hook.sh#L26, + # `mesonBuildType` defaults to `plain` if not specified. We want our Nix-built binaries to be optimized by default. + # More on build types here: https://mesonbuild.com/Builtin-options.html#details-for-buildtype. + mesonBuildType = "release"; + # NOTE: + # Users who are debugging Nix builds are expected to set the environment variable `mesonBuildType`, per the + # guidance in https://github.com/NixOS/nix/blob/8a3fc27f1b63a08ac983ee46435a56cf49ebaf4a/doc/manual/source/development/debugging.md?plain=1#L10. + # For this reason, we don't want to refer to `finalAttrs.mesonBuildType` here, but rather use the environment variable. + preConfigure = + prevAttrs.preConfigure or "" + + + lib.optionalString + ( + !stdenv.hostPlatform.isWindows + # build failure + && !stdenv.hostPlatform.isStatic + # LTO breaks exception handling on x86-64-darwin. + && stdenv.system != "x86_64-darwin" + ) + '' + case "$mesonBuildType" in + release|minsize) appendToVar mesonFlags "-Db_lto=true" ;; + *) appendToVar mesonFlags "-Db_lto=false" ;; + esac + ''; + nativeBuildInputs = [ + pkgs.buildPackages.meson + pkgs.buildPackages.ninja + ] ++ prevAttrs.nativeBuildInputs or [ ]; + mesonCheckFlags = prevAttrs.mesonCheckFlags or [ ] ++ [ + "--print-errorlogs" + ]; + }; - mesonBuildLayer = finalAttrs: prevAttrs: - { - nativeBuildInputs = prevAttrs.nativeBuildInputs or [] ++ [ - pkgs.buildPackages.pkg-config - ]; - separateDebugInfo = !stdenv.hostPlatform.isStatic; - hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie"; - env = prevAttrs.env or {} - // lib.optionalAttrs - (stdenv.isLinux - && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux") - && !(stdenv.hostPlatform.useLLVM or false)) - { LDFLAGS = "-fuse-ld=gold"; }; - }; + mesonBuildLayer = finalAttrs: prevAttrs: { + nativeBuildInputs = prevAttrs.nativeBuildInputs or [ ] ++ [ + pkgs.buildPackages.pkg-config + ]; + separateDebugInfo = !stdenv.hostPlatform.isStatic; + hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie"; + env = + prevAttrs.env or { } + // lib.optionalAttrs ( + stdenv.isLinux + && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux") + && !(stdenv.hostPlatform.useLLVM or false) + ) { LDFLAGS = "-fuse-ld=gold"; }; + }; - mesonLibraryLayer = finalAttrs: prevAttrs: - { - outputs = prevAttrs.outputs or [ "out" ] ++ [ "dev" ]; - }; + mesonLibraryLayer = finalAttrs: prevAttrs: { + outputs = prevAttrs.outputs or [ "out" ] ++ [ "dev" ]; + }; # Work around weird `--as-needed` linker behavior with BSD, see # https://github.com/mesonbuild/meson/issues/3593 - bsdNoLinkAsNeeded = finalAttrs: prevAttrs: + bsdNoLinkAsNeeded = + finalAttrs: prevAttrs: lib.optionalAttrs stdenv.hostPlatform.isBSD { - mesonFlags = [ (lib.mesonBool "b_asneeded" false) ] ++ prevAttrs.mesonFlags or []; + mesonFlags = [ (lib.mesonBool "b_asneeded" false) ] ++ prevAttrs.mesonFlags or [ ]; }; - miscGoodPractice = finalAttrs: prevAttrs: - { - strictDeps = prevAttrs.strictDeps or true; - enableParallelBuilding = true; - }; + miscGoodPractice = finalAttrs: prevAttrs: { + strictDeps = prevAttrs.strictDeps or true; + enableParallelBuilding = true; + }; in scope: { inherit stdenv; - aws-sdk-cpp = (pkgs.aws-sdk-cpp.override { - apis = [ "s3" "transfer" ]; - customMemoryManagement = false; - }).overrideAttrs { - # only a stripped down version is built, which takes a lot less resources - # to build, so we don't need a "big-parallel" machine. - requiredSystemFeatures = [ ]; - }; + aws-sdk-cpp = + (pkgs.aws-sdk-cpp.override { + apis = [ + "s3" + "transfer" + ]; + customMemoryManagement = false; + }).overrideAttrs + { + # only a stripped down version is built, which takes a lot less resources + # to build, so we don't need a "big-parallel" machine. + requiredSystemFeatures = [ ]; + }; boehmgc = pkgs.boehmgc.override { enableLargeConfig = true; }; # TODO Hack until https://github.com/NixOS/nixpkgs/issues/45462 is fixed. - boost = (pkgs.boost.override { - extraB2Args = [ - "--with-container" - "--with-context" - "--with-coroutine" - ]; - }).overrideAttrs (old: { - # Need to remove `--with-*` to use `--with-libraries=...` - buildPhase = lib.replaceStrings [ "--without-python" ] [ "" ] old.buildPhase; - installPhase = lib.replaceStrings [ "--without-python" ] [ "" ] old.installPhase; - }); + boost = + (pkgs.boost.override { + extraB2Args = [ + "--with-container" + "--with-context" + "--with-coroutine" + ]; + }).overrideAttrs + (old: { + # Need to remove `--with-*` to use `--with-libraries=...` + buildPhase = lib.replaceStrings [ "--without-python" ] [ "" ] old.buildPhase; + installPhase = lib.replaceStrings [ "--without-python" ] [ "" ] old.installPhase; + }); libgit2 = pkgs.libgit2.overrideAttrs (attrs: { - cmakeFlags = attrs.cmakeFlags or [] - ++ [ "-DUSE_SSH=exec" ]; - nativeBuildInputs = attrs.nativeBuildInputs or [] + cmakeFlags = attrs.cmakeFlags or [ ] ++ [ "-DUSE_SSH=exec" ]; + nativeBuildInputs = + attrs.nativeBuildInputs or [ ] # gitMinimal does not build on Windows. See packbuilder patch. ++ lib.optionals (!stdenv.hostPlatform.isWindows) [ # Needed for `git apply`; see `prePatch` pkgs.buildPackages.gitMinimal ]; # Only `git apply` can handle git binary patches - prePatch = attrs.prePatch or "" + prePatch = + attrs.prePatch or "" + lib.optionalString (!stdenv.hostPlatform.isWindows) '' patch() { git apply } ''; - patches = attrs.patches or [] + patches = + attrs.patches or [ ] ++ [ ./patches/libgit2-mempack-thin-packfile.patch ] @@ -188,27 +206,24 @@ scope: { inherit resolvePath filesetToSource; - mkMesonDerivation = - mkPackageBuilder [ - miscGoodPractice - localSourceLayer - mesonLayer - ]; - mkMesonExecutable = - mkPackageBuilder [ - miscGoodPractice - bsdNoLinkAsNeeded - localSourceLayer - mesonLayer - mesonBuildLayer - ]; - mkMesonLibrary = - mkPackageBuilder [ - miscGoodPractice - bsdNoLinkAsNeeded - localSourceLayer - mesonLayer - mesonBuildLayer - mesonLibraryLayer - ]; + mkMesonDerivation = mkPackageBuilder [ + miscGoodPractice + localSourceLayer + mesonLayer + ]; + mkMesonExecutable = mkPackageBuilder [ + miscGoodPractice + bsdNoLinkAsNeeded + localSourceLayer + mesonLayer + mesonBuildLayer + ]; + mkMesonLibrary = mkPackageBuilder [ + miscGoodPractice + bsdNoLinkAsNeeded + localSourceLayer + mesonLayer + mesonBuildLayer + mesonLibraryLayer + ]; } diff --git a/packaging/dev-shell.nix b/packaging/dev-shell.nix index b35a48f65b0..8e1bb89368a 100644 --- a/packaging/dev-shell.nix +++ b/packaging/dev-shell.nix @@ -1,129 +1,141 @@ -{ lib, inputs, devFlake }: +{ + lib, + inputs, + devFlake, +}: { pkgs }: -pkgs.nixComponents.nix-util.overrideAttrs (attrs: - -let - stdenv = pkgs.nixDependencies.stdenv; - buildCanExecuteHost = stdenv.buildPlatform.canExecute stdenv.hostPlatform; - modular = devFlake.getSystem stdenv.buildPlatform.system; - transformFlag = prefix: flag: - assert builtins.isString flag; - let - rest = builtins.substring 2 (builtins.stringLength flag) flag; - in +pkgs.nixComponents.nix-util.overrideAttrs ( + attrs: + + let + stdenv = pkgs.nixDependencies.stdenv; + buildCanExecuteHost = stdenv.buildPlatform.canExecute stdenv.hostPlatform; + modular = devFlake.getSystem stdenv.buildPlatform.system; + transformFlag = + prefix: flag: + assert builtins.isString flag; + let + rest = builtins.substring 2 (builtins.stringLength flag) flag; + in "-D${prefix}:${rest}"; - havePerl = stdenv.buildPlatform == stdenv.hostPlatform && stdenv.hostPlatform.isUnix; - ignoreCrossFile = flags: builtins.filter (flag: !(lib.strings.hasInfix "cross-file" flag)) flags; -in { - pname = "shell-for-" + attrs.pname; - - # Remove the version suffix to avoid unnecessary attempts to substitute in nix develop - version = lib.fileContents ../.version; - name = attrs.pname; - - installFlags = "sysconfdir=$(out)/etc"; - shellHook = '' - PATH=$prefix/bin:$PATH - unset PYTHONPATH - export MANPATH=$out/share/man:$MANPATH - - # Make bash completion work. - XDG_DATA_DIRS+=:$out/share - - # Make the default phases do the right thing. - # FIXME: this wouldn't be needed if the ninja package set buildPhase() instead of $buildPhase. - # FIXME: mesonConfigurePhase shouldn't cd to the build directory. It would be better to pass '-C ' to ninja. - - cdToBuildDir() { - if [[ ! -e build.ninja ]]; then - cd build - fi - } - - configurePhase() { - mesonConfigurePhase - } - - buildPhase() { - cdToBuildDir - ninjaBuildPhase - } - - checkPhase() { - cdToBuildDir - mesonCheckPhase - } - - installPhase() { - cdToBuildDir - ninjaInstallPhase - } - ''; - - # We use this shell with the local checkout, not unpackPhase. - src = null; - - env = { - # Needed for Meson to find Boost. - # https://github.com/NixOS/nixpkgs/issues/86131. - BOOST_INCLUDEDIR = "${lib.getDev pkgs.nixDependencies.boost}/include"; - BOOST_LIBRARYDIR = "${lib.getLib pkgs.nixDependencies.boost}/lib"; - # For `make format`, to work without installing pre-commit - _NIX_PRE_COMMIT_HOOKS_CONFIG = - "${(pkgs.formats.yaml { }).generate "pre-commit-config.yaml" modular.pre-commit.settings.rawConfig}"; - }; - - mesonFlags = - map (transformFlag "libutil") (ignoreCrossFile pkgs.nixComponents.nix-util.mesonFlags) - ++ map (transformFlag "libstore") (ignoreCrossFile pkgs.nixComponents.nix-store.mesonFlags) - ++ map (transformFlag "libfetchers") (ignoreCrossFile pkgs.nixComponents.nix-fetchers.mesonFlags) - ++ lib.optionals havePerl (map (transformFlag "perl") (ignoreCrossFile pkgs.nixComponents.nix-perl-bindings.mesonFlags)) - ++ map (transformFlag "libexpr") (ignoreCrossFile pkgs.nixComponents.nix-expr.mesonFlags) - ++ map (transformFlag "libcmd") (ignoreCrossFile pkgs.nixComponents.nix-cmd.mesonFlags) - ; - - nativeBuildInputs = attrs.nativeBuildInputs or [] - ++ pkgs.nixComponents.nix-util.nativeBuildInputs - ++ pkgs.nixComponents.nix-store.nativeBuildInputs - ++ pkgs.nixComponents.nix-fetchers.nativeBuildInputs - ++ pkgs.nixComponents.nix-expr.nativeBuildInputs - ++ lib.optionals havePerl pkgs.nixComponents.nix-perl-bindings.nativeBuildInputs - ++ lib.optionals buildCanExecuteHost pkgs.nixComponents.nix-manual.externalNativeBuildInputs - ++ pkgs.nixComponents.nix-internal-api-docs.nativeBuildInputs - ++ pkgs.nixComponents.nix-external-api-docs.nativeBuildInputs - ++ pkgs.nixComponents.nix-functional-tests.externalNativeBuildInputs - ++ lib.optional - (!buildCanExecuteHost - # Hack around https://github.com/nixos/nixpkgs/commit/bf7ad8cfbfa102a90463433e2c5027573b462479 - && !(stdenv.hostPlatform.isWindows && stdenv.buildPlatform.isDarwin) - && stdenv.hostPlatform.emulatorAvailable pkgs.buildPackages - && lib.meta.availableOn stdenv.buildPlatform (stdenv.hostPlatform.emulator pkgs.buildPackages)) - pkgs.buildPackages.mesonEmulatorHook - ++ [ - pkgs.buildPackages.cmake - pkgs.buildPackages.shellcheck - pkgs.buildPackages.changelog-d - modular.pre-commit.settings.package - (pkgs.writeScriptBin "pre-commit-hooks-install" - modular.pre-commit.settings.installationScript) - inputs.nixfmt.packages.${pkgs.hostPlatform.system}.default - ] - # TODO: Remove the darwin check once - # https://github.com/NixOS/nixpkgs/pull/291814 is available - ++ lib.optional (stdenv.cc.isClang && !stdenv.buildPlatform.isDarwin) pkgs.buildPackages.bear - ++ lib.optional (stdenv.cc.isClang && stdenv.hostPlatform == stdenv.buildPlatform) (lib.hiPrio pkgs.buildPackages.clang-tools); - - buildInputs = attrs.buildInputs or [] - ++ pkgs.nixComponents.nix-util.buildInputs - ++ pkgs.nixComponents.nix-store.buildInputs - ++ pkgs.nixComponents.nix-store-tests.externalBuildInputs - ++ pkgs.nixComponents.nix-fetchers.buildInputs - ++ pkgs.nixComponents.nix-expr.buildInputs - ++ pkgs.nixComponents.nix-expr.externalPropagatedBuildInputs - ++ pkgs.nixComponents.nix-cmd.buildInputs - ++ lib.optionals havePerl pkgs.nixComponents.nix-perl-bindings.externalBuildInputs - ++ lib.optional havePerl pkgs.perl - ; -}) + havePerl = stdenv.buildPlatform == stdenv.hostPlatform && stdenv.hostPlatform.isUnix; + ignoreCrossFile = flags: builtins.filter (flag: !(lib.strings.hasInfix "cross-file" flag)) flags; + in + { + pname = "shell-for-" + attrs.pname; + + # Remove the version suffix to avoid unnecessary attempts to substitute in nix develop + version = lib.fileContents ../.version; + name = attrs.pname; + + installFlags = "sysconfdir=$(out)/etc"; + shellHook = '' + PATH=$prefix/bin:$PATH + unset PYTHONPATH + export MANPATH=$out/share/man:$MANPATH + + # Make bash completion work. + XDG_DATA_DIRS+=:$out/share + + # Make the default phases do the right thing. + # FIXME: this wouldn't be needed if the ninja package set buildPhase() instead of $buildPhase. + # FIXME: mesonConfigurePhase shouldn't cd to the build directory. It would be better to pass '-C ' to ninja. + + cdToBuildDir() { + if [[ ! -e build.ninja ]]; then + cd build + fi + } + + configurePhase() { + mesonConfigurePhase + } + + buildPhase() { + cdToBuildDir + ninjaBuildPhase + } + + checkPhase() { + cdToBuildDir + mesonCheckPhase + } + + installPhase() { + cdToBuildDir + ninjaInstallPhase + } + ''; + + # We use this shell with the local checkout, not unpackPhase. + src = null; + + env = { + # Needed for Meson to find Boost. + # https://github.com/NixOS/nixpkgs/issues/86131. + BOOST_INCLUDEDIR = "${lib.getDev pkgs.nixDependencies.boost}/include"; + BOOST_LIBRARYDIR = "${lib.getLib pkgs.nixDependencies.boost}/lib"; + # For `make format`, to work without installing pre-commit + _NIX_PRE_COMMIT_HOOKS_CONFIG = "${(pkgs.formats.yaml { }).generate "pre-commit-config.yaml" + modular.pre-commit.settings.rawConfig + }"; + }; + + mesonFlags = + map (transformFlag "libutil") (ignoreCrossFile pkgs.nixComponents.nix-util.mesonFlags) + ++ map (transformFlag "libstore") (ignoreCrossFile pkgs.nixComponents.nix-store.mesonFlags) + ++ map (transformFlag "libfetchers") (ignoreCrossFile pkgs.nixComponents.nix-fetchers.mesonFlags) + ++ lib.optionals havePerl ( + map (transformFlag "perl") (ignoreCrossFile pkgs.nixComponents.nix-perl-bindings.mesonFlags) + ) + ++ map (transformFlag "libexpr") (ignoreCrossFile pkgs.nixComponents.nix-expr.mesonFlags) + ++ map (transformFlag "libcmd") (ignoreCrossFile pkgs.nixComponents.nix-cmd.mesonFlags); + + nativeBuildInputs = + attrs.nativeBuildInputs or [ ] + ++ pkgs.nixComponents.nix-util.nativeBuildInputs + ++ pkgs.nixComponents.nix-store.nativeBuildInputs + ++ pkgs.nixComponents.nix-fetchers.nativeBuildInputs + ++ pkgs.nixComponents.nix-expr.nativeBuildInputs + ++ lib.optionals havePerl pkgs.nixComponents.nix-perl-bindings.nativeBuildInputs + ++ lib.optionals buildCanExecuteHost pkgs.nixComponents.nix-manual.externalNativeBuildInputs + ++ pkgs.nixComponents.nix-internal-api-docs.nativeBuildInputs + ++ pkgs.nixComponents.nix-external-api-docs.nativeBuildInputs + ++ pkgs.nixComponents.nix-functional-tests.externalNativeBuildInputs + ++ lib.optional ( + !buildCanExecuteHost + # Hack around https://github.com/nixos/nixpkgs/commit/bf7ad8cfbfa102a90463433e2c5027573b462479 + && !(stdenv.hostPlatform.isWindows && stdenv.buildPlatform.isDarwin) + && stdenv.hostPlatform.emulatorAvailable pkgs.buildPackages + && lib.meta.availableOn stdenv.buildPlatform (stdenv.hostPlatform.emulator pkgs.buildPackages) + ) pkgs.buildPackages.mesonEmulatorHook + ++ [ + pkgs.buildPackages.cmake + pkgs.buildPackages.shellcheck + pkgs.buildPackages.changelog-d + modular.pre-commit.settings.package + (pkgs.writeScriptBin "pre-commit-hooks-install" modular.pre-commit.settings.installationScript) + inputs.nixfmt.packages.${pkgs.hostPlatform.system}.default + ] + # TODO: Remove the darwin check once + # https://github.com/NixOS/nixpkgs/pull/291814 is available + ++ lib.optional (stdenv.cc.isClang && !stdenv.buildPlatform.isDarwin) pkgs.buildPackages.bear + ++ lib.optional (stdenv.cc.isClang && stdenv.hostPlatform == stdenv.buildPlatform) ( + lib.hiPrio pkgs.buildPackages.clang-tools + ); + + buildInputs = + attrs.buildInputs or [ ] + ++ pkgs.nixComponents.nix-util.buildInputs + ++ pkgs.nixComponents.nix-store.buildInputs + ++ pkgs.nixComponents.nix-store-tests.externalBuildInputs + ++ pkgs.nixComponents.nix-fetchers.buildInputs + ++ pkgs.nixComponents.nix-expr.buildInputs + ++ pkgs.nixComponents.nix-expr.externalPropagatedBuildInputs + ++ pkgs.nixComponents.nix-cmd.buildInputs + ++ lib.optionals havePerl pkgs.nixComponents.nix-perl-bindings.externalBuildInputs + ++ lib.optional havePerl pkgs.perl; + } +) diff --git a/packaging/everything.nix b/packaging/everything.nix index 7ca878d8d53..2b47c31bbf5 100644 --- a/packaging/everything.nix +++ b/packaging/everything.nix @@ -42,27 +42,31 @@ }: let - libs = { - inherit - nix-util - nix-util-c - nix-store - nix-store-c - nix-fetchers - nix-expr - nix-expr-c - nix-flake - nix-flake-c - nix-main - nix-main-c - nix-cmd - ; - } // lib.optionalAttrs (!stdenv.hostPlatform.isStatic && stdenv.buildPlatform.canExecute stdenv.hostPlatform) { - # Currently fails in static build - inherit - nix-perl-bindings - ; - }; + libs = + { + inherit + nix-util + nix-util-c + nix-store + nix-store-c + nix-fetchers + nix-expr + nix-expr-c + nix-flake + nix-flake-c + nix-main + nix-main-c + nix-cmd + ; + } + // lib.optionalAttrs + (!stdenv.hostPlatform.isStatic && stdenv.buildPlatform.canExecute stdenv.hostPlatform) + { + # Currently fails in static build + inherit + nix-perl-bindings + ; + }; dev = stdenv.mkDerivation (finalAttrs: { name = "nix-${nix-cli.version}-dev"; @@ -77,10 +81,9 @@ let ''; passthru = { tests = { - pkg-config = - testers.hasPkgConfigModules { - package = finalAttrs.finalPackage; - }; + pkg-config = testers.hasPkgConfigModules { + package = finalAttrs.finalPackage; + }; }; # If we were to fully emulate output selection here, we'd confuse the Nix CLIs, @@ -123,70 +126,84 @@ in ]; meta.mainProgram = "nix"; -}).overrideAttrs (finalAttrs: prevAttrs: { - doCheck = true; - doInstallCheck = true; - - checkInputs = [ - # Make sure the unit tests have passed - nix-util-tests.tests.run - nix-store-tests.tests.run - nix-expr-tests.tests.run - nix-fetchers-tests.tests.run - nix-flake-tests.tests.run - - # Make sure the functional tests have passed - nix-functional-tests - - # dev bundle is ok - # (checkInputs must be empty paths??) - (runCommand "check-pkg-config" { checked = dev.tests.pkg-config; } "mkdir $out") - ] ++ lib.optionals (!stdenv.hostPlatform.isStatic && stdenv.buildPlatform.canExecute stdenv.hostPlatform) [ - # Perl currently fails in static build - # TODO: Split out tests into a separate derivation? - nix-perl-bindings - ]; - passthru = prevAttrs.passthru // { - inherit (nix-cli) version; - - /** - These are the libraries that are part of the Nix project. They are used - by the Nix CLI and other tools. - - If you need to use these libraries in your project, we recommend to use - the `-c` C API libraries exclusively, if possible. - - We also recommend that you build the complete package to ensure that the unit tests pass. - You could do this in CI, or by passing it in an unused environment variable. e.g in a `mkDerivation` call: - - ```nix - buildInputs = [ nix.libs.nix-util-c nix.libs.nix-store-c ]; - # Make sure the nix libs we use are ok - unusedInputsForTests = [ nix ]; - disallowedReferences = nix.all; - ``` - */ - inherit libs; - - tests = prevAttrs.passthru.tests or {} // { - # TODO: create a proper fixpoint and: - # pkg-config = - # testers.hasPkgConfigModules { - # package = finalPackage; - # }; - }; - - /** - A derivation referencing the `dev` outputs of the Nix libraries. - */ - inherit dev; - inherit devdoc; - doc = nix-manual; - outputs = [ "out" "dev" "devdoc" "doc" ]; - all = lib.attrValues (lib.genAttrs finalAttrs.passthru.outputs (outName: finalAttrs.finalPackage.${outName})); - }; - meta = prevAttrs.meta // { - description = "The Nix package manager"; - pkgConfigModules = dev.meta.pkgConfigModules; - }; -}) +}).overrideAttrs + ( + finalAttrs: prevAttrs: { + doCheck = true; + doInstallCheck = true; + + checkInputs = + [ + # Make sure the unit tests have passed + nix-util-tests.tests.run + nix-store-tests.tests.run + nix-expr-tests.tests.run + nix-fetchers-tests.tests.run + nix-flake-tests.tests.run + + # Make sure the functional tests have passed + nix-functional-tests + + # dev bundle is ok + # (checkInputs must be empty paths??) + (runCommand "check-pkg-config" { checked = dev.tests.pkg-config; } "mkdir $out") + ] + ++ lib.optionals + (!stdenv.hostPlatform.isStatic && stdenv.buildPlatform.canExecute stdenv.hostPlatform) + [ + # Perl currently fails in static build + # TODO: Split out tests into a separate derivation? + nix-perl-bindings + ]; + passthru = prevAttrs.passthru // { + inherit (nix-cli) version; + + /** + These are the libraries that are part of the Nix project. They are used + by the Nix CLI and other tools. + + If you need to use these libraries in your project, we recommend to use + the `-c` C API libraries exclusively, if possible. + + We also recommend that you build the complete package to ensure that the unit tests pass. + You could do this in CI, or by passing it in an unused environment variable. e.g in a `mkDerivation` call: + + ```nix + buildInputs = [ nix.libs.nix-util-c nix.libs.nix-store-c ]; + # Make sure the nix libs we use are ok + unusedInputsForTests = [ nix ]; + disallowedReferences = nix.all; + ``` + */ + inherit libs; + + tests = prevAttrs.passthru.tests or { } // { + # TODO: create a proper fixpoint and: + # pkg-config = + # testers.hasPkgConfigModules { + # package = finalPackage; + # }; + }; + + /** + A derivation referencing the `dev` outputs of the Nix libraries. + */ + inherit dev; + inherit devdoc; + doc = nix-manual; + outputs = [ + "out" + "dev" + "devdoc" + "doc" + ]; + all = lib.attrValues ( + lib.genAttrs finalAttrs.passthru.outputs (outName: finalAttrs.finalPackage.${outName}) + ); + }; + meta = prevAttrs.meta // { + description = "The Nix package manager"; + pkgConfigModules = dev.meta.pkgConfigModules; + }; + } + ) diff --git a/packaging/hydra.nix b/packaging/hydra.nix index 77fe93dc330..44cbd753c9b 100644 --- a/packaging/hydra.nix +++ b/packaging/hydra.nix @@ -1,21 +1,24 @@ -{ inputs -, forAllCrossSystems -, forAllSystems -, lib -, linux64BitSystems -, nixpkgsFor -, self -, officialRelease +{ + inputs, + forAllCrossSystems, + forAllSystems, + lib, + linux64BitSystems, + nixpkgsFor, + self, + officialRelease, }: let inherit (inputs) nixpkgs nixpkgs-regression; - installScriptFor = tarballs: + installScriptFor = + tarballs: nixpkgsFor.x86_64-linux.native.callPackage ./installer { inherit tarballs; }; - testNixVersions = pkgs: daemon: + testNixVersions = + pkgs: daemon: pkgs.nixComponents.nix-functional-tests.override { pname = "nix-daemon-compat-tests"; version = "${pkgs.nix.version}-with-daemon-${daemon.version}"; @@ -53,44 +56,72 @@ let in { # Binary package for various platforms. - build = forAllPackages (pkgName: - forAllSystems (system: nixpkgsFor.${system}.native.nixComponents.${pkgName})); - - shellInputs = removeAttrs - (forAllSystems (system: self.devShells.${system}.default.inputDerivation)) - [ "i686-linux" ]; - - buildStatic = forAllPackages (pkgName: - lib.genAttrs linux64BitSystems (system: nixpkgsFor.${system}.native.pkgsStatic.nixComponents.${pkgName})); - - buildCross = forAllPackages (pkgName: + build = forAllPackages ( + pkgName: forAllSystems (system: nixpkgsFor.${system}.native.nixComponents.${pkgName}) + ); + + shellInputs = removeAttrs (forAllSystems ( + system: self.devShells.${system}.default.inputDerivation + )) [ "i686-linux" ]; + + buildStatic = forAllPackages ( + pkgName: + lib.genAttrs linux64BitSystems ( + system: nixpkgsFor.${system}.native.pkgsStatic.nixComponents.${pkgName} + ) + ); + + buildCross = forAllPackages ( + pkgName: # Hack to avoid non-evaling package - (if pkgName == "nix-functional-tests" then lib.flip builtins.removeAttrs ["x86_64-w64-mingw32"] else lib.id) - (forAllCrossSystems (crossSystem: - lib.genAttrs [ "x86_64-linux" ] (system: nixpkgsFor.${system}.cross.${crossSystem}.nixComponents.${pkgName})))); - - buildNoGc = let - components = forAllSystems (system: - nixpkgsFor.${system}.native.nixComponents.overrideScope (self: super: { - nix-expr = super.nix-expr.override { enableGC = false; }; - }) - ); - in forAllPackages (pkgName: forAllSystems (system: components.${system}.${pkgName})); + ( + if pkgName == "nix-functional-tests" then + lib.flip builtins.removeAttrs [ "x86_64-w64-mingw32" ] + else + lib.id + ) + ( + forAllCrossSystems ( + crossSystem: + lib.genAttrs [ "x86_64-linux" ] ( + system: nixpkgsFor.${system}.cross.${crossSystem}.nixComponents.${pkgName} + ) + ) + ) + ); + + buildNoGc = + let + components = forAllSystems ( + system: + nixpkgsFor.${system}.native.nixComponents.overrideScope ( + self: super: { + nix-expr = super.nix-expr.override { enableGC = false; }; + } + ) + ); + in + forAllPackages (pkgName: forAllSystems (system: components.${system}.${pkgName})); buildNoTests = forAllSystems (system: nixpkgsFor.${system}.native.nixComponents.nix-cli); # Toggles some settings for better coverage. Windows needs these # library combinations, and Debian build Nix with GNU readline too. - buildReadlineNoMarkdown = let - components = forAllSystems (system: - nixpkgsFor.${system}.native.nixComponents.overrideScope (self: super: { - nix-cmd = super.nix-cmd.override { - enableMarkdown = false; - readlineFlavor = "readline"; - }; - }) - ); - in forAllPackages (pkgName: forAllSystems (system: components.${system}.${pkgName})); + buildReadlineNoMarkdown = + let + components = forAllSystems ( + system: + nixpkgsFor.${system}.native.nixComponents.overrideScope ( + self: super: { + nix-cmd = super.nix-cmd.override { + enableMarkdown = false; + readlineFlavor = "readline"; + }; + } + ) + ); + in + forAllPackages (pkgName: forAllSystems (system: components.${system}.${pkgName})); # Perl bindings for various platforms. perlBindings = forAllSystems (system: nixpkgsFor.${system}.native.nixComponents.nix-perl-bindings); @@ -98,12 +129,16 @@ in # Binary tarball for various platforms, containing a Nix store # with the closure of 'nix' package, and the second half of # the installation script. - binaryTarball = forAllSystems (system: - nixpkgsFor.${system}.native.callPackage ./binary-tarball.nix {}); + binaryTarball = forAllSystems ( + system: nixpkgsFor.${system}.native.callPackage ./binary-tarball.nix { } + ); - binaryTarballCross = lib.genAttrs [ "x86_64-linux" ] (system: - forAllCrossSystems (crossSystem: - nixpkgsFor.${system}.cross.${crossSystem}.callPackage ./binary-tarball.nix {})); + binaryTarballCross = lib.genAttrs [ "x86_64-linux" ] ( + system: + forAllCrossSystems ( + crossSystem: nixpkgsFor.${system}.cross.${crossSystem}.callPackage ./binary-tarball.nix { } + ) + ); # The first half of the installation script. This is uploaded # to https://nixos.org/nix/install. It downloads the binary @@ -122,9 +157,12 @@ in self.hydraJobs.binaryTarballCross."x86_64-linux"."riscv64-unknown-linux-gnu" ]; - installerScriptForGHA = forAllSystems (system: nixpkgsFor.${system}.native.callPackage ./installer { - tarballs = [ self.hydraJobs.binaryTarball.${system} ]; - }); + installerScriptForGHA = forAllSystems ( + system: + nixpkgsFor.${system}.native.callPackage ./installer { + tarballs = [ self.hydraJobs.binaryTarball.${system} ]; + } + ); # docker image with Nix inside dockerImage = lib.genAttrs linux64BitSystems (system: self.packages.${system}.dockerImage); @@ -145,19 +183,20 @@ in external-api-docs = nixpkgsFor.x86_64-linux.native.nixComponents.nix-external-api-docs; # System tests. - tests = import ../tests/nixos { - inherit lib nixpkgs nixpkgsFor; - inherit (self.inputs) nixpkgs-23-11; - } // { - - # Make sure that nix-env still produces the exact same result - # on a particular version of Nixpkgs. - evalNixpkgs = - let - inherit (nixpkgsFor.x86_64-linux.native) runCommand nix; - in - runCommand "eval-nixos" { buildInputs = [ nix ]; } - '' + tests = + import ../tests/nixos { + inherit lib nixpkgs nixpkgsFor; + inherit (self.inputs) nixpkgs-23-11; + } + // { + + # Make sure that nix-env still produces the exact same result + # on a particular version of Nixpkgs. + evalNixpkgs = + let + inherit (nixpkgsFor.x86_64-linux.native) runCommand nix; + in + runCommand "eval-nixos" { buildInputs = [ nix ]; } '' type -p nix-env # Note: we're filtering out nixos-install-tools because https://github.com/NixOS/nixpkgs/pull/153594#issuecomment-1020530593. ( @@ -168,36 +207,36 @@ in mkdir $out ''; - nixpkgsLibTests = - forAllSystems (system: - import (nixpkgs + "/lib/tests/test-with-nix.nix") - { - lib = nixpkgsFor.${system}.native.lib; - nix = self.packages.${system}.nix-cli; - pkgs = nixpkgsFor.${system}.native; - } + nixpkgsLibTests = forAllSystems ( + system: + import (nixpkgs + "/lib/tests/test-with-nix.nix") { + lib = nixpkgsFor.${system}.native.lib; + nix = self.packages.${system}.nix-cli; + pkgs = nixpkgsFor.${system}.native; + } ); - }; + }; metrics.nixpkgs = import "${nixpkgs-regression}/pkgs/top-level/metrics.nix" { pkgs = nixpkgsFor.x86_64-linux.native; nixpkgs = nixpkgs-regression; }; - installTests = forAllSystems (system: - let pkgs = nixpkgsFor.${system}.native; in - pkgs.runCommand "install-tests" - { - againstSelf = testNixVersions pkgs pkgs.nix; - againstCurrentLatest = - # FIXME: temporarily disable this on macOS because of #3605. - if system == "x86_64-linux" - then testNixVersions pkgs pkgs.nixVersions.latest - else null; - # Disabled because the latest stable version doesn't handle - # `NIX_DAEMON_SOCKET_PATH` which is required for the tests to work - # againstLatestStable = testNixVersions pkgs pkgs.nixStable; - } "touch $out"); + installTests = forAllSystems ( + system: + let + pkgs = nixpkgsFor.${system}.native; + in + pkgs.runCommand "install-tests" { + againstSelf = testNixVersions pkgs pkgs.nix; + againstCurrentLatest = + # FIXME: temporarily disable this on macOS because of #3605. + if system == "x86_64-linux" then testNixVersions pkgs pkgs.nixVersions.latest else null; + # Disabled because the latest stable version doesn't handle + # `NIX_DAEMON_SOCKET_PATH` which is required for the tests to work + # againstLatestStable = testNixVersions pkgs pkgs.nixStable; + } "touch $out" + ); installerTests = import ../tests/installer { binaryTarballs = self.hydraJobs.binaryTarball; diff --git a/packaging/installer/default.nix b/packaging/installer/default.nix index cc7759c2c8e..e171f36f99f 100644 --- a/packaging/installer/default.nix +++ b/packaging/installer/default.nix @@ -1,36 +1,42 @@ -{ lib -, runCommand -, nix -, tarballs +{ + lib, + runCommand, + nix, + tarballs, }: -runCommand "installer-script" { - buildInputs = [ nix ]; -} '' - mkdir -p $out/nix-support - - # Converts /nix/store/50p3qk8k...-nix-2.4pre20201102_550e11f/bin/nix to 50p3qk8k.../bin/nix. - tarballPath() { - # Remove the store prefix - local path=''${1#${builtins.storeDir}/} - # Get the path relative to the derivation root - local rest=''${path#*/} - # Get the derivation hash - local drvHash=''${path%%-*} - echo "$drvHash/$rest" +runCommand "installer-script" + { + buildInputs = [ nix ]; } + '' + mkdir -p $out/nix-support + + # Converts /nix/store/50p3qk8k...-nix-2.4pre20201102_550e11f/bin/nix to 50p3qk8k.../bin/nix. + tarballPath() { + # Remove the store prefix + local path=''${1#${builtins.storeDir}/} + # Get the path relative to the derivation root + local rest=''${path#*/} + # Get the derivation hash + local drvHash=''${path%%-*} + echo "$drvHash/$rest" + } - substitute ${./install.in} $out/install \ - ${lib.concatMapStrings - (tarball: let - inherit (tarball.stdenv.hostPlatform) system; - in '' \ - --replace '@tarballHash_${system}@' $(nix --experimental-features nix-command hash-file --base16 --type sha256 ${tarball}/*.tar.xz) \ - --replace '@tarballPath_${system}@' $(tarballPath ${tarball}/*.tar.xz) \ - '' - ) - tarballs - } --replace '@nixVersion@' ${nix.version} + substitute ${./install.in} $out/install \ + ${ + lib.concatMapStrings ( + tarball: + let + inherit (tarball.stdenv.hostPlatform) system; + in + '' + \ + --replace '@tarballHash_${system}@' $(nix --experimental-features nix-command hash-file --base16 --type sha256 ${tarball}/*.tar.xz) \ + --replace '@tarballPath_${system}@' $(tarballPath ${tarball}/*.tar.xz) \ + '' + ) tarballs + } --replace '@nixVersion@' ${nix.version} - echo "file installer $out/install" >> $out/nix-support/hydra-build-products -'' + echo "file installer $out/install" >> $out/nix-support/hydra-build-products + '' diff --git a/src/external-api-docs/package.nix b/src/external-api-docs/package.nix index 57c5138cfdb..b194e16d460 100644 --- a/src/external-api-docs/package.nix +++ b/src/external-api-docs/package.nix @@ -1,11 +1,12 @@ -{ lib -, mkMesonDerivation +{ + lib, + mkMesonDerivation, -, doxygen + doxygen, -# Configuration Options + # Configuration Options -, version + version, }: let @@ -39,11 +40,10 @@ mkMesonDerivation (finalAttrs: { doxygen ]; - preConfigure = - '' - chmod u+w ./.version - echo ${finalAttrs.version} > ./.version - ''; + preConfigure = '' + chmod u+w ./.version + echo ${finalAttrs.version} > ./.version + ''; postInstall = '' mkdir -p ''${!outputDoc}/nix-support diff --git a/src/internal-api-docs/package.nix b/src/internal-api-docs/package.nix index 993a257a69f..6c4f354aee5 100644 --- a/src/internal-api-docs/package.nix +++ b/src/internal-api-docs/package.nix @@ -1,11 +1,12 @@ -{ lib -, mkMesonDerivation +{ + lib, + mkMesonDerivation, -, doxygen + doxygen, -# Configuration Options + # Configuration Options -, version + version, }: let @@ -17,27 +18,28 @@ mkMesonDerivation (finalAttrs: { inherit version; workDir = ./.; - fileset = let - cpp = fileset.fileFilter (file: file.hasExt "cc" || file.hasExt "hh"); - in fileset.unions [ - ./.version - ../../.version - ./meson.build - ./doxygen.cfg.in - # Source is not compiled, but still must be available for Doxygen - # to gather comments. - (cpp ../.) - ]; + fileset = + let + cpp = fileset.fileFilter (file: file.hasExt "cc" || file.hasExt "hh"); + in + fileset.unions [ + ./.version + ../../.version + ./meson.build + ./doxygen.cfg.in + # Source is not compiled, but still must be available for Doxygen + # to gather comments. + (cpp ../.) + ]; nativeBuildInputs = [ doxygen ]; - preConfigure = - '' - chmod u+w ./.version - echo ${finalAttrs.version} > ./.version - ''; + preConfigure = '' + chmod u+w ./.version + echo ${finalAttrs.version} > ./.version + ''; postInstall = '' mkdir -p ''${!outputDoc}/nix-support diff --git a/src/libcmd/package.nix b/src/libcmd/package.nix index 5cafb4dc100..d155d9f1e62 100644 --- a/src/libcmd/package.nix +++ b/src/libcmd/package.nix @@ -1,32 +1,33 @@ -{ lib -, stdenv -, mkMesonLibrary +{ + lib, + stdenv, + mkMesonLibrary, -, nix-util -, nix-store -, nix-fetchers -, nix-expr -, nix-flake -, nix-main -, editline -, readline -, lowdown -, nlohmann_json + nix-util, + nix-store, + nix-fetchers, + nix-expr, + nix-flake, + nix-main, + editline, + readline, + lowdown, + nlohmann_json, -# Configuration Options + # Configuration Options -, version + version, -# Whether to enable Markdown rendering in the Nix binary. -, enableMarkdown ? !stdenv.hostPlatform.isWindows + # Whether to enable Markdown rendering in the Nix binary. + enableMarkdown ? !stdenv.hostPlatform.isWindows, -# Which interactive line editor library to use for Nix's repl. -# -# Currently supported choices are: -# -# - editline (default) -# - readline -, readlineFlavor ? if stdenv.hostPlatform.isWindows then "readline" else "editline" + # Which interactive line editor library to use for Nix's repl. + # + # Currently supported choices are: + # + # - editline (default) + # - readline + readlineFlavor ? if stdenv.hostPlatform.isWindows then "readline" else "editline", }: let diff --git a/src/libexpr-c/package.nix b/src/libexpr-c/package.nix index 5047f3e2e9a..ad1ea371c2d 100644 --- a/src/libexpr-c/package.nix +++ b/src/libexpr-c/package.nix @@ -1,12 +1,13 @@ -{ lib -, mkMesonLibrary +{ + lib, + mkMesonLibrary, -, nix-store-c -, nix-expr + nix-store-c, + nix-expr, -# Configuration Options + # Configuration Options -, version + version, }: let diff --git a/src/libexpr-test-support/package.nix b/src/libexpr-test-support/package.nix index 48118fa0c75..5628d606a45 100644 --- a/src/libexpr-test-support/package.nix +++ b/src/libexpr-test-support/package.nix @@ -1,15 +1,16 @@ -{ lib -, mkMesonLibrary +{ + lib, + mkMesonLibrary, -, nix-store-test-support -, nix-expr -, nix-expr-c + nix-store-test-support, + nix-expr, + nix-expr-c, -, rapidcheck + rapidcheck, -# Configuration Options + # Configuration Options -, version + version, }: let diff --git a/src/libexpr-tests/package.nix b/src/libexpr-tests/package.nix index a4a3bb0e7ec..bb5acb7c873 100644 --- a/src/libexpr-tests/package.nix +++ b/src/libexpr-tests/package.nix @@ -1,20 +1,21 @@ -{ lib -, buildPackages -, stdenv -, mkMesonExecutable +{ + lib, + buildPackages, + stdenv, + mkMesonExecutable, -, nix-expr -, nix-expr-c -, nix-expr-test-support + nix-expr, + nix-expr-c, + nix-expr-test-support, -, rapidcheck -, gtest -, runCommand + rapidcheck, + gtest, + runCommand, -# Configuration Options + # Configuration Options -, version -, resolvePath + version, + resolvePath, }: let @@ -58,16 +59,22 @@ mkMesonExecutable (finalAttrs: { passthru = { tests = { - run = runCommand "${finalAttrs.pname}-run" { - meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages; - } (lib.optionalString stdenv.hostPlatform.isWindows '' - export HOME="$PWD/home-dir" - mkdir -p "$HOME" - '' + '' - export _NIX_TEST_UNIT_DATA=${resolvePath ./data} - ${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage} - touch $out - ''); + run = + runCommand "${finalAttrs.pname}-run" + { + meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages; + } + ( + lib.optionalString stdenv.hostPlatform.isWindows '' + export HOME="$PWD/home-dir" + mkdir -p "$HOME" + '' + + '' + export _NIX_TEST_UNIT_DATA=${resolvePath ./data} + ${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage} + touch $out + '' + ); }; }; diff --git a/src/libexpr/call-flake.nix b/src/libexpr/call-flake.nix index 3a7a249c673..1e9e210481d 100644 --- a/src/libexpr/call-flake.nix +++ b/src/libexpr/call-flake.nix @@ -20,77 +20,77 @@ let # Resolve a input spec into a node name. An input spec is # either a node name, or a 'follows' path from the root # node. - resolveInput = inputSpec: - if builtins.isList inputSpec - then getInputByPath lockFile.root inputSpec - else inputSpec; + resolveInput = + inputSpec: if builtins.isList inputSpec then getInputByPath lockFile.root inputSpec else inputSpec; # Follow an input attrpath (e.g. ["dwarffs" "nixpkgs"]) from the # root node, returning the final node. - getInputByPath = nodeName: path: - if path == [] - then nodeName + getInputByPath = + nodeName: path: + if path == [ ] then + nodeName else getInputByPath # Since this could be a 'follows' input, call resolveInput. (resolveInput lockFile.nodes.${nodeName}.inputs.${builtins.head path}) (builtins.tail path); - allNodes = - builtins.mapAttrs - (key: node: - let - - parentNode = allNodes.${getInputByPath lockFile.root node.parent}; - - sourceInfo = - if overrides ? ${key} - then - overrides.${key}.sourceInfo - else if node.locked.type == "path" && builtins.substring 0 1 node.locked.path != "/" - then - parentNode.sourceInfo // { - outPath = parentNode.outPath + ("/" + node.locked.path); - } - else - # FIXME: remove obsolete node.info. - # Note: lock file entries are always final. - fetchTreeFinal (node.info or {} // removeAttrs node.locked ["dir"]); - - subdir = overrides.${key}.dir or node.locked.dir or ""; - - outPath = sourceInfo + ((if subdir == "" then "" else "/") + subdir); - - flake = import (outPath + "/flake.nix"); - - inputs = builtins.mapAttrs - (inputName: inputSpec: allNodes.${resolveInput inputSpec}) - (node.inputs or {}); - - outputs = flake.outputs (inputs // { self = result; }); - - result = - outputs - # We add the sourceInfo attribute for its metadata, as they are - # relevant metadata for the flake. However, the outPath of the - # sourceInfo does not necessarily match the outPath of the flake, - # as the flake may be in a subdirectory of a source. - # This is shadowed in the next // - // sourceInfo - // { - # This shadows the sourceInfo.outPath - inherit outPath; - - inherit inputs; inherit outputs; inherit sourceInfo; _type = "flake"; - }; - - in - if node.flake or true then - assert builtins.isFunction flake.outputs; - result - else - sourceInfo - ) - lockFile.nodes; - -in allNodes.${lockFile.root} + allNodes = builtins.mapAttrs ( + key: node: + let + + parentNode = allNodes.${getInputByPath lockFile.root node.parent}; + + sourceInfo = + if overrides ? ${key} then + overrides.${key}.sourceInfo + else if node.locked.type == "path" && builtins.substring 0 1 node.locked.path != "/" then + parentNode.sourceInfo + // { + outPath = parentNode.outPath + ("/" + node.locked.path); + } + else + # FIXME: remove obsolete node.info. + # Note: lock file entries are always final. + fetchTreeFinal (node.info or { } // removeAttrs node.locked [ "dir" ]); + + subdir = overrides.${key}.dir or node.locked.dir or ""; + + outPath = sourceInfo + ((if subdir == "" then "" else "/") + subdir); + + flake = import (outPath + "/flake.nix"); + + inputs = builtins.mapAttrs (inputName: inputSpec: allNodes.${resolveInput inputSpec}) ( + node.inputs or { } + ); + + outputs = flake.outputs (inputs // { self = result; }); + + result = + outputs + # We add the sourceInfo attribute for its metadata, as they are + # relevant metadata for the flake. However, the outPath of the + # sourceInfo does not necessarily match the outPath of the flake, + # as the flake may be in a subdirectory of a source. + # This is shadowed in the next // + // sourceInfo + // { + # This shadows the sourceInfo.outPath + inherit outPath; + + inherit inputs; + inherit outputs; + inherit sourceInfo; + _type = "flake"; + }; + + in + if node.flake or true then + assert builtins.isFunction flake.outputs; + result + else + sourceInfo + ) lockFile.nodes; + +in +allNodes.${lockFile.root} diff --git a/src/libexpr/fetchurl.nix b/src/libexpr/fetchurl.nix index 85a01d16179..72b3b00dffc 100644 --- a/src/libexpr/fetchurl.nix +++ b/src/libexpr/fetchurl.nix @@ -1,40 +1,72 @@ -{ system ? "" # obsolete -, url -, hash ? "" # an SRI hash - -# Legacy hash specification -, md5 ? "", sha1 ? "", sha256 ? "", sha512 ? "" -, outputHash ? - if hash != "" then hash else if sha512 != "" then sha512 else if sha1 != "" then sha1 else if md5 != "" then md5 else sha256 -, outputHashAlgo ? - if hash != "" then "" else if sha512 != "" then "sha512" else if sha1 != "" then "sha1" else if md5 != "" then "md5" else "sha256" - -, executable ? false -, unpack ? false -, name ? baseNameOf (toString url) -, impure ? false +{ + system ? "", # obsolete + url, + hash ? "", # an SRI hash + + # Legacy hash specification + md5 ? "", + sha1 ? "", + sha256 ? "", + sha512 ? "", + outputHash ? + if hash != "" then + hash + else if sha512 != "" then + sha512 + else if sha1 != "" then + sha1 + else if md5 != "" then + md5 + else + sha256, + outputHashAlgo ? + if hash != "" then + "" + else if sha512 != "" then + "sha512" + else if sha1 != "" then + "sha1" + else if md5 != "" then + "md5" + else + "sha256", + + executable ? false, + unpack ? false, + name ? baseNameOf (toString url), + impure ? false, }: -derivation ({ - builder = "builtin:fetchurl"; +derivation ( + { + builder = "builtin:fetchurl"; - # New-style output content requirements. - outputHashMode = if unpack || executable then "recursive" else "flat"; + # New-style output content requirements. + outputHashMode = if unpack || executable then "recursive" else "flat"; - inherit name url executable unpack; + inherit + name + url + executable + unpack + ; - system = "builtin"; + system = "builtin"; - # No need to double the amount of network traffic - preferLocalBuild = true; + # No need to double the amount of network traffic + preferLocalBuild = true; - # This attribute does nothing; it's here to avoid changing evaluation results. - impureEnvVars = [ - "http_proxy" "https_proxy" "ftp_proxy" "all_proxy" "no_proxy" - ]; + # This attribute does nothing; it's here to avoid changing evaluation results. + impureEnvVars = [ + "http_proxy" + "https_proxy" + "ftp_proxy" + "all_proxy" + "no_proxy" + ]; - # To make "nix-prefetch-url" work. - urls = [ url ]; -} // (if impure - then { __impure = true; } - else { inherit outputHashAlgo outputHash; })) + # To make "nix-prefetch-url" work. + urls = [ url ]; + } + // (if impure then { __impure = true; } else { inherit outputHashAlgo outputHash; }) +) diff --git a/src/libexpr/imported-drv-to-derivation.nix b/src/libexpr/imported-drv-to-derivation.nix index eab8b050e8f..e2cf7fd2652 100644 --- a/src/libexpr/imported-drv-to-derivation.nix +++ b/src/libexpr/imported-drv-to-derivation.nix @@ -1,21 +1,27 @@ -attrs @ { drvPath, outputs, name, ... }: +attrs@{ + drvPath, + outputs, + name, + ... +}: let - commonAttrs = (builtins.listToAttrs outputsList) // - { all = map (x: x.value) outputsList; - inherit drvPath name; - type = "derivation"; - }; + commonAttrs = (builtins.listToAttrs outputsList) // { + all = map (x: x.value) outputsList; + inherit drvPath name; + type = "derivation"; + }; - outputToAttrListElement = outputName: - { name = outputName; - value = commonAttrs // { - outPath = builtins.getAttr outputName attrs; - inherit outputName; - }; + outputToAttrListElement = outputName: { + name = outputName; + value = commonAttrs // { + outPath = builtins.getAttr outputName attrs; + inherit outputName; }; - + }; + outputsList = map outputToAttrListElement outputs; - -in (builtins.head outputsList).value + +in +(builtins.head outputsList).value diff --git a/src/libexpr/package.nix b/src/libexpr/package.nix index 3d5b78e35f2..afd01c3846e 100644 --- a/src/libexpr/package.nix +++ b/src/libexpr/package.nix @@ -1,33 +1,34 @@ -{ lib -, stdenv -, mkMesonLibrary - -, bison -, flex -, cmake # for resolving toml11 dep - -, nix-util -, nix-store -, nix-fetchers -, boost -, boehmgc -, nlohmann_json -, toml11 - -# Configuration Options - -, version - -# Whether to use garbage collection for the Nix language evaluator. -# -# If it is disabled, we just leak memory, but this is not as bad as it -# sounds so long as evaluation just takes places within short-lived -# processes. (When the process exits, the memory is reclaimed; it is -# only leaked *within* the process.) -# -# Temporarily disabled on Windows because the `GC_throw_bad_alloc` -# symbol is missing during linking. -, enableGC ? !stdenv.hostPlatform.isWindows +{ + lib, + stdenv, + mkMesonLibrary, + + bison, + flex, + cmake, # for resolving toml11 dep + + nix-util, + nix-store, + nix-fetchers, + boost, + boehmgc, + nlohmann_json, + toml11, + + # Configuration Options + + version, + + # Whether to use garbage collection for the Nix language evaluator. + # + # If it is disabled, we just leak memory, but this is not as bad as it + # sounds so long as evaluation just takes places within short-lived + # processes. (When the process exits, the memory is reclaimed; it is + # only leaked *within* the process.) + # + # Temporarily disabled on Windows because the `GC_throw_bad_alloc` + # symbol is missing during linking. + enableGC ? !stdenv.hostPlatform.isWindows, }: let @@ -51,10 +52,7 @@ mkMesonLibrary (finalAttrs: { (fileset.fileFilter (file: file.hasExt "hh") ./.) ./lexer.l ./parser.y - (fileset.difference - (fileset.fileFilter (file: file.hasExt "nix") ./.) - ./package.nix - ) + (fileset.difference (fileset.fileFilter (file: file.hasExt "nix") ./.) ./package.nix) ]; nativeBuildInputs = [ diff --git a/src/libexpr/primops/derivation.nix b/src/libexpr/primops/derivation.nix index f329ff71e32..dbb8c218688 100644 --- a/src/libexpr/primops/derivation.nix +++ b/src/libexpr/primops/derivation.nix @@ -26,27 +26,34 @@ Note that `derivation` is very bare-bones, and provides almost no commands during the build. Most likely, you'll want to use functions like `stdenv.mkDerivation` in Nixpkgs to set up a basic environment. */ -drvAttrs @ { outputs ? [ "out" ], ... }: +drvAttrs@{ + outputs ? [ "out" ], + ... +}: let strict = derivationStrict drvAttrs; - commonAttrs = drvAttrs // (builtins.listToAttrs outputsList) // - { all = map (x: x.value) outputsList; + commonAttrs = + drvAttrs + // (builtins.listToAttrs outputsList) + // { + all = map (x: x.value) outputsList; inherit drvAttrs; }; - outputToAttrListElement = outputName: - { name = outputName; - value = commonAttrs // { - outPath = builtins.getAttr outputName strict; - drvPath = strict.drvPath; - type = "derivation"; - inherit outputName; - }; + outputToAttrListElement = outputName: { + name = outputName; + value = commonAttrs // { + outPath = builtins.getAttr outputName strict; + drvPath = strict.drvPath; + type = "derivation"; + inherit outputName; }; + }; outputsList = map outputToAttrListElement outputs; -in (builtins.head outputsList).value +in +(builtins.head outputsList).value diff --git a/src/libfetchers-tests/package.nix b/src/libfetchers-tests/package.nix index 5336672a222..f2680e9b3c1 100644 --- a/src/libfetchers-tests/package.nix +++ b/src/libfetchers-tests/package.nix @@ -1,19 +1,20 @@ -{ lib -, buildPackages -, stdenv -, mkMesonExecutable +{ + lib, + buildPackages, + stdenv, + mkMesonExecutable, -, nix-fetchers -, nix-store-test-support + nix-fetchers, + nix-store-test-support, -, rapidcheck -, gtest -, runCommand + rapidcheck, + gtest, + runCommand, -# Configuration Options + # Configuration Options -, version -, resolvePath + version, + resolvePath, }: let @@ -56,16 +57,22 @@ mkMesonExecutable (finalAttrs: { passthru = { tests = { - run = runCommand "${finalAttrs.pname}-run" { - meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages; - } (lib.optionalString stdenv.hostPlatform.isWindows '' - export HOME="$PWD/home-dir" - mkdir -p "$HOME" - '' + '' - export _NIX_TEST_UNIT_DATA=${resolvePath ./data} - ${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage} - touch $out - ''); + run = + runCommand "${finalAttrs.pname}-run" + { + meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages; + } + ( + lib.optionalString stdenv.hostPlatform.isWindows '' + export HOME="$PWD/home-dir" + mkdir -p "$HOME" + '' + + '' + export _NIX_TEST_UNIT_DATA=${resolvePath ./data} + ${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage} + touch $out + '' + ); }; }; diff --git a/src/libfetchers/package.nix b/src/libfetchers/package.nix index d4ca1855503..b0aecd04979 100644 --- a/src/libfetchers/package.nix +++ b/src/libfetchers/package.nix @@ -1,14 +1,15 @@ -{ lib -, mkMesonLibrary +{ + lib, + mkMesonLibrary, -, nix-util -, nix-store -, nlohmann_json -, libgit2 + nix-util, + nix-store, + nlohmann_json, + libgit2, -# Configuration Options + # Configuration Options -, version + version, }: let diff --git a/src/libflake-c/package.nix b/src/libflake-c/package.nix index dcd6c496609..f0615a42798 100644 --- a/src/libflake-c/package.nix +++ b/src/libflake-c/package.nix @@ -1,13 +1,14 @@ -{ lib -, mkMesonLibrary +{ + lib, + mkMesonLibrary, -, nix-store-c -, nix-expr-c -, nix-flake + nix-store-c, + nix-expr-c, + nix-flake, -# Configuration Options + # Configuration Options -, version + version, }: let diff --git a/src/libflake-tests/package.nix b/src/libflake-tests/package.nix index 51b68ad581f..f9d9b0bc0c6 100644 --- a/src/libflake-tests/package.nix +++ b/src/libflake-tests/package.nix @@ -1,20 +1,21 @@ -{ lib -, buildPackages -, stdenv -, mkMesonExecutable +{ + lib, + buildPackages, + stdenv, + mkMesonExecutable, -, nix-flake -, nix-flake-c -, nix-expr-test-support + nix-flake, + nix-flake-c, + nix-expr-test-support, -, rapidcheck -, gtest -, runCommand + rapidcheck, + gtest, + runCommand, -# Configuration Options + # Configuration Options -, version -, resolvePath + version, + resolvePath, }: let @@ -58,17 +59,23 @@ mkMesonExecutable (finalAttrs: { passthru = { tests = { - run = runCommand "${finalAttrs.pname}-run" { - meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages; - } (lib.optionalString stdenv.hostPlatform.isWindows '' - export HOME="$PWD/home-dir" - mkdir -p "$HOME" - '' + '' - export _NIX_TEST_UNIT_DATA=${resolvePath ./data} - export NIX_CONFIG="extra-experimental-features = flakes" - ${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage} - touch $out - ''); + run = + runCommand "${finalAttrs.pname}-run" + { + meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages; + } + ( + lib.optionalString stdenv.hostPlatform.isWindows '' + export HOME="$PWD/home-dir" + mkdir -p "$HOME" + '' + + '' + export _NIX_TEST_UNIT_DATA=${resolvePath ./data} + export NIX_CONFIG="extra-experimental-features = flakes" + ${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage} + touch $out + '' + ); }; }; diff --git a/src/libflake/package.nix b/src/libflake/package.nix index 3fc96a20e58..ebd38e140d3 100644 --- a/src/libflake/package.nix +++ b/src/libflake/package.nix @@ -1,15 +1,16 @@ -{ lib -, mkMesonLibrary +{ + lib, + mkMesonLibrary, -, nix-util -, nix-store -, nix-fetchers -, nix-expr -, nlohmann_json + nix-util, + nix-store, + nix-fetchers, + nix-expr, + nlohmann_json, -# Configuration Options + # Configuration Options -, version + version, }: let diff --git a/src/libmain-c/package.nix b/src/libmain-c/package.nix index b96901bb46b..cf710e03b0d 100644 --- a/src/libmain-c/package.nix +++ b/src/libmain-c/package.nix @@ -1,14 +1,15 @@ -{ lib -, mkMesonLibrary +{ + lib, + mkMesonLibrary, -, nix-util-c -, nix-store -, nix-store-c -, nix-main + nix-util-c, + nix-store, + nix-store-c, + nix-main, -# Configuration Options + # Configuration Options -, version + version, }: let diff --git a/src/libmain/package.nix b/src/libmain/package.nix index 9a5b9e8c2df..046b505dfd4 100644 --- a/src/libmain/package.nix +++ b/src/libmain/package.nix @@ -1,14 +1,15 @@ -{ lib -, mkMesonLibrary +{ + lib, + mkMesonLibrary, -, openssl + openssl, -, nix-util -, nix-store + nix-util, + nix-store, -# Configuration Options + # Configuration Options -, version + version, }: let diff --git a/src/libstore-c/package.nix b/src/libstore-c/package.nix index c2413c3890d..89abeaab870 100644 --- a/src/libstore-c/package.nix +++ b/src/libstore-c/package.nix @@ -1,12 +1,13 @@ -{ lib -, mkMesonLibrary +{ + lib, + mkMesonLibrary, -, nix-util-c -, nix-store + nix-util-c, + nix-store, -# Configuration Options + # Configuration Options -, version + version, }: let diff --git a/src/libstore-test-support/package.nix b/src/libstore-test-support/package.nix index 5d3f41b3e8b..7cc29795c19 100644 --- a/src/libstore-test-support/package.nix +++ b/src/libstore-test-support/package.nix @@ -1,15 +1,16 @@ -{ lib -, mkMesonLibrary +{ + lib, + mkMesonLibrary, -, nix-util-test-support -, nix-store -, nix-store-c + nix-util-test-support, + nix-store, + nix-store-c, -, rapidcheck + rapidcheck, -# Configuration Options + # Configuration Options -, version + version, }: let diff --git a/src/libstore-tests/package.nix b/src/libstore-tests/package.nix index 3acf4e25c2c..670386c4a6f 100644 --- a/src/libstore-tests/package.nix +++ b/src/libstore-tests/package.nix @@ -1,21 +1,22 @@ -{ lib -, buildPackages -, stdenv -, mkMesonExecutable +{ + lib, + buildPackages, + stdenv, + mkMesonExecutable, -, nix-store -, nix-store-c -, nix-store-test-support -, sqlite + nix-store, + nix-store-c, + nix-store-test-support, + sqlite, -, rapidcheck -, gtest -, runCommand + rapidcheck, + gtest, + runCommand, -# Configuration Options + # Configuration Options -, version -, filesetToSource + version, + filesetToSource, }: let @@ -64,26 +65,33 @@ mkMesonExecutable (finalAttrs: { passthru = { tests = { - run = let - # Some data is shared with the functional tests: they create it, - # we consume it. - data = filesetToSource { - root = ../..; - fileset = lib.fileset.unions [ - ./data - ../../tests/functional/derivation - ]; - }; - in runCommand "${finalAttrs.pname}-run" { - meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages; - } (lib.optionalString stdenv.hostPlatform.isWindows '' - export HOME="$PWD/home-dir" - mkdir -p "$HOME" - '' + '' - export _NIX_TEST_UNIT_DATA=${data + "/src/libstore-tests/data"} - ${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage} - touch $out - ''); + run = + let + # Some data is shared with the functional tests: they create it, + # we consume it. + data = filesetToSource { + root = ../..; + fileset = lib.fileset.unions [ + ./data + ../../tests/functional/derivation + ]; + }; + in + runCommand "${finalAttrs.pname}-run" + { + meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages; + } + ( + lib.optionalString stdenv.hostPlatform.isWindows '' + export HOME="$PWD/home-dir" + mkdir -p "$HOME" + '' + + '' + export _NIX_TEST_UNIT_DATA=${data + "/src/libstore-tests/data"} + ${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage} + touch $out + '' + ); }; }; diff --git a/src/libstore/package.nix b/src/libstore/package.nix index 4fbaea4acc5..c982b44f0b7 100644 --- a/src/libstore/package.nix +++ b/src/libstore/package.nix @@ -1,25 +1,26 @@ -{ lib -, stdenv -, mkMesonLibrary +{ + lib, + stdenv, + mkMesonLibrary, -, unixtools -, darwin + unixtools, + darwin, -, nix-util -, boost -, curl -, aws-sdk-cpp -, libseccomp -, nlohmann_json -, sqlite + nix-util, + boost, + curl, + aws-sdk-cpp, + libseccomp, + nlohmann_json, + sqlite, -, busybox-sandbox-shell ? null + busybox-sandbox-shell ? null, -# Configuration Options + # Configuration Options -, version + version, -, embeddedSandboxShell ? stdenv.hostPlatform.isStatic + embeddedSandboxShell ? stdenv.hostPlatform.isStatic, }: let @@ -48,19 +49,20 @@ mkMesonLibrary (finalAttrs: { (fileset.fileFilter (file: file.hasExt "sql") ./.) ]; - nativeBuildInputs = - lib.optional embeddedSandboxShell unixtools.hexdump; + nativeBuildInputs = lib.optional embeddedSandboxShell unixtools.hexdump; - buildInputs = [ - boost - curl - sqlite - ] ++ lib.optional stdenv.hostPlatform.isLinux libseccomp + buildInputs = + [ + boost + curl + sqlite + ] + ++ lib.optional stdenv.hostPlatform.isLinux libseccomp # There have been issues building these dependencies ++ lib.optional stdenv.hostPlatform.isDarwin darwin.apple_sdk.libs.sandbox - ++ lib.optional (stdenv.hostPlatform == stdenv.buildPlatform && (stdenv.isLinux || stdenv.isDarwin)) - aws-sdk-cpp - ; + ++ lib.optional ( + stdenv.hostPlatform == stdenv.buildPlatform && (stdenv.isLinux || stdenv.isDarwin) + ) aws-sdk-cpp; propagatedBuildInputs = [ nix-util @@ -75,12 +77,14 @@ mkMesonLibrary (finalAttrs: { echo ${version} > ../../.version ''; - mesonFlags = [ - (lib.mesonEnable "seccomp-sandboxing" stdenv.hostPlatform.isLinux) - (lib.mesonBool "embedded-sandbox-shell" embeddedSandboxShell) - ] ++ lib.optionals stdenv.hostPlatform.isLinux [ - (lib.mesonOption "sandbox-shell" "${busybox-sandbox-shell}/bin/busybox") - ]; + mesonFlags = + [ + (lib.mesonEnable "seccomp-sandboxing" stdenv.hostPlatform.isLinux) + (lib.mesonBool "embedded-sandbox-shell" embeddedSandboxShell) + ] + ++ lib.optionals stdenv.hostPlatform.isLinux [ + (lib.mesonOption "sandbox-shell" "${busybox-sandbox-shell}/bin/busybox") + ]; env = { # Needed for Meson to find Boost. diff --git a/src/libutil-c/package.nix b/src/libutil-c/package.nix index f80e0b7f0a2..72f57d6f9c6 100644 --- a/src/libutil-c/package.nix +++ b/src/libutil-c/package.nix @@ -1,11 +1,12 @@ -{ lib -, mkMesonLibrary +{ + lib, + mkMesonLibrary, -, nix-util + nix-util, -# Configuration Options + # Configuration Options -, version + version, }: let diff --git a/src/libutil-test-support/package.nix b/src/libutil-test-support/package.nix index a8a239717a6..33cd5217def 100644 --- a/src/libutil-test-support/package.nix +++ b/src/libutil-test-support/package.nix @@ -1,14 +1,15 @@ -{ lib -, mkMesonLibrary +{ + lib, + mkMesonLibrary, -, nix-util -, nix-util-c + nix-util, + nix-util-c, -, rapidcheck + rapidcheck, -# Configuration Options + # Configuration Options -, version + version, }: let diff --git a/src/libutil-tests/package.nix b/src/libutil-tests/package.nix index 28769e11522..d89c544539e 100644 --- a/src/libutil-tests/package.nix +++ b/src/libutil-tests/package.nix @@ -1,19 +1,20 @@ -{ lib -, buildPackages -, stdenv -, mkMesonExecutable +{ + lib, + buildPackages, + stdenv, + mkMesonExecutable, -, nix-util -, nix-util-c -, nix-util-test-support + nix-util, + nix-util-c, + nix-util-test-support, -, rapidcheck -, gtest -, runCommand + rapidcheck, + gtest, + runCommand, -# Configuration Options + # Configuration Options -, version + version, }: let @@ -57,16 +58,22 @@ mkMesonExecutable (finalAttrs: { passthru = { tests = { - run = runCommand "${finalAttrs.pname}-run" { - meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages; - } (lib.optionalString stdenv.hostPlatform.isWindows '' - export HOME="$PWD/home-dir" - mkdir -p "$HOME" - '' + '' - export _NIX_TEST_UNIT_DATA=${./data} - ${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage} - touch $out - ''); + run = + runCommand "${finalAttrs.pname}-run" + { + meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages; + } + ( + lib.optionalString stdenv.hostPlatform.isWindows '' + export HOME="$PWD/home-dir" + mkdir -p "$HOME" + '' + + '' + export _NIX_TEST_UNIT_DATA=${./data} + ${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage} + touch $out + '' + ); }; }; diff --git a/src/libutil/package.nix b/src/libutil/package.nix index 679872a75c5..586119a6e5d 100644 --- a/src/libutil/package.nix +++ b/src/libutil/package.nix @@ -1,18 +1,19 @@ -{ lib -, stdenv -, mkMesonLibrary +{ + lib, + stdenv, + mkMesonLibrary, -, boost -, brotli -, libarchive -, libcpuid -, libsodium -, nlohmann_json -, openssl + boost, + brotli, + libarchive, + libcpuid, + libsodium, + nlohmann_json, + openssl, -# Configuration Options + # Configuration Options -, version + version, }: let @@ -43,8 +44,7 @@ mkMesonLibrary (finalAttrs: { brotli libsodium openssl - ] ++ lib.optional stdenv.hostPlatform.isx86_64 libcpuid - ; + ] ++ lib.optional stdenv.hostPlatform.isx86_64 libcpuid; propagatedBuildInputs = [ boost diff --git a/src/nix-channel/unpack-channel.nix b/src/nix-channel/unpack-channel.nix index 10515bc8b91..84e324a4d89 100644 --- a/src/nix-channel/unpack-channel.nix +++ b/src/nix-channel/unpack-channel.nix @@ -1,4 +1,8 @@ -{ name, channelName, src }: +{ + name, + channelName, + src, +}: derivation { builder = "builtin:unpack-channel"; diff --git a/src/nix-env/buildenv.nix b/src/nix-env/buildenv.nix index 0bac4c44b48..c8955a94e99 100644 --- a/src/nix-env/buildenv.nix +++ b/src/nix-env/buildenv.nix @@ -8,13 +8,15 @@ derivation { inherit manifest; # !!! grmbl, need structured data for passing this in a clean way. - derivations = - map (d: - [ (d.meta.active or "true") - (d.meta.priority or 5) - (builtins.length d.outputs) - ] ++ map (output: builtins.getAttr output d) d.outputs) - derivations; + derivations = map ( + d: + [ + (d.meta.active or "true") + (d.meta.priority or 5) + (builtins.length d.outputs) + ] + ++ map (output: builtins.getAttr output d) d.outputs + ) derivations; # Building user environments remotely just causes huge amounts of # network traffic, so don't do that. diff --git a/src/nix/package.nix b/src/nix/package.nix index 171621af917..89c52c3bb05 100644 --- a/src/nix/package.nix +++ b/src/nix/package.nix @@ -1,14 +1,15 @@ -{ lib -, mkMesonExecutable +{ + lib, + mkMesonExecutable, -, nix-store -, nix-expr -, nix-main -, nix-cmd + nix-store, + nix-expr, + nix-main, + nix-cmd, -# Configuration Options + # Configuration Options -, version + version, }: let @@ -20,64 +21,67 @@ mkMesonExecutable (finalAttrs: { inherit version; workDir = ./.; - fileset = fileset.unions ([ - ../../nix-meson-build-support - ./nix-meson-build-support - ../../.version - ./.version - ./meson.build - ./meson.options + fileset = fileset.unions ( + [ + ../../nix-meson-build-support + ./nix-meson-build-support + ../../.version + ./.version + ./meson.build + ./meson.options - # Symbolic links to other dirs - ## exes - ./build-remote - ./doc - ./nix-build - ./nix-channel - ./nix-collect-garbage - ./nix-copy-closure - ./nix-env - ./nix-instantiate - ./nix-store - ## dirs - ./scripts - ../../scripts - ./misc - ../../misc + # Symbolic links to other dirs + ## exes + ./build-remote + ./doc + ./nix-build + ./nix-channel + ./nix-collect-garbage + ./nix-copy-closure + ./nix-env + ./nix-instantiate + ./nix-store + ## dirs + ./scripts + ../../scripts + ./misc + ../../misc - # Doc nix files for --help - ../../doc/manual/generate-manpage.nix - ../../doc/manual/utils.nix - ../../doc/manual/generate-settings.nix - ../../doc/manual/generate-store-info.nix + # Doc nix files for --help + ../../doc/manual/generate-manpage.nix + ../../doc/manual/utils.nix + ../../doc/manual/generate-settings.nix + ../../doc/manual/generate-store-info.nix - # Other files to be included as string literals - ../nix-channel/unpack-channel.nix - ../nix-env/buildenv.nix - ./get-env.sh - ./help-stores.md - ../../doc/manual/source/store/types/index.md.in - ./profiles.md - ../../doc/manual/source/command-ref/files/profiles.md + # Other files to be included as string literals + ../nix-channel/unpack-channel.nix + ../nix-env/buildenv.nix + ./get-env.sh + ./help-stores.md + ../../doc/manual/source/store/types/index.md.in + ./profiles.md + ../../doc/manual/source/command-ref/files/profiles.md - # Files - ] ++ lib.concatMap - (dir: [ - (fileset.fileFilter (file: file.hasExt "cc") dir) - (fileset.fileFilter (file: file.hasExt "hh") dir) - (fileset.fileFilter (file: file.hasExt "md") dir) - ]) - [ - ./. - ../build-remote - ../nix-build - ../nix-channel - ../nix-collect-garbage - ../nix-copy-closure - ../nix-env - ../nix-instantiate - ../nix-store + # Files ] + ++ + lib.concatMap + (dir: [ + (fileset.fileFilter (file: file.hasExt "cc") dir) + (fileset.fileFilter (file: file.hasExt "hh") dir) + (fileset.fileFilter (file: file.hasExt "md") dir) + ]) + [ + ./. + ../build-remote + ../nix-build + ../nix-channel + ../nix-collect-garbage + ../nix-copy-closure + ../nix-env + ../nix-instantiate + ../nix-store + ] ); buildInputs = [ diff --git a/src/perl/package.nix b/src/perl/package.nix index 5ee0df13c9d..d95d13aa921 100644 --- a/src/perl/package.nix +++ b/src/perl/package.nix @@ -1,76 +1,82 @@ -{ lib -, stdenv -, mkMesonDerivation -, pkg-config -, perl -, perlPackages -, nix-store -, version -, curl -, bzip2 -, libsodium +{ + lib, + stdenv, + mkMesonDerivation, + pkg-config, + perl, + perlPackages, + nix-store, + version, + curl, + bzip2, + libsodium, }: let inherit (lib) fileset; in -perl.pkgs.toPerlModule (mkMesonDerivation (finalAttrs: { - pname = "nix-perl"; - inherit version; +perl.pkgs.toPerlModule ( + mkMesonDerivation (finalAttrs: { + pname = "nix-perl"; + inherit version; - workDir = ./.; - fileset = fileset.unions ([ - ./.version - ../../.version - ./MANIFEST - ./lib - ./meson.build - ./meson.options - ] ++ lib.optionals finalAttrs.doCheck [ - ./.yath.rc.in - ./t - ]); + workDir = ./.; + fileset = fileset.unions ( + [ + ./.version + ../../.version + ./MANIFEST + ./lib + ./meson.build + ./meson.options + ] + ++ lib.optionals finalAttrs.doCheck [ + ./.yath.rc.in + ./t + ] + ); - nativeBuildInputs = [ - pkg-config - perl - curl - ]; + nativeBuildInputs = [ + pkg-config + perl + curl + ]; - buildInputs = [ - nix-store - ] ++ finalAttrs.passthru.externalBuildInputs; + buildInputs = [ + nix-store + ] ++ finalAttrs.passthru.externalBuildInputs; - # Hack for sake of the dev shell - passthru.externalBuildInputs = [ - bzip2 - libsodium - ]; + # Hack for sake of the dev shell + passthru.externalBuildInputs = [ + bzip2 + libsodium + ]; - # `perlPackages.Test2Harness` is marked broken for Darwin - doCheck = !stdenv.isDarwin; + # `perlPackages.Test2Harness` is marked broken for Darwin + doCheck = !stdenv.isDarwin; - nativeCheckInputs = [ - perlPackages.Test2Harness - ]; + nativeCheckInputs = [ + perlPackages.Test2Harness + ]; - preConfigure = - # "Inline" .version so its not a symlink, and includes the suffix - '' - chmod u+w .version - echo ${finalAttrs.version} > .version - ''; + preConfigure = + # "Inline" .version so its not a symlink, and includes the suffix + '' + chmod u+w .version + echo ${finalAttrs.version} > .version + ''; - mesonFlags = [ - (lib.mesonOption "dbi_path" "${perlPackages.DBI}/${perl.libPrefix}") - (lib.mesonOption "dbd_sqlite_path" "${perlPackages.DBDSQLite}/${perl.libPrefix}") - (lib.mesonEnable "tests" finalAttrs.doCheck) - ]; + mesonFlags = [ + (lib.mesonOption "dbi_path" "${perlPackages.DBI}/${perl.libPrefix}") + (lib.mesonOption "dbd_sqlite_path" "${perlPackages.DBDSQLite}/${perl.libPrefix}") + (lib.mesonEnable "tests" finalAttrs.doCheck) + ]; - mesonCheckFlags = [ - "--print-errorlogs" - ]; + mesonCheckFlags = [ + "--print-errorlogs" + ]; - strictDeps = false; -})) + strictDeps = false; + }) +) diff --git a/tests/functional/big-derivation-attr.nix b/tests/functional/big-derivation-attr.nix index 35c1187f665..d370486d6c4 100644 --- a/tests/functional/big-derivation-attr.nix +++ b/tests/functional/big-derivation-attr.nix @@ -1,6 +1,25 @@ let sixteenBytes = "0123456789abcdef"; - times16 = s: builtins.concatStringsSep "" [s s s s s s s s s s s s s s s s]; + times16 = + s: + builtins.concatStringsSep "" [ + s + s + s + s + s + s + s + s + s + s + s + s + s + s + s + s + ]; exp = n: x: if n == 1 then x else times16 (exp (n - 1) x); sixteenMegabyte = exp 6 sixteenBytes; in diff --git a/tests/functional/build-hook-ca-fixed.nix b/tests/functional/build-hook-ca-fixed.nix index 0ce6d9b128b..3d2643c1321 100644 --- a/tests/functional/build-hook-ca-fixed.nix +++ b/tests/functional/build-hook-ca-fixed.nix @@ -4,24 +4,39 @@ with import ./config.nix; let - mkDerivation = args: - derivation ({ - inherit system; - builder = busybox; - args = ["sh" "-e" args.builder or (builtins.toFile "builder-${args.name}.sh" '' - if [ -e "$NIX_ATTRS_SH_FILE" ]; then source $NIX_ATTRS_SH_FILE; fi; - eval "$buildCommand" - '')]; - outputHashMode = "recursive"; - outputHashAlgo = "sha256"; - } // removeAttrs args ["builder" "meta" "passthru"]) - // { meta = args.meta or {}; passthru = args.passthru or {}; }; + mkDerivation = + args: + derivation ( + { + inherit system; + builder = busybox; + args = [ + "sh" + "-e" + args.builder or (builtins.toFile "builder-${args.name}.sh" '' + if [ -e "$NIX_ATTRS_SH_FILE" ]; then source $NIX_ATTRS_SH_FILE; fi; + eval "$buildCommand" + '') + ]; + outputHashMode = "recursive"; + outputHashAlgo = "sha256"; + } + // removeAttrs args [ + "builder" + "meta" + "passthru" + ] + ) + // { + meta = args.meta or { }; + passthru = args.passthru or { }; + }; input1 = mkDerivation { shell = busybox; name = "build-remote-input-1"; buildCommand = "echo hi-input1; echo FOO > $out"; - requiredSystemFeatures = ["foo"]; + requiredSystemFeatures = [ "foo" ]; outputHash = "sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="; }; @@ -29,7 +44,7 @@ let shell = busybox; name = "build-remote-input-2"; buildCommand = "echo hi; echo BAR > $out"; - requiredSystemFeatures = ["bar"]; + requiredSystemFeatures = [ "bar" ]; outputHash = "sha256-XArauVH91AVwP9hBBQNlkX9ccuPpSYx9o0zeIHb6e+Q="; }; @@ -41,21 +56,20 @@ let read x < ${input2} echo $x BAZ > $out ''; - requiredSystemFeatures = ["baz"]; + requiredSystemFeatures = [ "baz" ]; outputHash = "sha256-daKAcPp/+BYMQsVi/YYMlCKoNAxCNDsaivwSHgQqD2s="; }; in - mkDerivation { - shell = busybox; - name = "build-remote"; - passthru = { inherit input1 input2 input3; }; - buildCommand = - '' - read x < ${input1} - read y < ${input3} - echo "$x $y" > $out - ''; - outputHash = "sha256-5SxbkUw6xe2l9TE1uwCvTtTDysD1vhRor38OtDF0LqQ="; - } +mkDerivation { + shell = busybox; + name = "build-remote"; + passthru = { inherit input1 input2 input3; }; + buildCommand = '' + read x < ${input1} + read y < ${input3} + echo "$x $y" > $out + ''; + outputHash = "sha256-5SxbkUw6xe2l9TE1uwCvTtTDysD1vhRor38OtDF0LqQ="; +} diff --git a/tests/functional/build-hook.nix b/tests/functional/build-hook.nix index 99a13aee483..45a2a84d6d4 100644 --- a/tests/functional/build-hook.nix +++ b/tests/functional/build-hook.nix @@ -1,39 +1,61 @@ -{ busybox, contentAddressed ? false }: +{ + busybox, + contentAddressed ? false, +}: with import ./config.nix; let - caArgs = if contentAddressed then { - outputHashMode = "recursive"; - outputHashAlgo = "sha256"; - __contentAddressed = true; - } else {}; - - mkDerivation = args: - derivation ({ - inherit system; - builder = busybox; - args = ["sh" "-e" args.builder or (builtins.toFile "builder-${args.name}.sh" '' - if [ -e "$NIX_ATTRS_SH_FILE" ]; then source $NIX_ATTRS_SH_FILE; fi; - eval "$buildCommand" - '')]; - } // removeAttrs args ["builder" "meta" "passthru"] - // caArgs) - // { meta = args.meta or {}; passthru = args.passthru or {}; }; + caArgs = + if contentAddressed then + { + outputHashMode = "recursive"; + outputHashAlgo = "sha256"; + __contentAddressed = true; + } + else + { }; + + mkDerivation = + args: + derivation ( + { + inherit system; + builder = busybox; + args = [ + "sh" + "-e" + args.builder or (builtins.toFile "builder-${args.name}.sh" '' + if [ -e "$NIX_ATTRS_SH_FILE" ]; then source $NIX_ATTRS_SH_FILE; fi; + eval "$buildCommand" + '') + ]; + } + // removeAttrs args [ + "builder" + "meta" + "passthru" + ] + // caArgs + ) + // { + meta = args.meta or { }; + passthru = args.passthru or { }; + }; input1 = mkDerivation { shell = busybox; name = "build-remote-input-1"; buildCommand = "echo hi-input1; echo FOO > $out"; - requiredSystemFeatures = ["foo"]; + requiredSystemFeatures = [ "foo" ]; }; input2 = mkDerivation { shell = busybox; name = "build-remote-input-2"; buildCommand = "echo hi; echo BAR > $out"; - requiredSystemFeatures = ["bar"]; + requiredSystemFeatures = [ "bar" ]; }; input3 = mkDerivation { @@ -44,19 +66,18 @@ let read x < ${input2} echo $x BAZ > $out ''; - requiredSystemFeatures = ["baz"]; + requiredSystemFeatures = [ "baz" ]; }; in - mkDerivation { - shell = busybox; - name = "build-remote"; - passthru = { inherit input1 input2 input3; }; - buildCommand = - '' - read x < ${input1} - read y < ${input3} - echo "$x $y" > $out - ''; - } +mkDerivation { + shell = busybox; + name = "build-remote"; + passthru = { inherit input1 input2 input3; }; + buildCommand = '' + read x < ${input1} + read y < ${input3} + echo "$x $y" > $out + ''; +} diff --git a/tests/functional/ca-shell.nix b/tests/functional/ca-shell.nix index 36e1d1526f3..69ce6b6f17e 100644 --- a/tests/functional/ca-shell.nix +++ b/tests/functional/ca-shell.nix @@ -1 +1,5 @@ -{ inNixShell ? false, ... }@args: import ./shell.nix (args // { contentAddressed = true; }) +{ + inNixShell ? false, + ... +}@args: +import ./shell.nix (args // { contentAddressed = true; }) diff --git a/tests/functional/ca/content-addressed.nix b/tests/functional/ca/content-addressed.nix index 2559c562f92..6ed9c185b62 100644 --- a/tests/functional/ca/content-addressed.nix +++ b/tests/functional/ca/content-addressed.nix @@ -1,13 +1,21 @@ with import ./config.nix; -let mkCADerivation = args: mkDerivation ({ - __contentAddressed = true; - outputHashMode = "recursive"; - outputHashAlgo = "sha256"; -} // args); +let + mkCADerivation = + args: + mkDerivation ( + { + __contentAddressed = true; + outputHashMode = "recursive"; + outputHashAlgo = "sha256"; + } + // args + ); in -{ seed ? 0 }: +{ + seed ? 0, +}: # A simple content-addressed derivation. # The derivation can be arbitrarily modified by passing a different `seed`, # but the output will always be the same @@ -23,7 +31,11 @@ rec { }; rootCA = mkCADerivation { name = "rootCA"; - outputs = [ "out" "dev" "foo" ]; + outputs = [ + "out" + "dev" + "foo" + ]; buildCommand = '' echo "building a CA derivation" echo "The seed is ${toString seed}" diff --git a/tests/functional/ca/flake.nix b/tests/functional/ca/flake.nix index 332c92a6792..28a27c4b31d 100644 --- a/tests/functional/ca/flake.nix +++ b/tests/functional/ca/flake.nix @@ -1,3 +1,3 @@ { - outputs = { self }: import ./content-addressed.nix {}; + outputs = { self }: import ./content-addressed.nix { }; } diff --git a/tests/functional/ca/nondeterministic.nix b/tests/functional/ca/nondeterministic.nix index d6d099a3e0e..2af26f0ac2e 100644 --- a/tests/functional/ca/nondeterministic.nix +++ b/tests/functional/ca/nondeterministic.nix @@ -1,10 +1,16 @@ with import ./config.nix; -let mkCADerivation = args: mkDerivation ({ - __contentAddressed = true; - outputHashMode = "recursive"; - outputHashAlgo = "sha256"; -} // args); +let + mkCADerivation = + args: + mkDerivation ( + { + __contentAddressed = true; + outputHashMode = "recursive"; + outputHashAlgo = "sha256"; + } + // args + ); in rec { @@ -15,13 +21,15 @@ rec { echo $(date) > $out/current-time ''; }; - dep = seed: mkCADerivation { - name = "dep"; - inherit seed; - buildCommand = '' - echo ${currentTime} > $out - ''; - }; + dep = + seed: + mkCADerivation { + name = "dep"; + inherit seed; + buildCommand = '' + echo ${currentTime} > $out + ''; + }; dep1 = dep 1; dep2 = dep 2; toplevel = mkCADerivation { @@ -32,4 +40,3 @@ rec { ''; }; } - diff --git a/tests/functional/ca/racy.nix b/tests/functional/ca/racy.nix index 555a1548464..cbc0e1643a7 100644 --- a/tests/functional/ca/racy.nix +++ b/tests/functional/ca/racy.nix @@ -1,7 +1,6 @@ # A derivation that would certainly fail if several builders tried to # build it at once. - with import ./config.nix; mkDerivation { diff --git a/tests/functional/check-refs.nix b/tests/functional/check-refs.nix index 89690e456c1..471d9575360 100644 --- a/tests/functional/check-refs.nix +++ b/tests/functional/check-refs.nix @@ -2,11 +2,16 @@ with import ./config.nix; rec { - dep = import ./dependencies.nix {}; + dep = import ./dependencies.nix { }; - makeTest = nr: args: mkDerivation ({ - name = "check-refs-" + toString nr; - } // args); + makeTest = + nr: args: + mkDerivation ( + { + name = "check-refs-" + toString nr; + } + // args + ); src = builtins.toFile "aux-ref" "bla bla"; @@ -22,31 +27,31 @@ rec { test3 = makeTest 3 { builder = builtins.toFile "builder.sh" "mkdir $out; ln -s $dep $out/link"; - allowedReferences = []; + allowedReferences = [ ]; inherit dep; }; test4 = makeTest 4 { builder = builtins.toFile "builder.sh" "mkdir $out; ln -s $dep $out/link"; - allowedReferences = [dep]; + allowedReferences = [ dep ]; inherit dep; }; test5 = makeTest 5 { builder = builtins.toFile "builder.sh" "mkdir $out"; - allowedReferences = []; + allowedReferences = [ ]; inherit dep; }; test6 = makeTest 6 { builder = builtins.toFile "builder.sh" "mkdir $out; ln -s $out $out/link"; - allowedReferences = []; + allowedReferences = [ ]; inherit dep; }; test7 = makeTest 7 { builder = builtins.toFile "builder.sh" "mkdir $out; ln -s $out $out/link"; - allowedReferences = ["out"]; + allowedReferences = [ "out" ]; inherit dep; }; @@ -58,19 +63,19 @@ rec { test9 = makeTest 9 { builder = builtins.toFile "builder.sh" "mkdir $out; ln -s $dep $out/link"; inherit dep; - disallowedReferences = [dep]; + disallowedReferences = [ dep ]; }; test10 = makeTest 10 { builder = builtins.toFile "builder.sh" "mkdir $out; echo $test5; ln -s $dep $out/link"; inherit dep test5; - disallowedReferences = [test5]; + disallowedReferences = [ test5 ]; }; test11 = makeTest 11 { __structuredAttrs = true; unsafeDiscardReferences.out = true; - outputChecks.out.allowedReferences = []; + outputChecks.out.allowedReferences = [ ]; buildCommand = ''echo ${dep} > "''${outputs[out]}"''; }; diff --git a/tests/functional/check-reqs.nix b/tests/functional/check-reqs.nix index 41436cb48e0..3cca761846a 100644 --- a/tests/functional/check-reqs.nix +++ b/tests/functional/check-reqs.nix @@ -22,36 +22,48 @@ rec { ''; }; - makeTest = nr: allowreqs: mkDerivation { - name = "check-reqs-" + toString nr; - inherit deps; - builder = builtins.toFile "builder.sh" '' - mkdir $out - ln -s $deps $out/depdir1 - ''; - allowedRequisites = allowreqs; - }; + makeTest = + nr: allowreqs: + mkDerivation { + name = "check-reqs-" + toString nr; + inherit deps; + builder = builtins.toFile "builder.sh" '' + mkdir $out + ln -s $deps $out/depdir1 + ''; + allowedRequisites = allowreqs; + }; # When specifying all the requisites, the build succeeds. - test1 = makeTest 1 [ dep1 dep2 deps ]; + test1 = makeTest 1 [ + dep1 + dep2 + deps + ]; # But missing anything it fails. - test2 = makeTest 2 [ dep2 deps ]; - test3 = makeTest 3 [ dep1 deps ]; + test2 = makeTest 2 [ + dep2 + deps + ]; + test3 = makeTest 3 [ + dep1 + deps + ]; test4 = makeTest 4 [ deps ]; - test5 = makeTest 5 []; + test5 = makeTest 5 [ ]; test6 = mkDerivation { name = "check-reqs"; inherit deps; builder = builtins.toFile "builder.sh" "mkdir $out; ln -s $deps $out/depdir1"; - disallowedRequisites = [dep1]; + disallowedRequisites = [ dep1 ]; }; test7 = mkDerivation { name = "check-reqs"; inherit deps; builder = builtins.toFile "builder.sh" "mkdir $out; ln -s $deps $out/depdir1"; - disallowedRequisites = [test1]; + disallowedRequisites = [ test1 ]; }; } diff --git a/tests/functional/check.nix b/tests/functional/check.nix index ddab8eea9cb..d83c28ca2ee 100644 --- a/tests/functional/check.nix +++ b/tests/functional/check.nix @@ -1,4 +1,6 @@ -{checkBuildId ? 0}: +{ + checkBuildId ? 0, +}: with import ./config.nix; @@ -6,41 +8,38 @@ with import ./config.nix; nondeterministic = mkDerivation { inherit checkBuildId; name = "nondeterministic"; - buildCommand = - '' - mkdir $out - date +%s.%N > $out/date - echo "CHECK_TMPDIR=$TMPDIR" - echo "checkBuildId=$checkBuildId" - echo "$checkBuildId" > $TMPDIR/checkBuildId - ''; + buildCommand = '' + mkdir $out + date +%s.%N > $out/date + echo "CHECK_TMPDIR=$TMPDIR" + echo "checkBuildId=$checkBuildId" + echo "$checkBuildId" > $TMPDIR/checkBuildId + ''; }; deterministic = mkDerivation { inherit checkBuildId; name = "deterministic"; - buildCommand = - '' - mkdir $out - echo date > $out/date - echo "CHECK_TMPDIR=$TMPDIR" - echo "checkBuildId=$checkBuildId" - echo "$checkBuildId" > $TMPDIR/checkBuildId - ''; + buildCommand = '' + mkdir $out + echo date > $out/date + echo "CHECK_TMPDIR=$TMPDIR" + echo "checkBuildId=$checkBuildId" + echo "$checkBuildId" > $TMPDIR/checkBuildId + ''; }; failed = mkDerivation { inherit checkBuildId; name = "failed"; - buildCommand = - '' - mkdir $out - echo date > $out/date - echo "CHECK_TMPDIR=$TMPDIR" - echo "checkBuildId=$checkBuildId" - echo "$checkBuildId" > $TMPDIR/checkBuildId - false - ''; + buildCommand = '' + mkdir $out + echo date > $out/date + echo "CHECK_TMPDIR=$TMPDIR" + echo "checkBuildId=$checkBuildId" + echo "$checkBuildId" > $TMPDIR/checkBuildId + false + ''; }; hashmismatch = import { diff --git a/tests/functional/dependencies.nix b/tests/functional/dependencies.nix index 4ff29227fd3..570ea743135 100644 --- a/tests/functional/dependencies.nix +++ b/tests/functional/dependencies.nix @@ -1,4 +1,6 @@ -{ hashInvalidator ? "" }: +{ + hashInvalidator ? "", +}: with import ./config.nix; let diff --git a/tests/functional/derivation/advanced-attributes-defaults.nix b/tests/functional/derivation/advanced-attributes-defaults.nix index 51a8d0e7e1a..d466003b00d 100644 --- a/tests/functional/derivation/advanced-attributes-defaults.nix +++ b/tests/functional/derivation/advanced-attributes-defaults.nix @@ -2,5 +2,8 @@ derivation { name = "advanced-attributes-defaults"; system = "my-system"; builder = "/bin/bash"; - args = [ "-c" "echo hello > $out" ]; + args = [ + "-c" + "echo hello > $out" + ]; } diff --git a/tests/functional/derivation/advanced-attributes-structured-attrs-defaults.nix b/tests/functional/derivation/advanced-attributes-structured-attrs-defaults.nix index 0c13a76911f..3c6ad4900d6 100644 --- a/tests/functional/derivation/advanced-attributes-structured-attrs-defaults.nix +++ b/tests/functional/derivation/advanced-attributes-structured-attrs-defaults.nix @@ -2,7 +2,13 @@ derivation { name = "advanced-attributes-structured-attrs-defaults"; system = "my-system"; builder = "/bin/bash"; - args = [ "-c" "echo hello > $out" ]; - outputs = [ "out" "dev" ]; + args = [ + "-c" + "echo hello > $out" + ]; + outputs = [ + "out" + "dev" + ]; __structuredAttrs = true; } diff --git a/tests/functional/derivation/advanced-attributes-structured-attrs.nix b/tests/functional/derivation/advanced-attributes-structured-attrs.nix index 0044b65fd41..4c596be45e9 100644 --- a/tests/functional/derivation/advanced-attributes-structured-attrs.nix +++ b/tests/functional/derivation/advanced-attributes-structured-attrs.nix @@ -4,42 +4,58 @@ let inherit system; name = "foo"; builder = "/bin/bash"; - args = ["-c" "echo foo > $out"]; + args = [ + "-c" + "echo foo > $out" + ]; }; bar = derivation { inherit system; name = "bar"; builder = "/bin/bash"; - args = ["-c" "echo bar > $out"]; + args = [ + "-c" + "echo bar > $out" + ]; }; in derivation { inherit system; name = "advanced-attributes-structured-attrs"; builder = "/bin/bash"; - args = [ "-c" "echo hello > $out" ]; + args = [ + "-c" + "echo hello > $out" + ]; __sandboxProfile = "sandcastle"; __noChroot = true; - __impureHostDeps = ["/usr/bin/ditto"]; - impureEnvVars = ["UNICORN"]; + __impureHostDeps = [ "/usr/bin/ditto" ]; + impureEnvVars = [ "UNICORN" ]; __darwinAllowLocalNetworking = true; - outputs = [ "out" "bin" "dev" ]; + outputs = [ + "out" + "bin" + "dev" + ]; __structuredAttrs = true; outputChecks = { out = { - allowedReferences = [foo]; - allowedRequisites = [foo]; + allowedReferences = [ foo ]; + allowedRequisites = [ foo ]; }; bin = { - disallowedReferences = [bar]; - disallowedRequisites = [bar]; + disallowedReferences = [ bar ]; + disallowedRequisites = [ bar ]; }; dev = { maxSize = 789; maxClosureSize = 5909; }; }; - requiredSystemFeatures = ["rainbow" "uid-range"]; + requiredSystemFeatures = [ + "rainbow" + "uid-range" + ]; preferLocalBuild = true; allowSubstitutes = false; } diff --git a/tests/functional/derivation/advanced-attributes.nix b/tests/functional/derivation/advanced-attributes.nix index ff680c5677f..7f365ce65e2 100644 --- a/tests/functional/derivation/advanced-attributes.nix +++ b/tests/functional/derivation/advanced-attributes.nix @@ -4,30 +4,42 @@ let inherit system; name = "foo"; builder = "/bin/bash"; - args = ["-c" "echo foo > $out"]; + args = [ + "-c" + "echo foo > $out" + ]; }; bar = derivation { inherit system; name = "bar"; builder = "/bin/bash"; - args = ["-c" "echo bar > $out"]; + args = [ + "-c" + "echo bar > $out" + ]; }; in derivation { inherit system; name = "advanced-attributes"; builder = "/bin/bash"; - args = [ "-c" "echo hello > $out" ]; + args = [ + "-c" + "echo hello > $out" + ]; __sandboxProfile = "sandcastle"; __noChroot = true; - __impureHostDeps = ["/usr/bin/ditto"]; - impureEnvVars = ["UNICORN"]; + __impureHostDeps = [ "/usr/bin/ditto" ]; + impureEnvVars = [ "UNICORN" ]; __darwinAllowLocalNetworking = true; - allowedReferences = [foo]; - allowedRequisites = [foo]; - disallowedReferences = [bar]; - disallowedRequisites = [bar]; - requiredSystemFeatures = ["rainbow" "uid-range"]; + allowedReferences = [ foo ]; + allowedRequisites = [ foo ]; + disallowedReferences = [ bar ]; + disallowedRequisites = [ bar ]; + requiredSystemFeatures = [ + "rainbow" + "uid-range" + ]; preferLocalBuild = true; allowSubstitutes = false; } diff --git a/tests/functional/dyn-drv/recursive-mod-json.nix b/tests/functional/dyn-drv/recursive-mod-json.nix index c6a24ca4f3b..2d46e4e2e02 100644 --- a/tests/functional/dyn-drv/recursive-mod-json.nix +++ b/tests/functional/dyn-drv/recursive-mod-json.nix @@ -1,6 +1,8 @@ with import ./config.nix; -let innerName = "foo"; in +let + innerName = "foo"; +in mkDerivation rec { name = "${innerName}.drv"; diff --git a/tests/functional/export-graph.nix b/tests/functional/export-graph.nix index 64fe36bd1ef..5078eec8319 100644 --- a/tests/functional/export-graph.nix +++ b/tests/functional/export-graph.nix @@ -2,28 +2,33 @@ with import ./config.nix; rec { - printRefs = - '' - echo $exportReferencesGraph - while read path; do - read drv - read nrRefs - echo "$path has $nrRefs references" - echo "$path" >> $out - for ((n = 0; n < $nrRefs; n++)); do read ref; echo "ref $ref"; test -e "$ref"; done - done < refs - ''; + printRefs = '' + echo $exportReferencesGraph + while read path; do + read drv + read nrRefs + echo "$path has $nrRefs references" + echo "$path" >> $out + for ((n = 0; n < $nrRefs; n++)); do read ref; echo "ref $ref"; test -e "$ref"; done + done < refs + ''; foo."bar.runtimeGraph" = mkDerivation { name = "dependencies"; builder = builtins.toFile "build-graph-builder" "${printRefs}"; - exportReferencesGraph = ["refs" (import ./dependencies.nix {})]; + exportReferencesGraph = [ + "refs" + (import ./dependencies.nix { }) + ]; }; foo."bar.buildGraph" = mkDerivation { name = "dependencies"; builder = builtins.toFile "build-graph-builder" "${printRefs}"; - exportReferencesGraph = ["refs" (import ./dependencies.nix {}).drvPath]; + exportReferencesGraph = [ + "refs" + (import ./dependencies.nix { }).drvPath + ]; }; } diff --git a/tests/functional/failing.nix b/tests/functional/failing.nix index d25e2d6b62b..8abae1856cf 100644 --- a/tests/functional/failing.nix +++ b/tests/functional/failing.nix @@ -2,16 +2,29 @@ with import ./config.nix; let - mkDerivation = args: - derivation ({ - inherit system; - builder = busybox; - args = ["sh" "-e" args.builder or (builtins.toFile "builder-${args.name}.sh" '' - if [ -e "$NIX_ATTRS_SH_FILE" ]; then source $NIX_ATTRS_SH_FILE; fi; - eval "$buildCommand" - '')]; - } // removeAttrs args ["builder" "meta"]) - // { meta = args.meta or {}; }; + mkDerivation = + args: + derivation ( + { + inherit system; + builder = busybox; + args = [ + "sh" + "-e" + args.builder or (builtins.toFile "builder-${args.name}.sh" '' + if [ -e "$NIX_ATTRS_SH_FILE" ]; then source $NIX_ATTRS_SH_FILE; fi; + eval "$buildCommand" + '') + ]; + } + // removeAttrs args [ + "builder" + "meta" + ] + ) + // { + meta = args.meta or { }; + }; in { diff --git a/tests/functional/filter-source.nix b/tests/functional/filter-source.nix index 9071636394a..7bad263f842 100644 --- a/tests/functional/filter-source.nix +++ b/tests/functional/filter-source.nix @@ -4,9 +4,12 @@ mkDerivation { name = "filter"; builder = builtins.toFile "builder" "ln -s $input $out"; input = - let filter = path: type: - type != "symlink" - && baseNameOf path != "foo" - && !((import ./lang/lib.nix).hasSuffix ".bak" (baseNameOf path)); - in builtins.filterSource filter ((builtins.getEnv "TEST_ROOT") + "/filterin"); + let + filter = + path: type: + type != "symlink" + && baseNameOf path != "foo" + && !((import ./lang/lib.nix).hasSuffix ".bak" (baseNameOf path)); + in + builtins.filterSource filter ((builtins.getEnv "TEST_ROOT") + "/filterin"); } diff --git a/tests/functional/fixed.nix b/tests/functional/fixed.nix index 9f1ef3b61fe..eab3ee7073d 100644 --- a/tests/functional/fixed.nix +++ b/tests/functional/fixed.nix @@ -2,15 +2,20 @@ with import ./config.nix; rec { - f2 = dummy: builder: mode: algo: hash: mkDerivation { - name = "fixed"; - inherit builder; - outputHashMode = mode; - outputHashAlgo = algo; - outputHash = hash; - inherit dummy; - impureEnvVars = ["IMPURE_VAR1" "IMPURE_VAR2"]; - }; + f2 = + dummy: builder: mode: algo: hash: + mkDerivation { + name = "fixed"; + inherit builder; + outputHashMode = mode; + outputHashAlgo = algo; + outputHash = hash; + inherit dummy; + impureEnvVars = [ + "IMPURE_VAR1" + "IMPURE_VAR2" + ]; + }; f = f2 ""; @@ -37,7 +42,8 @@ rec { ]; sameAsAdd = - f ./fixed.builder2.sh "recursive" "sha256" "1ixr6yd3297ciyp9im522dfxpqbkhcw0pylkb2aab915278fqaik"; + f ./fixed.builder2.sh "recursive" "sha256" + "1ixr6yd3297ciyp9im522dfxpqbkhcw0pylkb2aab915278fqaik"; bad = [ (f ./fixed.builder1.sh "flat" "md5" "0ddd8be4b179a529afa5f2ffae4b9858") diff --git a/tests/functional/fod-failing.nix b/tests/functional/fod-failing.nix index 37c04fe12f8..0de676c1536 100644 --- a/tests/functional/fod-failing.nix +++ b/tests/functional/fod-failing.nix @@ -2,38 +2,34 @@ with import ./config.nix; rec { x1 = mkDerivation { name = "x1"; - builder = builtins.toFile "builder.sh" - '' - echo $name > $out - ''; + builder = builtins.toFile "builder.sh" '' + echo $name > $out + ''; outputHashMode = "recursive"; outputHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; }; x2 = mkDerivation { name = "x2"; - builder = builtins.toFile "builder.sh" - '' - echo $name > $out - ''; + builder = builtins.toFile "builder.sh" '' + echo $name > $out + ''; outputHashMode = "recursive"; outputHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; }; x3 = mkDerivation { name = "x3"; - builder = builtins.toFile "builder.sh" - '' - echo $name > $out - ''; + builder = builtins.toFile "builder.sh" '' + echo $name > $out + ''; outputHashMode = "recursive"; outputHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; }; x4 = mkDerivation { name = "x4"; inherit x2 x3; - builder = builtins.toFile "builder.sh" - '' - echo $x2 $x3 - exit 1 - ''; + builder = builtins.toFile "builder.sh" '' + echo $x2 $x3 + exit 1 + ''; }; } diff --git a/tests/functional/gc-concurrent.nix b/tests/functional/gc-concurrent.nix index 0aba1f98307..d7483d88f12 100644 --- a/tests/functional/gc-concurrent.nix +++ b/tests/functional/gc-concurrent.nix @@ -1,6 +1,8 @@ with import ./config.nix; -{ lockFifo ? null }: +{ + lockFifo ? null, +}: rec { diff --git a/tests/functional/hash-check.nix b/tests/functional/hash-check.nix index 4a8e9b8a8df..7a48a620b79 100644 --- a/tests/functional/hash-check.nix +++ b/tests/functional/hash-check.nix @@ -4,14 +4,22 @@ let { name = "dependencies-input-1"; system = "i086-msdos"; builder = "/bar/sh"; - args = ["-e" "-x" ./dummy]; + args = [ + "-e" + "-x" + ./dummy + ]; }; input2 = derivation { name = "dependencies-input-2"; system = "i086-msdos"; builder = "/bar/sh"; - args = ["-e" "-x" ./dummy]; + args = [ + "-e" + "-x" + ./dummy + ]; outputHashMode = "recursive"; outputHashAlgo = "md5"; outputHash = "ffffffffffffffffffffffffffffffff"; @@ -21,9 +29,13 @@ let { name = "dependencies"; system = "i086-msdos"; builder = "/bar/sh"; - args = ["-e" "-x" (./dummy + "/FOOBAR/../.")]; + args = [ + "-e" + "-x" + (./dummy + "/FOOBAR/../.") + ]; input1 = input1 + "/."; inherit input2; }; -} \ No newline at end of file +} diff --git a/tests/functional/hermetic.nix b/tests/functional/hermetic.nix index d1dccdff3d5..a5071466474 100644 --- a/tests/functional/hermetic.nix +++ b/tests/functional/hermetic.nix @@ -1,31 +1,51 @@ -{ busybox -, seed -# If we want the final derivation output to have references to its -# dependencies. Some tests need/want this, other don't. -, withFinalRefs ? false +{ + busybox, + seed, + # If we want the final derivation output to have references to its + # dependencies. Some tests need/want this, other don't. + withFinalRefs ? false, }: with import ./config.nix; let contentAddressedByDefault = builtins.getEnv "NIX_TESTS_CA_BY_DEFAULT" == "1"; - caArgs = if contentAddressedByDefault then { - __contentAddressed = true; - outputHashMode = "recursive"; - outputHashAlgo = "sha256"; - } else {}; + caArgs = + if contentAddressedByDefault then + { + __contentAddressed = true; + outputHashMode = "recursive"; + outputHashAlgo = "sha256"; + } + else + { }; - mkDerivation = args: - derivation ({ - inherit system; - builder = busybox; - args = ["sh" "-e" args.builder or (builtins.toFile "builder-${args.name}.sh" '' - if [ -e "$NIX_ATTRS_SH_FILE" ]; then source $NIX_ATTRS_SH_FILE; fi; - eval "$buildCommand" - '')]; - } // removeAttrs args ["builder" "meta" "passthru"] - // caArgs) - // { meta = args.meta or {}; passthru = args.passthru or {}; }; + mkDerivation = + args: + derivation ( + { + inherit system; + builder = busybox; + args = [ + "sh" + "-e" + args.builder or (builtins.toFile "builder-${args.name}.sh" '' + if [ -e "$NIX_ATTRS_SH_FILE" ]; then source $NIX_ATTRS_SH_FILE; fi; + eval "$buildCommand" + '') + ]; + } + // removeAttrs args [ + "builder" + "meta" + "passthru" + ] + // caArgs + ) + // { + meta = args.meta or { }; + passthru = args.passthru or { }; + }; input1 = mkDerivation { shell = busybox; @@ -51,14 +71,15 @@ let in - mkDerivation { - shell = busybox; - name = "hermetic"; - passthru = { inherit input1 input2 input3; }; - buildCommand = - '' - read x < ${input1} - read y < ${input3} - echo ${if (builtins.trace withFinalRefs withFinalRefs) then "${input1} ${input3}" else ""} "$x $y" > $out - ''; - } +mkDerivation { + shell = busybox; + name = "hermetic"; + passthru = { inherit input1 input2 input3; }; + buildCommand = '' + read x < ${input1} + read y < ${input3} + echo ${ + if (builtins.trace withFinalRefs withFinalRefs) then "${input1} ${input3}" else "" + } "$x $y" > $out + ''; +} diff --git a/tests/functional/ifd.nix b/tests/functional/ifd.nix index d0b9b54add0..b8c04f72cac 100644 --- a/tests/functional/ifd.nix +++ b/tests/functional/ifd.nix @@ -1,10 +1,8 @@ with import ./config.nix; -import ( - mkDerivation { - name = "foo"; - bla = import ./dependencies.nix {}; - buildCommand = " +import (mkDerivation { + name = "foo"; + bla = import ./dependencies.nix { }; + buildCommand = " echo \\\"hi\\\" > $out "; - } -) +}) diff --git a/tests/functional/import-from-derivation.nix b/tests/functional/import-from-derivation.nix index 770dd86cf73..600f448a6f9 100644 --- a/tests/functional/import-from-derivation.nix +++ b/tests/functional/import-from-derivation.nix @@ -3,10 +3,9 @@ with import ; rec { bar = mkDerivation { name = "bar"; - builder = builtins.toFile "builder.sh" - '' - echo 'builtins.add 123 456' > $out - ''; + builder = builtins.toFile "builder.sh" '' + echo 'builtins.add 123 456' > $out + ''; }; value = @@ -16,19 +15,17 @@ rec { result = mkDerivation { name = "foo"; - builder = builtins.toFile "builder.sh" - '' - echo -n FOO${toString value} > $out - ''; + builder = builtins.toFile "builder.sh" '' + echo -n FOO${toString value} > $out + ''; }; addPath = mkDerivation { name = "add-path"; src = builtins.filterSource (path: type: true) result; - builder = builtins.toFile "builder.sh" - '' - echo -n BLA$(cat $src) > $out - ''; + builder = builtins.toFile "builder.sh" '' + echo -n BLA$(cat $src) > $out + ''; }; step1 = mkDerivation { diff --git a/tests/functional/impure-derivations.nix b/tests/functional/impure-derivations.nix index 98547e6c1d6..806f20577d3 100644 --- a/tests/functional/impure-derivations.nix +++ b/tests/functional/impure-derivations.nix @@ -4,60 +4,58 @@ rec { impure = mkDerivation { name = "impure"; - outputs = [ "out" "stuff" ]; - buildCommand = - '' - echo impure - x=$(< $TEST_ROOT/counter) - mkdir $out $stuff - echo $x > $out/n - ln -s $out/n $stuff/bla - printf $((x + 1)) > $TEST_ROOT/counter - ''; + outputs = [ + "out" + "stuff" + ]; + buildCommand = '' + echo impure + x=$(< $TEST_ROOT/counter) + mkdir $out $stuff + echo $x > $out/n + ln -s $out/n $stuff/bla + printf $((x + 1)) > $TEST_ROOT/counter + ''; __impure = true; impureEnvVars = [ "TEST_ROOT" ]; }; impureOnImpure = mkDerivation { name = "impure-on-impure"; - buildCommand = - '' - echo impure-on-impure - x=$(< ${impure}/n) - mkdir $out - printf X$x > $out/n - ln -s ${impure.stuff} $out/symlink - ln -s $out $out/self - ''; + buildCommand = '' + echo impure-on-impure + x=$(< ${impure}/n) + mkdir $out + printf X$x > $out/n + ln -s ${impure.stuff} $out/symlink + ln -s $out $out/self + ''; __impure = true; }; # This is not allowed. inputAddressed = mkDerivation { name = "input-addressed"; - buildCommand = - '' - cat ${impure} > $out - ''; + buildCommand = '' + cat ${impure} > $out + ''; }; contentAddressed = mkDerivation { name = "content-addressed"; - buildCommand = - '' - echo content-addressed - x=$(< ${impureOnImpure}/n) - printf ''${x:0:1} > $out - ''; + buildCommand = '' + echo content-addressed + x=$(< ${impureOnImpure}/n) + printf ''${x:0:1} > $out + ''; outputHashMode = "recursive"; outputHash = "sha256-eBYxcgkuWuiqs4cKNgKwkb3vY/HR0vVsJnqe8itJGcQ="; }; inputAddressedAfterCA = mkDerivation { name = "input-addressed-after-ca"; - buildCommand = - '' - cat ${contentAddressed} > $out - ''; + buildCommand = '' + cat ${contentAddressed} > $out + ''; }; } diff --git a/tests/functional/lang-gc/issue-11141-gc-coroutine-test.nix b/tests/functional/lang-gc/issue-11141-gc-coroutine-test.nix index 4f311af75d7..6dae5c155dd 100644 --- a/tests/functional/lang-gc/issue-11141-gc-coroutine-test.nix +++ b/tests/functional/lang-gc/issue-11141-gc-coroutine-test.nix @@ -1,4 +1,3 @@ - # Run: # GC_INITIAL_HEAP_SIZE=$[1024 * 1024] NIX_SHOW_STATS=1 nix eval -f gc-coroutine-test.nix -vvvv @@ -11,55 +10,56 @@ let # Generate a tree of numbers, n deep, such that the numbers add up to (1 + salt) * 10^n. # The salting makes the numbers all different, increasing the likelihood of catching # any memory corruptions that might be caused by the GC or otherwise. - garbage = salt: n: - if n == 0 - then [(1 + salt)] - else [ - (garbage (10 * salt + 1) (n - 1)) - (garbage (10 * salt - 1) (n - 1)) - (garbage (10 * salt + 2) (n - 1)) - (garbage (10 * salt - 2) (n - 1)) - (garbage (10 * salt + 3) (n - 1)) - (garbage (10 * salt - 3) (n - 1)) - (garbage (10 * salt + 4) (n - 1)) - (garbage (10 * salt - 4) (n - 1)) - (garbage (10 * salt + 5) (n - 1)) - (garbage (10 * salt - 5) (n - 1)) - ]; + garbage = + salt: n: + if n == 0 then + [ (1 + salt) ] + else + [ + (garbage (10 * salt + 1) (n - 1)) + (garbage (10 * salt - 1) (n - 1)) + (garbage (10 * salt + 2) (n - 1)) + (garbage (10 * salt - 2) (n - 1)) + (garbage (10 * salt + 3) (n - 1)) + (garbage (10 * salt - 3) (n - 1)) + (garbage (10 * salt + 4) (n - 1)) + (garbage (10 * salt - 4) (n - 1)) + (garbage (10 * salt + 5) (n - 1)) + (garbage (10 * salt - 5) (n - 1)) + ]; - pow = base: n: - if n == 0 - then 1 - else base * (pow base (n - 1)); + pow = base: n: if n == 0 then 1 else base * (pow base (n - 1)); - sumNestedLists = l: - if isList l - then foldl' (a: b: a + sumNestedLists b) 0 l - else l; + sumNestedLists = l: if isList l then foldl' (a: b: a + sumNestedLists b) 0 l else l; in - assert sumNestedLists (garbage 0 3) == pow 10 3; - assert sumNestedLists (garbage 0 6) == pow 10 6; - builtins.foldl' - (a: b: - assert - "${ - builtins.path { - path = ./src; - filter = path: type: - # We're not doing common subexpression elimination, so this reallocates - # the fairly big tree over and over, producing a lot of garbage during - # source filtering, whose filter runs in a coroutine. - assert sumNestedLists (garbage 0 3) == pow 10 3; - true; - } - }" - == "${./src}"; +assert sumNestedLists (garbage 0 3) == pow 10 3; +assert sumNestedLists (garbage 0 6) == pow 10 6; +builtins.foldl' + ( + a: b: + assert + "${builtins.path { + path = ./src; + filter = + path: type: + # We're not doing common subexpression elimination, so this reallocates + # the fairly big tree over and over, producing a lot of garbage during + # source filtering, whose filter runs in a coroutine. + assert sumNestedLists (garbage 0 3) == pow 10 3; + true; + }}" == "${./src}"; - # These asserts don't seem necessary, as the lambda value get corrupted first - assert a.okay; - assert b.okay; - { okay = true; } - ) + # These asserts don't seem necessary, as the lambda value get corrupted first + assert a.okay; + assert b.okay; + { + okay = true; + } + ) + { okay = true; } + [ + { okay = true; } + { okay = true; } { okay = true; } - [ { okay = true; } { okay = true; } { okay = true; } ] + ] diff --git a/tests/functional/lang/eval-fail-addDrvOutputDependencies-multi-elem-context.nix b/tests/functional/lang/eval-fail-addDrvOutputDependencies-multi-elem-context.nix index dbde264dfae..a1c3461cf48 100644 --- a/tests/functional/lang/eval-fail-addDrvOutputDependencies-multi-elem-context.nix +++ b/tests/functional/lang/eval-fail-addDrvOutputDependencies-multi-elem-context.nix @@ -3,16 +3,23 @@ let name = "fail"; builder = "/bin/false"; system = "x86_64-linux"; - outputs = [ "out" "foo" ]; + outputs = [ + "out" + "foo" + ]; }; drv1 = derivation { name = "fail-2"; builder = "/bin/false"; system = "x86_64-linux"; - outputs = [ "out" "foo" ]; + outputs = [ + "out" + "foo" + ]; }; combo-path = "${drv0.drvPath}${drv1.drvPath}"; -in builtins.addDrvOutputDependencies combo-path +in +builtins.addDrvOutputDependencies combo-path diff --git a/tests/functional/lang/eval-fail-addDrvOutputDependencies-wrong-element-kind.nix b/tests/functional/lang/eval-fail-addDrvOutputDependencies-wrong-element-kind.nix index e379e1d9598..6aab61c4068 100644 --- a/tests/functional/lang/eval-fail-addDrvOutputDependencies-wrong-element-kind.nix +++ b/tests/functional/lang/eval-fail-addDrvOutputDependencies-wrong-element-kind.nix @@ -3,7 +3,11 @@ let name = "fail"; builder = "/bin/false"; system = "x86_64-linux"; - outputs = [ "out" "foo" ]; + outputs = [ + "out" + "foo" + ]; }; -in builtins.addDrvOutputDependencies drv.outPath +in +builtins.addDrvOutputDependencies drv.outPath diff --git a/tests/functional/lang/eval-fail-addErrorContext-example.nix b/tests/functional/lang/eval-fail-addErrorContext-example.nix index 996b2468849..96a9cef84e7 100644 --- a/tests/functional/lang/eval-fail-addErrorContext-example.nix +++ b/tests/functional/lang/eval-fail-addErrorContext-example.nix @@ -1,9 +1,9 @@ let - countDown = n: - if n == 0 - then throw "kaboom" + countDown = + n: + if n == 0 then + throw "kaboom" else - builtins.addErrorContext - "while counting down; n = ${toString n}" - ("x" + countDown (n - 1)); -in countDown 10 + builtins.addErrorContext "while counting down; n = ${toString n}" ("x" + countDown (n - 1)); +in +countDown 10 diff --git a/tests/functional/lang/eval-fail-assert-equal-attrs-names-2.nix b/tests/functional/lang/eval-fail-assert-equal-attrs-names-2.nix index 8e7ac9cf2be..4bce2645612 100644 --- a/tests/functional/lang/eval-fail-assert-equal-attrs-names-2.nix +++ b/tests/functional/lang/eval-fail-assert-equal-attrs-names-2.nix @@ -1,2 +1,8 @@ -assert { a = true; } == { a = true; b = true; }; +assert + { + a = true; + } == { + a = true; + b = true; + }; throw "unreachable" diff --git a/tests/functional/lang/eval-fail-assert-equal-attrs-names.nix b/tests/functional/lang/eval-fail-assert-equal-attrs-names.nix index e2f53a85ad6..f9956999fa4 100644 --- a/tests/functional/lang/eval-fail-assert-equal-attrs-names.nix +++ b/tests/functional/lang/eval-fail-assert-equal-attrs-names.nix @@ -1,2 +1,8 @@ -assert { a = true; b = true; } == { a = true; }; +assert + { + a = true; + b = true; + } == { + a = true; + }; throw "unreachable" diff --git a/tests/functional/lang/eval-fail-assert-equal-derivations-extra.nix b/tests/functional/lang/eval-fail-assert-equal-derivations-extra.nix index fd8bc3f26ca..14a782a7743 100644 --- a/tests/functional/lang/eval-fail-assert-equal-derivations-extra.nix +++ b/tests/functional/lang/eval-fail-assert-equal-derivations-extra.nix @@ -1,5 +1,14 @@ assert - { foo = { type = "derivation"; outPath = "/nix/store/0"; }; } - == - { foo = { type = "derivation"; outPath = "/nix/store/1"; devious = true; }; }; -throw "unreachable" \ No newline at end of file + { + foo = { + type = "derivation"; + outPath = "/nix/store/0"; + }; + } == { + foo = { + type = "derivation"; + outPath = "/nix/store/1"; + devious = true; + }; + }; +throw "unreachable" diff --git a/tests/functional/lang/eval-fail-assert-equal-derivations.nix b/tests/functional/lang/eval-fail-assert-equal-derivations.nix index c648eae374b..0f6748c58bf 100644 --- a/tests/functional/lang/eval-fail-assert-equal-derivations.nix +++ b/tests/functional/lang/eval-fail-assert-equal-derivations.nix @@ -1,5 +1,15 @@ assert - { foo = { type = "derivation"; outPath = "/nix/store/0"; ignored = abort "not ignored"; }; } - == - { foo = { type = "derivation"; outPath = "/nix/store/1"; ignored = abort "not ignored"; }; }; -throw "unreachable" \ No newline at end of file + { + foo = { + type = "derivation"; + outPath = "/nix/store/0"; + ignored = abort "not ignored"; + }; + } == { + foo = { + type = "derivation"; + outPath = "/nix/store/1"; + ignored = abort "not ignored"; + }; + }; +throw "unreachable" diff --git a/tests/functional/lang/eval-fail-assert-equal-function-direct.nix b/tests/functional/lang/eval-fail-assert-equal-function-direct.nix index 68e5e390823..cd15c4a36d8 100644 --- a/tests/functional/lang/eval-fail-assert-equal-function-direct.nix +++ b/tests/functional/lang/eval-fail-assert-equal-function-direct.nix @@ -1,7 +1,4 @@ # Note: functions in nested structures, e.g. attributes, may be optimized away by pointer identity optimization. # This only compares a direct comparison and makes no claims about functions in nested structures. -assert - (x: x) - == - (x: x); -abort "unreachable" \ No newline at end of file +assert (x: x) == (x: x); +abort "unreachable" diff --git a/tests/functional/lang/eval-fail-assert-equal-list-length.nix b/tests/functional/lang/eval-fail-assert-equal-list-length.nix index 6d40f4d8e83..bd74ccccd34 100644 --- a/tests/functional/lang/eval-fail-assert-equal-list-length.nix +++ b/tests/functional/lang/eval-fail-assert-equal-list-length.nix @@ -1,2 +1,6 @@ -assert [ 1 0 ] == [ 10 ]; -throw "unreachable" \ No newline at end of file +assert + [ + 1 + 0 + ] == [ 10 ]; +throw "unreachable" diff --git a/tests/functional/lang/eval-fail-assert-equal-paths.nix b/tests/functional/lang/eval-fail-assert-equal-paths.nix index ef0b6702466..647e891b8ac 100644 --- a/tests/functional/lang/eval-fail-assert-equal-paths.nix +++ b/tests/functional/lang/eval-fail-assert-equal-paths.nix @@ -1,2 +1,2 @@ assert ./foo == ./bar; -throw "unreachable" \ No newline at end of file +throw "unreachable" diff --git a/tests/functional/lang/eval-fail-assert-nested-bool.nix b/tests/functional/lang/eval-fail-assert-nested-bool.nix index 2285769839e..c75fe06106b 100644 --- a/tests/functional/lang/eval-fail-assert-nested-bool.nix +++ b/tests/functional/lang/eval-fail-assert-nested-bool.nix @@ -1,6 +1,3 @@ -assert - { a.b = [ { c.d = true; } ]; } - == - { a.b = [ { c.d = false; } ]; }; +assert { a.b = [ { c.d = true; } ]; } == { a.b = [ { c.d = false; } ]; }; -abort "unreachable" \ No newline at end of file +abort "unreachable" diff --git a/tests/functional/lang/eval-fail-assert.nix b/tests/functional/lang/eval-fail-assert.nix index 3b7a1e8bf0c..7cb77504507 100644 --- a/tests/functional/lang/eval-fail-assert.nix +++ b/tests/functional/lang/eval-fail-assert.nix @@ -1,5 +1,8 @@ let { - x = arg: assert arg == "y"; 123; + x = + arg: + assert arg == "y"; + 123; body = x "x"; -} \ No newline at end of file +} diff --git a/tests/functional/lang/eval-fail-attr-name-type.nix b/tests/functional/lang/eval-fail-attr-name-type.nix index a0e76004a39..fb6ccdd41d5 100644 --- a/tests/functional/lang/eval-fail-attr-name-type.nix +++ b/tests/functional/lang/eval-fail-attr-name-type.nix @@ -1,7 +1,7 @@ let attrs = { - puppy.doggy = {}; + puppy.doggy = { }; }; key = 1; in - attrs.puppy.${key} +attrs.puppy.${key} diff --git a/tests/functional/lang/eval-fail-attrset-merge-drops-later-rec.nix b/tests/functional/lang/eval-fail-attrset-merge-drops-later-rec.nix index fdb314b9193..b6b56bf7d42 100644 --- a/tests/functional/lang/eval-fail-attrset-merge-drops-later-rec.nix +++ b/tests/functional/lang/eval-fail-attrset-merge-drops-later-rec.nix @@ -1 +1,8 @@ -{ a.b = 1; a = rec { c = d + 2; d = 3; }; }.c +{ + a.b = 1; + a = rec { + c = d + 2; + d = 3; + }; +} +.c diff --git a/tests/functional/lang/eval-fail-bad-string-interpolation-4.nix b/tests/functional/lang/eval-fail-bad-string-interpolation-4.nix index 457b5f06a88..e8349bbdff3 100644 --- a/tests/functional/lang/eval-fail-bad-string-interpolation-4.nix +++ b/tests/functional/lang/eval-fail-bad-string-interpolation-4.nix @@ -1,6 +1,16 @@ let # Basically a "billion laughs" attack, but toned down to simulated `pkgs`. - ha = x: y: { a = x y; b = x y; c = x y; d = x y; e = x y; f = x y; g = x y; h = x y; j = x y; }; + ha = x: y: { + a = x y; + b = x y; + c = x y; + d = x y; + e = x y; + f = x y; + g = x y; + h = x y; + j = x y; + }; has = ha (ha (ha (ha (x: x)))) "ha"; # A large structure that has already been evaluated. pkgs = builtins.deepSeq has has; diff --git a/tests/functional/lang/eval-fail-dup-dynamic-attrs.nix b/tests/functional/lang/eval-fail-dup-dynamic-attrs.nix index 7ea17f6c878..93cceefa48e 100644 --- a/tests/functional/lang/eval-fail-dup-dynamic-attrs.nix +++ b/tests/functional/lang/eval-fail-dup-dynamic-attrs.nix @@ -1,4 +1,8 @@ { - set = { "${"" + "b"}" = 1; }; - set = { "${"b" + ""}" = 2; }; + set = { + "${"" + "b"}" = 1; + }; + set = { + "${"b" + ""}" = 2; + }; } diff --git a/tests/functional/lang/eval-fail-duplicate-traces.nix b/tests/functional/lang/eval-fail-duplicate-traces.nix index 17ce374ece7..90526f6d48c 100644 --- a/tests/functional/lang/eval-fail-duplicate-traces.nix +++ b/tests/functional/lang/eval-fail-duplicate-traces.nix @@ -1,9 +1,6 @@ # Check that we only omit duplicate stack traces when there's a bunch of them. # Here, there's only a couple duplicate entries, so we output them all. let - throwAfter = n: - if n > 0 - then throwAfter (n - 1) - else throw "Uh oh!"; + throwAfter = n: if n > 0 then throwAfter (n - 1) else throw "Uh oh!"; in - throwAfter 2 +throwAfter 2 diff --git a/tests/functional/lang/eval-fail-fetchurl-baseName-attrs-name.nix b/tests/functional/lang/eval-fail-fetchurl-baseName-attrs-name.nix index 5838055390d..dcaf7202b11 100644 --- a/tests/functional/lang/eval-fail-fetchurl-baseName-attrs-name.nix +++ b/tests/functional/lang/eval-fail-fetchurl-baseName-attrs-name.nix @@ -1 +1,4 @@ -builtins.fetchurl { url = "https://example.com/foo.tar.gz"; name = "~wobble~"; } +builtins.fetchurl { + url = "https://example.com/foo.tar.gz"; + name = "~wobble~"; +} diff --git a/tests/functional/lang/eval-fail-flake-ref-to-string-negative-integer.nix b/tests/functional/lang/eval-fail-flake-ref-to-string-negative-integer.nix index e0208eb2519..9cc9ef6295b 100644 --- a/tests/functional/lang/eval-fail-flake-ref-to-string-negative-integer.nix +++ b/tests/functional/lang/eval-fail-flake-ref-to-string-negative-integer.nix @@ -1,7 +1,12 @@ -let n = -1; in builtins.seq n (builtins.flakeRefToString { - type = "github"; - owner = "NixOS"; - repo = n; - ref = "23.05"; - dir = "lib"; -}) +let + n = -1; +in +builtins.seq n ( + builtins.flakeRefToString { + type = "github"; + owner = "NixOS"; + repo = n; + ref = "23.05"; + dir = "lib"; + } +) diff --git a/tests/functional/lang/eval-fail-foldlStrict-strict-op-application.nix b/tests/functional/lang/eval-fail-foldlStrict-strict-op-application.nix index 1620cc76eeb..f85486d441e 100644 --- a/tests/functional/lang/eval-fail-foldlStrict-strict-op-application.nix +++ b/tests/functional/lang/eval-fail-foldlStrict-strict-op-application.nix @@ -1,5 +1,5 @@ # Tests that the result of applying op is forced even if the value is never used -builtins.foldl' - (_: f: f null) - null - [ (_: throw "Not the final value, but is still forced!") (_: 23) ] +builtins.foldl' (_: f: f null) null [ + (_: throw "Not the final value, but is still forced!") + (_: 23) +] diff --git a/tests/functional/lang/eval-fail-hashfile-missing.nix b/tests/functional/lang/eval-fail-hashfile-missing.nix index ce098b82380..0f2872b7155 100644 --- a/tests/functional/lang/eval-fail-hashfile-missing.nix +++ b/tests/functional/lang/eval-fail-hashfile-missing.nix @@ -1,5 +1,16 @@ let - paths = [ ./this-file-is-definitely-not-there-7392097 "/and/neither/is/this/37293620" ]; + paths = [ + ./this-file-is-definitely-not-there-7392097 + "/and/neither/is/this/37293620" + ]; in - toString (builtins.concatLists (map (hash: map (builtins.hashFile hash) paths) ["md5" "sha1" "sha256" "sha512"])) - +toString ( + builtins.concatLists ( + map (hash: map (builtins.hashFile hash) paths) [ + "md5" + "sha1" + "sha256" + "sha512" + ] + ) +) diff --git a/tests/functional/lang/eval-fail-list.nix b/tests/functional/lang/eval-fail-list.nix index fa749f2f740..14eb4efa9f6 100644 --- a/tests/functional/lang/eval-fail-list.nix +++ b/tests/functional/lang/eval-fail-list.nix @@ -1 +1 @@ -8++1 +8 ++ 1 diff --git a/tests/functional/lang/eval-fail-missing-arg.nix b/tests/functional/lang/eval-fail-missing-arg.nix index c4be9797c53..9037aa40a54 100644 --- a/tests/functional/lang/eval-fail-missing-arg.nix +++ b/tests/functional/lang/eval-fail-missing-arg.nix @@ -1 +1,12 @@ -({x, y, z}: x + y + z) {x = "foo"; z = "bar";} +( + { + x, + y, + z, + }: + x + y + z +) + { + x = "foo"; + z = "bar"; + } diff --git a/tests/functional/lang/eval-fail-mutual-recursion.nix b/tests/functional/lang/eval-fail-mutual-recursion.nix index d090d3158a3..421e464dd86 100644 --- a/tests/functional/lang/eval-fail-mutual-recursion.nix +++ b/tests/functional/lang/eval-fail-mutual-recursion.nix @@ -19,18 +19,22 @@ # - a few frames of A (skip the rest) # - a few frames of B (skip the rest, _and_ skip the remaining frames of A) let - throwAfterB = recurse: n: - if n > 0 - then throwAfterB recurse (n - 1) - else if recurse - then throwAfterA false 10 - else throw "Uh oh!"; + throwAfterB = + recurse: n: + if n > 0 then + throwAfterB recurse (n - 1) + else if recurse then + throwAfterA false 10 + else + throw "Uh oh!"; - throwAfterA = recurse: n: - if n > 0 - then throwAfterA recurse (n - 1) - else if recurse - then throwAfterB true 10 - else throw "Uh oh!"; + throwAfterA = + recurse: n: + if n > 0 then + throwAfterA recurse (n - 1) + else if recurse then + throwAfterB true 10 + else + throw "Uh oh!"; in - throwAfterA true 10 +throwAfterA true 10 diff --git a/tests/functional/lang/eval-fail-nested-list-items.nix b/tests/functional/lang/eval-fail-nested-list-items.nix index af45b1dd49a..d0aa1b5d3b9 100644 --- a/tests/functional/lang/eval-fail-nested-list-items.nix +++ b/tests/functional/lang/eval-fail-nested-list-items.nix @@ -8,4 +8,27 @@ # # error: cannot coerce a list to a string: [ [ 1 2 3 4 5 6 7 8 ] [ 1 «4294967290 items elided» ] ] -"" + (let v = [ [ 1 2 3 4 5 6 7 8 ] [1 2 3 4]]; in builtins.deepSeq v v) +"" ++ ( + let + v = [ + [ + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + ] + [ + 1 + 2 + 3 + 4 + ] + ]; + in + builtins.deepSeq v v +) diff --git a/tests/functional/lang/eval-fail-not-throws.nix b/tests/functional/lang/eval-fail-not-throws.nix index a74ce4ebeea..2e024738b68 100644 --- a/tests/functional/lang/eval-fail-not-throws.nix +++ b/tests/functional/lang/eval-fail-not-throws.nix @@ -1 +1 @@ -! (throw "uh oh!") +!(throw "uh oh!") diff --git a/tests/functional/lang/eval-fail-overflowing-add.nix b/tests/functional/lang/eval-fail-overflowing-add.nix index 24258fc200e..9e1e8aa7571 100644 --- a/tests/functional/lang/eval-fail-overflowing-add.nix +++ b/tests/functional/lang/eval-fail-overflowing-add.nix @@ -1,4 +1,5 @@ let a = 9223372036854775807; b = 1; -in a + b +in +a + b diff --git a/tests/functional/lang/eval-fail-overflowing-div.nix b/tests/functional/lang/eval-fail-overflowing-div.nix index 44fbe9d7e31..e21b0b2e57d 100644 --- a/tests/functional/lang/eval-fail-overflowing-div.nix +++ b/tests/functional/lang/eval-fail-overflowing-div.nix @@ -4,4 +4,5 @@ let # of range intMin = -9223372036854775807 - 1; b = -1; -in builtins.seq intMin (builtins.seq b (intMin / b)) +in +builtins.seq intMin (builtins.seq b (intMin / b)) diff --git a/tests/functional/lang/eval-fail-overflowing-mul.nix b/tests/functional/lang/eval-fail-overflowing-mul.nix index 6081d9c7b14..95b1375bb01 100644 --- a/tests/functional/lang/eval-fail-overflowing-mul.nix +++ b/tests/functional/lang/eval-fail-overflowing-mul.nix @@ -1,3 +1,4 @@ let a = 4294967297; -in a * a * a +in +a * a * a diff --git a/tests/functional/lang/eval-fail-overflowing-sub.nix b/tests/functional/lang/eval-fail-overflowing-sub.nix index 229b8c6d264..4f0203a6da5 100644 --- a/tests/functional/lang/eval-fail-overflowing-sub.nix +++ b/tests/functional/lang/eval-fail-overflowing-sub.nix @@ -1,4 +1,5 @@ let a = -9223372036854775807; b = 2; -in a - b +in +a - b diff --git a/tests/functional/lang/eval-fail-recursion.nix b/tests/functional/lang/eval-fail-recursion.nix index 075b5ed066b..88718a6e507 100644 --- a/tests/functional/lang/eval-fail-recursion.nix +++ b/tests/functional/lang/eval-fail-recursion.nix @@ -1 +1,4 @@ -let a = {} // a; in a.foo +let + a = { } // a; +in +a.foo diff --git a/tests/functional/lang/eval-fail-remove.nix b/tests/functional/lang/eval-fail-remove.nix index 539e0eb0a6f..9de066abe73 100644 --- a/tests/functional/lang/eval-fail-remove.nix +++ b/tests/functional/lang/eval-fail-remove.nix @@ -1,5 +1,8 @@ let { - attrs = {x = 123; y = 456;}; + attrs = { + x = 123; + y = 456; + }; - body = (removeAttrs attrs ["x"]).x; -} \ No newline at end of file + body = (removeAttrs attrs [ "x" ]).x; +} diff --git a/tests/functional/lang/eval-fail-scope-5.nix b/tests/functional/lang/eval-fail-scope-5.nix index f89a65a99be..ef6f1bb640e 100644 --- a/tests/functional/lang/eval-fail-scope-5.nix +++ b/tests/functional/lang/eval-fail-scope-5.nix @@ -3,8 +3,13 @@ let { x = "a"; y = "b"; - f = {x ? y, y ? x}: x + y; - - body = f {}; + f = + { + x ? y, + y ? x, + }: + x + y; + + body = f { }; } diff --git a/tests/functional/lang/eval-fail-undeclared-arg.nix b/tests/functional/lang/eval-fail-undeclared-arg.nix index cafdf163627..aca4511bbff 100644 --- a/tests/functional/lang/eval-fail-undeclared-arg.nix +++ b/tests/functional/lang/eval-fail-undeclared-arg.nix @@ -1 +1,5 @@ -({x, z}: x + z) {x = "foo"; y = "bla"; z = "bar";} +({ x, z }: x + z) { + x = "foo"; + y = "bla"; + z = "bar"; +} diff --git a/tests/functional/lang/eval-fail-using-set-as-attr-name.nix b/tests/functional/lang/eval-fail-using-set-as-attr-name.nix index 48e071a41cf..96390e35f6a 100644 --- a/tests/functional/lang/eval-fail-using-set-as-attr-name.nix +++ b/tests/functional/lang/eval-fail-using-set-as-attr-name.nix @@ -1,5 +1,7 @@ let - attr = {foo = "bar";}; - key = {}; + attr = { + foo = "bar"; + }; + key = { }; in - attr.${key} +attr.${key} diff --git a/tests/functional/lang/eval-okay-any-all.nix b/tests/functional/lang/eval-okay-any-all.nix index a3f26ea2aa8..643d36cb704 100644 --- a/tests/functional/lang/eval-okay-any-all.nix +++ b/tests/functional/lang/eval-okay-any-all.nix @@ -1,11 +1,34 @@ with builtins; -[ (any (x: x == 1) []) - (any (x: x == 1) [2 3 4]) - (any (x: x == 1) [1 2 3 4]) - (any (x: x == 1) [4 3 2 1]) - (all (x: x == 1) []) - (all (x: x == 1) [1]) - (all (x: x == 1) [1 2 3]) - (all (x: x == 1) [1 1 1]) +[ + (any (x: x == 1) [ ]) + (any (x: x == 1) [ + 2 + 3 + 4 + ]) + (any (x: x == 1) [ + 1 + 2 + 3 + 4 + ]) + (any (x: x == 1) [ + 4 + 3 + 2 + 1 + ]) + (all (x: x == 1) [ ]) + (all (x: x == 1) [ 1 ]) + (all (x: x == 1) [ + 1 + 2 + 3 + ]) + (all (x: x == 1) [ + 1 + 1 + 1 + ]) ] diff --git a/tests/functional/lang/eval-okay-arithmetic.nix b/tests/functional/lang/eval-okay-arithmetic.nix index 7e9e6a0b666..8160b4d84ca 100644 --- a/tests/functional/lang/eval-okay-arithmetic.nix +++ b/tests/functional/lang/eval-okay-arithmetic.nix @@ -2,58 +2,59 @@ with import ./lib.nix; let { - /* Supposedly tail recursive version: + /* + Supposedly tail recursive version: - range_ = accum: first: last: - if first == last then ([first] ++ accum) - else range_ ([first] ++ accum) (builtins.add first 1) last; + range_ = accum: first: last: + if first == last then ([first] ++ accum) + else range_ ([first] ++ accum) (builtins.add first 1) last; - range = range_ []; + range = range_ []; */ x = 12; err = abort "urgh"; - body = sum - [ (sum (range 1 50)) - (123 + 456) - (0 + -10 + -(-11) + -x) - (10 - 7 - -2) - (10 - (6 - -1)) - (10 - 1 + 2) - (3 * 4 * 5) - (56088 / 123 / 2) - (3 + 4 * const 5 0 - 6 / id 2) - - (builtins.bitAnd 12 10) # 0b1100 & 0b1010 = 8 - (builtins.bitOr 12 10) # 0b1100 | 0b1010 = 14 - (builtins.bitXor 12 10) # 0b1100 ^ 0b1010 = 6 - - (if 3 < 7 then 1 else err) - (if 7 < 3 then err else 1) - (if 3 < 3 then err else 1) - - (if 3 <= 7 then 1 else err) - (if 7 <= 3 then err else 1) - (if 3 <= 3 then 1 else err) - - (if 3 > 7 then err else 1) - (if 7 > 3 then 1 else err) - (if 3 > 3 then err else 1) - - (if 3 >= 7 then err else 1) - (if 7 >= 3 then 1 else err) - (if 3 >= 3 then 1 else err) - - (if 2 > 1 == 1 < 2 then 1 else err) - (if 1 + 2 * 3 >= 7 then 1 else err) - (if 1 + 2 * 3 < 7 then err else 1) - - # Not integer, but so what. - (if "aa" < "ab" then 1 else err) - (if "aa" < "aa" then err else 1) - (if "foo" < "foobar" then 1 else err) - ]; + body = sum [ + (sum (range 1 50)) + (123 + 456) + (0 + -10 + -(-11) + -x) + (10 - 7 - -2) + (10 - (6 - -1)) + (10 - 1 + 2) + (3 * 4 * 5) + (56088 / 123 / 2) + (3 + 4 * const 5 0 - 6 / id 2) + + (builtins.bitAnd 12 10) # 0b1100 & 0b1010 = 8 + (builtins.bitOr 12 10) # 0b1100 | 0b1010 = 14 + (builtins.bitXor 12 10) # 0b1100 ^ 0b1010 = 6 + + (if 3 < 7 then 1 else err) + (if 7 < 3 then err else 1) + (if 3 < 3 then err else 1) + + (if 3 <= 7 then 1 else err) + (if 7 <= 3 then err else 1) + (if 3 <= 3 then 1 else err) + + (if 3 > 7 then err else 1) + (if 7 > 3 then 1 else err) + (if 3 > 3 then err else 1) + + (if 3 >= 7 then err else 1) + (if 7 >= 3 then 1 else err) + (if 3 >= 3 then 1 else err) + + (if 2 > 1 == 1 < 2 then 1 else err) + (if 1 + 2 * 3 >= 7 then 1 else err) + (if 1 + 2 * 3 < 7 then err else 1) + + # Not integer, but so what. + (if "aa" < "ab" then 1 else err) + (if "aa" < "aa" then err else 1) + (if "foo" < "foobar" then 1 else err) + ]; } diff --git a/tests/functional/lang/eval-okay-attrnames.nix b/tests/functional/lang/eval-okay-attrnames.nix index e5b26e9f2e3..085e78084b0 100644 --- a/tests/functional/lang/eval-okay-attrnames.nix +++ b/tests/functional/lang/eval-okay-attrnames.nix @@ -2,10 +2,21 @@ with import ./lib.nix; let - attrs = {y = "y"; x = "x"; foo = "foo";} // rec {x = "newx"; bar = x;}; + attrs = + { + y = "y"; + x = "x"; + foo = "foo"; + } + // rec { + x = "newx"; + bar = x; + }; names = builtins.attrNames attrs; values = map (name: builtins.getAttr name attrs) names; -in assert values == builtins.attrValues attrs; concat values +in +assert values == builtins.attrValues attrs; +concat values diff --git a/tests/functional/lang/eval-okay-attrs.nix b/tests/functional/lang/eval-okay-attrs.nix index 810b31a5da9..787b9a933cf 100644 --- a/tests/functional/lang/eval-okay-attrs.nix +++ b/tests/functional/lang/eval-okay-attrs.nix @@ -1,5 +1,20 @@ let { - as = { x = 123; y = 456; } // { z = 789; } // { z = 987; }; + as = + { + x = 123; + y = 456; + } + // { + z = 789; + } + // { + z = 987; + }; - body = if as ? a then as.a else assert as ? z; as.z; + body = + if as ? a then + as.a + else + assert as ? z; + as.z; } diff --git a/tests/functional/lang/eval-okay-attrs2.nix b/tests/functional/lang/eval-okay-attrs2.nix index 9e06b83ac1f..0896f9cf1e1 100644 --- a/tests/functional/lang/eval-okay-attrs2.nix +++ b/tests/functional/lang/eval-okay-attrs2.nix @@ -1,10 +1,23 @@ let { - as = { x = 123; y = 456; } // { z = 789; } // { z = 987; }; + as = + { + x = 123; + y = 456; + } + // { + z = 789; + } + // { + z = 987; + }; A = "a"; Z = "z"; - body = if builtins.hasAttr A as - then builtins.getAttr A as - else assert builtins.hasAttr Z as; builtins.getAttr Z as; + body = + if builtins.hasAttr A as then + builtins.getAttr A as + else + assert builtins.hasAttr Z as; + builtins.getAttr Z as; } diff --git a/tests/functional/lang/eval-okay-attrs3.nix b/tests/functional/lang/eval-okay-attrs3.nix index f29de11fe66..cab345337dd 100644 --- a/tests/functional/lang/eval-okay-attrs3.nix +++ b/tests/functional/lang/eval-okay-attrs3.nix @@ -1,22 +1,22 @@ let - config = - { - services.sshd.enable = true; - services.sshd.port = 22; - services.httpd.port = 80; - hostName = "itchy"; - a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z = "x"; - foo = { - a = "a"; - b.c = "c"; - }; + config = { + services.sshd.enable = true; + services.sshd.port = 22; + services.httpd.port = 80; + hostName = "itchy"; + a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z = "x"; + foo = { + a = "a"; + b.c = "c"; }; + }; in - if config.services.sshd.enable - then "foo ${toString config.services.sshd.port} ${toString config.services.httpd.port} ${config.hostName}" - + "${config.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z}" - + "${config.foo.a}" - + "${config.foo.b.c}" - else "bar" +if config.services.sshd.enable then + "foo ${toString config.services.sshd.port} ${toString config.services.httpd.port} ${config.hostName}" + + "${config.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z}" + + "${config.foo.a}" + + "${config.foo.b.c}" +else + "bar" diff --git a/tests/functional/lang/eval-okay-attrs4.nix b/tests/functional/lang/eval-okay-attrs4.nix index 43ec81210f3..3e43e4bae4f 100644 --- a/tests/functional/lang/eval-okay-attrs4.nix +++ b/tests/functional/lang/eval-okay-attrs4.nix @@ -1,7 +1,20 @@ let - as = { x.y.z = 123; a.b.c = 456; }; + as = { + x.y.z = 123; + a.b.c = 456; + }; bs = null; -in [ (as ? x) (as ? y) (as ? x.y.z) (as ? x.y.z.a) (as ? x.y.a) (as ? a.b.c) (bs ? x) (bs ? x.y.z) ] +in +[ + (as ? x) + (as ? y) + (as ? x.y.z) + (as ? x.y.z.a) + (as ? x.y.a) + (as ? a.b.c) + (bs ? x) + (bs ? x.y.z) +] diff --git a/tests/functional/lang/eval-okay-attrs6.nix b/tests/functional/lang/eval-okay-attrs6.nix index 2e5c85483be..76c94af785a 100644 --- a/tests/functional/lang/eval-okay-attrs6.nix +++ b/tests/functional/lang/eval-okay-attrs6.nix @@ -1,4 +1,6 @@ rec { "${"foo"}" = "bar"; - __overrides = { bar = "qux"; }; + __overrides = { + bar = "qux"; + }; } diff --git a/tests/functional/lang/eval-okay-autoargs.nix b/tests/functional/lang/eval-okay-autoargs.nix index 815f51b1d67..bc82c569b48 100644 --- a/tests/functional/lang/eval-okay-autoargs.nix +++ b/tests/functional/lang/eval-okay-autoargs.nix @@ -4,12 +4,17 @@ let in -{ xyzzy2 ? xyzzy # mutually recursive args -, xyzzy ? "blaat" # will be overridden by --argstr -, fb ? foobar -, lib # will be set by --arg +{ + xyzzy2 ? xyzzy, # mutually recursive args + xyzzy ? "blaat", # will be overridden by --argstr + fb ? foobar, + lib, # will be set by --arg }: { - result = lib.concat [xyzzy xyzzy2 fb]; + result = lib.concat [ + xyzzy + xyzzy2 + fb + ]; } diff --git a/tests/functional/lang/eval-okay-builtins-add.nix b/tests/functional/lang/eval-okay-builtins-add.nix index c841816222a..f678f640f12 100644 --- a/tests/functional/lang/eval-okay-builtins-add.nix +++ b/tests/functional/lang/eval-okay-builtins-add.nix @@ -1,8 +1,8 @@ [ -(builtins.add 2 3) -(builtins.add 2 2) -(builtins.typeOf (builtins.add 2 2)) -("t" + "t") -(builtins.typeOf (builtins.add 2.0 2)) -(builtins.add 2.0 2) + (builtins.add 2 3) + (builtins.add 2 2) + (builtins.typeOf (builtins.add 2 2)) + ("t" + "t") + (builtins.typeOf (builtins.add 2.0 2)) + (builtins.add 2.0 2) ] diff --git a/tests/functional/lang/eval-okay-builtins.nix b/tests/functional/lang/eval-okay-builtins.nix index e9d65e88a81..be4114116f3 100644 --- a/tests/functional/lang/eval-okay-builtins.nix +++ b/tests/functional/lang/eval-okay-builtins.nix @@ -8,5 +8,5 @@ let { y = if builtins ? fnord then builtins.fnord "foo" else ""; body = x + y; - + } diff --git a/tests/functional/lang/eval-okay-callable-attrs.nix b/tests/functional/lang/eval-okay-callable-attrs.nix index 310a030df00..a4c1ace362b 100644 --- a/tests/functional/lang/eval-okay-callable-attrs.nix +++ b/tests/functional/lang/eval-okay-callable-attrs.nix @@ -1 +1,10 @@ -({ __functor = self: x: self.foo && x; foo = false; } // { foo = true; }) true +( + { + __functor = self: x: self.foo && x; + foo = false; + } + // { + foo = true; + } +) + true diff --git a/tests/functional/lang/eval-okay-catattrs.nix b/tests/functional/lang/eval-okay-catattrs.nix index 2c3dc10da52..7ec4ba7aeb2 100644 --- a/tests/functional/lang/eval-okay-catattrs.nix +++ b/tests/functional/lang/eval-okay-catattrs.nix @@ -1 +1,5 @@ -builtins.catAttrs "a" [ { a = 1; } { b = 0; } { a = 2; } ] +builtins.catAttrs "a" [ + { a = 1; } + { b = 0; } + { a = 2; } +] diff --git a/tests/functional/lang/eval-okay-closure.nix b/tests/functional/lang/eval-okay-closure.nix index cccd4dc3573..67c53d08947 100644 --- a/tests/functional/lang/eval-okay-closure.nix +++ b/tests/functional/lang/eval-okay-closure.nix @@ -1,13 +1,25 @@ let closure = builtins.genericClosure { - startSet = [{key = 80;}]; - operator = {key, foo ? false}: - if builtins.lessThan key 0 - then [] - else [{key = builtins.sub key 9;} {key = builtins.sub key 13; foo = true;}]; + startSet = [ { key = 80; } ]; + operator = + { + key, + foo ? false, + }: + if builtins.lessThan key 0 then + [ ] + else + [ + { key = builtins.sub key 9; } + { + key = builtins.sub key 13; + foo = true; + } + ]; }; sort = (import ./lib.nix).sortBy (a: b: builtins.lessThan a.key b.key); -in sort closure +in +sort closure diff --git a/tests/functional/lang/eval-okay-concat.nix b/tests/functional/lang/eval-okay-concat.nix index d158a9bf05b..ce754ca005f 100644 --- a/tests/functional/lang/eval-okay-concat.nix +++ b/tests/functional/lang/eval-okay-concat.nix @@ -1 +1,15 @@ -[1 2 3] ++ [4 5 6] ++ [7 8 9] +[ + 1 + 2 + 3 +] +++ [ + 4 + 5 + 6 +] +++ [ + 7 + 8 + 9 +] diff --git a/tests/functional/lang/eval-okay-concatmap.nix b/tests/functional/lang/eval-okay-concatmap.nix index 97da5d37a41..14b5461319e 100644 --- a/tests/functional/lang/eval-okay-concatmap.nix +++ b/tests/functional/lang/eval-okay-concatmap.nix @@ -1,5 +1,9 @@ with import ./lib.nix; -[ (builtins.concatMap (x: if x / 2 * 2 == x then [] else [ x ]) (range 0 10)) - (builtins.concatMap (x: [x] ++ ["z"]) ["a" "b"]) +[ + (builtins.concatMap (x: if x / 2 * 2 == x then [ ] else [ x ]) (range 0 10)) + (builtins.concatMap (x: [ x ] ++ [ "z" ]) [ + "a" + "b" + ]) ] diff --git a/tests/functional/lang/eval-okay-concatstringssep.nix b/tests/functional/lang/eval-okay-concatstringssep.nix index adc4c41bd55..2270d11b4c4 100644 --- a/tests/functional/lang/eval-okay-concatstringssep.nix +++ b/tests/functional/lang/eval-okay-concatstringssep.nix @@ -1,8 +1,17 @@ with builtins; -[ (concatStringsSep "" []) - (concatStringsSep "" ["foo" "bar" "xyzzy"]) - (concatStringsSep ", " ["foo" "bar" "xyzzy"]) - (concatStringsSep ", " ["foo"]) - (concatStringsSep ", " []) +[ + (concatStringsSep "" [ ]) + (concatStringsSep "" [ + "foo" + "bar" + "xyzzy" + ]) + (concatStringsSep ", " [ + "foo" + "bar" + "xyzzy" + ]) + (concatStringsSep ", " [ "foo" ]) + (concatStringsSep ", " [ ]) ] diff --git a/tests/functional/lang/eval-okay-context-introspection.nix b/tests/functional/lang/eval-okay-context-introspection.nix index 8886cf32e94..5ed99471901 100644 --- a/tests/functional/lang/eval-okay-context-introspection.nix +++ b/tests/functional/lang/eval-okay-context-introspection.nix @@ -3,7 +3,10 @@ let name = "fail"; builder = "/bin/false"; system = "x86_64-linux"; - outputs = [ "out" "foo" ]; + outputs = [ + "out" + "foo" + ]; }; path = "${./eval-okay-context-introspection.nix}"; @@ -13,7 +16,10 @@ let path = true; }; "${builtins.unsafeDiscardStringContext drv.drvPath}" = { - outputs = [ "foo" "out" ]; + outputs = [ + "foo" + "out" + ]; allOutputs = true; }; }; @@ -21,25 +27,22 @@ let combo-path = "${path}${drv.outPath}${drv.foo.outPath}${drv.drvPath}"; legit-context = builtins.getContext combo-path; - reconstructed-path = builtins.appendContext - (builtins.unsafeDiscardStringContext combo-path) - desired-context; + reconstructed-path = builtins.appendContext (builtins.unsafeDiscardStringContext combo-path) desired-context; # Eta rule for strings with context. - etaRule = str: - str == builtins.appendContext - (builtins.unsafeDiscardStringContext str) - (builtins.getContext str); + etaRule = + str: + str == builtins.appendContext (builtins.unsafeDiscardStringContext str) (builtins.getContext str); # Only holds true if string context contains both a `DrvDeep` and # `Opaque` element. - almostEtaRule = str: - str == builtins.addDrvOutputDependencies - (builtins.unsafeDiscardOutputDependency str); + almostEtaRule = + str: str == builtins.addDrvOutputDependencies (builtins.unsafeDiscardOutputDependency str); - addDrvOutputDependencies_idempotent = str: - builtins.addDrvOutputDependencies str == - builtins.addDrvOutputDependencies (builtins.addDrvOutputDependencies str); + addDrvOutputDependencies_idempotent = + str: + builtins.addDrvOutputDependencies str + == builtins.addDrvOutputDependencies (builtins.addDrvOutputDependencies str); rules = str: [ (etaRule str) @@ -47,12 +50,14 @@ let (addDrvOutputDependencies_idempotent str) ]; -in [ +in +[ (legit-context == desired-context) (reconstructed-path == combo-path) (etaRule "foo") (etaRule drv.foo.outPath) -] ++ builtins.concatMap rules [ +] +++ builtins.concatMap rules [ drv.drvPath (builtins.addDrvOutputDependencies drv.drvPath) (builtins.unsafeDiscardOutputDependency drv.drvPath) diff --git a/tests/functional/lang/eval-okay-context.nix b/tests/functional/lang/eval-okay-context.nix index 7b9531cfe9e..102bc22599c 100644 --- a/tests/functional/lang/eval-okay-context.nix +++ b/tests/functional/lang/eval-okay-context.nix @@ -1,6 +1,7 @@ -let s = "foo ${builtins.substring 33 100 (baseNameOf "${./eval-okay-context.nix}")} bar"; +let + s = "foo ${builtins.substring 33 100 (baseNameOf "${./eval-okay-context.nix}")} bar"; in - if s != "foo eval-okay-context.nix bar" - then abort "context not discarded" - else builtins.unsafeDiscardStringContext s - +if s != "foo eval-okay-context.nix bar" then + abort "context not discarded" +else + builtins.unsafeDiscardStringContext s diff --git a/tests/functional/lang/eval-okay-convertHash.nix b/tests/functional/lang/eval-okay-convertHash.nix index a0191ee8df1..6d5074fea23 100644 --- a/tests/functional/lang/eval-okay-convertHash.nix +++ b/tests/functional/lang/eval-okay-convertHash.nix @@ -1,33 +1,131 @@ let - hashAlgos = [ "md5" "md5" "md5" "sha1" "sha1" "sha1" "sha256" "sha256" "sha256" "sha512" "sha512" "sha512" ]; + hashAlgos = [ + "md5" + "md5" + "md5" + "sha1" + "sha1" + "sha1" + "sha256" + "sha256" + "sha256" + "sha512" + "sha512" + "sha512" + ]; hashesBase16 = import ./eval-okay-hashstring.exp; - map2 = f: { fsts, snds }: if fsts == [ ] then [ ] else [ (f (builtins.head fsts) (builtins.head snds)) ] ++ map2 f { fsts = builtins.tail fsts; snds = builtins.tail snds; }; - map2' = f: fsts: snds: map2 f { inherit fsts snds; }; + map2 = + f: + { fsts, snds }: + if fsts == [ ] then + [ ] + else + [ (f (builtins.head fsts) (builtins.head snds)) ] + ++ map2 f { + fsts = builtins.tail fsts; + snds = builtins.tail snds; + }; + map2' = + f: fsts: snds: + map2 f { inherit fsts snds; }; getOutputHashes = hashes: { - hashesBase16 = map2' (hashAlgo: hash: builtins.convertHash { inherit hash hashAlgo; toHashFormat = "base16";}) hashAlgos hashes; - hashesNix32 = map2' (hashAlgo: hash: builtins.convertHash { inherit hash hashAlgo; toHashFormat = "nix32";}) hashAlgos hashes; - hashesBase32 = map2' (hashAlgo: hash: builtins.convertHash { inherit hash hashAlgo; toHashFormat = "base32";}) hashAlgos hashes; - hashesBase64 = map2' (hashAlgo: hash: builtins.convertHash { inherit hash hashAlgo; toHashFormat = "base64";}) hashAlgos hashes; - hashesSRI = map2' (hashAlgo: hash: builtins.convertHash { inherit hash hashAlgo; toHashFormat = "sri" ;}) hashAlgos hashes; + hashesBase16 = map2' ( + hashAlgo: hash: + builtins.convertHash { + inherit hash hashAlgo; + toHashFormat = "base16"; + } + ) hashAlgos hashes; + hashesNix32 = map2' ( + hashAlgo: hash: + builtins.convertHash { + inherit hash hashAlgo; + toHashFormat = "nix32"; + } + ) hashAlgos hashes; + hashesBase32 = map2' ( + hashAlgo: hash: + builtins.convertHash { + inherit hash hashAlgo; + toHashFormat = "base32"; + } + ) hashAlgos hashes; + hashesBase64 = map2' ( + hashAlgo: hash: + builtins.convertHash { + inherit hash hashAlgo; + toHashFormat = "base64"; + } + ) hashAlgos hashes; + hashesSRI = map2' ( + hashAlgo: hash: + builtins.convertHash { + inherit hash hashAlgo; + toHashFormat = "sri"; + } + ) hashAlgos hashes; }; getOutputHashesColon = hashes: { - hashesBase16 = map2' (hashAlgo: hashBody: builtins.convertHash { hash = hashAlgo + ":" + hashBody; toHashFormat = "base16";}) hashAlgos hashes; - hashesNix32 = map2' (hashAlgo: hashBody: builtins.convertHash { hash = hashAlgo + ":" + hashBody; toHashFormat = "nix32";}) hashAlgos hashes; - hashesBase32 = map2' (hashAlgo: hashBody: builtins.convertHash { hash = hashAlgo + ":" + hashBody; toHashFormat = "base32";}) hashAlgos hashes; - hashesBase64 = map2' (hashAlgo: hashBody: builtins.convertHash { hash = hashAlgo + ":" + hashBody; toHashFormat = "base64";}) hashAlgos hashes; - hashesSRI = map2' (hashAlgo: hashBody: builtins.convertHash { hash = hashAlgo + ":" + hashBody; toHashFormat = "sri" ;}) hashAlgos hashes; + hashesBase16 = map2' ( + hashAlgo: hashBody: + builtins.convertHash { + hash = hashAlgo + ":" + hashBody; + toHashFormat = "base16"; + } + ) hashAlgos hashes; + hashesNix32 = map2' ( + hashAlgo: hashBody: + builtins.convertHash { + hash = hashAlgo + ":" + hashBody; + toHashFormat = "nix32"; + } + ) hashAlgos hashes; + hashesBase32 = map2' ( + hashAlgo: hashBody: + builtins.convertHash { + hash = hashAlgo + ":" + hashBody; + toHashFormat = "base32"; + } + ) hashAlgos hashes; + hashesBase64 = map2' ( + hashAlgo: hashBody: + builtins.convertHash { + hash = hashAlgo + ":" + hashBody; + toHashFormat = "base64"; + } + ) hashAlgos hashes; + hashesSRI = map2' ( + hashAlgo: hashBody: + builtins.convertHash { + hash = hashAlgo + ":" + hashBody; + toHashFormat = "sri"; + } + ) hashAlgos hashes; }; outputHashes = getOutputHashes hashesBase16; in # map2'` -assert map2' (s1: s2: s1 + s2) [ "a" "b" ] [ "c" "d" ] == [ "ac" "bd" ]; +assert + map2' (s1: s2: s1 + s2) [ "a" "b" ] [ "c" "d" ] == [ + "ac" + "bd" + ]; # hashesBase16 assert outputHashes.hashesBase16 == hashesBase16; # standard SRI hashes -assert outputHashes.hashesSRI == (map2' (hashAlgo: hashBody: hashAlgo + "-" + hashBody) hashAlgos outputHashes.hashesBase64); +assert + outputHashes.hashesSRI + == (map2' (hashAlgo: hashBody: hashAlgo + "-" + hashBody) hashAlgos outputHashes.hashesBase64); # without prefix assert builtins.all (x: getOutputHashes x == outputHashes) (builtins.attrValues outputHashes); # colon-separated. # Note that colon prefix must not be applied to the standard SRI. e.g. "sha256:sha256-..." is illegal. -assert builtins.all (x: getOutputHashesColon x == outputHashes) (with outputHashes; [ hashesBase16 hashesBase32 hashesBase64 ]); +assert builtins.all (x: getOutputHashesColon x == outputHashes) ( + with outputHashes; + [ + hashesBase16 + hashesBase32 + hashesBase64 + ] +); outputHashes diff --git a/tests/functional/lang/eval-okay-deepseq.nix b/tests/functional/lang/eval-okay-deepseq.nix index 53aa4b1dc25..f9aa5f720f3 100644 --- a/tests/functional/lang/eval-okay-deepseq.nix +++ b/tests/functional/lang/eval-okay-deepseq.nix @@ -1 +1,9 @@ -builtins.deepSeq (let as = { x = 123; y = as; }; in as) 456 +builtins.deepSeq ( + let + as = { + x = 123; + y = as; + }; + in + as +) 456 diff --git a/tests/functional/lang/eval-okay-delayed-with-inherit.nix b/tests/functional/lang/eval-okay-delayed-with-inherit.nix index 84b388c2713..10ce7df13c0 100644 --- a/tests/functional/lang/eval-okay-delayed-with-inherit.nix +++ b/tests/functional/lang/eval-okay-delayed-with-inherit.nix @@ -4,7 +4,10 @@ let name = "a"; system = builtins.currentSystem; builder = "/bin/sh"; - args = [ "-c" "touch $out" ]; + args = [ + "-c" + "touch $out" + ]; inherit b; }; @@ -16,9 +19,13 @@ let name = "b-overridden"; system = builtins.currentSystem; builder = "/bin/sh"; - args = [ "-c" "touch $out" ]; + args = [ + "-c" + "touch $out" + ]; }; }; pkgs = pkgs_ // (packageOverrides pkgs_); -in pkgs.a.b.name +in +pkgs.a.b.name diff --git a/tests/functional/lang/eval-okay-delayed-with.nix b/tests/functional/lang/eval-okay-delayed-with.nix index 3fb023e1cd4..52ec24e12e4 100644 --- a/tests/functional/lang/eval-okay-delayed-with.nix +++ b/tests/functional/lang/eval-okay-delayed-with.nix @@ -5,7 +5,10 @@ let name = "a"; system = builtins.currentSystem; builder = "/bin/sh"; - args = [ "-c" "touch $out" ]; + args = [ + "-c" + "touch $out" + ]; inherit b; }; @@ -13,17 +16,22 @@ let name = "b"; system = builtins.currentSystem; builder = "/bin/sh"; - args = [ "-c" "touch $out" ]; + args = [ + "-c" + "touch $out" + ]; inherit a; }; c = b; }; - packageOverrides = pkgs: with pkgs; { - b = derivation (b.drvAttrs // { name = "${b.name}-overridden"; }); - }; + packageOverrides = + pkgs: with pkgs; { + b = derivation (b.drvAttrs // { name = "${b.name}-overridden"; }); + }; pkgs = pkgs_ // (packageOverrides pkgs_); -in "${pkgs.a.b.name} ${pkgs.c.name} ${pkgs.b.a.name}" +in +"${pkgs.a.b.name} ${pkgs.c.name} ${pkgs.b.a.name}" diff --git a/tests/functional/lang/eval-okay-dynamic-attrs-2.nix b/tests/functional/lang/eval-okay-dynamic-attrs-2.nix index 6d57bf85490..95fe79e2558 100644 --- a/tests/functional/lang/eval-okay-dynamic-attrs-2.nix +++ b/tests/functional/lang/eval-okay-dynamic-attrs-2.nix @@ -1 +1,5 @@ -{ a."${"b"}" = true; a."${"c"}" = false; }.a.b +{ + a."${"b"}" = true; + a."${"c"}" = false; +} +.a.b diff --git a/tests/functional/lang/eval-okay-dynamic-attrs-bare.nix b/tests/functional/lang/eval-okay-dynamic-attrs-bare.nix index 0dbe15e6384..a612bf69dfa 100644 --- a/tests/functional/lang/eval-okay-dynamic-attrs-bare.nix +++ b/tests/functional/lang/eval-okay-dynamic-attrs-bare.nix @@ -2,7 +2,8 @@ let aString = "a"; bString = "b"; -in { +in +{ hasAttrs = { a.b = null; } ? ${aString}.b; selectAttrs = { a.b = true; }.a.${bString}; @@ -11,7 +12,17 @@ in { binds = { ${aString}."${bString}c" = true; }.a.bc; - recBinds = rec { ${bString} = a; a = true; }.b; + recBinds = + rec { + ${bString} = a; + a = true; + } + .b; - multiAttrs = { ${aString} = true; ${bString} = false; }.a; + multiAttrs = + { + ${aString} = true; + ${bString} = false; + } + .a; } diff --git a/tests/functional/lang/eval-okay-dynamic-attrs.nix b/tests/functional/lang/eval-okay-dynamic-attrs.nix index ee02ac7e657..f46e26b992f 100644 --- a/tests/functional/lang/eval-okay-dynamic-attrs.nix +++ b/tests/functional/lang/eval-okay-dynamic-attrs.nix @@ -2,7 +2,8 @@ let aString = "a"; bString = "b"; -in { +in +{ hasAttrs = { a.b = null; } ? "${aString}".b; selectAttrs = { a.b = true; }.a."${bString}"; @@ -11,7 +12,17 @@ in { binds = { "${aString}"."${bString}c" = true; }.a.bc; - recBinds = rec { "${bString}" = a; a = true; }.b; + recBinds = + rec { + "${bString}" = a; + a = true; + } + .b; - multiAttrs = { "${aString}" = true; "${bString}" = false; }.a; + multiAttrs = + { + "${aString}" = true; + "${bString}" = false; + } + .a; } diff --git a/tests/functional/lang/eval-okay-elem.nix b/tests/functional/lang/eval-okay-elem.nix index 71ea7a4ed03..004111dcc69 100644 --- a/tests/functional/lang/eval-okay-elem.nix +++ b/tests/functional/lang/eval-okay-elem.nix @@ -1,6 +1,11 @@ with import ./lib.nix; -let xs = range 10 40; in - -[ (builtins.elem 23 xs) (builtins.elem 42 xs) (builtins.elemAt xs 20) ] +let + xs = range 10 40; +in +[ + (builtins.elem 23 xs) + (builtins.elem 42 xs) + (builtins.elemAt xs 20) +] diff --git a/tests/functional/lang/eval-okay-empty-args.nix b/tests/functional/lang/eval-okay-empty-args.nix index 78c133afdd9..9466749f6ab 100644 --- a/tests/functional/lang/eval-okay-empty-args.nix +++ b/tests/functional/lang/eval-okay-empty-args.nix @@ -1 +1,4 @@ -({}: {x,y,}: "${x}${y}") {} {x = "a"; y = "b";} +({ }: { x, y }: "${x}${y}") { } { + x = "a"; + y = "b"; +} diff --git a/tests/functional/lang/eval-okay-eq-derivations.nix b/tests/functional/lang/eval-okay-eq-derivations.nix index d526cb4a216..ac802f433c7 100644 --- a/tests/functional/lang/eval-okay-eq-derivations.nix +++ b/tests/functional/lang/eval-okay-eq-derivations.nix @@ -1,10 +1,40 @@ let - drvA1 = derivation { name = "a"; builder = "/foo"; system = "i686-linux"; }; - drvA2 = derivation { name = "a"; builder = "/foo"; system = "i686-linux"; }; - drvA3 = derivation { name = "a"; builder = "/foo"; system = "i686-linux"; } // { dummy = 1; }; - - drvC1 = derivation { name = "c"; builder = "/foo"; system = "i686-linux"; }; - drvC2 = derivation { name = "c"; builder = "/bar"; system = "i686-linux"; }; + drvA1 = derivation { + name = "a"; + builder = "/foo"; + system = "i686-linux"; + }; + drvA2 = derivation { + name = "a"; + builder = "/foo"; + system = "i686-linux"; + }; + drvA3 = + derivation { + name = "a"; + builder = "/foo"; + system = "i686-linux"; + } + // { + dummy = 1; + }; -in [ (drvA1 == drvA1) (drvA1 == drvA2) (drvA1 == drvA3) (drvC1 == drvC2) ] + drvC1 = derivation { + name = "c"; + builder = "/foo"; + system = "i686-linux"; + }; + drvC2 = derivation { + name = "c"; + builder = "/bar"; + system = "i686-linux"; + }; + +in +[ + (drvA1 == drvA1) + (drvA1 == drvA2) + (drvA1 == drvA3) + (drvC1 == drvC2) +] diff --git a/tests/functional/lang/eval-okay-eq.nix b/tests/functional/lang/eval-okay-eq.nix index 73d200b3814..21cb08790ca 100644 --- a/tests/functional/lang/eval-okay-eq.nix +++ b/tests/functional/lang/eval-okay-eq.nix @@ -1,3 +1,13 @@ -["foobar" (rec {x = 1; y = x;})] -== -[("foo" + "bar") ({x = 1; y = 1;})] +[ + "foobar" + (rec { + x = 1; + y = x; + }) +] == [ + ("foo" + "bar") + ({ + x = 1; + y = 1; + }) +] diff --git a/tests/functional/lang/eval-okay-filter.nix b/tests/functional/lang/eval-okay-filter.nix index 85109b0d0eb..ef4e490c0fd 100644 --- a/tests/functional/lang/eval-okay-filter.nix +++ b/tests/functional/lang/eval-okay-filter.nix @@ -1,5 +1,8 @@ with import ./lib.nix; -builtins.filter - (x: x / 2 * 2 == x) - (builtins.concatLists [ (range 0 10) (range 100 110) ]) +builtins.filter (x: x / 2 * 2 == x) ( + builtins.concatLists [ + (range 0 10) + (range 100 110) + ] +) diff --git a/tests/functional/lang/eval-okay-flake-ref-to-string.nix b/tests/functional/lang/eval-okay-flake-ref-to-string.nix index dbb4e5b2af4..f477ba52caf 100644 --- a/tests/functional/lang/eval-okay-flake-ref-to-string.nix +++ b/tests/functional/lang/eval-okay-flake-ref-to-string.nix @@ -1,7 +1,7 @@ builtins.flakeRefToString { - type = "github"; + type = "github"; owner = "NixOS"; - repo = "nixpkgs"; - ref = "23.05"; - dir = "lib"; + repo = "nixpkgs"; + ref = "23.05"; + dir = "lib"; } diff --git a/tests/functional/lang/eval-okay-flatten.nix b/tests/functional/lang/eval-okay-flatten.nix index fe911e9683e..ade74c8e8fe 100644 --- a/tests/functional/lang/eval-okay-flatten.nix +++ b/tests/functional/lang/eval-okay-flatten.nix @@ -2,7 +2,19 @@ with import ./lib.nix; let { - l = ["1" "2" ["3" ["4"] ["5" "6"]] "7"]; + l = [ + "1" + "2" + [ + "3" + [ "4" ] + [ + "5" + "6" + ] + ] + "7" + ]; body = concat (flatten l); } diff --git a/tests/functional/lang/eval-okay-floor-ceil.nix b/tests/functional/lang/eval-okay-floor-ceil.nix index d76a0d86ea7..06f1a13d252 100644 --- a/tests/functional/lang/eval-okay-floor-ceil.nix +++ b/tests/functional/lang/eval-okay-floor-ceil.nix @@ -6,4 +6,11 @@ let n3 = builtins.floor 23; n4 = builtins.ceil 23; in - builtins.concatStringsSep ";" (map toString [ n1 n2 n3 n4 ]) +builtins.concatStringsSep ";" ( + map toString [ + n1 + n2 + n3 + n4 + ] +) diff --git a/tests/functional/lang/eval-okay-foldlStrict-lazy-elements.nix b/tests/functional/lang/eval-okay-foldlStrict-lazy-elements.nix index c666e07f3ae..49751c759d0 100644 --- a/tests/functional/lang/eval-okay-foldlStrict-lazy-elements.nix +++ b/tests/functional/lang/eval-okay-foldlStrict-lazy-elements.nix @@ -1,9 +1,6 @@ # Tests that the rhs argument of op is not forced unconditionally let - lst = builtins.foldl' - (acc: x: acc ++ [ x ]) - [ ] - [ 42 (throw "this shouldn't be evaluated") ]; + lst = builtins.foldl' (acc: x: acc ++ [ x ]) [ ] [ 42 (throw "this shouldn't be evaluated") ]; in builtins.head lst diff --git a/tests/functional/lang/eval-okay-foldlStrict-lazy-initial-accumulator.nix b/tests/functional/lang/eval-okay-foldlStrict-lazy-initial-accumulator.nix index abcd5366ab8..9cf0ef32c87 100644 --- a/tests/functional/lang/eval-okay-foldlStrict-lazy-initial-accumulator.nix +++ b/tests/functional/lang/eval-okay-foldlStrict-lazy-initial-accumulator.nix @@ -1,6 +1,6 @@ # Checks that the nul value for the accumulator is not forced unconditionally. # Some languages provide a foldl' that is strict in this argument, but Nix does not. -builtins.foldl' - (_: x: x) - (throw "This is never forced") - [ "but the results of applying op are" 42 ] +builtins.foldl' (_: x: x) (throw "This is never forced") [ + "but the results of applying op are" + 42 +] diff --git a/tests/functional/lang/eval-okay-fromjson-escapes.nix b/tests/functional/lang/eval-okay-fromjson-escapes.nix index f0071350773..6330e9c8667 100644 --- a/tests/functional/lang/eval-okay-fromjson-escapes.nix +++ b/tests/functional/lang/eval-okay-fromjson-escapes.nix @@ -1,3 +1,4 @@ # This string contains all supported escapes in a JSON string, per json.org # \b and \f are not supported by Nix -builtins.fromJSON ''"quote \" reverse solidus \\ solidus \/ backspace \b formfeed \f newline \n carriage return \r horizontal tab \t 1 char unicode encoded backspace \u0008 1 char unicode encoded e with accent \u00e9 2 char unicode encoded s with caron \u0161 3 char unicode encoded rightwards arrow \u2192"'' +builtins.fromJSON + ''"quote \" reverse solidus \\ solidus \/ backspace \b formfeed \f newline \n carriage return \r horizontal tab \t 1 char unicode encoded backspace \u0008 1 char unicode encoded e with accent \u00e9 2 char unicode encoded s with caron \u0161 3 char unicode encoded rightwards arrow \u2192"'' diff --git a/tests/functional/lang/eval-okay-fromjson.nix b/tests/functional/lang/eval-okay-fromjson.nix index 4c526b9ae5d..0e8a2351fe8 100644 --- a/tests/functional/lang/eval-okay-fromjson.nix +++ b/tests/functional/lang/eval-okay-fromjson.nix @@ -1,41 +1,55 @@ -builtins.fromJSON - '' - { - "Video": { - "Title": "The Penguin Chronicles", - "Width": 1920, - "Height": 1080, - "EmbeddedData": [3.14159, 23493,null, true ,false, -10], - "Thumb": { - "Url": "http://www.example.com/video/5678931", - "Width": 200, - "Height": 250 - }, - "Animated" : false, - "IDs": [116, 943, 234, 38793, true ,false,null, -100], - "Escapes": "\"\\\/\t\n\r\t", - "Subtitle" : false, - "Latitude": 37.7668, - "Longitude": -122.3959 - } - } - '' -== - { Video = - { Title = "The Penguin Chronicles"; - Width = 1920; - Height = 1080; - EmbeddedData = [ 3.14159 23493 null true false (0-10) ]; - Thumb = - { Url = "http://www.example.com/video/5678931"; - Width = 200; - Height = 250; - }; - Animated = false; - IDs = [ 116 943 234 38793 true false null (0-100) ]; - Escapes = "\"\\\/\t\n\r\t"; # supported in JSON but not Nix: \b\f - Subtitle = false; - Latitude = 37.7668; - Longitude = -122.3959; - }; +builtins.fromJSON '' + { + "Video": { + "Title": "The Penguin Chronicles", + "Width": 1920, + "Height": 1080, + "EmbeddedData": [3.14159, 23493,null, true ,false, -10], + "Thumb": { + "Url": "http://www.example.com/video/5678931", + "Width": 200, + "Height": 250 + }, + "Animated" : false, + "IDs": [116, 943, 234, 38793, true ,false,null, -100], + "Escapes": "\"\\\/\t\n\r\t", + "Subtitle" : false, + "Latitude": 37.7668, + "Longitude": -122.3959 + } } +'' == { + Video = { + Title = "The Penguin Chronicles"; + Width = 1920; + Height = 1080; + EmbeddedData = [ + 3.14159 + 23493 + null + true + false + (0 - 10) + ]; + Thumb = { + Url = "http://www.example.com/video/5678931"; + Width = 200; + Height = 250; + }; + Animated = false; + IDs = [ + 116 + 943 + 234 + 38793 + true + false + null + (0 - 100) + ]; + Escapes = "\"\\\/\t\n\r\t"; # supported in JSON but not Nix: \b\f + Subtitle = false; + Latitude = 37.7668; + Longitude = -122.3959; + }; +} diff --git a/tests/functional/lang/eval-okay-functionargs.nix b/tests/functional/lang/eval-okay-functionargs.nix index 68dca62ee18..7c11f19c235 100644 --- a/tests/functional/lang/eval-okay-functionargs.nix +++ b/tests/functional/lang/eval-okay-functionargs.nix @@ -1,29 +1,74 @@ let - stdenvFun = { }: { name = "stdenv"; }; - stdenv2Fun = { }: { name = "stdenv2"; }; - fetchurlFun = { stdenv }: assert stdenv.name == "stdenv"; { name = "fetchurl"; }; - atermFun = { stdenv, fetchurl }: { name = "aterm-${stdenv.name}"; }; - aterm2Fun = { stdenv, fetchurl }: { name = "aterm2-${stdenv.name}"; }; - nixFun = { stdenv, fetchurl, aterm }: { name = "nix-${stdenv.name}-${aterm.name}"; }; - + stdenvFun = + { }: + { + name = "stdenv"; + }; + stdenv2Fun = + { }: + { + name = "stdenv2"; + }; + fetchurlFun = + { stdenv }: + assert stdenv.name == "stdenv"; + { + name = "fetchurl"; + }; + atermFun = + { stdenv, fetchurl }: + { + name = "aterm-${stdenv.name}"; + }; + aterm2Fun = + { stdenv, fetchurl }: + { + name = "aterm2-${stdenv.name}"; + }; + nixFun = + { + stdenv, + fetchurl, + aterm, + }: + { + name = "nix-${stdenv.name}-${aterm.name}"; + }; + mplayerFun = - { stdenv, fetchurl, enableX11 ? false, xorg ? null, enableFoo ? true, foo ? null }: + { + stdenv, + fetchurl, + enableX11 ? false, + xorg ? null, + enableFoo ? true, + foo ? null, + }: assert stdenv.name == "stdenv2"; assert enableX11 -> xorg.libXv.name == "libXv"; assert enableFoo -> foo != null; - { name = "mplayer-${stdenv.name}.${xorg.libXv.name}-${xorg.libX11.name}"; }; + { + name = "mplayer-${stdenv.name}.${xorg.libXv.name}-${xorg.libX11.name}"; + }; - makeOverridable = f: origArgs: f origArgs // - { override = newArgs: + makeOverridable = + f: origArgs: + f origArgs + // { + override = + newArgs: makeOverridable f (origArgs // (if builtins.isFunction newArgs then newArgs origArgs else newArgs)); }; - - callPackage_ = pkgs: f: args: + + callPackage_ = + pkgs: f: args: makeOverridable f ((builtins.intersectAttrs (builtins.functionArgs f) pkgs) // args); allPackages = - { overrides ? (pkgs: pkgsPrev: { }) }: + { + overrides ? (pkgs: pkgsPrev: { }), + }: let callPackage = callPackage_ pkgs; pkgs = pkgsStd // (overrides pkgs pkgsStd); @@ -34,18 +79,40 @@ let fetchurl = callPackage fetchurlFun { }; aterm = callPackage atermFun { }; xorg = callPackage xorgFun { }; - mplayer = callPackage mplayerFun { stdenv = pkgs.stdenv2; enableFoo = false; }; + mplayer = callPackage mplayerFun { + stdenv = pkgs.stdenv2; + enableFoo = false; + }; nix = callPackage nixFun { }; }; - in pkgs; + in + pkgs; + + libX11Fun = + { stdenv, fetchurl }: + { + name = "libX11"; + }; + libX11_2Fun = + { stdenv, fetchurl }: + { + name = "libX11_2"; + }; + libXvFun = + { + stdenv, + fetchurl, + libX11, + }: + { + name = "libXv"; + }; - libX11Fun = { stdenv, fetchurl }: { name = "libX11"; }; - libX11_2Fun = { stdenv, fetchurl }: { name = "libX11_2"; }; - libXvFun = { stdenv, fetchurl, libX11 }: { name = "libXv"; }; - xorgFun = { pkgs }: - let callPackage = callPackage_ (pkgs // pkgs.xorg); in + let + callPackage = callPackage_ (pkgs // pkgs.xorg); + in { libX11 = callPackage libX11Fun { }; libXv = callPackage libXvFun { }; @@ -56,25 +123,28 @@ in let pkgs = allPackages { }; - + pkgs2 = allPackages { overrides = pkgs: pkgsPrev: { stdenv = pkgs.stdenv2; nix = pkgsPrev.nix.override { aterm = aterm2Fun { inherit (pkgs) stdenv fetchurl; }; }; - xorg = pkgsPrev.xorg // { libX11 = libX11_2Fun { inherit (pkgs) stdenv fetchurl; }; }; + xorg = pkgsPrev.xorg // { + libX11 = libX11_2Fun { inherit (pkgs) stdenv fetchurl; }; + }; }; }; - + in - [ pkgs.stdenv.name - pkgs.fetchurl.name - pkgs.aterm.name - pkgs2.aterm.name - pkgs.xorg.libX11.name - pkgs.xorg.libXv.name - pkgs.mplayer.name - pkgs2.mplayer.name - pkgs.nix.name - pkgs2.nix.name - ] +[ + pkgs.stdenv.name + pkgs.fetchurl.name + pkgs.aterm.name + pkgs2.aterm.name + pkgs.xorg.libX11.name + pkgs.xorg.libXv.name + pkgs.mplayer.name + pkgs2.mplayer.name + pkgs.nix.name + pkgs2.nix.name +] diff --git a/tests/functional/lang/eval-okay-getattrpos-functionargs.nix b/tests/functional/lang/eval-okay-getattrpos-functionargs.nix index 11d6bb0e3ac..9692911cfc9 100644 --- a/tests/functional/lang/eval-okay-getattrpos-functionargs.nix +++ b/tests/functional/lang/eval-okay-getattrpos-functionargs.nix @@ -1,4 +1,8 @@ let - fun = { foo }: {}; + fun = { foo }: { }; pos = builtins.unsafeGetAttrPos "foo" (builtins.functionArgs fun); -in { inherit (pos) column line; file = baseNameOf pos.file; } +in +{ + inherit (pos) column line; + file = baseNameOf pos.file; +} diff --git a/tests/functional/lang/eval-okay-getattrpos.nix b/tests/functional/lang/eval-okay-getattrpos.nix index ca6b0796154..25bc57444fa 100644 --- a/tests/functional/lang/eval-okay-getattrpos.nix +++ b/tests/functional/lang/eval-okay-getattrpos.nix @@ -3,4 +3,8 @@ let foo = "bar"; }; pos = builtins.unsafeGetAttrPos "foo" as; -in { inherit (pos) column line; file = baseNameOf pos.file; } +in +{ + inherit (pos) column line; + file = baseNameOf pos.file; +} diff --git a/tests/functional/lang/eval-okay-groupBy.nix b/tests/functional/lang/eval-okay-groupBy.nix index 862d89dbd67..f4de5444a3c 100644 --- a/tests/functional/lang/eval-okay-groupBy.nix +++ b/tests/functional/lang/eval-okay-groupBy.nix @@ -1,5 +1,5 @@ with import ./lib.nix; -builtins.groupBy (n: - builtins.substring 0 1 (builtins.hashString "sha256" (toString n)) -) (range 0 31) +builtins.groupBy (n: builtins.substring 0 1 (builtins.hashString "sha256" (toString n))) ( + range 0 31 +) diff --git a/tests/functional/lang/eval-okay-hashfile.nix b/tests/functional/lang/eval-okay-hashfile.nix index aff5a185681..aeaf09f43f6 100644 --- a/tests/functional/lang/eval-okay-hashfile.nix +++ b/tests/functional/lang/eval-okay-hashfile.nix @@ -1,4 +1,14 @@ let - paths = [ ./data ./binary-data ]; + paths = [ + ./data + ./binary-data + ]; in - builtins.concatLists (map (hash: map (builtins.hashFile hash) paths) ["md5" "sha1" "sha256" "sha512"]) +builtins.concatLists ( + map (hash: map (builtins.hashFile hash) paths) [ + "md5" + "sha1" + "sha256" + "sha512" + ] +) diff --git a/tests/functional/lang/eval-okay-hashstring.nix b/tests/functional/lang/eval-okay-hashstring.nix index b0f62b245ca..c760b00435e 100644 --- a/tests/functional/lang/eval-okay-hashstring.nix +++ b/tests/functional/lang/eval-okay-hashstring.nix @@ -1,4 +1,15 @@ let - strings = [ "" "text 1" "text 2" ]; + strings = [ + "" + "text 1" + "text 2" + ]; in - builtins.concatLists (map (hash: map (builtins.hashString hash) strings) ["md5" "sha1" "sha256" "sha512"]) +builtins.concatLists ( + map (hash: map (builtins.hashString hash) strings) [ + "md5" + "sha1" + "sha256" + "sha512" + ] +) diff --git a/tests/functional/lang/eval-okay-if.nix b/tests/functional/lang/eval-okay-if.nix index 23e4c74d501..66b9d15b8cc 100644 --- a/tests/functional/lang/eval-okay-if.nix +++ b/tests/functional/lang/eval-okay-if.nix @@ -1 +1,6 @@ -if "foo" != "f" + "oo" then 1 else if false then 2 else 3 +if "foo" != "f" + "oo" then + 1 +else if false then + 2 +else + 3 diff --git a/tests/functional/lang/eval-okay-import.nix b/tests/functional/lang/eval-okay-import.nix index 0b18d941312..484dccac0e1 100644 --- a/tests/functional/lang/eval-okay-import.nix +++ b/tests/functional/lang/eval-okay-import.nix @@ -8,4 +8,5 @@ let builtins = builtins // overrides; } // import ./lib.nix; -in scopedImport overrides ./imported.nix +in +scopedImport overrides ./imported.nix diff --git a/tests/functional/lang/eval-okay-inherit-attr-pos.nix b/tests/functional/lang/eval-okay-inherit-attr-pos.nix index 017ab1d364d..c162d119677 100644 --- a/tests/functional/lang/eval-okay-inherit-attr-pos.nix +++ b/tests/functional/lang/eval-okay-inherit-attr-pos.nix @@ -4,9 +4,9 @@ let y = { inherit d x; }; z = { inherit (y) d x; }; in - [ - (builtins.unsafeGetAttrPos "d" y) - (builtins.unsafeGetAttrPos "x" y) - (builtins.unsafeGetAttrPos "d" z) - (builtins.unsafeGetAttrPos "x" z) - ] +[ + (builtins.unsafeGetAttrPos "d" y) + (builtins.unsafeGetAttrPos "x" y) + (builtins.unsafeGetAttrPos "d" z) + (builtins.unsafeGetAttrPos "x" z) +] diff --git a/tests/functional/lang/eval-okay-inherit-from.nix b/tests/functional/lang/eval-okay-inherit-from.nix index b72a1c639fd..1a0980aafb1 100644 --- a/tests/functional/lang/eval-okay-inherit-from.nix +++ b/tests/functional/lang/eval-okay-inherit-from.nix @@ -1,5 +1,12 @@ let - inherit (builtins.trace "used" { a = 1; b = 2; }) a b; + inherit + (builtins.trace "used" { + a = 1; + b = 2; + }) + a + b + ; x.c = 3; y.d = 4; @@ -13,4 +20,14 @@ let }; }; in - [ a b rec { x.c = []; inherit (x) c; inherit (y) d; __overrides.y.d = []; } merged ] +[ + a + b + rec { + x.c = [ ]; + inherit (x) c; + inherit (y) d; + __overrides.y.d = [ ]; + } + merged +] diff --git a/tests/functional/lang/eval-okay-intersectAttrs.nix b/tests/functional/lang/eval-okay-intersectAttrs.nix index 39d49938cc2..bf4d58a9969 100644 --- a/tests/functional/lang/eval-okay-intersectAttrs.nix +++ b/tests/functional/lang/eval-okay-intersectAttrs.nix @@ -1,6 +1,6 @@ let - alphabet = - { a = "a"; + alphabet = { + a = "a"; b = "b"; c = "c"; d = "d"; @@ -28,23 +28,46 @@ let z = "z"; }; foo = { - inherit (alphabet) f o b a r z q u x; + inherit (alphabet) + f + o + b + a + r + z + q + u + x + ; aa = throw "aa"; }; alphabetFail = builtins.mapAttrs throw alphabet; in -[ (builtins.intersectAttrs { a = abort "l1"; } { b = abort "r1"; }) +[ + (builtins.intersectAttrs { a = abort "l1"; } { b = abort "r1"; }) (builtins.intersectAttrs { a = abort "l2"; } { a = 1; }) (builtins.intersectAttrs alphabetFail { a = 1; }) - (builtins.intersectAttrs { a = abort "laa"; } alphabet) + (builtins.intersectAttrs { a = abort "laa"; } alphabet) (builtins.intersectAttrs alphabetFail { m = 1; }) - (builtins.intersectAttrs { m = abort "lam"; } alphabet) + (builtins.intersectAttrs { m = abort "lam"; } alphabet) (builtins.intersectAttrs alphabetFail { n = 1; }) - (builtins.intersectAttrs { n = abort "lan"; } alphabet) - (builtins.intersectAttrs alphabetFail { n = 1; p = 2; }) - (builtins.intersectAttrs { n = abort "lan2"; p = abort "lap"; } alphabet) - (builtins.intersectAttrs alphabetFail { n = 1; p = 2; }) - (builtins.intersectAttrs { n = abort "lan2"; p = abort "lap"; } alphabet) + (builtins.intersectAttrs { n = abort "lan"; } alphabet) + (builtins.intersectAttrs alphabetFail { + n = 1; + p = 2; + }) + (builtins.intersectAttrs { + n = abort "lan2"; + p = abort "lap"; + } alphabet) + (builtins.intersectAttrs alphabetFail { + n = 1; + p = 2; + }) + (builtins.intersectAttrs { + n = abort "lan2"; + p = abort "lap"; + } alphabet) (builtins.intersectAttrs alphabetFail alphabet) (builtins.intersectAttrs alphabet foo == builtins.intersectAttrs foo alphabet) ] diff --git a/tests/functional/lang/eval-okay-list.nix b/tests/functional/lang/eval-okay-list.nix index d433bcf908b..b5045a75378 100644 --- a/tests/functional/lang/eval-okay-list.nix +++ b/tests/functional/lang/eval-okay-list.nix @@ -2,6 +2,11 @@ with import ./lib.nix; let { - body = concat ["foo" "bar" "bla" "test"]; - -} \ No newline at end of file + body = concat [ + "foo" + "bar" + "bla" + "test" + ]; + +} diff --git a/tests/functional/lang/eval-okay-listtoattrs.nix b/tests/functional/lang/eval-okay-listtoattrs.nix index 4186e029b53..1de9d6d62f5 100644 --- a/tests/functional/lang/eval-okay-listtoattrs.nix +++ b/tests/functional/lang/eval-okay-listtoattrs.nix @@ -1,11 +1,24 @@ # this test shows how to use listToAttrs and that evaluation is still lazy (throw isn't called) with import ./lib.nix; -let - asi = name: value : { inherit name value; }; - list = [ ( asi "a" "A" ) ( asi "b" "B" ) ]; +let + asi = name: value: { inherit name value; }; + list = [ + (asi "a" "A") + (asi "b" "B") + ]; a = builtins.listToAttrs list; - b = builtins.listToAttrs ( list ++ list ); - r = builtins.listToAttrs [ (asi "result" [ a b ]) ( asi "throw" (throw "this should not be thrown")) ]; - x = builtins.listToAttrs [ (asi "foo" "bar") (asi "foo" "bla") ]; -in concat (map (x: x.a) r.result) + x.foo + b = builtins.listToAttrs (list ++ list); + r = builtins.listToAttrs [ + (asi "result" [ + a + b + ]) + (asi "throw" (throw "this should not be thrown")) + ]; + x = builtins.listToAttrs [ + (asi "foo" "bar") + (asi "foo" "bla") + ]; +in +concat (map (x: x.a) r.result) + x.foo diff --git a/tests/functional/lang/eval-okay-logic.nix b/tests/functional/lang/eval-okay-logic.nix index fbb12794401..55cd2fc00fd 100644 --- a/tests/functional/lang/eval-okay-logic.nix +++ b/tests/functional/lang/eval-okay-logic.nix @@ -1 +1,2 @@ -assert !false && (true || false) -> true; 1 +assert !false && (true || false) -> true; +1 diff --git a/tests/functional/lang/eval-okay-map.nix b/tests/functional/lang/eval-okay-map.nix index a76c1d81145..22059f37a57 100644 --- a/tests/functional/lang/eval-okay-map.nix +++ b/tests/functional/lang/eval-okay-map.nix @@ -1,3 +1,9 @@ with import ./lib.nix; -concat (map (x: x + "bar") [ "foo" "bla" "xyzzy" ]) \ No newline at end of file +concat ( + map (x: x + "bar") [ + "foo" + "bla" + "xyzzy" + ] +) diff --git a/tests/functional/lang/eval-okay-mapattrs.nix b/tests/functional/lang/eval-okay-mapattrs.nix index f075b6275e5..c1182d13db5 100644 --- a/tests/functional/lang/eval-okay-mapattrs.nix +++ b/tests/functional/lang/eval-okay-mapattrs.nix @@ -1,3 +1,6 @@ with import ./lib.nix; -builtins.mapAttrs (name: value: name + "-" + value) { x = "foo"; y = "bar"; } +builtins.mapAttrs (name: value: name + "-" + value) { + x = "foo"; + y = "bar"; +} diff --git a/tests/functional/lang/eval-okay-merge-dynamic-attrs.nix b/tests/functional/lang/eval-okay-merge-dynamic-attrs.nix index f459a554f34..8ee8e503a6a 100644 --- a/tests/functional/lang/eval-okay-merge-dynamic-attrs.nix +++ b/tests/functional/lang/eval-okay-merge-dynamic-attrs.nix @@ -1,9 +1,17 @@ { - set1 = { a = 1; }; - set1 = { "${"b" + ""}" = 2; }; + set1 = { + a = 1; + }; + set1 = { + "${"b" + ""}" = 2; + }; - set2 = { "${"b" + ""}" = 2; }; - set2 = { a = 1; }; + set2 = { + "${"b" + ""}" = 2; + }; + set2 = { + a = 1; + }; set3.a = 1; set3."${"b" + ""}" = 2; diff --git a/tests/functional/lang/eval-okay-nested-with.nix b/tests/functional/lang/eval-okay-nested-with.nix index ba9d79aa79b..ee069eaa1c2 100644 --- a/tests/functional/lang/eval-okay-nested-with.nix +++ b/tests/functional/lang/eval-okay-nested-with.nix @@ -1,3 +1 @@ -with { x = 1; }; -with { x = 2; }; -x +with { x = 1; }; with { x = 2; }; x diff --git a/tests/functional/lang/eval-okay-new-let.nix b/tests/functional/lang/eval-okay-new-let.nix index 73812314150..1a938ce718f 100644 --- a/tests/functional/lang/eval-okay-new-let.nix +++ b/tests/functional/lang/eval-okay-new-let.nix @@ -1,14 +1,16 @@ let - f = z: + f = + z: let x = "foo"; y = "bar"; body = 1; # compat test in - z + x + y; + z + x + y; arg = "xyzzy"; -in f arg +in +f arg diff --git a/tests/functional/lang/eval-okay-null-dynamic-attrs.nix b/tests/functional/lang/eval-okay-null-dynamic-attrs.nix index b060c0bc985..76286b6225c 100644 --- a/tests/functional/lang/eval-okay-null-dynamic-attrs.nix +++ b/tests/functional/lang/eval-okay-null-dynamic-attrs.nix @@ -1 +1 @@ -{ ${null} = true; } == {} +{ ${null} = true; } == { } diff --git a/tests/functional/lang/eval-okay-overrides.nix b/tests/functional/lang/eval-okay-overrides.nix index 719bdc9c05e..1c0d5d7c2ea 100644 --- a/tests/functional/lang/eval-okay-overrides.nix +++ b/tests/functional/lang/eval-okay-overrides.nix @@ -1,8 +1,12 @@ let - overrides = { a = 2; b = 3; }; + overrides = { + a = 2; + b = 3; + }; -in (rec { +in +(rec { __overrides = overrides; x = a; a = 1; diff --git a/tests/functional/lang/eval-okay-parse-flake-ref.nix b/tests/functional/lang/eval-okay-parse-flake-ref.nix index db4ed2742cd..404c5df0824 100644 --- a/tests/functional/lang/eval-okay-parse-flake-ref.nix +++ b/tests/functional/lang/eval-okay-parse-flake-ref.nix @@ -1 +1 @@ - builtins.parseFlakeRef "github:NixOS/nixpkgs/23.05?dir=lib" +builtins.parseFlakeRef "github:NixOS/nixpkgs/23.05?dir=lib" diff --git a/tests/functional/lang/eval-okay-partition.nix b/tests/functional/lang/eval-okay-partition.nix index 846d2ce4948..b9566edf979 100644 --- a/tests/functional/lang/eval-okay-partition.nix +++ b/tests/functional/lang/eval-okay-partition.nix @@ -1,5 +1,8 @@ with import ./lib.nix; -builtins.partition - (x: x / 2 * 2 == x) - (builtins.concatLists [ (range 0 10) (range 100 110) ]) +builtins.partition (x: x / 2 * 2 == x) ( + builtins.concatLists [ + (range 0 10) + (range 100 110) + ] +) diff --git a/tests/functional/lang/eval-okay-path.nix b/tests/functional/lang/eval-okay-path.nix index 599b3354147..b8b48aae1a6 100644 --- a/tests/functional/lang/eval-okay-path.nix +++ b/tests/functional/lang/eval-okay-path.nix @@ -1,15 +1,15 @@ [ - (builtins.path - { path = ./.; - filter = path: _: baseNameOf path == "data"; - recursive = true; - sha256 = "1yhm3gwvg5a41yylymgblsclk95fs6jy72w0wv925mmidlhcq4sw"; - name = "output"; - }) - (builtins.path - { path = ./data; - recursive = false; - sha256 = "0k4lwj58f2w5yh92ilrwy9917pycipbrdrr13vbb3yd02j09vfxm"; - name = "output"; - }) + (builtins.path { + path = ./.; + filter = path: _: baseNameOf path == "data"; + recursive = true; + sha256 = "1yhm3gwvg5a41yylymgblsclk95fs6jy72w0wv925mmidlhcq4sw"; + name = "output"; + }) + (builtins.path { + path = ./data; + recursive = false; + sha256 = "0k4lwj58f2w5yh92ilrwy9917pycipbrdrr13vbb3yd02j09vfxm"; + name = "output"; + }) ] diff --git a/tests/functional/lang/eval-okay-patterns.nix b/tests/functional/lang/eval-okay-patterns.nix index 96fd25a0151..b92b232d2fa 100644 --- a/tests/functional/lang/eval-okay-patterns.nix +++ b/tests/functional/lang/eval-okay-patterns.nix @@ -1,16 +1,59 @@ let - f = args@{x, y, z}: x + args.y + z; + f = + args@{ + x, + y, + z, + }: + x + args.y + z; - g = {x, y, z}@args: f args; + g = + { + x, + y, + z, + }@args: + f args; - h = {x ? "d", y ? x, z ? args.x}@args: x + y + z; + h = + { + x ? "d", + y ? x, + z ? args.x, + }@args: + x + y + z; - j = {x, y, z, ...}: x + y + z; + j = + { + x, + y, + z, + ... + }: + x + y + z; in - f {x = "a"; y = "b"; z = "c";} + - g {x = "x"; y = "y"; z = "z";} + - h {x = "D";} + - h {x = "D"; y = "E"; z = "F";} + - j {x = "i"; y = "j"; z = "k"; bla = "bla"; foo = "bar";} +f { + x = "a"; + y = "b"; + z = "c"; +} ++ g { + x = "x"; + y = "y"; + z = "z"; +} ++ h { x = "D"; } ++ h { + x = "D"; + y = "E"; + z = "F"; +} ++ j { + x = "i"; + y = "j"; + z = "k"; + bla = "bla"; + foo = "bar"; +} diff --git a/tests/functional/lang/eval-okay-print.nix b/tests/functional/lang/eval-okay-print.nix index d36ba4da31c..1ad46560235 100644 --- a/tests/functional/lang/eval-okay-print.nix +++ b/tests/functional/lang/eval-okay-print.nix @@ -1 +1,15 @@ -with builtins; trace [(1+1)] [ null toString (deepSeq "x") (a: a) (let x=[x]; in x) ] +with builtins; +trace + [ (1 + 1) ] + [ + null + toString + (deepSeq "x") + (a: a) + ( + let + x = [ x ]; + in + x + ) + ] diff --git a/tests/functional/lang/eval-okay-readFileType.nix b/tests/functional/lang/eval-okay-readFileType.nix index 174fb6c3a02..79beb9a6e25 100644 --- a/tests/functional/lang/eval-okay-readFileType.nix +++ b/tests/functional/lang/eval-okay-readFileType.nix @@ -1,6 +1,6 @@ { - bar = builtins.readFileType ./readDir/bar; - foo = builtins.readFileType ./readDir/foo; + bar = builtins.readFileType ./readDir/bar; + foo = builtins.readFileType ./readDir/foo; linked = builtins.readFileType ./readDir/linked; - ldir = builtins.readFileType ./readDir/ldir; + ldir = builtins.readFileType ./readDir/ldir; } diff --git a/tests/functional/lang/eval-okay-redefine-builtin.nix b/tests/functional/lang/eval-okay-redefine-builtin.nix index df9fc3f37d2..ec95ffa932a 100644 --- a/tests/functional/lang/eval-okay-redefine-builtin.nix +++ b/tests/functional/lang/eval-okay-redefine-builtin.nix @@ -1,3 +1,4 @@ let throw = abort "Error!"; -in (builtins.tryEval ).success +in +(builtins.tryEval ).success diff --git a/tests/functional/lang/eval-okay-regex-match.nix b/tests/functional/lang/eval-okay-regex-match.nix index 273e2590713..54b995996f1 100644 --- a/tests/functional/lang/eval-okay-regex-match.nix +++ b/tests/functional/lang/eval-okay-regex-match.nix @@ -8,22 +8,34 @@ let in -assert matches "foobar" "foobar"; -assert matches "fo*" "f"; +assert matches "foobar" "foobar"; +assert matches "fo*" "f"; assert !matches "fo+" "f"; -assert matches "fo*" "fo"; -assert matches "fo*" "foo"; -assert matches "fo+" "foo"; -assert matches "fo{1,2}" "foo"; +assert matches "fo*" "fo"; +assert matches "fo*" "foo"; +assert matches "fo+" "foo"; +assert matches "fo{1,2}" "foo"; assert !matches "fo{1,2}" "fooo"; assert !matches "fo*" "foobar"; -assert matches "[[:space:]]+([^[:space:]]+)[[:space:]]+" " foo "; +assert matches "[[:space:]]+([^[:space:]]+)[[:space:]]+" " foo "; assert !matches "[[:space:]]+([[:upper:]]+)[[:space:]]+" " foo "; assert match "(.*)\\.nix" "foobar.nix" == [ "foobar" ]; assert match "[[:space:]]+([[:upper:]]+)[[:space:]]+" " FOO " == [ "FOO" ]; -assert splitFN "/path/to/foobar.nix" == [ "/path/to/" "/path/to" "foobar" "nix" ]; -assert splitFN "foobar.cc" == [ null null "foobar" "cc" ]; +assert + splitFN "/path/to/foobar.nix" == [ + "/path/to/" + "/path/to" + "foobar" + "nix" + ]; +assert + splitFN "foobar.cc" == [ + null + null + "foobar" + "cc" + ]; true diff --git a/tests/functional/lang/eval-okay-regex-split.nix b/tests/functional/lang/eval-okay-regex-split.nix index 0073e057787..8ab3e60cbb2 100644 --- a/tests/functional/lang/eval-okay-regex-split.nix +++ b/tests/functional/lang/eval-okay-regex-split.nix @@ -1,48 +1,197 @@ with builtins; # Non capturing regex returns empty lists -assert split "foobar" "foobar" == ["" [] ""]; -assert split "fo*" "f" == ["" [] ""]; -assert split "fo+" "f" == ["f"]; -assert split "fo*" "fo" == ["" [] ""]; -assert split "fo*" "foo" == ["" [] ""]; -assert split "fo+" "foo" == ["" [] ""]; -assert split "fo{1,2}" "foo" == ["" [] ""]; -assert split "fo{1,2}" "fooo" == ["" [] "o"]; -assert split "fo*" "foobar" == ["" [] "bar"]; +assert + split "foobar" "foobar" == [ + "" + [ ] + "" + ]; +assert + split "fo*" "f" == [ + "" + [ ] + "" + ]; +assert split "fo+" "f" == [ "f" ]; +assert + split "fo*" "fo" == [ + "" + [ ] + "" + ]; +assert + split "fo*" "foo" == [ + "" + [ ] + "" + ]; +assert + split "fo+" "foo" == [ + "" + [ ] + "" + ]; +assert + split "fo{1,2}" "foo" == [ + "" + [ ] + "" + ]; +assert + split "fo{1,2}" "fooo" == [ + "" + [ ] + "o" + ]; +assert + split "fo*" "foobar" == [ + "" + [ ] + "bar" + ]; # Capturing regex returns a list of sub-matches -assert split "(fo*)" "f" == ["" ["f"] ""]; -assert split "(fo+)" "f" == ["f"]; -assert split "(fo*)" "fo" == ["" ["fo"] ""]; -assert split "(f)(o*)" "f" == ["" ["f" ""] ""]; -assert split "(f)(o*)" "foo" == ["" ["f" "oo"] ""]; -assert split "(fo+)" "foo" == ["" ["foo"] ""]; -assert split "(fo{1,2})" "foo" == ["" ["foo"] ""]; -assert split "(fo{1,2})" "fooo" == ["" ["foo"] "o"]; -assert split "(fo*)" "foobar" == ["" ["foo"] "bar"]; +assert + split "(fo*)" "f" == [ + "" + [ "f" ] + "" + ]; +assert split "(fo+)" "f" == [ "f" ]; +assert + split "(fo*)" "fo" == [ + "" + [ "fo" ] + "" + ]; +assert + split "(f)(o*)" "f" == [ + "" + [ + "f" + "" + ] + "" + ]; +assert + split "(f)(o*)" "foo" == [ + "" + [ + "f" + "oo" + ] + "" + ]; +assert + split "(fo+)" "foo" == [ + "" + [ "foo" ] + "" + ]; +assert + split "(fo{1,2})" "foo" == [ + "" + [ "foo" ] + "" + ]; +assert + split "(fo{1,2})" "fooo" == [ + "" + [ "foo" ] + "o" + ]; +assert + split "(fo*)" "foobar" == [ + "" + [ "foo" ] + "bar" + ]; # Matches are greedy. -assert split "(o+)" "oooofoooo" == ["" ["oooo"] "f" ["oooo"] ""]; +assert + split "(o+)" "oooofoooo" == [ + "" + [ "oooo" ] + "f" + [ "oooo" ] + "" + ]; # Matches multiple times. -assert split "(b)" "foobarbaz" == ["foo" ["b"] "ar" ["b"] "az"]; +assert + split "(b)" "foobarbaz" == [ + "foo" + [ "b" ] + "ar" + [ "b" ] + "az" + ]; # Split large strings containing newlines. null are inserted when a # pattern within the current did not match anything. -assert split "[[:space:]]+|([',.!?])" '' - Nix Rocks! - That's why I use it. -'' == [ - "Nix" [ null ] "Rocks" ["!"] "" [ null ] - "That" ["'"] "s" [ null ] "why" [ null ] "I" [ null ] "use" [ null ] "it" ["."] "" [ null ] - "" -]; +assert + split "[[:space:]]+|([',.!?])" '' + Nix Rocks! + That's why I use it. + '' == [ + "Nix" + [ null ] + "Rocks" + [ "!" ] + "" + [ null ] + "That" + [ "'" ] + "s" + [ null ] + "why" + [ null ] + "I" + [ null ] + "use" + [ null ] + "it" + [ "." ] + "" + [ null ] + "" + ]; # Documentation examples -assert split "(a)b" "abc" == [ "" [ "a" ] "c" ]; -assert split "([ac])" "abc" == [ "" [ "a" ] "b" [ "c" ] "" ]; -assert split "(a)|(c)" "abc" == [ "" [ "a" null ] "b" [ null "c" ] "" ]; -assert split "([[:upper:]]+)" " FOO " == [ " " [ "FOO" ] " " ]; +assert + split "(a)b" "abc" == [ + "" + [ "a" ] + "c" + ]; +assert + split "([ac])" "abc" == [ + "" + [ "a" ] + "b" + [ "c" ] + "" + ]; +assert + split "(a)|(c)" "abc" == [ + "" + [ + "a" + null + ] + "b" + [ + null + "c" + ] + "" + ]; +assert + split "([[:upper:]]+)" " FOO " == [ + " " + [ "FOO" ] + " " + ]; true diff --git a/tests/functional/lang/eval-okay-regression-20220125.nix b/tests/functional/lang/eval-okay-regression-20220125.nix index 48550237394..1c4b8e09f39 100644 --- a/tests/functional/lang/eval-okay-regression-20220125.nix +++ b/tests/functional/lang/eval-okay-regression-20220125.nix @@ -1,2 +1 @@ ((__curPosFoo: __curPosFoo) 1) + ((__curPosBar: __curPosBar) 2) - diff --git a/tests/functional/lang/eval-okay-regrettable-rec-attrset-merge.nix b/tests/functional/lang/eval-okay-regrettable-rec-attrset-merge.nix index 8df6a2ad81d..e92ae8125a6 100644 --- a/tests/functional/lang/eval-okay-regrettable-rec-attrset-merge.nix +++ b/tests/functional/lang/eval-okay-regrettable-rec-attrset-merge.nix @@ -1,3 +1,10 @@ # This is for backwards compatibility, not because we like it. # See https://github.com/NixOS/nix/issues/9020. -{ a = rec { b = c + 1; d = 2; }; a.c = d + 3; }.a.b +{ + a = rec { + b = c + 1; + d = 2; + }; + a.c = d + 3; +} +.a.b diff --git a/tests/functional/lang/eval-okay-remove.nix b/tests/functional/lang/eval-okay-remove.nix index 4ad5ba897fa..a7ee3a07148 100644 --- a/tests/functional/lang/eval-okay-remove.nix +++ b/tests/functional/lang/eval-okay-remove.nix @@ -1,5 +1,8 @@ let { - attrs = {x = 123; y = 456;}; + attrs = { + x = 123; + y = 456; + }; - body = (removeAttrs attrs ["x"]).y; -} \ No newline at end of file + body = (removeAttrs attrs [ "x" ]).y; +} diff --git a/tests/functional/lang/eval-okay-repeated-empty-attrs.nix b/tests/functional/lang/eval-okay-repeated-empty-attrs.nix index 030a3b85c76..0749e21a57c 100644 --- a/tests/functional/lang/eval-okay-repeated-empty-attrs.nix +++ b/tests/functional/lang/eval-okay-repeated-empty-attrs.nix @@ -1,2 +1,5 @@ # Tests that empty attribute sets are not printed as `«repeated»`. -[ {} {} ] +[ + { } + { } +] diff --git a/tests/functional/lang/eval-okay-repeated-empty-list.nix b/tests/functional/lang/eval-okay-repeated-empty-list.nix index 376c51be886..7e24fe81b27 100644 --- a/tests/functional/lang/eval-okay-repeated-empty-list.nix +++ b/tests/functional/lang/eval-okay-repeated-empty-list.nix @@ -1 +1,4 @@ -[ [] [] ] +[ + [ ] + [ ] +] diff --git a/tests/functional/lang/eval-okay-replacestrings.nix b/tests/functional/lang/eval-okay-replacestrings.nix index a803e65199a..81a932a1daa 100644 --- a/tests/functional/lang/eval-okay-replacestrings.nix +++ b/tests/functional/lang/eval-okay-replacestrings.nix @@ -1,12 +1,13 @@ with builtins; -[ (replaceStrings ["o"] ["a"] "foobar") - (replaceStrings ["o"] [""] "foobar") - (replaceStrings ["oo"] ["u"] "foobar") - (replaceStrings ["oo" "a"] ["a" "oo"] "foobar") - (replaceStrings ["oo" "oo"] ["u" "i"] "foobar") - (replaceStrings [""] ["X"] "abc") - (replaceStrings [""] ["X"] "") - (replaceStrings ["-"] ["_"] "a-b") - (replaceStrings ["oo" "XX"] ["u" (throw "unreachable")] "foobar") +[ + (replaceStrings [ "o" ] [ "a" ] "foobar") + (replaceStrings [ "o" ] [ "" ] "foobar") + (replaceStrings [ "oo" ] [ "u" ] "foobar") + (replaceStrings [ "oo" "a" ] [ "a" "oo" ] "foobar") + (replaceStrings [ "oo" "oo" ] [ "u" "i" ] "foobar") + (replaceStrings [ "" ] [ "X" ] "abc") + (replaceStrings [ "" ] [ "X" ] "") + (replaceStrings [ "-" ] [ "_" ] "a-b") + (replaceStrings [ "oo" "XX" ] [ "u" (throw "unreachable") ] "foobar") ] diff --git a/tests/functional/lang/eval-okay-scope-1.nix b/tests/functional/lang/eval-okay-scope-1.nix index fa38a7174e0..b7bbcc432d5 100644 --- a/tests/functional/lang/eval-okay-scope-1.nix +++ b/tests/functional/lang/eval-okay-scope-1.nix @@ -1,6 +1,13 @@ -(({x}: x: +( + ( + { x }: + x: - { x = 1; - y = x; - } -) {x = 2;} 3).y + { + x = 1; + y = x; + } + ) + { x = 2; } + 3 +).y diff --git a/tests/functional/lang/eval-okay-scope-2.nix b/tests/functional/lang/eval-okay-scope-2.nix index eb8b02bc499..54f7ec3b230 100644 --- a/tests/functional/lang/eval-okay-scope-2.nix +++ b/tests/functional/lang/eval-okay-scope-2.nix @@ -1,6 +1,12 @@ -((x: {x}: - rec { - x = 1; - y = x; - } -) 2 {x = 3;}).y +( + ( + x: + { x }: + rec { + x = 1; + y = x; + } + ) + 2 + { x = 3; } +).y diff --git a/tests/functional/lang/eval-okay-scope-3.nix b/tests/functional/lang/eval-okay-scope-3.nix index 10d6bc04d83..6a77583b7da 100644 --- a/tests/functional/lang/eval-okay-scope-3.nix +++ b/tests/functional/lang/eval-okay-scope-3.nix @@ -1,6 +1,13 @@ -((x: as: {x}: - rec { - inherit (as) x; - y = x; - } -) 2 {x = 4;} {x = 3;}).y +( + ( + x: as: + { x }: + rec { + inherit (as) x; + y = x; + } + ) + 2 + { x = 4; } + { x = 3; } +).y diff --git a/tests/functional/lang/eval-okay-scope-4.nix b/tests/functional/lang/eval-okay-scope-4.nix index dc8243bc854..ccae8564cda 100644 --- a/tests/functional/lang/eval-okay-scope-4.nix +++ b/tests/functional/lang/eval-okay-scope-4.nix @@ -3,8 +3,13 @@ let { x = "a"; y = "b"; - f = {x ? y, y ? x}: x + y; - - body = f {x = "c";} + f {y = "d";}; + f = + { + x ? y, + y ? x, + }: + x + y; + + body = f { x = "c"; } + f { y = "d"; }; } diff --git a/tests/functional/lang/eval-okay-scope-6.nix b/tests/functional/lang/eval-okay-scope-6.nix index 0995d4e7e7e..be2cc31a1f2 100644 --- a/tests/functional/lang/eval-okay-scope-6.nix +++ b/tests/functional/lang/eval-okay-scope-6.nix @@ -1,7 +1,12 @@ let { - f = {x ? y, y ? x}: x + y; + f = + { + x ? y, + y ? x, + }: + x + y; - body = f {x = "c";} + f {y = "d";}; + body = f { x = "c"; } + f { y = "d"; }; } diff --git a/tests/functional/lang/eval-okay-scope-7.nix b/tests/functional/lang/eval-okay-scope-7.nix index 4da02968f6b..91f22f55388 100644 --- a/tests/functional/lang/eval-okay-scope-7.nix +++ b/tests/functional/lang/eval-okay-scope-7.nix @@ -3,4 +3,5 @@ rec { x = { y = 1; }; -}.y +} +.y diff --git a/tests/functional/lang/eval-okay-search-path.nix b/tests/functional/lang/eval-okay-search-path.nix index 6fe33decc01..702e1b64c15 100644 --- a/tests/functional/lang/eval-okay-search-path.nix +++ b/tests/functional/lang/eval-okay-search-path.nix @@ -6,5 +6,16 @@ assert isFunction (import ); assert length __nixPath == 5; assert length (filter (x: baseNameOf x.path == "dir4") __nixPath) == 1; -import + import + import + import - + (let __nixPath = [ { path = ./dir2; } { path = ./dir1; } ]; in import ) +import ++ import ++ import ++ import ++ ( + let + __nixPath = [ + { path = ./dir2; } + { path = ./dir1; } + ]; + in + import +) diff --git a/tests/functional/lang/eval-okay-sort.nix b/tests/functional/lang/eval-okay-sort.nix index 50aa78e4032..412bda4a09f 100644 --- a/tests/functional/lang/eval-okay-sort.nix +++ b/tests/functional/lang/eval-okay-sort.nix @@ -1,20 +1,64 @@ with builtins; -[ (sort lessThan [ 483 249 526 147 42 77 ]) - (sort (x: y: y < x) [ 483 249 526 147 42 77 ]) - (sort lessThan [ "foo" "bar" "xyzzy" "fnord" ]) - (sort (x: y: x.key < y.key) - [ { key = 1; value = "foo"; } { key = 2; value = "bar"; } { key = 1; value = "fnord"; } ]) +[ (sort lessThan [ - [ 1 6 ] + 483 + 249 + 526 + 147 + 42 + 77 + ]) + (sort (x: y: y < x) [ + 483 + 249 + 526 + 147 + 42 + 77 + ]) + (sort lessThan [ + "foo" + "bar" + "xyzzy" + "fnord" + ]) + (sort (x: y: x.key < y.key) [ + { + key = 1; + value = "foo"; + } + { + key = 2; + value = "bar"; + } + { + key = 1; + value = "fnord"; + } + ]) + (sort lessThan [ + [ + 1 + 6 + ] [ ] - [ 2 3 ] + [ + 2 + 3 + ] [ 3 ] - [ 1 5 ] + [ + 1 + 5 + ] [ 2 ] [ 1 ] [ ] - [ 1 4 ] + [ + 1 + 4 + ] [ 3 ] ]) ] diff --git a/tests/functional/lang/eval-okay-string.nix b/tests/functional/lang/eval-okay-string.nix index 47cc989ad46..d3b743fdbed 100644 --- a/tests/functional/lang/eval-okay-string.nix +++ b/tests/functional/lang/eval-okay-string.nix @@ -1,12 +1,13 @@ -"foo" + "bar" - + toString (/a/b + /c/d) - + toString (/foo/bar + "/../xyzzy/." + "/foo.txt") - + ("/../foo" + toString /x/y) - + "escape: \"quote\" \n \\" - + "end +"foo" ++ "bar" ++ toString (/a/b + /c/d) ++ toString (/foo/bar + "/../xyzzy/." + "/foo.txt") ++ ("/../foo" + toString /x/y) ++ "escape: \"quote\" \n \\" ++ "end of line" - + "foo${if true then "b${"a" + "r"}" else "xyzzy"}blaat" - + "foo$bar" - + "$\"$\"" - + "$" ++ "foo${if true then "b${"a" + "r"}" else "xyzzy"}blaat" ++ "foo$bar" ++ "$\"$\"" ++ "$" diff --git a/tests/functional/lang/eval-okay-strings-as-attrs-names.nix b/tests/functional/lang/eval-okay-strings-as-attrs-names.nix index 5e40928dbe3..158dc8e754e 100644 --- a/tests/functional/lang/eval-okay-strings-as-attrs-names.nix +++ b/tests/functional/lang/eval-okay-strings-as-attrs-names.nix @@ -14,7 +14,5 @@ let # variable. "foo bar" = 1; -in t1 == "test" - && t2 == "caseok" - && t3 == true - && t4 == ["key 1"] +in +t1 == "test" && t2 == "caseok" && t3 == true && t4 == [ "key 1" ] diff --git a/tests/functional/lang/eval-okay-substring-context.nix b/tests/functional/lang/eval-okay-substring-context.nix index d0ef70d4e67..9e9d3a1aa95 100644 --- a/tests/functional/lang/eval-okay-substring-context.nix +++ b/tests/functional/lang/eval-okay-substring-context.nix @@ -2,10 +2,15 @@ with builtins; let - s = "${builtins.derivation { name = "test"; builder = "/bin/sh"; system = "x86_64-linux"; }}"; + s = "${builtins.derivation { + name = "test"; + builder = "/bin/sh"; + system = "x86_64-linux"; + }}"; in -if getContext s == getContext "${substring 0 0 s + unsafeDiscardStringContext s}" -then "okay" -else throw "empty substring should preserve context" +if getContext s == getContext "${substring 0 0 s + unsafeDiscardStringContext s}" then + "okay" +else + throw "empty substring should preserve context" diff --git a/tests/functional/lang/eval-okay-tail-call-1.nix b/tests/functional/lang/eval-okay-tail-call-1.nix index a3962ce3fdb..d3ec0c9adfd 100644 --- a/tests/functional/lang/eval-okay-tail-call-1.nix +++ b/tests/functional/lang/eval-okay-tail-call-1.nix @@ -1,3 +1,4 @@ let f = n: if n == 100000 then n else f (n + 1); -in f 0 +in +f 0 diff --git a/tests/functional/lang/eval-okay-tojson.nix b/tests/functional/lang/eval-okay-tojson.nix index ce67943bead..863c0766392 100644 --- a/tests/functional/lang/eval-okay-tojson.nix +++ b/tests/functional/lang/eval-okay-tojson.nix @@ -1,13 +1,26 @@ -builtins.toJSON - { a = 123; - b = -456; - c = "foo"; - d = "foo\n\"bar\""; - e = true; - f = false; - g = [ 1 2 3 ]; - h = [ "a" [ "b" { "foo\nbar" = {}; } ] ]; - i = 1 + 2; - j = 1.44; - k = { __toString = self: self.a; a = "foo"; }; - } +builtins.toJSON { + a = 123; + b = -456; + c = "foo"; + d = "foo\n\"bar\""; + e = true; + f = false; + g = [ + 1 + 2 + 3 + ]; + h = [ + "a" + [ + "b" + { "foo\nbar" = { }; } + ] + ]; + i = 1 + 2; + j = 1.44; + k = { + __toString = self: self.a; + a = "foo"; + }; +} diff --git a/tests/functional/lang/eval-okay-toxml2.nix b/tests/functional/lang/eval-okay-toxml2.nix index ff1791b30eb..0d5989a50e7 100644 --- a/tests/functional/lang/eval-okay-toxml2.nix +++ b/tests/functional/lang/eval-okay-toxml2.nix @@ -1 +1,8 @@ -builtins.toXML [("a" + "b") 10 (rec {x = "x"; y = x;})] +builtins.toXML [ + ("a" + "b") + 10 + (rec { + x = "x"; + y = x; + }) +] diff --git a/tests/functional/lang/eval-okay-tryeval.nix b/tests/functional/lang/eval-okay-tryeval.nix index 629bc440a85..22b23d88342 100644 --- a/tests/functional/lang/eval-okay-tryeval.nix +++ b/tests/functional/lang/eval-okay-tryeval.nix @@ -1,5 +1,8 @@ { x = builtins.tryEval "x"; - y = builtins.tryEval (assert false; "y"); + y = builtins.tryEval ( + assert false; + "y" + ); z = builtins.tryEval (throw "bla"); } diff --git a/tests/functional/lang/eval-okay-types.nix b/tests/functional/lang/eval-okay-types.nix index 9b58be5d1dd..0814489edd3 100644 --- a/tests/functional/lang/eval-okay-types.nix +++ b/tests/functional/lang/eval-okay-types.nix @@ -1,6 +1,7 @@ with builtins; -[ (isNull null) +[ + (isNull null) (isNull (x: x)) (isFunction (x: x)) (isFunction "fnord") @@ -29,7 +30,11 @@ with builtins; (typeOf "xyzzy") (typeOf null) (typeOf { x = 456; }) - (typeOf [ 1 2 3 ]) + (typeOf [ + 1 + 2 + 3 + ]) (typeOf (x: x)) (typeOf ((x: y: x) 1)) (typeOf map) diff --git a/tests/functional/lang/eval-okay-versions.nix b/tests/functional/lang/eval-okay-versions.nix index e9111f5f433..3456015e538 100644 --- a/tests/functional/lang/eval-okay-versions.nix +++ b/tests/functional/lang/eval-okay-versions.nix @@ -10,10 +10,13 @@ let lt = builtins.sub 0 1; gt = 1; - versionTest = v1: v2: expected: - let d1 = builtins.compareVersions v1 v2; - d2 = builtins.compareVersions v2 v1; - in d1 == builtins.sub 0 d2 && d1 == expected; + versionTest = + v1: v2: expected: + let + d1 = builtins.compareVersions v1 v2; + d2 = builtins.compareVersions v2 v1; + in + d1 == builtins.sub 0 d2 && d1 == expected; tests = [ ((builtins.parseDrvName name1).name == "hello") @@ -40,4 +43,5 @@ let (versionTest "2.3pre1" "2.3q" lt) ]; -in (import ./lib.nix).and tests +in +(import ./lib.nix).and tests diff --git a/tests/functional/lang/eval-okay-xml.nix b/tests/functional/lang/eval-okay-xml.nix index 9ee9f8a0b4f..9785c66ef42 100644 --- a/tests/functional/lang/eval-okay-xml.nix +++ b/tests/functional/lang/eval-okay-xml.nix @@ -10,12 +10,31 @@ rec { c = "foo" + "bar"; - f = {z, x, y}: if y then x else z; + f = + { + z, + x, + y, + }: + if y then x else z; id = x: x; - at = args@{x, y, z}: x; - - ellipsis = {x, y, z, ...}: x; + at = + args@{ + x, + y, + z, + }: + x; + + ellipsis = + { + x, + y, + z, + ... + }: + x; } diff --git a/tests/functional/lang/eval-okay-zipAttrsWith.nix b/tests/functional/lang/eval-okay-zipAttrsWith.nix index 877d4e5fa31..20f6891115e 100644 --- a/tests/functional/lang/eval-okay-zipAttrsWith.nix +++ b/tests/functional/lang/eval-okay-zipAttrsWith.nix @@ -3,7 +3,6 @@ with import ./lib.nix; let str = builtins.hashString "sha256" "test"; in -builtins.zipAttrsWith - (n: v: { inherit n v; }) - (map (n: { ${builtins.substring n 1 str} = n; }) - (range 0 31)) +builtins.zipAttrsWith (n: v: { inherit n v; }) ( + map (n: { ${builtins.substring n 1 str} = n; }) (range 0 31) +) diff --git a/tests/functional/lang/lib.nix b/tests/functional/lang/lib.nix index 028a538314b..126128abe7a 100644 --- a/tests/functional/lang/lib.nix +++ b/tests/functional/lang/lib.nix @@ -2,60 +2,76 @@ with builtins; rec { - fold = op: nul: list: - if list == [] - then nul - else op (head list) (fold op nul (tail list)); + fold = + op: nul: list: + if list == [ ] then nul else op (head list) (fold op nul (tail list)); - concat = - fold (x: y: x + y) ""; + concat = fold (x: y: x + y) ""; and = fold (x: y: x && y) true; - flatten = x: - if isList x - then fold (x: y: (flatten x) ++ y) [] x - else [x]; + flatten = x: if isList x then fold (x: y: (flatten x) ++ y) [ ] x else [ x ]; sum = foldl' (x: y: add x y) 0; - hasSuffix = ext: fileName: - let lenFileName = stringLength fileName; - lenExt = stringLength ext; - in !(lessThan lenFileName lenExt) && - substring (sub lenFileName lenExt) lenFileName fileName == ext; + hasSuffix = + ext: fileName: + let + lenFileName = stringLength fileName; + lenExt = stringLength ext; + in + !(lessThan lenFileName lenExt) && substring (sub lenFileName lenExt) lenFileName fileName == ext; # Split a list at the given position. - splitAt = pos: list: - if pos == 0 then {first = []; second = list;} else - if list == [] then {first = []; second = [];} else - let res = splitAt (sub pos 1) (tail list); - in {first = [(head list)] ++ res.first; second = res.second;}; + splitAt = + pos: list: + if pos == 0 then + { + first = [ ]; + second = list; + } + else if list == [ ] then + { + first = [ ]; + second = [ ]; + } + else + let + res = splitAt (sub pos 1) (tail list); + in + { + first = [ (head list) ] ++ res.first; + second = res.second; + }; # Stable merge sort. - sortBy = comp: list: - if lessThan 1 (length list) - then + sortBy = + comp: list: + if lessThan 1 (length list) then let split = splitAt (div (length list) 2) list; first = sortBy comp split.first; second = sortBy comp split.second; - in mergeLists comp first second - else list; + in + mergeLists comp first second + else + list; - mergeLists = comp: list1: list2: - if list1 == [] then list2 else - if list2 == [] then list1 else - if comp (head list2) (head list1) then [(head list2)] ++ mergeLists comp list1 (tail list2) else - [(head list1)] ++ mergeLists comp (tail list1) list2; + mergeLists = + comp: list1: list2: + if list1 == [ ] then + list2 + else if list2 == [ ] then + list1 + else if comp (head list2) (head list1) then + [ (head list2) ] ++ mergeLists comp list1 (tail list2) + else + [ (head list1) ] ++ mergeLists comp (tail list1) list2; id = x: x; const = x: y: x; - range = first: last: - if first > last - then [] - else genList (n: first + n) (last - first + 1); + range = first: last: if first > last then [ ] else genList (n: first + n) (last - first + 1); } diff --git a/tests/functional/linux-sandbox-cert-test.nix b/tests/functional/linux-sandbox-cert-test.nix index 2fc083ea932..82989c64f88 100644 --- a/tests/functional/linux-sandbox-cert-test.nix +++ b/tests/functional/linux-sandbox-cert-test.nix @@ -22,9 +22,12 @@ mkDerivation ( # derivations being cached, and do not want to compute the right hash. false; ''; - } // { - fixed-output = { outputHash = "sha256:0000000000000000000000000000000000000000000000000000000000000000"; }; + } + // { + fixed-output = { + outputHash = "sha256:0000000000000000000000000000000000000000000000000000000000000000"; + }; normal = { }; - }.${mode} + } + .${mode} ) - diff --git a/tests/functional/multiple-outputs.nix b/tests/functional/multiple-outputs.nix index 6ba7c523d8e..2c9243097d5 100644 --- a/tests/functional/multiple-outputs.nix +++ b/tests/functional/multiple-outputs.nix @@ -5,94 +5,111 @@ rec { # Want to ensure that "out" doesn't get a suffix on it's path. nameCheck = mkDerivation { name = "multiple-outputs-a"; - outputs = [ "out" "dev" ]; - builder = builtins.toFile "builder.sh" - '' - mkdir $first $second - test -z $all - echo "first" > $first/file - echo "second" > $second/file - ln -s $first $second/link - ''; + outputs = [ + "out" + "dev" + ]; + builder = builtins.toFile "builder.sh" '' + mkdir $first $second + test -z $all + echo "first" > $first/file + echo "second" > $second/file + ln -s $first $second/link + ''; helloString = "Hello, world!"; }; a = mkDerivation { name = "multiple-outputs-a"; - outputs = [ "first" "second" ]; - builder = builtins.toFile "builder.sh" - '' - mkdir $first $second - test -z $all - echo "first" > $first/file - echo "second" > $second/file - ln -s $first $second/link - ''; + outputs = [ + "first" + "second" + ]; + builder = builtins.toFile "builder.sh" '' + mkdir $first $second + test -z $all + echo "first" > $first/file + echo "second" > $second/file + ln -s $first $second/link + ''; helloString = "Hello, world!"; }; use-a = mkDerivation { name = "use-a"; inherit (a) first second; - builder = builtins.toFile "builder.sh" - '' - cat $first/file $second/file >$out - ''; + builder = builtins.toFile "builder.sh" '' + cat $first/file $second/file >$out + ''; }; b = mkDerivation { - defaultOutput = assert a.second.helloString == "Hello, world!"; a; - firstOutput = assert a.outputName == "first"; a.first.first; - secondOutput = assert a.second.outputName == "second"; a.second.first.first.second.second.first.second; + defaultOutput = + assert a.second.helloString == "Hello, world!"; + a; + firstOutput = + assert a.outputName == "first"; + a.first.first; + secondOutput = + assert a.second.outputName == "second"; + a.second.first.first.second.second.first.second; allOutputs = a.all; name = "multiple-outputs-b"; - builder = builtins.toFile "builder.sh" - '' - mkdir $out - test "$firstOutput $secondOutput" = "$allOutputs" - test "$defaultOutput" = "$firstOutput" - test "$(cat $firstOutput/file)" = "first" - test "$(cat $secondOutput/file)" = "second" - echo "success" > $out/file - ''; + builder = builtins.toFile "builder.sh" '' + mkdir $out + test "$firstOutput $secondOutput" = "$allOutputs" + test "$defaultOutput" = "$firstOutput" + test "$(cat $firstOutput/file)" = "first" + test "$(cat $secondOutput/file)" = "second" + echo "success" > $out/file + ''; }; c = mkDerivation { name = "multiple-outputs-c"; drv = b.drvPath; - builder = builtins.toFile "builder.sh" - '' - mkdir $out - ln -s $drv $out/drv - ''; + builder = builtins.toFile "builder.sh" '' + mkdir $out + ln -s $drv $out/drv + ''; }; d = mkDerivation { name = "multiple-outputs-d"; drv = builtins.unsafeDiscardOutputDependency b.drvPath; - builder = builtins.toFile "builder.sh" - '' - mkdir $out - echo $drv > $out/drv - ''; + builder = builtins.toFile "builder.sh" '' + mkdir $out + echo $drv > $out/drv + ''; }; - cyclic = (mkDerivation { - name = "cyclic-outputs"; - outputs = [ "a" "b" "c" ]; - builder = builtins.toFile "builder.sh" - '' + cyclic = + (mkDerivation { + name = "cyclic-outputs"; + outputs = [ + "a" + "b" + "c" + ]; + builder = builtins.toFile "builder.sh" '' mkdir $a $b $c echo $a > $b/foo echo $b > $c/bar echo $c > $a/baz ''; - }).a; + }).a; e = mkDerivation { name = "multiple-outputs-e"; - outputs = [ "a_a" "b" "c" ]; - meta.outputsToInstall = [ "a_a" "b" ]; + outputs = [ + "a_a" + "b" + "c" + ]; + meta.outputsToInstall = [ + "a_a" + "b" + ]; buildCommand = "mkdir $a_a $b $c"; }; @@ -104,33 +121,37 @@ rec { independent = mkDerivation { name = "multiple-outputs-independent"; - outputs = [ "first" "second" ]; - builder = builtins.toFile "builder.sh" - '' - mkdir $first $second - test -z $all - echo "first" > $first/file - echo "second" > $second/file - ''; + outputs = [ + "first" + "second" + ]; + builder = builtins.toFile "builder.sh" '' + mkdir $first $second + test -z $all + echo "first" > $first/file + echo "second" > $second/file + ''; }; use-independent = mkDerivation { name = "use-independent"; inherit (a) first second; - builder = builtins.toFile "builder.sh" - '' - cat $first/file $second/file >$out - ''; + builder = builtins.toFile "builder.sh" '' + cat $first/file $second/file >$out + ''; }; invalid-output-name-1 = mkDerivation { name = "invalid-output-name-1"; - outputs = [ "out/"]; + outputs = [ "out/" ]; }; invalid-output-name-2 = mkDerivation { name = "invalid-output-name-2"; - outputs = [ "x" "foo$"]; + outputs = [ + "x" + "foo$" + ]; }; } diff --git a/tests/functional/nar-access.nix b/tests/functional/nar-access.nix index 9948abe59ff..b1e88189a39 100644 --- a/tests/functional/nar-access.nix +++ b/tests/functional/nar-access.nix @@ -1,23 +1,22 @@ with import ./config.nix; rec { - a = mkDerivation { - name = "nar-index-a"; - builder = builtins.toFile "builder.sh" - '' - mkdir $out - mkdir $out/foo - touch $out/foo-x - touch $out/foo/bar - touch $out/foo/baz - touch $out/qux - mkdir $out/zyx + a = mkDerivation { + name = "nar-index-a"; + builder = builtins.toFile "builder.sh" '' + mkdir $out + mkdir $out/foo + touch $out/foo-x + touch $out/foo/bar + touch $out/foo/baz + touch $out/qux + mkdir $out/zyx - cat >$out/foo/data <$out/foo/data < $out - '' else '' - cp -r ${../common} ./common - cp ${../common.sh} ./common.sh - cp ${../config.nix} ./config.nix - cp -r ${./.} ./nested-sandboxing + buildCommand = + '' + set -x + set -eu -o pipefail + '' + + ( + if altitude == 0 then + '' + echo Deep enough! > $out + '' + else + '' + cp -r ${../common} ./common + cp ${../common.sh} ./common.sh + cp ${../config.nix} ./config.nix + cp -r ${./.} ./nested-sandboxing - export PATH=${builtins.getEnv "NIX_BIN_DIR"}:$PATH + export PATH=${builtins.getEnv "NIX_BIN_DIR"}:$PATH - export _NIX_TEST_SOURCE_DIR=$PWD - export _NIX_TEST_BUILD_DIR=$PWD + export _NIX_TEST_SOURCE_DIR=$PWD + export _NIX_TEST_BUILD_DIR=$PWD - source common.sh - source ./nested-sandboxing/command.sh + source common.sh + source ./nested-sandboxing/command.sh - runNixBuild ${storeFun} ${toString altitude} >> $out - ''); + runNixBuild ${storeFun} ${toString altitude} >> $out + '' + ); } diff --git a/tests/functional/package.nix b/tests/functional/package.nix index d1582b05d14..74c034196fd 100644 --- a/tests/functional/package.nix +++ b/tests/functional/package.nix @@ -1,103 +1,110 @@ -{ lib -, stdenv -, mkMesonDerivation +{ + lib, + stdenv, + mkMesonDerivation, -, meson -, ninja -, pkg-config + meson, + ninja, + pkg-config, -, jq -, git -, mercurial -, util-linux + jq, + git, + mercurial, + util-linux, -, nix-store -, nix-expr -, nix-cli + nix-store, + nix-expr, + nix-cli, -, busybox-sandbox-shell ? null + busybox-sandbox-shell ? null, -# Configuration Options + # Configuration Options -, pname ? "nix-functional-tests" -, version + pname ? "nix-functional-tests", + version, -# For running the functional tests against a different pre-built Nix. -, test-daemon ? null + # For running the functional tests against a different pre-built Nix. + test-daemon ? null, }: let inherit (lib) fileset; in -mkMesonDerivation (finalAttrs: { - inherit pname version; - - workDir = ./.; - fileset = fileset.unions [ - ../../scripts/nix-profile.sh.in - ../../.version - ../../tests/functional - ./. - ]; - - # Hack for sake of the dev shell - passthru.externalNativeBuildInputs = [ - meson - ninja - pkg-config - - jq - git - mercurial - ] ++ lib.optionals stdenv.hostPlatform.isLinux [ - # For various sandboxing tests that needs a statically-linked shell, - # etc. - busybox-sandbox-shell - # For Overlay FS tests need `mount`, `umount`, and `unshare`. - # For `script` command (ensuring a TTY) - # TODO use `unixtools` to be precise over which executables instead? - util-linux - ]; - - nativeBuildInputs = finalAttrs.passthru.externalNativeBuildInputs ++ [ - nix-cli - ]; - - buildInputs = [ - nix-store - nix-expr - ]; - - preConfigure = - # "Inline" .version so it's not a symlink, and includes the suffix. - # Do the meson utils, without modification. - '' - chmod u+w ./.version - echo ${version} > ../../../.version - '' - # TEMP hack for Meson before make is gone, where - # `src/nix-functional-tests` is during the transition a symlink and - # not the actual directory directory. - + '' - cd $(readlink -e $PWD) - echo $PWD | grep tests/functional +mkMesonDerivation ( + finalAttrs: + { + inherit pname version; + + workDir = ./.; + fileset = fileset.unions [ + ../../scripts/nix-profile.sh.in + ../../.version + ../../tests/functional + ./. + ]; + + # Hack for sake of the dev shell + passthru.externalNativeBuildInputs = + [ + meson + ninja + pkg-config + + jq + git + mercurial + ] + ++ lib.optionals stdenv.hostPlatform.isLinux [ + # For various sandboxing tests that needs a statically-linked shell, + # etc. + busybox-sandbox-shell + # For Overlay FS tests need `mount`, `umount`, and `unshare`. + # For `script` command (ensuring a TTY) + # TODO use `unixtools` to be precise over which executables instead? + util-linux + ]; + + nativeBuildInputs = finalAttrs.passthru.externalNativeBuildInputs ++ [ + nix-cli + ]; + + buildInputs = [ + nix-store + nix-expr + ]; + + preConfigure = + # "Inline" .version so it's not a symlink, and includes the suffix. + # Do the meson utils, without modification. + '' + chmod u+w ./.version + echo ${version} > ../../../.version + '' + # TEMP hack for Meson before make is gone, where + # `src/nix-functional-tests` is during the transition a symlink and + # not the actual directory directory. + + '' + cd $(readlink -e $PWD) + echo $PWD | grep tests/functional + ''; + + mesonCheckFlags = [ + "--print-errorlogs" + ]; + + doCheck = true; + + installPhase = '' + mkdir $out ''; - mesonCheckFlags = [ - "--print-errorlogs" - ]; + meta = { + platforms = lib.platforms.unix; + }; - doCheck = true; - - installPhase = '' - mkdir $out - ''; - - meta = { - platforms = lib.platforms.unix; - }; - -} // lib.optionalAttrs (test-daemon != null) { - NIX_DAEMON_PACKAGE = test-daemon; -}) + } + // lib.optionalAttrs (test-daemon != null) { + NIX_DAEMON_PACKAGE = test-daemon; + } +) diff --git a/tests/functional/parallel.nix b/tests/functional/parallel.nix index 23f142059f5..0adfe7d8e53 100644 --- a/tests/functional/parallel.nix +++ b/tests/functional/parallel.nix @@ -1,19 +1,33 @@ -{sleepTime ? 3}: +{ + sleepTime ? 3, +}: with import ./config.nix; let - mkDrv = text: inputs: mkDerivation { - name = "parallel"; - builder = ./parallel.builder.sh; - inherit text inputs shared sleepTime; - }; + mkDrv = + text: inputs: + mkDerivation { + name = "parallel"; + builder = ./parallel.builder.sh; + inherit + text + inputs + shared + sleepTime + ; + }; - a = mkDrv "a" []; - b = mkDrv "b" [a]; - c = mkDrv "c" [a]; - d = mkDrv "d" [a]; - e = mkDrv "e" [b c d]; + a = mkDrv "a" [ ]; + b = mkDrv "b" [ a ]; + c = mkDrv "c" [ a ]; + d = mkDrv "d" [ a ]; + e = mkDrv "e" [ + b + c + d + ]; -in e +in +e diff --git a/tests/functional/path.nix b/tests/functional/path.nix index 883c3c41bb1..b554765e85e 100644 --- a/tests/functional/path.nix +++ b/tests/functional/path.nix @@ -3,12 +3,12 @@ with import ./config.nix; mkDerivation { name = "filter"; builder = builtins.toFile "builder" "ln -s $input $out"; - input = - builtins.path { - path = ((builtins.getEnv "TEST_ROOT") + "/filterin"); - filter = path: type: - type != "symlink" - && baseNameOf path != "foo" - && !((import ./lang/lib.nix).hasSuffix ".bak" (baseNameOf path)); - }; + input = builtins.path { + path = ((builtins.getEnv "TEST_ROOT") + "/filterin"); + filter = + path: type: + type != "symlink" + && baseNameOf path != "foo" + && !((import ./lang/lib.nix).hasSuffix ".bak" (baseNameOf path)); + }; } diff --git a/tests/functional/readfile-context.nix b/tests/functional/readfile-context.nix index 54cd1afd9d3..d9880ca3201 100644 --- a/tests/functional/readfile-context.nix +++ b/tests/functional/readfile-context.nix @@ -25,4 +25,5 @@ let input = builtins.readFile (dependent + "/file1"); }; -in readDependent +in +readDependent diff --git a/tests/functional/recursive.nix b/tests/functional/recursive.nix index fe438f0ba5c..be9e55da37e 100644 --- a/tests/functional/recursive.nix +++ b/tests/functional/recursive.nix @@ -1,4 +1,6 @@ -let config_nix = /. + "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/config.nix"; in +let + config_nix = /. + "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/config.nix"; +in with import config_nix; mkDerivation rec { @@ -15,7 +17,9 @@ mkDerivation rec { buildCommand = '' mkdir $out - opts="--experimental-features nix-command ${if (NIX_TESTS_CA_BY_DEFAULT == "1") then "--extra-experimental-features ca-derivations" else ""}" + opts="--experimental-features nix-command ${ + if (NIX_TESTS_CA_BY_DEFAULT == "1") then "--extra-experimental-features ca-derivations" else "" + }" PATH=${builtins.getEnv "NIX_BIN_DIR"}:$PATH diff --git a/tests/functional/repl/doc-comment-function.nix b/tests/functional/repl/doc-comment-function.nix index cdd2413476f..a85d4a99fdb 100644 --- a/tests/functional/repl/doc-comment-function.nix +++ b/tests/functional/repl/doc-comment-function.nix @@ -1,3 +1,4 @@ -/** A doc comment for a file that only contains a function */ -{ ... }: -{ } +/** + A doc comment for a file that only contains a function +*/ +{ ... }: { } diff --git a/tests/functional/repl/doc-comments.nix b/tests/functional/repl/doc-comments.nix index e91ee0b513d..a7a285d48b9 100644 --- a/tests/functional/repl/doc-comments.nix +++ b/tests/functional/repl/doc-comments.nix @@ -6,55 +6,106 @@ multiply 2 3 => 6 ``` - */ + */ multiply = x: y: x * y; - /**👈 precisely this wide 👉*/ + /** + 👈 precisely this wide 👉 + */ measurement = x: x; - floatedIn = /** This also works. */ + floatedIn = + /** + This also works. + */ x: y: x; - compact=/**boom*/x: x; + compact = + /** + boom + */ + x: x; # https://github.com/NixOS/rfcs/blob/master/rfcs/0145-doc-strings.md#ambiguous-placement - /** Ignore!!! */ - unambiguous = - /** Very close */ + /** + Ignore!!! + */ + unambiguous = + /** + Very close + */ x: x; - /** Firmly rigid. */ + /** + Firmly rigid. + */ constant = true; - /** Immovably fixed. */ + /** + Immovably fixed. + */ lib.version = "9000"; - /** Unchangeably constant. */ + /** + Unchangeably constant. + */ lib.attr.empty = { }; lib.attr.undocumented = { }; - nonStrict = /** My syntax is not strict, but I'm strict anyway. */ x: x; - strict = /** I don't have to be strict, but I am anyway. */ { ... }: null; + nonStrict = + /** + My syntax is not strict, but I'm strict anyway. + */ + x: x; + strict = + /** + I don't have to be strict, but I am anyway. + */ + { ... }: null; # Note that pre and post are the same here. I just had to name them somehow. - strictPre = /** Here's one way to do this */ a@{ ... }: a; - strictPost = /** Here's another way to do this */ { ... }@a: a; + strictPre = + /** + Here's one way to do this + */ + a@{ ... }: a; + strictPost = + /** + Here's another way to do this + */ + { ... }@a: a; # TODO - /** You won't see this. */ + /** + You won't see this. + */ curriedArgs = - /** A documented function. */ + /** + A documented function. + */ x: - /** The function returned by applying once */ + /** + The function returned by applying once + */ y: - /** A function body performing summation of two items */ + /** + A function body performing summation of two items + */ x + y; - /** Documented formals (but you won't see this comment) */ + /** + Documented formals (but you won't see this comment) + */ documentedFormals = - /** Finds x */ - { /** The x attribute */ - x - }: x; + /** + Finds x + */ + { + /** + The x attribute + */ + x, + }: + x; } diff --git a/tests/functional/repl/doc-functor.nix b/tests/functional/repl/doc-functor.nix index f526f453f19..8a663886cf2 100644 --- a/tests/functional/repl/doc-functor.nix +++ b/tests/functional/repl/doc-functor.nix @@ -25,14 +25,14 @@ rec { makeOverridable = f: { /** This is a function that can be overridden. - */ + */ __functor = self: f; override = throw "not implemented"; }; /** Compute x^2 - */ + */ square = x: x * x; helper = makeOverridable square; @@ -41,8 +41,14 @@ rec { makeVeryOverridable = f: { /** This is a function that can be overridden. - */ - __functor = self: arg: f arg // { override = throw "not implemented"; overrideAttrs = throw "not implemented"; }; + */ + __functor = + self: arg: + f arg + // { + override = throw "not implemented"; + overrideAttrs = throw "not implemented"; + }; override = throw "not implemented"; }; @@ -64,7 +70,6 @@ rec { */ helper3 = makeVeryOverridable (x: x * x * x); - # ------ # getDoc traverses a potentially infinite structure in case of __functor, so @@ -73,7 +78,7 @@ rec { recursive = { /** This looks bad, but the docs are ok because of the eta expansion. - */ + */ __functor = self: x: self x; }; @@ -81,21 +86,23 @@ rec { /** Docs probably won't work in this case, because the "partial" application of self results in an infinite recursion. - */ + */ __functor = self: self.__functor self; }; - diverging = let - /** - Docs probably won't work in this case, because the "partial" application - of self results in an diverging computation that causes a stack overflow. - It's not an infinite recursion because each call is different. - This must be handled by the documentation retrieval logic, as it - reimplements the __functor invocation to be partial. - */ - f = x: { - __functor = self: (f (x + 1)); - }; - in f null; + diverging = + let + /** + Docs probably won't work in this case, because the "partial" application + of self results in an diverging computation that causes a stack overflow. + It's not an infinite recursion because each call is different. + This must be handled by the documentation retrieval logic, as it + reimplements the __functor invocation to be partial. + */ + f = x: { + __functor = self: (f (x + 1)); + }; + in + f null; } diff --git a/tests/functional/secure-drv-outputs.nix b/tests/functional/secure-drv-outputs.nix index b4ac8ff531f..169c3c5875b 100644 --- a/tests/functional/secure-drv-outputs.nix +++ b/tests/functional/secure-drv-outputs.nix @@ -4,20 +4,18 @@ with import ./config.nix; good = mkDerivation { name = "good"; - builder = builtins.toFile "builder" - '' - mkdir $out - echo > $out/good - ''; + builder = builtins.toFile "builder" '' + mkdir $out + echo > $out/good + ''; }; bad = mkDerivation { name = "good"; - builder = builtins.toFile "builder" - '' - mkdir $out - echo > $out/bad - ''; + builder = builtins.toFile "builder" '' + mkdir $out + echo > $out/bad + ''; }; } diff --git a/tests/functional/shell-hello.nix b/tests/functional/shell-hello.nix index c920d7cb459..470798dd9e1 100644 --- a/tests/functional/shell-hello.nix +++ b/tests/functional/shell-hello.nix @@ -3,57 +3,56 @@ with import ./config.nix; rec { hello = mkDerivation { name = "hello"; - outputs = [ "out" "dev" ]; + outputs = [ + "out" + "dev" + ]; meta.outputsToInstall = [ "out" ]; - buildCommand = - '' - mkdir -p $out/bin $dev/bin + buildCommand = '' + mkdir -p $out/bin $dev/bin - cat > $out/bin/hello < $out/bin/hello < $dev/bin/hello2 < $dev/bin/hello2 < $out/bin/hello < $out/bin/hello < $out/bin/env <&2 - exit 1 - fi - exec env - EOF - chmod +x $out/bin/env - ''; + cat > $out/bin/env <&2 + exit 1 + fi + exec env + EOF + chmod +x $out/bin/env + ''; }; } diff --git a/tests/functional/shell.nix b/tests/functional/shell.nix index 4b1a0623a81..5e9f4881819 100644 --- a/tests/functional/shell.nix +++ b/tests/functional/shell.nix @@ -1,102 +1,130 @@ -{ inNixShell ? false, contentAddressed ? false, fooContents ? "foo" }: +{ + inNixShell ? false, + contentAddressed ? false, + fooContents ? "foo", +}: -let cfg = import ./config.nix; in +let + cfg = import ./config.nix; +in with cfg; let mkDerivation = if contentAddressed then - args: cfg.mkDerivation ({ - __contentAddressed = true; - outputHashMode = "recursive"; - outputHashAlgo = "sha256"; - } // args) - else cfg.mkDerivation; + args: + cfg.mkDerivation ( + { + __contentAddressed = true; + outputHashMode = "recursive"; + outputHashAlgo = "sha256"; + } + // args + ) + else + cfg.mkDerivation; in -let pkgs = rec { - setupSh = builtins.toFile "setup" '' - export VAR_FROM_STDENV_SETUP=foo - for pkg in $buildInputs; do - export PATH=$PATH:$pkg/bin - done - - declare -a arr1=(1 2 "3 4" 5) - declare -a arr2=(x $'\n' $'x\ny') - fun() { - echo blabla - } - runHook() { - eval "''${!1}" - } - ''; +let + pkgs = rec { + setupSh = builtins.toFile "setup" '' + export VAR_FROM_STDENV_SETUP=foo + for pkg in $buildInputs; do + export PATH=$PATH:$pkg/bin + done - stdenv = mkDerivation { - name = "stdenv"; - buildCommand = '' - mkdir -p $out - ln -s ${setupSh} $out/setup + declare -a arr1=(1 2 "3 4" 5) + declare -a arr2=(x $'\n' $'x\ny') + fun() { + echo blabla + } + runHook() { + eval "''${!1}" + } ''; - } // { inherit mkDerivation; }; - shellDrv = mkDerivation { - name = "shellDrv"; - builder = "/does/not/exist"; - VAR_FROM_NIX = "bar"; - ASCII_PERCENT = "%"; - ASCII_AT = "@"; - TEST_inNixShell = if inNixShell then "true" else "false"; - FOO = fooContents; - inherit stdenv; - outputs = ["dev" "out"]; - } // { - shellHook = abort "Ignore non-drv shellHook attr"; - }; + stdenv = + mkDerivation { + name = "stdenv"; + buildCommand = '' + mkdir -p $out + ln -s ${setupSh} $out/setup + ''; + } + // { + inherit mkDerivation; + }; - # https://github.com/NixOS/nix/issues/5431 - # See nix-shell.sh - polo = mkDerivation { - name = "polo"; - inherit stdenv; - shellHook = '' - echo Polo - ''; - }; + shellDrv = + mkDerivation { + name = "shellDrv"; + builder = "/does/not/exist"; + VAR_FROM_NIX = "bar"; + ASCII_PERCENT = "%"; + ASCII_AT = "@"; + TEST_inNixShell = if inNixShell then "true" else "false"; + FOO = fooContents; + inherit stdenv; + outputs = [ + "dev" + "out" + ]; + } + // { + shellHook = abort "Ignore non-drv shellHook attr"; + }; - # Used by nix-shell -p - runCommand = name: args: buildCommand: mkDerivation (args // { - inherit name buildCommand stdenv; - }); + # https://github.com/NixOS/nix/issues/5431 + # See nix-shell.sh + polo = mkDerivation { + name = "polo"; + inherit stdenv; + shellHook = '' + echo Polo + ''; + }; - foo = runCommand "foo" {} '' - mkdir -p $out/bin - echo 'echo ${fooContents}' > $out/bin/foo - chmod a+rx $out/bin/foo - ln -s ${shell} $out/bin/bash - ''; + # Used by nix-shell -p + runCommand = + name: args: buildCommand: + mkDerivation ( + args + // { + inherit name buildCommand stdenv; + } + ); - bar = runCommand "bar" {} '' - mkdir -p $out/bin - echo 'echo bar' > $out/bin/bar - chmod a+rx $out/bin/bar - ''; + foo = runCommand "foo" { } '' + mkdir -p $out/bin + echo 'echo ${fooContents}' > $out/bin/foo + chmod a+rx $out/bin/foo + ln -s ${shell} $out/bin/bash + ''; - bash = shell; - bashInteractive = runCommand "bash" {} '' - mkdir -p $out/bin - ln -s ${shell} $out/bin/bash - ''; + bar = runCommand "bar" { } '' + mkdir -p $out/bin + echo 'echo bar' > $out/bin/bar + chmod a+rx $out/bin/bar + ''; - # ruby "interpreter" that outputs "$@" - ruby = runCommand "ruby" {} '' - mkdir -p $out/bin - echo 'printf %s "$*"' > $out/bin/ruby - chmod a+rx $out/bin/ruby - ''; + bash = shell; + bashInteractive = runCommand "bash" { } '' + mkdir -p $out/bin + ln -s ${shell} $out/bin/bash + ''; - inherit (cfg) shell; + # ruby "interpreter" that outputs "$@" + ruby = runCommand "ruby" { } '' + mkdir -p $out/bin + echo 'printf %s "$*"' > $out/bin/ruby + chmod a+rx $out/bin/ruby + ''; - callPackage = f: args: f (pkgs // args); + inherit (cfg) shell; - inherit pkgs; -}; in pkgs + callPackage = f: args: f (pkgs // args); + + inherit pkgs; + }; +in +pkgs diff --git a/tests/functional/simple-failing.nix b/tests/functional/simple-failing.nix index d176c9c51e6..6cf29ae3842 100644 --- a/tests/functional/simple-failing.nix +++ b/tests/functional/simple-failing.nix @@ -2,11 +2,10 @@ with import ./config.nix; mkDerivation { name = "simple-failing"; - builder = builtins.toFile "builder.sh" - '' - echo "This should fail" - exit 1 - ''; + builder = builtins.toFile "builder.sh" '' + echo "This should fail" + exit 1 + ''; PATH = ""; goodPath = path; } diff --git a/tests/functional/structured-attrs-shell.nix b/tests/functional/structured-attrs-shell.nix index 57c1e6bd2da..a819e39cdae 100644 --- a/tests/functional/structured-attrs-shell.nix +++ b/tests/functional/structured-attrs-shell.nix @@ -12,8 +12,15 @@ mkDerivation { name = "structured2"; __structuredAttrs = true; inherit stdenv; - outputs = [ "out" "dev" ]; - my.list = [ "a" "b" "c" ]; + outputs = [ + "out" + "dev" + ]; + my.list = [ + "a" + "b" + "c" + ]; exportReferencesGraph.refs = [ dep ]; buildCommand = '' touch ''${outputs[out]}; touch ''${outputs[dev]} diff --git a/tests/functional/structured-attrs.nix b/tests/functional/structured-attrs.nix index e93139a4457..4e19845176e 100644 --- a/tests/functional/structured-attrs.nix +++ b/tests/functional/structured-attrs.nix @@ -16,7 +16,10 @@ mkDerivation { __structuredAttrs = true; - outputs = [ "out" "dev" ]; + outputs = [ + "out" + "dev" + ]; buildCommand = '' set -x @@ -43,12 +46,24 @@ mkDerivation { [[ $json =~ '"references":[]' ]] ''; - buildInputs = [ "a" "b" "c" 123 "'" "\"" null ]; + buildInputs = [ + "a" + "b" + "c" + 123 + "'" + "\"" + null + ]; hardening.format = true; hardening.fortify = false; - outer.inner = [ 1 2 3 ]; + outer.inner = [ + 1 + 2 + 3 + ]; int = 123456789; diff --git a/tests/functional/undefined-variable.nix b/tests/functional/undefined-variable.nix index 579985497e9..8e88dd8fe02 100644 --- a/tests/functional/undefined-variable.nix +++ b/tests/functional/undefined-variable.nix @@ -1 +1,4 @@ -let f = builtins.toFile "test-file.nix" "asd"; in import f +let + f = builtins.toFile "test-file.nix" "asd"; +in +import f diff --git a/tests/functional/user-envs.nix b/tests/functional/user-envs.nix index 46f8b51dda1..cc63812c4a7 100644 --- a/tests/functional/user-envs.nix +++ b/tests/functional/user-envs.nix @@ -1,5 +1,6 @@ # Some dummy arguments... -{ foo ? "foo" +{ + foo ? "foo", }: with import ./config.nix; @@ -8,27 +9,41 @@ assert foo == "foo"; let - platforms = let x = "foobar"; in [ x x ]; + platforms = + let + x = "foobar"; + in + [ + x + x + ]; - makeDrv = name: progName: (mkDerivation { - name = assert progName != "fail"; name; - inherit progName system; - builder = ./user-envs.builder.sh; - } // { - meta = { - description = "A silly test package with some \${escaped anti-quotation} in it"; - inherit platforms; - }; - }); + makeDrv = + name: progName: + ( + mkDerivation { + name = + assert progName != "fail"; + name; + inherit progName system; + builder = ./user-envs.builder.sh; + } + // { + meta = { + description = "A silly test package with some \${escaped anti-quotation} in it"; + inherit platforms; + }; + } + ); in - [ - (makeDrv "foo-1.0" "foo") - (makeDrv "foo-2.0pre1" "foo") - (makeDrv "bar-0.1" "bar") - (makeDrv "foo-2.0" "foo") - (makeDrv "bar-0.1.1" "bar") - (makeDrv "foo-0.1" "foo" // { meta.priority = 10; }) - (makeDrv "fail-0.1" "fail") - ] +[ + (makeDrv "foo-1.0" "foo") + (makeDrv "foo-2.0pre1" "foo") + (makeDrv "bar-0.1" "bar") + (makeDrv "foo-2.0" "foo") + (makeDrv "bar-0.1.1" "bar") + (makeDrv "foo-0.1" "foo" // { meta.priority = 10; }) + (makeDrv "fail-0.1" "fail") +] diff --git a/tests/installer/default.nix b/tests/installer/default.nix index 4aed6eae489..d48537dd0d0 100644 --- a/tests/installer/default.nix +++ b/tests/installer/default.nix @@ -1,5 +1,6 @@ -{ binaryTarballs -, nixpkgsFor +{ + binaryTarballs, + nixpkgsFor, }: let @@ -41,8 +42,9 @@ let }; }; - mockChannel = pkgs: - pkgs.runCommandNoCC "mock-channel" {} '' + mockChannel = + pkgs: + pkgs.runCommandNoCC "mock-channel" { } '' mkdir nixexprs mkdir -p $out/channel echo -n 'someContent' > nixexprs/someFile @@ -54,14 +56,14 @@ let images = { /* - "ubuntu-14-04" = { - image = import { - url = "https://app.vagrantup.com/ubuntu/boxes/trusty64/versions/20190514.0.0/providers/virtualbox.box"; - hash = "sha256-iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="; + "ubuntu-14-04" = { + image = import { + url = "https://app.vagrantup.com/ubuntu/boxes/trusty64/versions/20190514.0.0/providers/virtualbox.box"; + hash = "sha256-iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="; + }; + rootDisk = "box-disk1.vmdk"; + system = "x86_64-linux"; }; - rootDisk = "box-disk1.vmdk"; - system = "x86_64-linux"; - }; */ "ubuntu-16-04" = { @@ -95,14 +97,14 @@ let # Currently fails with 'error while loading shared libraries: # libsodium.so.23: cannot stat shared object: Invalid argument'. /* - "rhel-6" = { - image = import { - url = "https://app.vagrantup.com/generic/boxes/rhel6/versions/4.1.12/providers/libvirt.box"; - hash = "sha256-QwzbvRoRRGqUCQptM7X/InRWFSP2sqwRt2HaaO6zBGM="; + "rhel-6" = { + image = import { + url = "https://app.vagrantup.com/generic/boxes/rhel6/versions/4.1.12/providers/libvirt.box"; + hash = "sha256-QwzbvRoRRGqUCQptM7X/InRWFSP2sqwRt2HaaO6zBGM="; + }; + rootDisk = "box.img"; + system = "x86_64-linux"; }; - rootDisk = "box.img"; - system = "x86_64-linux"; - }; */ "rhel-7" = { @@ -137,12 +139,18 @@ let }; - makeTest = imageName: testName: - let image = images.${imageName}; in + makeTest = + imageName: testName: + let + image = images.${imageName}; + in with nixpkgsFor.${image.system}.native; - runCommand - "installer-test-${imageName}-${testName}" - { buildInputs = [ qemu_kvm openssh ]; + runCommand "installer-test-${imageName}-${testName}" + { + buildInputs = [ + qemu_kvm + openssh + ]; image = image.image; postBoot = image.postBoot or ""; installScript = installScripts.${testName}.script; @@ -247,9 +255,6 @@ let in -builtins.mapAttrs (imageName: image: - { ${image.system} = builtins.mapAttrs (testName: test: - makeTest imageName testName - ) installScripts; - } -) images +builtins.mapAttrs (imageName: image: { + ${image.system} = builtins.mapAttrs (testName: test: makeTest imageName testName) installScripts; +}) images diff --git a/tests/nixos/authorization.nix b/tests/nixos/authorization.nix index fdeae06ed34..6540e9fa337 100644 --- a/tests/nixos/authorization.nix +++ b/tests/nixos/authorization.nix @@ -4,8 +4,11 @@ nodes.machine = { virtualisation.writableStore = true; # TODO add a test without allowed-users setting. allowed-users is uncommon among NixOS users. - nix.settings.allowed-users = ["alice" "bob"]; - nix.settings.trusted-users = ["alice"]; + nix.settings.allowed-users = [ + "alice" + "bob" + ]; + nix.settings.trusted-users = [ "alice" ]; users.users.alice.isNormalUser = true; users.users.bob.isNormalUser = true; @@ -15,80 +18,80 @@ }; testScript = - let - pathFour = "/nix/store/20xfy868aiic0r0flgzq4n5dq1yvmxkn-four"; - in - '' - machine.wait_for_unit("multi-user.target") - machine.succeed(""" - exec 1>&2 - echo kSELDhobKaF8/VdxIxdP7EQe+Q > one - diff $(nix store add-file one) one - """) - machine.succeed(""" - su --login alice -c ' - set -x - cd ~ - echo ehHtmfuULXYyBV6NBk6QUi8iE0 > two - ls - diff $(echo $(nix store add-file two)) two' 1>&2 - """) - machine.succeed(""" - su --login bob -c ' - set -x - cd ~ - echo 0Jw8RNp7cK0W2AdNbcquofcOVk > three - diff $(nix store add-file three) three - ' 1>&2 - """) + let + pathFour = "/nix/store/20xfy868aiic0r0flgzq4n5dq1yvmxkn-four"; + in + '' + machine.wait_for_unit("multi-user.target") + machine.succeed(""" + exec 1>&2 + echo kSELDhobKaF8/VdxIxdP7EQe+Q > one + diff $(nix store add-file one) one + """) + machine.succeed(""" + su --login alice -c ' + set -x + cd ~ + echo ehHtmfuULXYyBV6NBk6QUi8iE0 > two + ls + diff $(echo $(nix store add-file two)) two' 1>&2 + """) + machine.succeed(""" + su --login bob -c ' + set -x + cd ~ + echo 0Jw8RNp7cK0W2AdNbcquofcOVk > three + diff $(nix store add-file three) three + ' 1>&2 + """) - # We're going to check that a path is not created - machine.succeed(""" - ! [[ -e ${pathFour} ]] - """) - machine.succeed(""" - su --login mallory -c ' - set -x - cd ~ - echo 5mgtDj0ohrWkT50TLR0f4tIIxY > four; - (! nix store add-file four 2>&1) | grep -F "cannot open connection to remote store" - (! nix store add-file four 2>&1) | grep -F "Connection reset by peer" + # We're going to check that a path is not created + machine.succeed(""" ! [[ -e ${pathFour} ]] - ' 1>&2 - """) - - # Check that the file _can_ be added, and matches the expected path we were checking - machine.succeed(""" - exec 1>&2 - echo 5mgtDj0ohrWkT50TLR0f4tIIxY > four - four="$(nix store add-file four)" - diff $four four - diff <(echo $four) <(echo ${pathFour}) - """) + """) + machine.succeed(""" + su --login mallory -c ' + set -x + cd ~ + echo 5mgtDj0ohrWkT50TLR0f4tIIxY > four; + (! nix store add-file four 2>&1) | grep -F "cannot open connection to remote store" + (! nix store add-file four 2>&1) | grep -F "Connection reset by peer" + ! [[ -e ${pathFour} ]] + ' 1>&2 + """) - machine.succeed(""" - su --login alice -c 'nix-store --verify --repair' - """) + # Check that the file _can_ be added, and matches the expected path we were checking + machine.succeed(""" + exec 1>&2 + echo 5mgtDj0ohrWkT50TLR0f4tIIxY > four + four="$(nix store add-file four)" + diff $four four + diff <(echo $four) <(echo ${pathFour}) + """) - machine.succeed(""" - set -x - su --login bob -c '(! nix-store --verify --repair 2>&1)' | tee diag 1>&2 - grep -F "you are not privileged to repair paths" diag - """) + machine.succeed(""" + su --login alice -c 'nix-store --verify --repair' + """) - machine.succeed(""" + machine.succeed(""" set -x - su --login mallory -c ' - nix-store --generate-binary-cache-key cache1.example.org sk1 pk1 - (! nix store sign --key-file sk1 ${pathFour} 2>&1)' | tee diag 1>&2 - grep -F "cannot open connection to remote store 'daemon'" diag - """) + su --login bob -c '(! nix-store --verify --repair 2>&1)' | tee diag 1>&2 + grep -F "you are not privileged to repair paths" diag + """) - machine.succeed(""" - su --login bob -c ' - nix-store --generate-binary-cache-key cache1.example.org sk1 pk1 - nix store sign --key-file sk1 ${pathFour} - ' - """) - ''; + machine.succeed(""" + set -x + su --login mallory -c ' + nix-store --generate-binary-cache-key cache1.example.org sk1 pk1 + (! nix store sign --key-file sk1 ${pathFour} 2>&1)' | tee diag 1>&2 + grep -F "cannot open connection to remote store 'daemon'" diag + """) + + machine.succeed(""" + su --login bob -c ' + nix-store --generate-binary-cache-key cache1.example.org sk1 pk1 + nix store sign --key-file sk1 ${pathFour} + ' + """) + ''; } diff --git a/tests/nixos/ca-fd-leak/default.nix b/tests/nixos/ca-fd-leak/default.nix index a6ae72adc93..902aacdc650 100644 --- a/tests/nixos/ca-fd-leak/default.nix +++ b/tests/nixos/ca-fd-leak/default.nix @@ -27,12 +27,15 @@ let # domain socket. # Compiled statically so that we can easily send it to the VM and use it # inside the build sandbox. - sender = pkgs.runCommandWith { - name = "sender"; - stdenv = pkgs.pkgsStatic.stdenv; - } '' - $CC -static -o $out ${./sender.c} - ''; + sender = + pkgs.runCommandWith + { + name = "sender"; + stdenv = pkgs.pkgsStatic.stdenv; + } + '' + $CC -static -o $out ${./sender.c} + ''; # Okay, so we have a file descriptor shipped out of the FOD now. But the # Nix store is read-only, right? .. Well, yeah. But this file descriptor @@ -47,44 +50,57 @@ in name = "ca-fd-leak"; nodes.machine = - { config, lib, pkgs, ... }: - { virtualisation.writableStore = true; + { + config, + lib, + pkgs, + ... + }: + { + virtualisation.writableStore = true; nix.settings.substituters = lib.mkForce [ ]; - virtualisation.additionalPaths = [ pkgs.busybox-sandbox-shell sender smuggler pkgs.socat ]; + virtualisation.additionalPaths = [ + pkgs.busybox-sandbox-shell + sender + smuggler + pkgs.socat + ]; }; - testScript = { nodes }: '' - start_all() + testScript = + { nodes }: + '' + start_all() - machine.succeed("echo hello") - # Start the smuggler server - machine.succeed("${smuggler}/bin/smuggler ${socketName} >&2 &") + machine.succeed("echo hello") + # Start the smuggler server + machine.succeed("${smuggler}/bin/smuggler ${socketName} >&2 &") - # Build the smuggled derivation. - # This will connect to the smuggler server and send it the file descriptor - machine.succeed(r""" - nix-build -E ' - builtins.derivation { - name = "smuggled"; - system = builtins.currentSystem; - # look ma, no tricks! - outputHashMode = "flat"; - outputHashAlgo = "sha256"; - outputHash = builtins.hashString "sha256" "hello, world\n"; - builder = "${pkgs.busybox-sandbox-shell}/bin/sh"; - args = [ "-c" "echo \"hello, world\" > $out; ''${${sender}} ${socketName}" ]; - }' - """.strip()) + # Build the smuggled derivation. + # This will connect to the smuggler server and send it the file descriptor + machine.succeed(r""" + nix-build -E ' + builtins.derivation { + name = "smuggled"; + system = builtins.currentSystem; + # look ma, no tricks! + outputHashMode = "flat"; + outputHashAlgo = "sha256"; + outputHash = builtins.hashString "sha256" "hello, world\n"; + builder = "${pkgs.busybox-sandbox-shell}/bin/sh"; + args = [ "-c" "echo \"hello, world\" > $out; ''${${sender}} ${socketName}" ]; + }' + """.strip()) - # Tell the smuggler server that we're done - machine.execute("echo done | ${pkgs.socat}/bin/socat - ABSTRACT-CONNECT:${socketName}") + # Tell the smuggler server that we're done + machine.execute("echo done | ${pkgs.socat}/bin/socat - ABSTRACT-CONNECT:${socketName}") - # Check that the file was not modified - machine.succeed(r""" - cat ./result - test "$(cat ./result)" = "hello, world" - """.strip()) - ''; + # Check that the file was not modified + machine.succeed(r""" + cat ./result + test "$(cat ./result)" = "hello, world" + """.strip()) + ''; } diff --git a/tests/nixos/cgroups/default.nix b/tests/nixos/cgroups/default.nix index b8febbf4bda..a6b4bca8c76 100644 --- a/tests/nixos/cgroups/default.nix +++ b/tests/nixos/cgroups/default.nix @@ -3,38 +3,39 @@ { name = "cgroups"; - nodes = - { - host = - { config, pkgs, ... }: - { virtualisation.additionalPaths = [ pkgs.stdenvNoCC ]; - nix.extraOptions = - '' - extra-experimental-features = nix-command auto-allocate-uids cgroups - extra-system-features = uid-range - ''; - nix.settings.use-cgroups = true; - nix.nixPath = [ "nixpkgs=${nixpkgs}" ]; - }; - }; - - testScript = { nodes }: '' - start_all() - - host.wait_for_unit("multi-user.target") - - # Start build in background - host.execute("NIX_REMOTE=daemon nix build --auto-allocate-uids --file ${./hang.nix} >&2 &") - service = "/sys/fs/cgroup/system.slice/nix-daemon.service" - - # Wait for cgroups to be created - host.succeed(f"until [ -e {service}/nix-daemon ]; do sleep 1; done", timeout=30) - host.succeed(f"until [ -e {service}/nix-build-uid-* ]; do sleep 1; done", timeout=30) - - # Check that there aren't processes where there shouldn't be, and that there are where there should be - host.succeed(f'[ -z "$(cat {service}/cgroup.procs)" ]') - host.succeed(f'[ -n "$(cat {service}/nix-daemon/cgroup.procs)" ]') - host.succeed(f'[ -n "$(cat {service}/nix-build-uid-*/cgroup.procs)" ]') - ''; + nodes = { + host = + { config, pkgs, ... }: + { + virtualisation.additionalPaths = [ pkgs.stdenvNoCC ]; + nix.extraOptions = '' + extra-experimental-features = nix-command auto-allocate-uids cgroups + extra-system-features = uid-range + ''; + nix.settings.use-cgroups = true; + nix.nixPath = [ "nixpkgs=${nixpkgs}" ]; + }; + }; + + testScript = + { nodes }: + '' + start_all() + + host.wait_for_unit("multi-user.target") + + # Start build in background + host.execute("NIX_REMOTE=daemon nix build --auto-allocate-uids --file ${./hang.nix} >&2 &") + service = "/sys/fs/cgroup/system.slice/nix-daemon.service" + + # Wait for cgroups to be created + host.succeed(f"until [ -e {service}/nix-daemon ]; do sleep 1; done", timeout=30) + host.succeed(f"until [ -e {service}/nix-build-uid-* ]; do sleep 1; done", timeout=30) + + # Check that there aren't processes where there shouldn't be, and that there are where there should be + host.succeed(f'[ -z "$(cat {service}/cgroup.procs)" ]') + host.succeed(f'[ -n "$(cat {service}/nix-daemon/cgroup.procs)" ]') + host.succeed(f'[ -n "$(cat {service}/nix-build-uid-*/cgroup.procs)" ]') + ''; } diff --git a/tests/nixos/cgroups/hang.nix b/tests/nixos/cgroups/hang.nix index cefe2d031c0..d7b337b0c05 100644 --- a/tests/nixos/cgroups/hang.nix +++ b/tests/nixos/cgroups/hang.nix @@ -1,9 +1,10 @@ { }: -with import {}; +with import { }; runCommand "hang" - { requiredSystemFeatures = "uid-range"; + { + requiredSystemFeatures = "uid-range"; } '' sleep infinity diff --git a/tests/nixos/chroot-store.nix b/tests/nixos/chroot-store.nix index 4b167fc3839..f89a20bc4d5 100644 --- a/tests/nixos/chroot-store.nix +++ b/tests/nixos/chroot-store.nix @@ -1,31 +1,45 @@ -{ lib, config, nixpkgs, ... }: +{ + lib, + config, + nixpkgs, + ... +}: let pkgs = config.nodes.machine.nixpkgs.pkgs; pkgA = pkgs.hello; pkgB = pkgs.cowsay; -in { +in +{ name = "chroot-store"; - nodes = - { machine = - { config, lib, pkgs, ... }: - { virtualisation.writableStore = true; - virtualisation.additionalPaths = [ pkgA ]; - environment.systemPackages = [ pkgB ]; - nix.extraOptions = "experimental-features = nix-command"; - }; - }; + nodes = { + machine = + { + config, + lib, + pkgs, + ... + }: + { + virtualisation.writableStore = true; + virtualisation.additionalPaths = [ pkgA ]; + environment.systemPackages = [ pkgB ]; + nix.extraOptions = "experimental-features = nix-command"; + }; + }; - testScript = { nodes }: '' - # fmt: off - start_all() + testScript = + { nodes }: + '' + # fmt: off + start_all() - machine.succeed("nix copy --no-check-sigs --to /tmp/nix ${pkgA}") + machine.succeed("nix copy --no-check-sigs --to /tmp/nix ${pkgA}") - machine.succeed("nix shell --store /tmp/nix ${pkgA} --command hello >&2") + machine.succeed("nix shell --store /tmp/nix ${pkgA} --command hello >&2") - # Test that /nix/store is available via an overlayfs mount. - machine.succeed("nix shell --store /tmp/nix ${pkgA} --command cowsay foo >&2") - ''; + # Test that /nix/store is available via an overlayfs mount. + machine.succeed("nix shell --store /tmp/nix ${pkgA} --command cowsay foo >&2") + ''; } diff --git a/tests/nixos/containers/containers.nix b/tests/nixos/containers/containers.nix index 6773f5628a3..b590dc8498f 100644 --- a/tests/nixos/containers/containers.nix +++ b/tests/nixos/containers/containers.nix @@ -4,60 +4,67 @@ { name = "containers"; - nodes = - { - host = - { config, lib, pkgs, nodes, ... }: - { virtualisation.writableStore = true; - virtualisation.diskSize = 2048; - virtualisation.additionalPaths = - [ pkgs.stdenvNoCC - (import ./systemd-nspawn.nix { inherit nixpkgs; }).toplevel - ]; - virtualisation.memorySize = 4096; - nix.settings.substituters = lib.mkForce [ ]; - nix.extraOptions = - '' - extra-experimental-features = nix-command auto-allocate-uids cgroups - extra-system-features = uid-range - ''; - nix.nixPath = [ "nixpkgs=${nixpkgs}" ]; - }; - }; - - testScript = { nodes }: '' - start_all() - - host.succeed("nix --version >&2") - - # Test that 'id' gives the expected result in various configurations. - - # Existing UIDs, sandbox. - host.succeed("nix build --no-auto-allocate-uids --sandbox -L --offline --impure --file ${./id-test.nix} --argstr name id-test-1") - host.succeed("[[ $(cat ./result) = 'uid=1000(nixbld) gid=100(nixbld) groups=100(nixbld)' ]]") - - # Existing UIDs, no sandbox. - host.succeed("nix build --no-auto-allocate-uids --no-sandbox -L --offline --impure --file ${./id-test.nix} --argstr name id-test-2") - host.succeed("[[ $(cat ./result) = 'uid=30001(nixbld1) gid=30000(nixbld) groups=30000(nixbld)' ]]") - - # Auto-allocated UIDs, sandbox. - host.succeed("nix build --auto-allocate-uids --sandbox -L --offline --impure --file ${./id-test.nix} --argstr name id-test-3") - host.succeed("[[ $(cat ./result) = 'uid=1000(nixbld) gid=100(nixbld) groups=100(nixbld)' ]]") - - # Auto-allocated UIDs, no sandbox. - host.succeed("nix build --auto-allocate-uids --no-sandbox -L --offline --impure --file ${./id-test.nix} --argstr name id-test-4") - host.succeed("[[ $(cat ./result) = 'uid=872415232 gid=30000(nixbld) groups=30000(nixbld)' ]]") - - # Auto-allocated UIDs, UID range, sandbox. - host.succeed("nix build --auto-allocate-uids --sandbox -L --offline --impure --file ${./id-test.nix} --argstr name id-test-5 --arg uidRange true") - host.succeed("[[ $(cat ./result) = 'uid=0(root) gid=0(root) groups=0(root)' ]]") - - # Auto-allocated UIDs, UID range, no sandbox. - host.fail("nix build --auto-allocate-uids --no-sandbox -L --offline --impure --file ${./id-test.nix} --argstr name id-test-6 --arg uidRange true") - - # Run systemd-nspawn in a Nix build. - host.succeed("nix build --auto-allocate-uids --sandbox -L --offline --impure --file ${./systemd-nspawn.nix} --argstr nixpkgs ${nixpkgs}") - host.succeed("[[ $(cat ./result/msg) = 'Hello World' ]]") - ''; + nodes = { + host = + { + config, + lib, + pkgs, + nodes, + ... + }: + { + virtualisation.writableStore = true; + virtualisation.diskSize = 2048; + virtualisation.additionalPaths = [ + pkgs.stdenvNoCC + (import ./systemd-nspawn.nix { inherit nixpkgs; }).toplevel + ]; + virtualisation.memorySize = 4096; + nix.settings.substituters = lib.mkForce [ ]; + nix.extraOptions = '' + extra-experimental-features = nix-command auto-allocate-uids cgroups + extra-system-features = uid-range + ''; + nix.nixPath = [ "nixpkgs=${nixpkgs}" ]; + }; + }; + + testScript = + { nodes }: + '' + start_all() + + host.succeed("nix --version >&2") + + # Test that 'id' gives the expected result in various configurations. + + # Existing UIDs, sandbox. + host.succeed("nix build --no-auto-allocate-uids --sandbox -L --offline --impure --file ${./id-test.nix} --argstr name id-test-1") + host.succeed("[[ $(cat ./result) = 'uid=1000(nixbld) gid=100(nixbld) groups=100(nixbld)' ]]") + + # Existing UIDs, no sandbox. + host.succeed("nix build --no-auto-allocate-uids --no-sandbox -L --offline --impure --file ${./id-test.nix} --argstr name id-test-2") + host.succeed("[[ $(cat ./result) = 'uid=30001(nixbld1) gid=30000(nixbld) groups=30000(nixbld)' ]]") + + # Auto-allocated UIDs, sandbox. + host.succeed("nix build --auto-allocate-uids --sandbox -L --offline --impure --file ${./id-test.nix} --argstr name id-test-3") + host.succeed("[[ $(cat ./result) = 'uid=1000(nixbld) gid=100(nixbld) groups=100(nixbld)' ]]") + + # Auto-allocated UIDs, no sandbox. + host.succeed("nix build --auto-allocate-uids --no-sandbox -L --offline --impure --file ${./id-test.nix} --argstr name id-test-4") + host.succeed("[[ $(cat ./result) = 'uid=872415232 gid=30000(nixbld) groups=30000(nixbld)' ]]") + + # Auto-allocated UIDs, UID range, sandbox. + host.succeed("nix build --auto-allocate-uids --sandbox -L --offline --impure --file ${./id-test.nix} --argstr name id-test-5 --arg uidRange true") + host.succeed("[[ $(cat ./result) = 'uid=0(root) gid=0(root) groups=0(root)' ]]") + + # Auto-allocated UIDs, UID range, no sandbox. + host.fail("nix build --auto-allocate-uids --no-sandbox -L --offline --impure --file ${./id-test.nix} --argstr name id-test-6 --arg uidRange true") + + # Run systemd-nspawn in a Nix build. + host.succeed("nix build --auto-allocate-uids --sandbox -L --offline --impure --file ${./systemd-nspawn.nix} --argstr nixpkgs ${nixpkgs}") + host.succeed("[[ $(cat ./result/msg) = 'Hello World' ]]") + ''; } diff --git a/tests/nixos/containers/id-test.nix b/tests/nixos/containers/id-test.nix index 8eb9d38f9a2..2139327ad88 100644 --- a/tests/nixos/containers/id-test.nix +++ b/tests/nixos/containers/id-test.nix @@ -1,8 +1,10 @@ -{ name, uidRange ? false }: +{ + name, + uidRange ? false, +}: -with import {}; +with import { }; -runCommand name - { requiredSystemFeatures = if uidRange then ["uid-range"] else []; - } - "id; id > $out" +runCommand name { + requiredSystemFeatures = if uidRange then [ "uid-range" ] else [ ]; +} "id; id > $out" diff --git a/tests/nixos/containers/systemd-nspawn.nix b/tests/nixos/containers/systemd-nspawn.nix index 1dad4ebd754..4516f4e1394 100644 --- a/tests/nixos/containers/systemd-nspawn.nix +++ b/tests/nixos/containers/systemd-nspawn.nix @@ -2,7 +2,8 @@ let - machine = { config, pkgs, ... }: + machine = + { config, pkgs, ... }: { system.stateVersion = "22.05"; boot.isContainer = true; @@ -31,10 +32,12 @@ let }; }; - cfg = (import (nixpkgs + "/nixos/lib/eval-config.nix") { - modules = [ machine ]; - system = "x86_64-linux"; - }); + cfg = ( + import (nixpkgs + "/nixos/lib/eval-config.nix") { + modules = [ machine ]; + system = "x86_64-linux"; + } + ); config = cfg.config; @@ -43,7 +46,8 @@ in with cfg._module.args.pkgs; runCommand "test" - { buildInputs = [ config.system.path ]; + { + buildInputs = [ config.system.path ]; requiredSystemFeatures = [ "uid-range" ]; toplevel = config.system.build.toplevel; } diff --git a/tests/nixos/default.nix b/tests/nixos/default.nix index 1c207fba55b..92f89d8dbca 100644 --- a/tests/nixos/default.nix +++ b/tests/nixos/default.nix @@ -1,17 +1,26 @@ -{ lib, nixpkgs, nixpkgsFor, nixpkgs-23-11 }: +{ + lib, + nixpkgs, + nixpkgsFor, + nixpkgs-23-11, +}: let nixos-lib = import (nixpkgs + "/nixos/lib") { }; - noTests = pkg: pkg.overrideAttrs ( - finalAttrs: prevAttrs: { - doCheck = false; - doInstallCheck = false; - }); + noTests = + pkg: + pkg.overrideAttrs ( + finalAttrs: prevAttrs: { + doCheck = false; + doInstallCheck = false; + } + ); # https://nixos.org/manual/nixos/unstable/index.html#sec-calling-nixos-tests - runNixOSTestFor = system: test: + runNixOSTestFor = + system: test: (nixos-lib.runTest { imports = [ test @@ -36,44 +45,61 @@ let # allow running tests against older nix versions via `nix eval --apply` # Example: # nix build "$(nix eval --raw --impure .#hydraJobs.tests.fetch-git --apply 't: (t.forNix "2.19.2").drvPath')^*" - forNix = nixVersion: runNixOSTestFor system { - imports = [test]; - defaults.nixpkgs.overlays = [(curr: prev: { - nix = let - packages = (builtins.getFlake "nix/${nixVersion}").packages.${system}; - in packages.nix-cli or packages.nix; - })]; - }; + forNix = + nixVersion: + runNixOSTestFor system { + imports = [ test ]; + defaults.nixpkgs.overlays = [ + (curr: prev: { + nix = + let + packages = (builtins.getFlake "nix/${nixVersion}").packages.${system}; + in + packages.nix-cli or packages.nix; + }) + ]; + }; }; # Checks that a NixOS configuration does not contain any references to our # locally defined Nix version. - checkOverrideNixVersion = { pkgs, lib, ... }: { - # pkgs.nix: The new Nix in this repo - # We disallow it, to make sure we don't accidentally use it. - system.forbiddenDependenciesRegexes = [ - (lib.strings.escapeRegex "nix-${pkgs.nix.version}") - ]; - }; - - otherNixes.nix_2_3.setNixPackage = { lib, pkgs, ... }: { - imports = [ checkOverrideNixVersion ]; - nix.package = lib.mkForce pkgs.nixVersions.nix_2_3; - }; - - otherNixes.nix_2_13.setNixPackage = { lib, pkgs, ... }: { - imports = [ checkOverrideNixVersion ]; - nix.package = lib.mkForce ( - nixpkgs-23-11.legacyPackages.${pkgs.stdenv.hostPlatform.system}.nixVersions.nix_2_13.overrideAttrs (o: { - meta = o.meta // { knownVulnerabilities = []; }; - }) - ); - }; + checkOverrideNixVersion = + { pkgs, lib, ... }: + { + # pkgs.nix: The new Nix in this repo + # We disallow it, to make sure we don't accidentally use it. + system.forbiddenDependenciesRegexes = [ + (lib.strings.escapeRegex "nix-${pkgs.nix.version}") + ]; + }; + + otherNixes.nix_2_3.setNixPackage = + { lib, pkgs, ... }: + { + imports = [ checkOverrideNixVersion ]; + nix.package = lib.mkForce pkgs.nixVersions.nix_2_3; + }; + + otherNixes.nix_2_13.setNixPackage = + { lib, pkgs, ... }: + { + imports = [ checkOverrideNixVersion ]; + nix.package = lib.mkForce ( + nixpkgs-23-11.legacyPackages.${pkgs.stdenv.hostPlatform.system}.nixVersions.nix_2_13.overrideAttrs + (o: { + meta = o.meta // { + knownVulnerabilities = [ ]; + }; + }) + ); + }; - otherNixes.nix_2_18.setNixPackage = { lib, pkgs, ... }: { - imports = [ checkOverrideNixVersion ]; - nix.package = lib.mkForce pkgs.nixVersions.nix_2_18; - }; + otherNixes.nix_2_18.setNixPackage = + { lib, pkgs, ... }: + { + imports = [ checkOverrideNixVersion ]; + nix.package = lib.mkForce pkgs.nixVersions.nix_2_18; + }; in @@ -86,30 +112,37 @@ in } // lib.concatMapAttrs ( - nixVersion: { setNixPackage, ... }: + nixVersion: + { setNixPackage, ... }: { "remoteBuilds_remote_${nixVersion}" = runNixOSTestFor "x86_64-linux" { name = "remoteBuilds_remote_${nixVersion}"; imports = [ ./remote-builds.nix ]; - builders.config = { lib, pkgs, ... }: { - imports = [ setNixPackage ]; - }; + builders.config = + { lib, pkgs, ... }: + { + imports = [ setNixPackage ]; + }; }; "remoteBuilds_local_${nixVersion}" = runNixOSTestFor "x86_64-linux" { name = "remoteBuilds_local_${nixVersion}"; imports = [ ./remote-builds.nix ]; - nodes.client = { lib, pkgs, ... }: { - imports = [ setNixPackage ]; - }; + nodes.client = + { lib, pkgs, ... }: + { + imports = [ setNixPackage ]; + }; }; "remoteBuildsSshNg_remote_${nixVersion}" = runNixOSTestFor "x86_64-linux" { name = "remoteBuildsSshNg_remote_${nixVersion}"; imports = [ ./remote-builds-ssh-ng.nix ]; - builders.config = { lib, pkgs, ... }: { - imports = [ setNixPackage ]; - }; + builders.config = + { lib, pkgs, ... }: + { + imports = [ setNixPackage ]; + }; }; # FIXME: these tests don't work yet @@ -143,9 +176,7 @@ in containers = runNixOSTestFor "x86_64-linux" ./containers/containers.nix; - setuid = lib.genAttrs - ["x86_64-linux"] - (system: runNixOSTestFor system ./setuid.nix); + setuid = lib.genAttrs [ "x86_64-linux" ] (system: runNixOSTestFor system ./setuid.nix); fetch-git = runNixOSTestFor "x86_64-linux" ./fetch-git; diff --git a/tests/nixos/fetch-git/default.nix b/tests/nixos/fetch-git/default.nix index 1d6bcb63783..329fb463e8e 100644 --- a/tests/nixos/fetch-git/default.nix +++ b/tests/nixos/fetch-git/default.nix @@ -7,26 +7,27 @@ ]; /* - Test cases + Test cases - Test cases are automatically imported from ./test-cases/{name} + Test cases are automatically imported from ./test-cases/{name} - The following is set up automatically for each test case: - - a repo with the {name} is created on the gitea server - - a repo with the {name} is created on the client - - the client repo is configured to push to the server repo + The following is set up automatically for each test case: + - a repo with the {name} is created on the gitea server + - a repo with the {name} is created on the client + - the client repo is configured to push to the server repo - Python variables: - - repo.path: the path to the directory of the client repo - - repo.git: the git command with the client repo as the working directory - - repo.remote: the url to the server repo + Python variables: + - repo.path: the path to the directory of the client repo + - repo.git: the git command with the client repo as the working directory + - repo.remote: the url to the server repo */ - testCases = - map - (testCaseName: {...}: { + testCases = map ( + testCaseName: + { ... }: + { imports = [ (./test-cases + "/${testCaseName}") ]; # ensures tests are named like their directories they are defined in name = testCaseName; - }) - (lib.attrNames (builtins.readDir ./test-cases)); + } + ) (lib.attrNames (builtins.readDir ./test-cases)); } diff --git a/tests/nixos/fetch-git/test-cases/http-auth/default.nix b/tests/nixos/fetch-git/test-cases/http-auth/default.nix index d483d54fb24..7ad9a8914e2 100644 --- a/tests/nixos/fetch-git/test-cases/http-auth/default.nix +++ b/tests/nixos/fetch-git/test-cases/http-auth/default.nix @@ -5,7 +5,8 @@ script = '' # add a file to the repo client.succeed(f""" - echo ${config.name /* to make the git tree and store path unique */} > {repo.path}/test-case \ + echo ${config.name # to make the git tree and store path unique + } > {repo.path}/test-case \ && echo lutyabrook > {repo.path}/new-york-state \ && {repo.git} add test-case new-york-state \ && {repo.git} commit -m 'commit1' diff --git a/tests/nixos/fetch-git/test-cases/http-simple/default.nix b/tests/nixos/fetch-git/test-cases/http-simple/default.nix index dcab8067e59..51b3882b5a6 100644 --- a/tests/nixos/fetch-git/test-cases/http-simple/default.nix +++ b/tests/nixos/fetch-git/test-cases/http-simple/default.nix @@ -4,7 +4,8 @@ script = '' # add a file to the repo client.succeed(f""" - echo ${config.name /* to make the git tree and store path unique */} > {repo.path}/test-case \ + echo ${config.name # to make the git tree and store path unique + } > {repo.path}/test-case \ && echo chiang-mai > {repo.path}/thailand \ && {repo.git} add test-case thailand \ && {repo.git} commit -m 'commit1' diff --git a/tests/nixos/fetch-git/test-cases/ssh-simple/default.nix b/tests/nixos/fetch-git/test-cases/ssh-simple/default.nix index f5fba169846..89285d00ed4 100644 --- a/tests/nixos/fetch-git/test-cases/ssh-simple/default.nix +++ b/tests/nixos/fetch-git/test-cases/ssh-simple/default.nix @@ -4,7 +4,8 @@ script = '' # add a file to the repo client.succeed(f""" - echo ${config.name /* to make the git tree and store path unique */} > {repo.path}/test-case \ + echo ${config.name # to make the git tree and store path unique + } > {repo.path}/test-case \ && echo chiang-mai > {repo.path}/thailand \ && {repo.git} add test-case thailand \ && {repo.git} commit -m 'commit1' diff --git a/tests/nixos/fetch-git/testsupport/gitea-repo.nix b/tests/nixos/fetch-git/testsupport/gitea-repo.nix index e9f4adcc1d3..c8244207fbb 100644 --- a/tests/nixos/fetch-git/testsupport/gitea-repo.nix +++ b/tests/nixos/fetch-git/testsupport/gitea-repo.nix @@ -8,25 +8,27 @@ let boolPyLiteral = b: if b then "True" else "False"; - testCaseExtension = { config, ... }: { - options = { - repo.enable = mkOption { - type = types.bool; - default = true; - description = "Whether to provide a repo variable - automatic repo creation."; + testCaseExtension = + { config, ... }: + { + options = { + repo.enable = mkOption { + type = types.bool; + default = true; + description = "Whether to provide a repo variable - automatic repo creation."; + }; + repo.private = mkOption { + type = types.bool; + default = false; + description = "Whether the repo should be private."; + }; }; - repo.private = mkOption { - type = types.bool; - default = false; - description = "Whether the repo should be private."; + config = mkIf config.repo.enable { + setupScript = '' + repo = Repo("${config.name}", private=${boolPyLiteral config.repo.private}) + ''; }; }; - config = mkIf config.repo.enable { - setupScript = '' - repo = Repo("${config.name}", private=${boolPyLiteral config.repo.private}) - ''; - }; - }; in { options = { diff --git a/tests/nixos/fetch-git/testsupport/gitea.nix b/tests/nixos/fetch-git/testsupport/gitea.nix index cf87bb4662d..9409acff7cb 100644 --- a/tests/nixos/fetch-git/testsupport/gitea.nix +++ b/tests/nixos/fetch-git/testsupport/gitea.nix @@ -1,4 +1,11 @@ -{ lib, nixpkgs, system, pkgs, ... }: let +{ + lib, + nixpkgs, + system, + pkgs, + ... +}: +let clientPrivateKey = pkgs.writeText "id_ed25519" '' -----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW @@ -9,41 +16,52 @@ -----END OPENSSH PRIVATE KEY----- ''; - clientPublicKey = - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFt5a8eH8BYZYjoQhzXGVKKHJe1pw1D0p7O2Vb9VTLzB"; + clientPublicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFt5a8eH8BYZYjoQhzXGVKKHJe1pw1D0p7O2Vb9VTLzB"; -in { +in +{ imports = [ ../testsupport/setup.nix ../testsupport/gitea-repo.nix ]; nodes = { - gitea = { pkgs, ... }: { - services.gitea.enable = true; - services.gitea.settings.service.DISABLE_REGISTRATION = true; - services.gitea.settings.log.LEVEL = "Info"; - services.gitea.settings.database.LOG_SQL = false; - services.openssh.enable = true; - networking.firewall.allowedTCPPorts = [ 3000 ]; - environment.systemPackages = [ pkgs.git pkgs.gitea ]; + gitea = + { pkgs, ... }: + { + services.gitea.enable = true; + services.gitea.settings.service.DISABLE_REGISTRATION = true; + services.gitea.settings.log.LEVEL = "Info"; + services.gitea.settings.database.LOG_SQL = false; + services.openssh.enable = true; + networking.firewall.allowedTCPPorts = [ 3000 ]; + environment.systemPackages = [ + pkgs.git + pkgs.gitea + ]; - users.users.root.openssh.authorizedKeys.keys = [clientPublicKey]; + users.users.root.openssh.authorizedKeys.keys = [ clientPublicKey ]; - # TODO: remove this after updating to nixos-23.11 - nixpkgs.pkgs = lib.mkForce (import nixpkgs { - inherit system; - config.permittedInsecurePackages = [ - "gitea-1.19.4" - ]; - }); - }; - client = { pkgs, ... }: { - environment.systemPackages = [ pkgs.git ]; - }; - }; - defaults = { pkgs, ... }: { - environment.systemPackages = [ pkgs.jq ]; + # TODO: remove this after updating to nixos-23.11 + nixpkgs.pkgs = lib.mkForce ( + import nixpkgs { + inherit system; + config.permittedInsecurePackages = [ + "gitea-1.19.4" + ]; + } + ); + }; + client = + { pkgs, ... }: + { + environment.systemPackages = [ pkgs.git ]; + }; }; + defaults = + { pkgs, ... }: + { + environment.systemPackages = [ pkgs.jq ]; + }; setupScript = '' import shlex diff --git a/tests/nixos/fetch-git/testsupport/setup.nix b/tests/nixos/fetch-git/testsupport/setup.nix index a81d5614b44..c13386c7223 100644 --- a/tests/nixos/fetch-git/testsupport/setup.nix +++ b/tests/nixos/fetch-git/testsupport/setup.nix @@ -1,11 +1,16 @@ -{ lib, config, extendModules, ... }: +{ + lib, + config, + extendModules, + ... +}: let inherit (lib) mkOption types ; - indent = lib.replaceStrings ["\n"] ["\n "]; + indent = lib.replaceStrings [ "\n" ] [ "\n " ]; execTestCase = testCase: '' @@ -35,37 +40,39 @@ in description = '' The test cases. See `testScript`. ''; - type = types.listOf (types.submodule { - options.name = mkOption { - type = types.str; - description = '' - The name of the test case. + type = types.listOf ( + types.submodule { + options.name = mkOption { + type = types.str; + description = '' + The name of the test case. - A repository with that name will be set up on the gitea server and locally. - ''; - }; - options.description = mkOption { - type = types.str; - description = '' - A description of the test case. - ''; - }; - options.setupScript = mkOption { - type = types.lines; - description = '' - Python code that runs before the test case. - ''; - default = ""; - }; - options.script = mkOption { - type = types.lines; - description = '' - Python code that runs the test. + A repository with that name will be set up on the gitea server and locally. + ''; + }; + options.description = mkOption { + type = types.str; + description = '' + A description of the test case. + ''; + }; + options.setupScript = mkOption { + type = types.lines; + description = '' + Python code that runs before the test case. + ''; + default = ""; + }; + options.script = mkOption { + type = types.lines; + description = '' + Python code that runs the test. - Variables defined by the global `setupScript`, as well as `testCases.*.setupScript` will be available here. - ''; - }; - }); + Variables defined by the global `setupScript`, as well as `testCases.*.setupScript` will be available here. + ''; + }; + } + ); }; }; @@ -74,10 +81,12 @@ in environment.variables = { _NIX_FORCE_HTTP = "1"; }; - nix.settings.experimental-features = ["nix-command" "flakes"]; + nix.settings.experimental-features = [ + "nix-command" + "flakes" + ]; }; - setupScript = '' - ''; + setupScript = ''''; testScript = '' start_all(); diff --git a/tests/nixos/fetchurl.nix b/tests/nixos/fetchurl.nix index bfae8deecac..e8663debbcd 100644 --- a/tests/nixos/fetchurl.nix +++ b/tests/nixos/fetchurl.nix @@ -5,16 +5,20 @@ let - makeTlsCert = name: pkgs.runCommand name { - nativeBuildInputs = with pkgs; [ openssl ]; - } '' - mkdir -p $out - openssl req -x509 \ - -subj '/CN=${name}/' -days 49710 \ - -addext 'subjectAltName = DNS:${name}' \ - -keyout "$out/key.pem" -newkey ed25519 \ - -out "$out/cert.pem" -noenc - ''; + makeTlsCert = + name: + pkgs.runCommand name + { + nativeBuildInputs = with pkgs; [ openssl ]; + } + '' + mkdir -p $out + openssl req -x509 \ + -subj '/CN=${name}/' -days 49710 \ + -addext 'subjectAltName = DNS:${name}' \ + -keyout "$out/key.pem" -newkey ed25519 \ + -out "$out/cert.pem" -noenc + ''; goodCert = makeTlsCert "good"; badCert = makeTlsCert "bad"; @@ -25,39 +29,44 @@ in name = "fetchurl"; nodes = { - machine = { pkgs, ... }: { - services.nginx = { - enable = true; - - virtualHosts."good" = { - addSSL = true; - sslCertificate = "${goodCert}/cert.pem"; - sslCertificateKey = "${goodCert}/key.pem"; - root = pkgs.runCommand "nginx-root" {} '' - mkdir "$out" - echo 'hello world' > "$out/index.html" - ''; + machine = + { pkgs, ... }: + { + services.nginx = { + enable = true; + + virtualHosts."good" = { + addSSL = true; + sslCertificate = "${goodCert}/cert.pem"; + sslCertificateKey = "${goodCert}/key.pem"; + root = pkgs.runCommand "nginx-root" { } '' + mkdir "$out" + echo 'hello world' > "$out/index.html" + ''; + }; + + virtualHosts."bad" = { + addSSL = true; + sslCertificate = "${badCert}/cert.pem"; + sslCertificateKey = "${badCert}/key.pem"; + root = pkgs.runCommand "nginx-root" { } '' + mkdir "$out" + echo 'foobar' > "$out/index.html" + ''; + }; }; - virtualHosts."bad" = { - addSSL = true; - sslCertificate = "${badCert}/cert.pem"; - sslCertificateKey = "${badCert}/key.pem"; - root = pkgs.runCommand "nginx-root" {} '' - mkdir "$out" - echo 'foobar' > "$out/index.html" - ''; - }; - }; + security.pki.certificateFiles = [ "${goodCert}/cert.pem" ]; - security.pki.certificateFiles = [ "${goodCert}/cert.pem" ]; + networking.hosts."127.0.0.1" = [ + "good" + "bad" + ]; - networking.hosts."127.0.0.1" = [ "good" "bad" ]; + virtualisation.writableStore = true; - virtualisation.writableStore = true; - - nix.settings.experimental-features = "nix-command"; - }; + nix.settings.experimental-features = "nix-command"; + }; }; testScript = '' diff --git a/tests/nixos/fsync.nix b/tests/nixos/fsync.nix index 99ac2b25d50..e215e5b3c25 100644 --- a/tests/nixos/fsync.nix +++ b/tests/nixos/fsync.nix @@ -1,4 +1,10 @@ -{ lib, config, nixpkgs, pkgs, ... }: +{ + lib, + config, + nixpkgs, + pkgs, + ... +}: let pkg1 = pkgs.go; @@ -8,32 +14,44 @@ in name = "fsync"; nodes.machine = - { config, lib, pkgs, ... }: - { virtualisation.emptyDiskImages = [ 1024 ]; + { + config, + lib, + pkgs, + ... + }: + { + virtualisation.emptyDiskImages = [ 1024 ]; environment.systemPackages = [ pkg1 ]; nix.settings.experimental-features = [ "nix-command" ]; nix.settings.fsync-store-paths = true; nix.settings.require-sigs = false; - boot.supportedFilesystems = [ "ext4" "btrfs" "xfs" ]; + boot.supportedFilesystems = [ + "ext4" + "btrfs" + "xfs" + ]; }; - testScript = { nodes }: '' - # fmt: off - for fs in ("ext4", "btrfs", "xfs"): - machine.succeed("mkfs.{} {} /dev/vdb".format(fs, "-F" if fs == "ext4" else "-f")) - machine.succeed("mkdir -p /mnt") - machine.succeed("mount /dev/vdb /mnt") - machine.succeed("sync") - machine.succeed("nix copy --offline ${pkg1} --to /mnt") - machine.crash() + testScript = + { nodes }: + '' + # fmt: off + for fs in ("ext4", "btrfs", "xfs"): + machine.succeed("mkfs.{} {} /dev/vdb".format(fs, "-F" if fs == "ext4" else "-f")) + machine.succeed("mkdir -p /mnt") + machine.succeed("mount /dev/vdb /mnt") + machine.succeed("sync") + machine.succeed("nix copy --offline ${pkg1} --to /mnt") + machine.crash() - machine.start() - machine.wait_for_unit("multi-user.target") - machine.succeed("mkdir -p /mnt") - machine.succeed("mount /dev/vdb /mnt") - machine.succeed("nix path-info --offline --store /mnt ${pkg1}") - machine.succeed("nix store verify --all --store /mnt --no-trust") + machine.start() + machine.wait_for_unit("multi-user.target") + machine.succeed("mkdir -p /mnt") + machine.succeed("mount /dev/vdb /mnt") + machine.succeed("nix path-info --offline --store /mnt ${pkg1}") + machine.succeed("nix store verify --all --store /mnt --no-trust") - machine.succeed("umount /dev/vdb") - ''; + machine.succeed("umount /dev/vdb") + ''; } diff --git a/tests/nixos/functional/as-trusted-user.nix b/tests/nixos/functional/as-trusted-user.nix index d6f825697e9..25c1b399c1c 100644 --- a/tests/nixos/functional/as-trusted-user.nix +++ b/tests/nixos/functional/as-trusted-user.nix @@ -4,7 +4,9 @@ imports = [ ./common.nix ]; nodes.machine = { - users.users.alice = { isNormalUser = true; }; + users.users.alice = { + isNormalUser = true; + }; nix.settings.trusted-users = [ "alice" ]; }; @@ -15,4 +17,4 @@ su --login --command "run-test-suite" alice >&2 """) ''; -} \ No newline at end of file +} diff --git a/tests/nixos/functional/as-user.nix b/tests/nixos/functional/as-user.nix index 1443f6e6ccd..b93c8d798a3 100644 --- a/tests/nixos/functional/as-user.nix +++ b/tests/nixos/functional/as-user.nix @@ -4,7 +4,9 @@ imports = [ ./common.nix ]; nodes.machine = { - users.users.alice = { isNormalUser = true; }; + users.users.alice = { + isNormalUser = true; + }; }; testScript = '' diff --git a/tests/nixos/functional/common.nix b/tests/nixos/functional/common.nix index 561271ba0ec..f3cab47259b 100644 --- a/tests/nixos/functional/common.nix +++ b/tests/nixos/functional/common.nix @@ -2,9 +2,11 @@ let # FIXME (roberth) reference issue - inputDerivation = pkg: (pkg.overrideAttrs (o: { - disallowedReferences = [ ]; - })).inputDerivation; + inputDerivation = + pkg: + (pkg.overrideAttrs (o: { + disallowedReferences = [ ]; + })).inputDerivation; in { @@ -12,59 +14,63 @@ in # we skip it to save time. skipTypeCheck = true; - nodes.machine = { config, pkgs, ... }: { + nodes.machine = + { config, pkgs, ... }: + { - virtualisation.writableStore = true; - system.extraDependencies = [ - (inputDerivation config.nix.package) - ]; + virtualisation.writableStore = true; + system.extraDependencies = [ + (inputDerivation config.nix.package) + ]; - nix.settings.substituters = lib.mkForce []; + nix.settings.substituters = lib.mkForce [ ]; - environment.systemPackages = let - run-test-suite = pkgs.writeShellApplication { - name = "run-test-suite"; - runtimeInputs = [ - pkgs.meson - pkgs.ninja - pkgs.jq - pkgs.git + environment.systemPackages = + let + run-test-suite = pkgs.writeShellApplication { + name = "run-test-suite"; + runtimeInputs = [ + pkgs.meson + pkgs.ninja + pkgs.jq + pkgs.git - # Want to avoid `/run/current-system/sw/bin/bash` because we - # want a store path. Likewise for coreutils. - pkgs.bash - pkgs.coreutils - ]; - text = '' - set -x + # Want to avoid `/run/current-system/sw/bin/bash` because we + # want a store path. Likewise for coreutils. + pkgs.bash + pkgs.coreutils + ]; + text = '' + set -x - cat /proc/sys/fs/file-max - ulimit -Hn - ulimit -Sn + cat /proc/sys/fs/file-max + ulimit -Hn + ulimit -Sn - cd ~ + cd ~ - cp -r ${pkgs.nixComponents.nix-functional-tests.src} nix - chmod -R +w nix + cp -r ${pkgs.nixComponents.nix-functional-tests.src} nix + chmod -R +w nix - chmod u+w nix/.version - echo ${pkgs.nixComponents.version} > nix/.version + chmod u+w nix/.version + echo ${pkgs.nixComponents.version} > nix/.version - export isTestOnNixOS=1 + export isTestOnNixOS=1 - export NIX_REMOTE_=daemon - export NIX_REMOTE=daemon + export NIX_REMOTE_=daemon + export NIX_REMOTE=daemon - export NIX_STORE=${builtins.storeDir} + export NIX_STORE=${builtins.storeDir} - meson setup nix/tests/functional build - cd build - meson test -j1 --print-errorlogs - ''; - }; - in [ - run-test-suite - pkgs.git - ]; - }; + meson setup nix/tests/functional build + cd build + meson test -j1 --print-errorlogs + ''; + }; + in + [ + run-test-suite + pkgs.git + ]; + }; } diff --git a/tests/nixos/functional/symlinked-home.nix b/tests/nixos/functional/symlinked-home.nix index 57c45d5d592..900543d0cfe 100644 --- a/tests/nixos/functional/symlinked-home.nix +++ b/tests/nixos/functional/symlinked-home.nix @@ -16,7 +16,9 @@ imports = [ ./common.nix ]; nodes.machine = { - users.users.alice = { isNormalUser = true; }; + users.users.alice = { + isNormalUser = true; + }; }; testScript = '' diff --git a/tests/nixos/git-submodules.nix b/tests/nixos/git-submodules.nix index a82ddf418eb..5b1d9ed5f5f 100644 --- a/tests/nixos/git-submodules.nix +++ b/tests/nixos/git-submodules.nix @@ -6,68 +6,74 @@ config = { name = lib.mkDefault "git-submodules"; - nodes = - { - remote = - { config, pkgs, ... }: - { - services.openssh.enable = true; - environment.systemPackages = [ pkgs.git ]; - }; + nodes = { + remote = + { config, pkgs, ... }: + { + services.openssh.enable = true; + environment.systemPackages = [ pkgs.git ]; + }; - client = - { config, lib, pkgs, ... }: - { - programs.ssh.extraConfig = "ConnectTimeout 30"; - environment.systemPackages = [ pkgs.git ]; - nix.extraOptions = "experimental-features = nix-command flakes"; - }; - }; + client = + { + config, + lib, + pkgs, + ... + }: + { + programs.ssh.extraConfig = "ConnectTimeout 30"; + environment.systemPackages = [ pkgs.git ]; + nix.extraOptions = "experimental-features = nix-command flakes"; + }; + }; - testScript = { nodes }: '' - # fmt: off - import subprocess + testScript = + { nodes }: + '' + # fmt: off + import subprocess - start_all() + start_all() - # Create an SSH key on the client. - subprocess.run([ - "${hostPkgs.openssh}/bin/ssh-keygen", "-t", "ed25519", "-f", "key", "-N", "" - ], capture_output=True, check=True) - client.succeed("mkdir -p -m 700 /root/.ssh") - client.copy_from_host("key", "/root/.ssh/id_ed25519") - client.succeed("chmod 600 /root/.ssh/id_ed25519") + # Create an SSH key on the client. + subprocess.run([ + "${hostPkgs.openssh}/bin/ssh-keygen", "-t", "ed25519", "-f", "key", "-N", "" + ], capture_output=True, check=True) + client.succeed("mkdir -p -m 700 /root/.ssh") + client.copy_from_host("key", "/root/.ssh/id_ed25519") + client.succeed("chmod 600 /root/.ssh/id_ed25519") - # Install the SSH key on the builders. - client.wait_for_unit("network-online.target") + # Install the SSH key on the builders. + client.wait_for_unit("network-online.target") - remote.succeed("mkdir -p -m 700 /root/.ssh") - remote.copy_from_host("key.pub", "/root/.ssh/authorized_keys") - remote.wait_for_unit("sshd") - remote.wait_for_unit("multi-user.target") - remote.wait_for_unit("network-online.target") - client.wait_for_unit("network-online.target") - client.succeed(f"ssh -o StrictHostKeyChecking=no {remote.name} 'echo hello world'") + remote.succeed("mkdir -p -m 700 /root/.ssh") + remote.copy_from_host("key.pub", "/root/.ssh/authorized_keys") + remote.wait_for_unit("sshd") + remote.wait_for_unit("multi-user.target") + remote.wait_for_unit("network-online.target") + client.wait_for_unit("network-online.target") + client.succeed(f"ssh -o StrictHostKeyChecking=no {remote.name} 'echo hello world'") - remote.succeed(""" - git init bar - git -C bar config user.email foobar@example.com - git -C bar config user.name Foobar - echo test >> bar/content - git -C bar add content - git -C bar commit -m 'Initial commit' - """) + remote.succeed(""" + git init bar + git -C bar config user.email foobar@example.com + git -C bar config user.name Foobar + echo test >> bar/content + git -C bar add content + git -C bar commit -m 'Initial commit' + """) - client.succeed(f""" - git init foo - git -C foo config user.email foobar@example.com - git -C foo config user.name Foobar - git -C foo submodule add root@{remote.name}:/tmp/bar sub - git -C foo add sub - git -C foo commit -m 'Add submodule' - """) + client.succeed(f""" + git init foo + git -C foo config user.email foobar@example.com + git -C foo config user.name Foobar + git -C foo submodule add root@{remote.name}:/tmp/bar sub + git -C foo add sub + git -C foo commit -m 'Add submodule' + """) - client.succeed("nix --flake-registry \"\" flake prefetch 'git+file:///tmp/foo?submodules=1&ref=master'") - ''; + client.succeed("nix --flake-registry \"\" flake prefetch 'git+file:///tmp/foo?submodules=1&ref=master'") + ''; }; } diff --git a/tests/nixos/github-flakes.nix b/tests/nixos/github-flakes.nix index 69d1df410d3..dcba464a34d 100644 --- a/tests/nixos/github-flakes.nix +++ b/tests/nixos/github-flakes.nix @@ -1,21 +1,25 @@ -{ lib, config, nixpkgs, ... }: +{ + lib, + config, + nixpkgs, + ... +}: let pkgs = config.nodes.client.nixpkgs.pkgs; # Generate a fake root CA and a fake api.github.com / github.com / channels.nixos.org certificate. - cert = pkgs.runCommand "cert" { nativeBuildInputs = [ pkgs.openssl ]; } - '' - mkdir -p $out + cert = pkgs.runCommand "cert" { nativeBuildInputs = [ pkgs.openssl ]; } '' + mkdir -p $out - openssl genrsa -out ca.key 2048 - openssl req -new -x509 -days 36500 -key ca.key \ - -subj "/C=NL/ST=Denial/L=Springfield/O=Dis/CN=Root CA" -out $out/ca.crt + openssl genrsa -out ca.key 2048 + openssl req -new -x509 -days 36500 -key ca.key \ + -subj "/C=NL/ST=Denial/L=Springfield/O=Dis/CN=Root CA" -out $out/ca.crt - openssl req -newkey rsa:2048 -nodes -keyout $out/server.key \ - -subj "/C=CN/ST=Denial/L=Springfield/O=Dis/CN=github.com" -out server.csr - openssl x509 -req -extfile <(printf "subjectAltName=DNS:api.github.com,DNS:github.com,DNS:channels.nixos.org") \ - -days 36500 -in server.csr -CA $out/ca.crt -CAkey ca.key -CAcreateserial -out $out/server.crt - ''; + openssl req -newkey rsa:2048 -nodes -keyout $out/server.key \ + -subj "/C=CN/ST=Denial/L=Springfield/O=Dis/CN=github.com" -out server.csr + openssl x509 -req -extfile <(printf "subjectAltName=DNS:api.github.com,DNS:github.com,DNS:channels.nixos.org") \ + -days 36500 -in server.csr -CA $out/ca.crt -CAkey ca.key -CAcreateserial -out $out/server.crt + ''; registry = pkgs.writeTextFile { name = "registry"; @@ -53,168 +57,190 @@ let private-flake-rev = "9f1dd0df5b54a7dc75b618034482ed42ce34383d"; - private-flake-api = pkgs.runCommand "private-flake" {} - '' - mkdir -p $out/{commits,tarball} + private-flake-api = pkgs.runCommand "private-flake" { } '' + mkdir -p $out/{commits,tarball} - # Setup https://docs.github.com/en/rest/commits/commits#get-a-commit - echo '{"sha": "${private-flake-rev}", "commit": {"tree": {"sha": "ffffffffffffffffffffffffffffffffffffffff"}}}' > $out/commits/HEAD + # Setup https://docs.github.com/en/rest/commits/commits#get-a-commit + echo '{"sha": "${private-flake-rev}", "commit": {"tree": {"sha": "ffffffffffffffffffffffffffffffffffffffff"}}}' > $out/commits/HEAD - # Setup tarball download via API - dir=private-flake - mkdir $dir - echo '{ outputs = {...}: {}; }' > $dir/flake.nix - tar cfz $out/tarball/${private-flake-rev} $dir --hard-dereference - ''; + # Setup tarball download via API + dir=private-flake + mkdir $dir + echo '{ outputs = {...}: {}; }' > $dir/flake.nix + tar cfz $out/tarball/${private-flake-rev} $dir --hard-dereference + ''; - nixpkgs-api = pkgs.runCommand "nixpkgs-flake" {} - '' - mkdir -p $out/commits + nixpkgs-api = pkgs.runCommand "nixpkgs-flake" { } '' + mkdir -p $out/commits - # Setup https://docs.github.com/en/rest/commits/commits#get-a-commit - echo '{"sha": "${nixpkgs.rev}", "commit": {"tree": {"sha": "ffffffffffffffffffffffffffffffffffffffff"}}}' > $out/commits/HEAD - ''; + # Setup https://docs.github.com/en/rest/commits/commits#get-a-commit + echo '{"sha": "${nixpkgs.rev}", "commit": {"tree": {"sha": "ffffffffffffffffffffffffffffffffffffffff"}}}' > $out/commits/HEAD + ''; - archive = pkgs.runCommand "nixpkgs-flake" {} - '' - mkdir -p $out/archive + archive = pkgs.runCommand "nixpkgs-flake" { } '' + mkdir -p $out/archive - dir=NixOS-nixpkgs-${nixpkgs.shortRev} - cp -prd ${nixpkgs} $dir - # Set the correct timestamp in the tarball. - find $dir -print0 | xargs -0 touch -h -t ${builtins.substring 0 12 nixpkgs.lastModifiedDate}.${builtins.substring 12 2 nixpkgs.lastModifiedDate} -- - tar cfz $out/archive/${nixpkgs.rev}.tar.gz $dir --hard-dereference - ''; + dir=NixOS-nixpkgs-${nixpkgs.shortRev} + cp -prd ${nixpkgs} $dir + # Set the correct timestamp in the tarball. + find $dir -print0 | xargs -0 touch -h -t ${builtins.substring 0 12 nixpkgs.lastModifiedDate}.${ + builtins.substring 12 2 nixpkgs.lastModifiedDate + } -- + tar cfz $out/archive/${nixpkgs.rev}.tar.gz $dir --hard-dereference + ''; in { name = "github-flakes"; - nodes = - { - github = - { config, pkgs, ... }: - { networking.firewall.allowedTCPPorts = [ 80 443 ]; - - services.httpd.enable = true; - services.httpd.adminAddr = "foo@example.org"; - services.httpd.extraConfig = '' - ErrorLog syslog:local6 - ''; - services.httpd.virtualHosts."channels.nixos.org" = - { forceSSL = true; - sslServerKey = "${cert}/server.key"; - sslServerCert = "${cert}/server.crt"; - servedDirs = - [ { urlPath = "/"; - dir = registry; - } - ]; - }; - services.httpd.virtualHosts."api.github.com" = - { forceSSL = true; - sslServerKey = "${cert}/server.key"; - sslServerCert = "${cert}/server.crt"; - servedDirs = - [ { urlPath = "/repos/NixOS/nixpkgs"; - dir = nixpkgs-api; - } - { urlPath = "/repos/fancy-enterprise/private-flake"; - dir = private-flake-api; - } - ]; - }; - services.httpd.virtualHosts."github.com" = - { forceSSL = true; - sslServerKey = "${cert}/server.key"; - sslServerCert = "${cert}/server.crt"; - servedDirs = - [ { urlPath = "/NixOS/nixpkgs"; - dir = archive; - } - ]; - }; + nodes = { + github = + { config, pkgs, ... }: + { + networking.firewall.allowedTCPPorts = [ + 80 + 443 + ]; + + services.httpd.enable = true; + services.httpd.adminAddr = "foo@example.org"; + services.httpd.extraConfig = '' + ErrorLog syslog:local6 + ''; + services.httpd.virtualHosts."channels.nixos.org" = { + forceSSL = true; + sslServerKey = "${cert}/server.key"; + sslServerCert = "${cert}/server.crt"; + servedDirs = [ + { + urlPath = "/"; + dir = registry; + } + ]; }; - - client = - { config, lib, pkgs, nodes, ... }: - { virtualisation.writableStore = true; - virtualisation.diskSize = 2048; - virtualisation.additionalPaths = [ pkgs.hello pkgs.fuse ]; - virtualisation.memorySize = 4096; - nix.settings.substituters = lib.mkForce [ ]; - nix.extraOptions = "experimental-features = nix-command flakes"; - networking.hosts.${(builtins.head nodes.github.networking.interfaces.eth1.ipv4.addresses).address} = - [ "channels.nixos.org" "api.github.com" "github.com" ]; - security.pki.certificateFiles = [ "${cert}/ca.crt" ]; + services.httpd.virtualHosts."api.github.com" = { + forceSSL = true; + sslServerKey = "${cert}/server.key"; + sslServerCert = "${cert}/server.crt"; + servedDirs = [ + { + urlPath = "/repos/NixOS/nixpkgs"; + dir = nixpkgs-api; + } + { + urlPath = "/repos/fancy-enterprise/private-flake"; + dir = private-flake-api; + } + ]; }; - }; - - testScript = { nodes }: '' - # fmt: off - import json - import time - - start_all() - - def cat_log(): - github.succeed("cat /var/log/httpd/*.log >&2") - - github.wait_for_unit("httpd.service") - github.wait_for_unit("network-online.target") - - client.wait_for_unit("network-online.target") - client.succeed("curl -v https://github.com/ >&2") - out = client.succeed("nix registry list") - print(out) - assert "github:NixOS/nixpkgs" in out, "nixpkgs flake not found" - assert "github:fancy-enterprise/private-flake" in out, "private flake not found" - cat_log() - - # If no github access token is provided, nix should use the public archive url... - out = client.succeed("nix flake metadata nixpkgs --json") - print(out) - info = json.loads(out) - assert info["revision"] == "${nixpkgs.rev}", f"revision mismatch: {info['revision']} != ${nixpkgs.rev}" - cat_log() - - # ... otherwise it should use the API - out = client.succeed("nix flake metadata private-flake --json --access-tokens github.com=ghp_000000000000000000000000000000000000 --tarball-ttl 0") - print(out) - info = json.loads(out) - assert info["revision"] == "${private-flake-rev}", f"revision mismatch: {info['revision']} != ${private-flake-rev}" - assert info["fingerprint"] - cat_log() - - # Fetching with the resolved URL should produce the same result. - info2 = json.loads(client.succeed(f"nix flake metadata {info['url']} --json --access-tokens github.com=ghp_000000000000000000000000000000000000 --tarball-ttl 0")) - print(info["fingerprint"], info2["fingerprint"]) - assert info["fingerprint"] == info2["fingerprint"], "fingerprint mismatch" - - client.succeed("nix registry pin nixpkgs") - client.succeed("nix flake metadata nixpkgs --tarball-ttl 0 >&2") - - # Test fetchTree on a github URL. - hash = client.succeed(f"nix eval --no-trust-tarballs-from-git-forges --raw --expr '(fetchTree {info['url']}).narHash'") - assert hash == info['locked']['narHash'] - - # Fetching without a narHash should succeed if trust-github is set and fail otherwise. - client.succeed(f"nix eval --raw --expr 'builtins.fetchTree github:github:fancy-enterprise/private-flake/{info['revision']}'") - out = client.fail(f"nix eval --no-trust-tarballs-from-git-forges --raw --expr 'builtins.fetchTree github:github:fancy-enterprise/private-flake/{info['revision']}' 2>&1") - assert "will not fetch unlocked input" in out, "--no-trust-tarballs-from-git-forges did not fail with the expected error" - - # Shut down the web server. The flake should be cached on the client. - github.succeed("systemctl stop httpd.service") - - info = json.loads(client.succeed("nix flake metadata nixpkgs --json")) - date = time.strftime("%Y%m%d%H%M%S", time.gmtime(info['lastModified'])) - assert date == "${nixpkgs.lastModifiedDate}", "time mismatch" - - client.succeed("nix build nixpkgs#hello") - - # The build shouldn't fail even with --tarball-ttl 0 (the server - # being down should not be a fatal error). - client.succeed("nix build nixpkgs#fuse --tarball-ttl 0") - ''; + services.httpd.virtualHosts."github.com" = { + forceSSL = true; + sslServerKey = "${cert}/server.key"; + sslServerCert = "${cert}/server.crt"; + servedDirs = [ + { + urlPath = "/NixOS/nixpkgs"; + dir = archive; + } + ]; + }; + }; + + client = + { + config, + lib, + pkgs, + nodes, + ... + }: + { + virtualisation.writableStore = true; + virtualisation.diskSize = 2048; + virtualisation.additionalPaths = [ + pkgs.hello + pkgs.fuse + ]; + virtualisation.memorySize = 4096; + nix.settings.substituters = lib.mkForce [ ]; + nix.extraOptions = "experimental-features = nix-command flakes"; + networking.hosts.${(builtins.head nodes.github.networking.interfaces.eth1.ipv4.addresses).address} = + [ + "channels.nixos.org" + "api.github.com" + "github.com" + ]; + security.pki.certificateFiles = [ "${cert}/ca.crt" ]; + }; + }; + + testScript = + { nodes }: + '' + # fmt: off + import json + import time + + start_all() + + def cat_log(): + github.succeed("cat /var/log/httpd/*.log >&2") + + github.wait_for_unit("httpd.service") + github.wait_for_unit("network-online.target") + + client.wait_for_unit("network-online.target") + client.succeed("curl -v https://github.com/ >&2") + out = client.succeed("nix registry list") + print(out) + assert "github:NixOS/nixpkgs" in out, "nixpkgs flake not found" + assert "github:fancy-enterprise/private-flake" in out, "private flake not found" + cat_log() + + # If no github access token is provided, nix should use the public archive url... + out = client.succeed("nix flake metadata nixpkgs --json") + print(out) + info = json.loads(out) + assert info["revision"] == "${nixpkgs.rev}", f"revision mismatch: {info['revision']} != ${nixpkgs.rev}" + cat_log() + + # ... otherwise it should use the API + out = client.succeed("nix flake metadata private-flake --json --access-tokens github.com=ghp_000000000000000000000000000000000000 --tarball-ttl 0") + print(out) + info = json.loads(out) + assert info["revision"] == "${private-flake-rev}", f"revision mismatch: {info['revision']} != ${private-flake-rev}" + assert info["fingerprint"] + cat_log() + + # Fetching with the resolved URL should produce the same result. + info2 = json.loads(client.succeed(f"nix flake metadata {info['url']} --json --access-tokens github.com=ghp_000000000000000000000000000000000000 --tarball-ttl 0")) + print(info["fingerprint"], info2["fingerprint"]) + assert info["fingerprint"] == info2["fingerprint"], "fingerprint mismatch" + + client.succeed("nix registry pin nixpkgs") + client.succeed("nix flake metadata nixpkgs --tarball-ttl 0 >&2") + + # Test fetchTree on a github URL. + hash = client.succeed(f"nix eval --no-trust-tarballs-from-git-forges --raw --expr '(fetchTree {info['url']}).narHash'") + assert hash == info['locked']['narHash'] + + # Fetching without a narHash should succeed if trust-github is set and fail otherwise. + client.succeed(f"nix eval --raw --expr 'builtins.fetchTree github:github:fancy-enterprise/private-flake/{info['revision']}'") + out = client.fail(f"nix eval --no-trust-tarballs-from-git-forges --raw --expr 'builtins.fetchTree github:github:fancy-enterprise/private-flake/{info['revision']}' 2>&1") + assert "will not fetch unlocked input" in out, "--no-trust-tarballs-from-git-forges did not fail with the expected error" + + # Shut down the web server. The flake should be cached on the client. + github.succeed("systemctl stop httpd.service") + + info = json.loads(client.succeed("nix flake metadata nixpkgs --json")) + date = time.strftime("%Y%m%d%H%M%S", time.gmtime(info['lastModified'])) + assert date == "${nixpkgs.lastModifiedDate}", "time mismatch" + + client.succeed("nix build nixpkgs#hello") + + # The build shouldn't fail even with --tarball-ttl 0 (the server + # being down should not be a fatal error). + client.succeed("nix build nixpkgs#fuse --tarball-ttl 0") + ''; } diff --git a/tests/nixos/gzip-content-encoding.nix b/tests/nixos/gzip-content-encoding.nix index a5a0033fd19..22d196c6186 100644 --- a/tests/nixos/gzip-content-encoding.nix +++ b/tests/nixos/gzip-content-encoding.nix @@ -30,42 +30,45 @@ in { name = "gzip-content-encoding"; - nodes = - { machine = + nodes = { + machine = { config, pkgs, ... }: - { networking.firewall.allowedTCPPorts = [ 80 ]; + { + networking.firewall.allowedTCPPorts = [ 80 ]; services.nginx.enable = true; - services.nginx.virtualHosts."localhost" = - { root = "${ztdCompressedFile}/share/"; - # Make sure that nginx really tries to compress the - # file on the fly with no regard to size/mime. - # http://nginx.org/en/docs/http/ngx_http_gzip_module.html - extraConfig = '' - gzip on; - gzip_types *; - gzip_proxied any; - gzip_min_length 0; - ''; - }; + services.nginx.virtualHosts."localhost" = { + root = "${ztdCompressedFile}/share/"; + # Make sure that nginx really tries to compress the + # file on the fly with no regard to size/mime. + # http://nginx.org/en/docs/http/ngx_http_gzip_module.html + extraConfig = '' + gzip on; + gzip_types *; + gzip_proxied any; + gzip_min_length 0; + ''; + }; virtualisation.writableStore = true; virtualisation.additionalPaths = with pkgs; [ file ]; nix.settings.substituters = lib.mkForce [ ]; }; - }; + }; # Check that when nix-prefetch-url is used with a zst tarball it does not get decompressed. - testScript = { nodes }: '' - # fmt: off - start_all() + testScript = + { nodes }: + '' + # fmt: off + start_all() - machine.wait_for_unit("nginx.service") - machine.succeed(""" - # Make sure that the file is properly compressed as the test would be meaningless otherwise - curl --compressed -v http://localhost/archive |& tr -s ' ' |& grep --ignore-case 'content-encoding: gzip' - archive_path=$(nix-prefetch-url http://localhost/archive --print-path | tail -n1) - [[ $(${fileCmd} --brief --mime-type $archive_path) == "application/zstd" ]] - tar --zstd -xf $archive_path - """) - ''; + machine.wait_for_unit("nginx.service") + machine.succeed(""" + # Make sure that the file is properly compressed as the test would be meaningless otherwise + curl --compressed -v http://localhost/archive |& tr -s ' ' |& grep --ignore-case 'content-encoding: gzip' + archive_path=$(nix-prefetch-url http://localhost/archive --print-path | tail -n1) + [[ $(${fileCmd} --brief --mime-type $archive_path) == "application/zstd" ]] + tar --zstd -xf $archive_path + """) + ''; } diff --git a/tests/nixos/nix-copy-closure.nix b/tests/nixos/nix-copy-closure.nix index 44324e989b3..b6ec856e0e4 100644 --- a/tests/nixos/nix-copy-closure.nix +++ b/tests/nixos/nix-copy-closure.nix @@ -1,6 +1,11 @@ # Test ‘nix-copy-closure’. -{ lib, config, nixpkgs, ... }: +{ + lib, + config, + nixpkgs, + ... +}: let pkgs = config.nodes.client.nixpkgs.pkgs; @@ -10,74 +15,90 @@ let pkgC = pkgs.hello; pkgD = pkgs.tmux; -in { +in +{ name = "nix-copy-closure"; - nodes = - { client = - { config, lib, pkgs, ... }: - { virtualisation.writableStore = true; - virtualisation.additionalPaths = [ pkgA pkgD.drvPath ]; - nix.settings.substituters = lib.mkForce [ ]; - }; - - server = - { config, pkgs, ... }: - { services.openssh.enable = true; - virtualisation.writableStore = true; - virtualisation.additionalPaths = [ pkgB pkgC ]; - }; - }; - - testScript = { nodes }: '' - # fmt: off - import subprocess - - start_all() - - # Create an SSH key on the client. - subprocess.run([ - "${pkgs.openssh}/bin/ssh-keygen", "-t", "ed25519", "-f", "key", "-N", "" - ], capture_output=True, check=True) - - client.succeed("mkdir -m 700 /root/.ssh") - client.copy_from_host("key", "/root/.ssh/id_ed25519") - client.succeed("chmod 600 /root/.ssh/id_ed25519") - - # Install the SSH key on the server. - server.succeed("mkdir -m 700 /root/.ssh") - server.copy_from_host("key.pub", "/root/.ssh/authorized_keys") - server.wait_for_unit("sshd") - server.wait_for_unit("multi-user.target") - server.wait_for_unit("network-online.target") - - client.wait_for_unit("network-online.target") - client.succeed(f"ssh -o StrictHostKeyChecking=no {server.name} 'echo hello world'") - - # Copy the closure of package A from the client to the server. - server.fail("nix-store --check-validity ${pkgA}") - client.succeed("nix-copy-closure --to server --gzip ${pkgA} >&2") - server.succeed("nix-store --check-validity ${pkgA}") - - # Copy the closure of package B from the server to the client. - client.fail("nix-store --check-validity ${pkgB}") - client.succeed("nix-copy-closure --from server --gzip ${pkgB} >&2") - client.succeed("nix-store --check-validity ${pkgB}") - - # Copy the closure of package C via the SSH substituter. - client.fail("nix-store -r ${pkgC}") - - # Copy the derivation of package D's derivation from the client to the server. - server.fail("nix-store --check-validity ${pkgD.drvPath}") - client.succeed("nix-copy-closure --to server --gzip ${pkgD.drvPath} >&2") - server.succeed("nix-store --check-validity ${pkgD.drvPath}") - - # FIXME - # client.succeed( - # "nix-store --option use-ssh-substituter true" - # " --option ssh-substituter-hosts root\@server" - # " -r ${pkgC} >&2" - # ) - # client.succeed("nix-store --check-validity ${pkgC}") - ''; + nodes = { + client = + { + config, + lib, + pkgs, + ... + }: + { + virtualisation.writableStore = true; + virtualisation.additionalPaths = [ + pkgA + pkgD.drvPath + ]; + nix.settings.substituters = lib.mkForce [ ]; + }; + + server = + { config, pkgs, ... }: + { + services.openssh.enable = true; + virtualisation.writableStore = true; + virtualisation.additionalPaths = [ + pkgB + pkgC + ]; + }; + }; + + testScript = + { nodes }: + '' + # fmt: off + import subprocess + + start_all() + + # Create an SSH key on the client. + subprocess.run([ + "${pkgs.openssh}/bin/ssh-keygen", "-t", "ed25519", "-f", "key", "-N", "" + ], capture_output=True, check=True) + + client.succeed("mkdir -m 700 /root/.ssh") + client.copy_from_host("key", "/root/.ssh/id_ed25519") + client.succeed("chmod 600 /root/.ssh/id_ed25519") + + # Install the SSH key on the server. + server.succeed("mkdir -m 700 /root/.ssh") + server.copy_from_host("key.pub", "/root/.ssh/authorized_keys") + server.wait_for_unit("sshd") + server.wait_for_unit("multi-user.target") + server.wait_for_unit("network-online.target") + + client.wait_for_unit("network-online.target") + client.succeed(f"ssh -o StrictHostKeyChecking=no {server.name} 'echo hello world'") + + # Copy the closure of package A from the client to the server. + server.fail("nix-store --check-validity ${pkgA}") + client.succeed("nix-copy-closure --to server --gzip ${pkgA} >&2") + server.succeed("nix-store --check-validity ${pkgA}") + + # Copy the closure of package B from the server to the client. + client.fail("nix-store --check-validity ${pkgB}") + client.succeed("nix-copy-closure --from server --gzip ${pkgB} >&2") + client.succeed("nix-store --check-validity ${pkgB}") + + # Copy the closure of package C via the SSH substituter. + client.fail("nix-store -r ${pkgC}") + + # Copy the derivation of package D's derivation from the client to the server. + server.fail("nix-store --check-validity ${pkgD.drvPath}") + client.succeed("nix-copy-closure --to server --gzip ${pkgD.drvPath} >&2") + server.succeed("nix-store --check-validity ${pkgD.drvPath}") + + # FIXME + # client.succeed( + # "nix-store --option use-ssh-substituter true" + # " --option ssh-substituter-hosts root\@server" + # " -r ${pkgC} >&2" + # ) + # client.succeed("nix-store --check-validity ${pkgC}") + ''; } diff --git a/tests/nixos/nix-copy.nix b/tests/nixos/nix-copy.nix index a6a04b52ca6..3565e83e71a 100644 --- a/tests/nixos/nix-copy.nix +++ b/tests/nixos/nix-copy.nix @@ -2,7 +2,13 @@ # Run interactively with: # rm key key.pub; nix run .#hydraJobs.tests.nix-copy.driverInteractive -{ lib, config, nixpkgs, hostPkgs, ... }: +{ + lib, + config, + nixpkgs, + hostPkgs, + ... +}: let pkgs = config.nodes.client.nixpkgs.pkgs; @@ -12,101 +18,117 @@ let pkgC = pkgs.hello; pkgD = pkgs.tmux; -in { +in +{ name = "nix-copy"; enableOCR = true; - nodes = - { client = - { config, lib, pkgs, ... }: - { virtualisation.writableStore = true; - virtualisation.additionalPaths = [ pkgA pkgD.drvPath ]; - nix.settings.substituters = lib.mkForce [ ]; - nix.settings.experimental-features = [ "nix-command" ]; - services.getty.autologinUser = "root"; - programs.ssh.extraConfig = '' - Host * - ControlMaster auto - ControlPath ~/.ssh/master-%h:%r@%n:%p - ControlPersist 15m - ''; - }; - - server = - { config, pkgs, ... }: - { services.openssh.enable = true; - services.openssh.settings.PermitRootLogin = "yes"; - users.users.root.hashedPasswordFile = null; - users.users.root.password = "foobar"; - virtualisation.writableStore = true; - virtualisation.additionalPaths = [ pkgB pkgC ]; - }; - }; - - testScript = { nodes }: '' - # fmt: off - import subprocess - - # Create an SSH key on the client. - subprocess.run([ - "${pkgs.openssh}/bin/ssh-keygen", "-t", "ed25519", "-f", "key", "-N", "" - ], capture_output=True, check=True) - - start_all() - - server.wait_for_unit("sshd") - server.wait_for_unit("multi-user.target") - server.wait_for_unit("network-online.target") - - client.wait_for_unit("network-online.target") - client.wait_for_unit("getty@tty1.service") - # Either the prompt: ]# - # or an OCR misreading of it: 1# - client.wait_for_text("[]1]#") - - # Copy the closure of package A from the client to the server using password authentication, - # and check that all prompts are visible - server.fail("nix-store --check-validity ${pkgA}") - client.send_chars("nix copy --to ssh://server ${pkgA} >&2; echo -n do; echo ne\n") - client.wait_for_text("continue connecting") - client.send_chars("yes\n") - client.wait_for_text("Password:") - client.send_chars("foobar\n") - client.wait_for_text("done") - server.succeed("nix-store --check-validity ${pkgA}") - - # Check that ControlMaster is working - client.send_chars("nix copy --to ssh://server ${pkgA} >&2; echo done\n") - client.wait_for_text("done") - - client.copy_from_host("key", "/root/.ssh/id_ed25519") - client.succeed("chmod 600 /root/.ssh/id_ed25519") - - # Install the SSH key on the server. - server.copy_from_host("key.pub", "/root/.ssh/authorized_keys") - server.succeed("systemctl restart sshd") - client.succeed(f"ssh -o StrictHostKeyChecking=no {server.name} 'echo hello world'") - client.succeed(f"ssh -O check {server.name}") - client.succeed(f"ssh -O exit {server.name}") - client.fail(f"ssh -O check {server.name}") - - # Check that an explicit master will work - client.succeed(f"ssh -MNfS /tmp/master {server.name}") - client.succeed(f"ssh -S /tmp/master -O check {server.name}") - client.succeed("NIX_SSHOPTS='-oControlPath=/tmp/master' nix copy --to ssh://server ${pkgA} >&2") - client.succeed(f"ssh -S /tmp/master -O exit {server.name}") - - # Copy the closure of package B from the server to the client, using ssh-ng. - client.fail("nix-store --check-validity ${pkgB}") - # Shouldn't download untrusted paths by default - client.fail("nix copy --from ssh-ng://server ${pkgB} >&2") - client.succeed("nix copy --no-check-sigs --from ssh-ng://server ${pkgB} >&2") - client.succeed("nix-store --check-validity ${pkgB}") - - # Copy the derivation of package D's derivation from the client to the server. - server.fail("nix-store --check-validity ${pkgD.drvPath}") - client.succeed("nix copy --derivation --to ssh://server ${pkgD.drvPath} >&2") - server.succeed("nix-store --check-validity ${pkgD.drvPath}") - ''; + nodes = { + client = + { + config, + lib, + pkgs, + ... + }: + { + virtualisation.writableStore = true; + virtualisation.additionalPaths = [ + pkgA + pkgD.drvPath + ]; + nix.settings.substituters = lib.mkForce [ ]; + nix.settings.experimental-features = [ "nix-command" ]; + services.getty.autologinUser = "root"; + programs.ssh.extraConfig = '' + Host * + ControlMaster auto + ControlPath ~/.ssh/master-%h:%r@%n:%p + ControlPersist 15m + ''; + }; + + server = + { config, pkgs, ... }: + { + services.openssh.enable = true; + services.openssh.settings.PermitRootLogin = "yes"; + users.users.root.hashedPasswordFile = null; + users.users.root.password = "foobar"; + virtualisation.writableStore = true; + virtualisation.additionalPaths = [ + pkgB + pkgC + ]; + }; + }; + + testScript = + { nodes }: + '' + # fmt: off + import subprocess + + # Create an SSH key on the client. + subprocess.run([ + "${pkgs.openssh}/bin/ssh-keygen", "-t", "ed25519", "-f", "key", "-N", "" + ], capture_output=True, check=True) + + start_all() + + server.wait_for_unit("sshd") + server.wait_for_unit("multi-user.target") + server.wait_for_unit("network-online.target") + + client.wait_for_unit("network-online.target") + client.wait_for_unit("getty@tty1.service") + # Either the prompt: ]# + # or an OCR misreading of it: 1# + client.wait_for_text("[]1]#") + + # Copy the closure of package A from the client to the server using password authentication, + # and check that all prompts are visible + server.fail("nix-store --check-validity ${pkgA}") + client.send_chars("nix copy --to ssh://server ${pkgA} >&2; echo -n do; echo ne\n") + client.wait_for_text("continue connecting") + client.send_chars("yes\n") + client.wait_for_text("Password:") + client.send_chars("foobar\n") + client.wait_for_text("done") + server.succeed("nix-store --check-validity ${pkgA}") + + # Check that ControlMaster is working + client.send_chars("nix copy --to ssh://server ${pkgA} >&2; echo done\n") + client.wait_for_text("done") + + client.copy_from_host("key", "/root/.ssh/id_ed25519") + client.succeed("chmod 600 /root/.ssh/id_ed25519") + + # Install the SSH key on the server. + server.copy_from_host("key.pub", "/root/.ssh/authorized_keys") + server.succeed("systemctl restart sshd") + client.succeed(f"ssh -o StrictHostKeyChecking=no {server.name} 'echo hello world'") + client.succeed(f"ssh -O check {server.name}") + client.succeed(f"ssh -O exit {server.name}") + client.fail(f"ssh -O check {server.name}") + + # Check that an explicit master will work + client.succeed(f"ssh -MNfS /tmp/master {server.name}") + client.succeed(f"ssh -S /tmp/master -O check {server.name}") + client.succeed("NIX_SSHOPTS='-oControlPath=/tmp/master' nix copy --to ssh://server ${pkgA} >&2") + client.succeed(f"ssh -S /tmp/master -O exit {server.name}") + + # Copy the closure of package B from the server to the client, using ssh-ng. + client.fail("nix-store --check-validity ${pkgB}") + # Shouldn't download untrusted paths by default + client.fail("nix copy --from ssh-ng://server ${pkgB} >&2") + client.succeed("nix copy --no-check-sigs --from ssh-ng://server ${pkgB} >&2") + client.succeed("nix-store --check-validity ${pkgB}") + + # Copy the derivation of package D's derivation from the client to the server. + server.fail("nix-store --check-validity ${pkgD.drvPath}") + client.succeed("nix copy --derivation --to ssh://server ${pkgD.drvPath} >&2") + server.succeed("nix-store --check-validity ${pkgD.drvPath}") + ''; } diff --git a/tests/nixos/nix-docker.nix b/tests/nixos/nix-docker.nix index 00b04482c15..bd77b25c8b2 100644 --- a/tests/nixos/nix-docker.nix +++ b/tests/nixos/nix-docker.nix @@ -1,6 +1,12 @@ # Test the container built by ../../docker.nix. -{ lib, config, nixpkgs, hostPkgs, ... }: +{ + lib, + config, + nixpkgs, + hostPkgs, + ... +}: let pkgs = config.nodes.machine.nixpkgs.pkgs; @@ -19,36 +25,54 @@ let containerTestScript = ./nix-docker-test.sh; -in { +in +{ name = "nix-docker"; - nodes = - { machine = - { config, lib, pkgs, ... }: - { virtualisation.diskSize = 4096; - }; - cache = - { config, lib, pkgs, ... }: - { virtualisation.additionalPaths = [ pkgs.stdenv pkgs.hello ]; - services.harmonia.enable = true; - networking.firewall.allowedTCPPorts = [ 5000 ]; - }; - }; - - testScript = { nodes }: '' - cache.wait_for_unit("harmonia.service") - cache.wait_for_unit("network-online.target") - - machine.succeed("mkdir -p /etc/containers") - machine.succeed("""echo '{"default":[{"type":"insecureAcceptAnything"}]}' > /etc/containers/policy.json""") - - machine.succeed("${pkgs.podman}/bin/podman load -i ${nixImage}") - machine.succeed("${pkgs.podman}/bin/podman run --rm nix nix --version") - machine.succeed("${pkgs.podman}/bin/podman run --rm -i nix < ${containerTestScript}") - - machine.succeed("${pkgs.podman}/bin/podman load -i ${nixUserImage}") - machine.succeed("${pkgs.podman}/bin/podman run --rm nix-user nix --version") - machine.succeed("${pkgs.podman}/bin/podman run --rm -i nix-user < ${containerTestScript}") - machine.succeed("[[ $(${pkgs.podman}/bin/podman run --rm nix-user stat -c %u /nix/store) = 1000 ]]") - ''; + nodes = { + machine = + { + config, + lib, + pkgs, + ... + }: + { + virtualisation.diskSize = 4096; + }; + cache = + { + config, + lib, + pkgs, + ... + }: + { + virtualisation.additionalPaths = [ + pkgs.stdenv + pkgs.hello + ]; + services.harmonia.enable = true; + networking.firewall.allowedTCPPorts = [ 5000 ]; + }; + }; + + testScript = + { nodes }: + '' + cache.wait_for_unit("harmonia.service") + cache.wait_for_unit("network-online.target") + + machine.succeed("mkdir -p /etc/containers") + machine.succeed("""echo '{"default":[{"type":"insecureAcceptAnything"}]}' > /etc/containers/policy.json""") + + machine.succeed("${pkgs.podman}/bin/podman load -i ${nixImage}") + machine.succeed("${pkgs.podman}/bin/podman run --rm nix nix --version") + machine.succeed("${pkgs.podman}/bin/podman run --rm -i nix < ${containerTestScript}") + + machine.succeed("${pkgs.podman}/bin/podman load -i ${nixUserImage}") + machine.succeed("${pkgs.podman}/bin/podman run --rm nix-user nix --version") + machine.succeed("${pkgs.podman}/bin/podman run --rm -i nix-user < ${containerTestScript}") + machine.succeed("[[ $(${pkgs.podman}/bin/podman run --rm nix-user stat -c %u /nix/store) = 1000 ]]") + ''; } diff --git a/tests/nixos/nss-preload.nix b/tests/nixos/nss-preload.nix index b7e704f395d..29cd5e6a296 100644 --- a/tests/nixos/nss-preload.nix +++ b/tests/nixos/nss-preload.nix @@ -1,4 +1,9 @@ -{ lib, config, nixpkgs, ... }: +{ + lib, + config, + nixpkgs, + ... +}: let @@ -44,81 +49,119 @@ in name = "nss-preload"; nodes = { - http_dns = { lib, pkgs, config, ... }: { - networking.firewall.enable = false; - networking.interfaces.eth1.ipv6.addresses = lib.mkForce [ - { address = "fd21::1"; prefixLength = 64; } - ]; - networking.interfaces.eth1.ipv4.addresses = lib.mkForce [ - { address = "192.168.0.1"; prefixLength = 24; } - ]; - - services.unbound = { - enable = true; - enableRootTrustAnchor = false; - settings = { - server = { - interface = [ "192.168.0.1" "fd21::1" "::1" "127.0.0.1" ]; - access-control = [ "192.168.0.0/24 allow" "fd21::/64 allow" "::1 allow" "127.0.0.0/8 allow" ]; - local-data = [ - ''"example.com. IN A 192.168.0.1"'' - ''"example.com. IN AAAA fd21::1"'' - ''"tarballs.nixos.org. IN A 192.168.0.1"'' - ''"tarballs.nixos.org. IN AAAA fd21::1"'' - ]; + http_dns = + { + lib, + pkgs, + config, + ... + }: + { + networking.firewall.enable = false; + networking.interfaces.eth1.ipv6.addresses = lib.mkForce [ + { + address = "fd21::1"; + prefixLength = 64; + } + ]; + networking.interfaces.eth1.ipv4.addresses = lib.mkForce [ + { + address = "192.168.0.1"; + prefixLength = 24; + } + ]; + + services.unbound = { + enable = true; + enableRootTrustAnchor = false; + settings = { + server = { + interface = [ + "192.168.0.1" + "fd21::1" + "::1" + "127.0.0.1" + ]; + access-control = [ + "192.168.0.0/24 allow" + "fd21::/64 allow" + "::1 allow" + "127.0.0.0/8 allow" + ]; + local-data = [ + ''"example.com. IN A 192.168.0.1"'' + ''"example.com. IN AAAA fd21::1"'' + ''"tarballs.nixos.org. IN A 192.168.0.1"'' + ''"tarballs.nixos.org. IN AAAA fd21::1"'' + ]; + }; }; }; - }; - services.nginx = { - enable = true; - virtualHosts."example.com" = { - root = pkgs.runCommand "testdir" {} '' - mkdir "$out" - echo hello world > "$out/index.html" - ''; + services.nginx = { + enable = true; + virtualHosts."example.com" = { + root = pkgs.runCommand "testdir" { } '' + mkdir "$out" + echo hello world > "$out/index.html" + ''; + }; }; }; - }; # client consumes a remote resolver - client = { lib, nodes, pkgs, ... }: { - networking.useDHCP = false; - networking.nameservers = [ - (lib.head nodes.http_dns.networking.interfaces.eth1.ipv6.addresses).address - (lib.head nodes.http_dns.networking.interfaces.eth1.ipv4.addresses).address - ]; - networking.interfaces.eth1.ipv6.addresses = [ - { address = "fd21::10"; prefixLength = 64; } - ]; - networking.interfaces.eth1.ipv4.addresses = [ - { address = "192.168.0.10"; prefixLength = 24; } - ]; - - nix.settings.extra-sandbox-paths = lib.mkForce []; - nix.settings.substituters = lib.mkForce []; - nix.settings.sandbox = lib.mkForce true; - }; + client = + { + lib, + nodes, + pkgs, + ... + }: + { + networking.useDHCP = false; + networking.nameservers = [ + (lib.head nodes.http_dns.networking.interfaces.eth1.ipv6.addresses).address + (lib.head nodes.http_dns.networking.interfaces.eth1.ipv4.addresses).address + ]; + networking.interfaces.eth1.ipv6.addresses = [ + { + address = "fd21::10"; + prefixLength = 64; + } + ]; + networking.interfaces.eth1.ipv4.addresses = [ + { + address = "192.168.0.10"; + prefixLength = 24; + } + ]; + + nix.settings.extra-sandbox-paths = lib.mkForce [ ]; + nix.settings.substituters = lib.mkForce [ ]; + nix.settings.sandbox = lib.mkForce true; + }; }; - testScript = { nodes, ... }: '' - http_dns.wait_for_unit("network-online.target") - http_dns.wait_for_unit("nginx") - http_dns.wait_for_open_port(80) - http_dns.wait_for_unit("unbound") - http_dns.wait_for_open_port(53) - - client.start() - client.wait_for_unit('multi-user.target') - client.wait_for_unit('network-online.target') - - with subtest("can fetch data from a remote server outside sandbox"): - client.succeed("nix --version >&2") - client.succeed("curl -vvv http://example.com/index.html >&2") - - with subtest("nix-build can lookup dns and fetch data"): - client.succeed(""" - nix-build ${nix-fetch} >&2 - """) - ''; + testScript = + { nodes, ... }: + '' + http_dns.wait_for_unit("network-online.target") + http_dns.wait_for_unit("nginx") + http_dns.wait_for_open_port(80) + http_dns.wait_for_unit("unbound") + http_dns.wait_for_open_port(53) + + client.start() + client.wait_for_unit('multi-user.target') + client.wait_for_unit('network-online.target') + + with subtest("can fetch data from a remote server outside sandbox"): + client.succeed("nix --version >&2") + client.succeed("curl -vvv http://example.com/index.html >&2") + + with subtest("nix-build can lookup dns and fetch data"): + client.succeed(""" + nix-build ${nix-fetch} >&2 + """) + ''; } diff --git a/tests/nixos/remote-builds-ssh-ng.nix b/tests/nixos/remote-builds-ssh-ng.nix index 3562d2d2f6b..72652202932 100644 --- a/tests/nixos/remote-builds-ssh-ng.nix +++ b/tests/nixos/remote-builds-ssh-ng.nix @@ -1,11 +1,17 @@ -test@{ config, lib, hostPkgs, ... }: +test@{ + config, + lib, + hostPkgs, + ... +}: let pkgs = config.nodes.client.nixpkgs.pkgs; # Trivial Nix expression to build remotely. - expr = config: nr: pkgs.writeText "expr.nix" - '' + expr = + config: nr: + pkgs.writeText "expr.nix" '' let utils = builtins.storePath ${config.system.build.extraUtils}; in derivation { name = "hello-${toString nr}"; @@ -41,87 +47,94 @@ in config = { name = lib.mkDefault "remote-builds-ssh-ng"; - nodes = - { - builder = - { config, pkgs, ... }: - { - imports = [ test.config.builders.config ]; - services.openssh.enable = true; - virtualisation.writableStore = true; - nix.settings.sandbox = true; - nix.settings.substituters = lib.mkForce [ ]; - }; - - client = - { config, lib, pkgs, ... }: - { - nix.settings.max-jobs = 0; # force remote building - nix.distributedBuilds = true; - nix.buildMachines = - [{ - hostName = "builder"; - sshUser = "root"; - sshKey = "/root/.ssh/id_ed25519"; - system = "i686-linux"; - maxJobs = 1; - protocol = "ssh-ng"; - }]; - virtualisation.writableStore = true; - virtualisation.additionalPaths = [ config.system.build.extraUtils ]; - nix.settings.substituters = lib.mkForce [ ]; - programs.ssh.extraConfig = "ConnectTimeout 30"; - }; - }; - - testScript = { nodes }: '' - # fmt: off - import subprocess - - start_all() - - # Create an SSH key on the client. - subprocess.run([ - "${hostPkgs.openssh}/bin/ssh-keygen", "-t", "ed25519", "-f", "key", "-N", "" - ], capture_output=True, check=True) - client.succeed("mkdir -p -m 700 /root/.ssh") - client.copy_from_host("key", "/root/.ssh/id_ed25519") - client.succeed("chmod 600 /root/.ssh/id_ed25519") - - # Install the SSH key on the builder. - client.wait_for_unit("network-online.target") - builder.succeed("mkdir -p -m 700 /root/.ssh") - builder.copy_from_host("key.pub", "/root/.ssh/authorized_keys") - builder.wait_for_unit("sshd") - builder.wait_for_unit("multi-user.target") - builder.wait_for_unit("network-online.target") - - client.succeed(f"ssh -o StrictHostKeyChecking=no {builder.name} 'echo hello world'") - - # Perform a build - out = client.succeed("nix-build ${expr nodes.client 1} 2> build-output") - - # Verify that the build was done on the builder - builder.succeed(f"test -e {out.strip()}") - - # Print the build log, prefix the log lines to avoid nix intercepting lines starting with @nix - buildOutput = client.succeed("sed -e 's/^/build-output:/' build-output") - print(buildOutput) - - # Make sure that we get the expected build output - client.succeed("grep -qF Hello build-output") - - # We don't want phase reporting in the build output - client.fail("grep -qF '@nix' build-output") - - # Get the log file - client.succeed(f"nix-store --read-log {out.strip()} > log-output") - # Prefix the log lines to avoid nix intercepting lines starting with @nix - logOutput = client.succeed("sed -e 's/^/log-file:/' log-output") - print(logOutput) - - # Check that we get phase reporting in the log file - client.succeed("grep -q '@nix {\"action\":\"setPhase\",\"phase\":\"buildPhase\"}' log-output") - ''; + nodes = { + builder = + { config, pkgs, ... }: + { + imports = [ test.config.builders.config ]; + services.openssh.enable = true; + virtualisation.writableStore = true; + nix.settings.sandbox = true; + nix.settings.substituters = lib.mkForce [ ]; + }; + + client = + { + config, + lib, + pkgs, + ... + }: + { + nix.settings.max-jobs = 0; # force remote building + nix.distributedBuilds = true; + nix.buildMachines = [ + { + hostName = "builder"; + sshUser = "root"; + sshKey = "/root/.ssh/id_ed25519"; + system = "i686-linux"; + maxJobs = 1; + protocol = "ssh-ng"; + } + ]; + virtualisation.writableStore = true; + virtualisation.additionalPaths = [ config.system.build.extraUtils ]; + nix.settings.substituters = lib.mkForce [ ]; + programs.ssh.extraConfig = "ConnectTimeout 30"; + }; + }; + + testScript = + { nodes }: + '' + # fmt: off + import subprocess + + start_all() + + # Create an SSH key on the client. + subprocess.run([ + "${hostPkgs.openssh}/bin/ssh-keygen", "-t", "ed25519", "-f", "key", "-N", "" + ], capture_output=True, check=True) + client.succeed("mkdir -p -m 700 /root/.ssh") + client.copy_from_host("key", "/root/.ssh/id_ed25519") + client.succeed("chmod 600 /root/.ssh/id_ed25519") + + # Install the SSH key on the builder. + client.wait_for_unit("network-online.target") + builder.succeed("mkdir -p -m 700 /root/.ssh") + builder.copy_from_host("key.pub", "/root/.ssh/authorized_keys") + builder.wait_for_unit("sshd") + builder.wait_for_unit("multi-user.target") + builder.wait_for_unit("network-online.target") + + client.succeed(f"ssh -o StrictHostKeyChecking=no {builder.name} 'echo hello world'") + + # Perform a build + out = client.succeed("nix-build ${expr nodes.client 1} 2> build-output") + + # Verify that the build was done on the builder + builder.succeed(f"test -e {out.strip()}") + + # Print the build log, prefix the log lines to avoid nix intercepting lines starting with @nix + buildOutput = client.succeed("sed -e 's/^/build-output:/' build-output") + print(buildOutput) + + # Make sure that we get the expected build output + client.succeed("grep -qF Hello build-output") + + # We don't want phase reporting in the build output + client.fail("grep -qF '@nix' build-output") + + # Get the log file + client.succeed(f"nix-store --read-log {out.strip()} > log-output") + # Prefix the log lines to avoid nix intercepting lines starting with @nix + logOutput = client.succeed("sed -e 's/^/log-file:/' log-output") + print(logOutput) + + # Check that we get phase reporting in the log file + client.succeed("grep -q '@nix {\"action\":\"setPhase\",\"phase\":\"buildPhase\"}' log-output") + ''; }; } diff --git a/tests/nixos/remote-builds.nix b/tests/nixos/remote-builds.nix index 4fca4b93849..3251984db5e 100644 --- a/tests/nixos/remote-builds.nix +++ b/tests/nixos/remote-builds.nix @@ -1,6 +1,11 @@ # Test Nix's remote build feature. -test@{ config, lib, hostPkgs, ... }: +test@{ + config, + lib, + hostPkgs, + ... +}: let pkgs = config.nodes.client.nixpkgs.pkgs; @@ -21,8 +26,9 @@ let }; # Trivial Nix expression to build remotely. - expr = config: nr: pkgs.writeText "expr.nix" - '' + expr = + config: nr: + pkgs.writeText "expr.nix" '' let utils = builtins.storePath ${config.system.build.extraUtils}; in derivation { name = "hello-${toString nr}"; @@ -52,107 +58,112 @@ in config = { name = lib.mkDefault "remote-builds"; - nodes = - { - builder1 = builder; - builder2 = builder; - - client = - { config, lib, pkgs, ... }: - { - nix.settings.max-jobs = 0; # force remote building - nix.distributedBuilds = true; - nix.buildMachines = - [ - { - hostName = "builder1"; - sshUser = "root"; - sshKey = "/root/.ssh/id_ed25519"; - system = "i686-linux"; - maxJobs = 1; - } - { - hostName = "builder2"; - sshUser = "root"; - sshKey = "/root/.ssh/id_ed25519"; - system = "i686-linux"; - maxJobs = 1; - } - ]; - virtualisation.writableStore = true; - virtualisation.additionalPaths = [ config.system.build.extraUtils ]; - nix.settings.substituters = lib.mkForce [ ]; - programs.ssh.extraConfig = "ConnectTimeout 30"; - environment.systemPackages = [ - # `bad-shell` is used to make sure Nix works in an environment with a misbehaving shell. - # - # More realistically, a bad shell would still run the command ("echo started") - # but considering that our solution is to avoid this shell (set via $SHELL), we - # don't need to bother with a more functional mock shell. - (pkgs.writeScriptBin "bad-shell" '' - #!${pkgs.runtimeShell} - echo "Hello, I am a broken shell" - '') - ]; - }; - }; - - testScript = { nodes }: '' - # fmt: off - import subprocess - - start_all() - - # Create an SSH key on the client. - subprocess.run([ - "${hostPkgs.openssh}/bin/ssh-keygen", "-t", "ed25519", "-f", "key", "-N", "" - ], capture_output=True, check=True) - client.succeed("mkdir -p -m 700 /root/.ssh") - client.copy_from_host("key", "/root/.ssh/id_ed25519") - client.succeed("chmod 600 /root/.ssh/id_ed25519") - - # Install the SSH key on the builders. - client.wait_for_unit("network-online.target") - for builder in [builder1, builder2]: - builder.succeed("mkdir -p -m 700 /root/.ssh") - builder.copy_from_host("key.pub", "/root/.ssh/authorized_keys") - builder.wait_for_unit("sshd") - builder.wait_for_unit("network-online.target") - # Make sure the builder can handle our login correctly - builder.wait_for_unit("multi-user.target") - # Make sure there's no funny business on the client either - # (should not be necessary, but we have reason to be careful) - client.wait_for_unit("multi-user.target") - client.succeed(f""" - ssh -o StrictHostKeyChecking=no {builder.name} \ - 'echo hello world on $(hostname)' >&2 - """) - - ${lib.optionalString supportsBadShell '' - # Check that SSH uses SHELL for LocalCommand, as expected, and check that - # our test setup here is working. The next test will use this bad SHELL. - client.succeed(f"SHELL=$(which bad-shell) ssh -oLocalCommand='true' -oPermitLocalCommand=yes {builder1.name} 'echo hello world' | grep -F 'Hello, I am a broken shell'") - ''} - - # Perform a build and check that it was performed on the builder. - out = client.succeed( - "${lib.optionalString supportsBadShell "SHELL=$(which bad-shell)"} nix-build ${expr nodes.client 1} 2> build-output", - "grep -q Hello build-output" - ) - builder1.succeed(f"test -e {out}") - - # And a parallel build. - paths = client.succeed(r'nix-store -r $(nix-instantiate ${expr nodes.client 2})\!out $(nix-instantiate ${expr nodes.client 3})\!out') - out1, out2 = paths.split() - builder1.succeed(f"test -e {out1} -o -e {out2}") - builder2.succeed(f"test -e {out1} -o -e {out2}") - - # And a failing build. - client.fail("nix-build ${expr nodes.client 5}") - - # Test whether the build hook automatically skips unavailable builders. - builder1.block() - client.succeed("nix-build ${expr nodes.client 4}") - ''; + nodes = { + builder1 = builder; + builder2 = builder; + + client = + { + config, + lib, + pkgs, + ... + }: + { + nix.settings.max-jobs = 0; # force remote building + nix.distributedBuilds = true; + nix.buildMachines = [ + { + hostName = "builder1"; + sshUser = "root"; + sshKey = "/root/.ssh/id_ed25519"; + system = "i686-linux"; + maxJobs = 1; + } + { + hostName = "builder2"; + sshUser = "root"; + sshKey = "/root/.ssh/id_ed25519"; + system = "i686-linux"; + maxJobs = 1; + } + ]; + virtualisation.writableStore = true; + virtualisation.additionalPaths = [ config.system.build.extraUtils ]; + nix.settings.substituters = lib.mkForce [ ]; + programs.ssh.extraConfig = "ConnectTimeout 30"; + environment.systemPackages = [ + # `bad-shell` is used to make sure Nix works in an environment with a misbehaving shell. + # + # More realistically, a bad shell would still run the command ("echo started") + # but considering that our solution is to avoid this shell (set via $SHELL), we + # don't need to bother with a more functional mock shell. + (pkgs.writeScriptBin "bad-shell" '' + #!${pkgs.runtimeShell} + echo "Hello, I am a broken shell" + '') + ]; + }; + }; + + testScript = + { nodes }: + '' + # fmt: off + import subprocess + + start_all() + + # Create an SSH key on the client. + subprocess.run([ + "${hostPkgs.openssh}/bin/ssh-keygen", "-t", "ed25519", "-f", "key", "-N", "" + ], capture_output=True, check=True) + client.succeed("mkdir -p -m 700 /root/.ssh") + client.copy_from_host("key", "/root/.ssh/id_ed25519") + client.succeed("chmod 600 /root/.ssh/id_ed25519") + + # Install the SSH key on the builders. + client.wait_for_unit("network-online.target") + for builder in [builder1, builder2]: + builder.succeed("mkdir -p -m 700 /root/.ssh") + builder.copy_from_host("key.pub", "/root/.ssh/authorized_keys") + builder.wait_for_unit("sshd") + builder.wait_for_unit("network-online.target") + # Make sure the builder can handle our login correctly + builder.wait_for_unit("multi-user.target") + # Make sure there's no funny business on the client either + # (should not be necessary, but we have reason to be careful) + client.wait_for_unit("multi-user.target") + client.succeed(f""" + ssh -o StrictHostKeyChecking=no {builder.name} \ + 'echo hello world on $(hostname)' >&2 + """) + + ${lib.optionalString supportsBadShell '' + # Check that SSH uses SHELL for LocalCommand, as expected, and check that + # our test setup here is working. The next test will use this bad SHELL. + client.succeed(f"SHELL=$(which bad-shell) ssh -oLocalCommand='true' -oPermitLocalCommand=yes {builder1.name} 'echo hello world' | grep -F 'Hello, I am a broken shell'") + ''} + + # Perform a build and check that it was performed on the builder. + out = client.succeed( + "${lib.optionalString supportsBadShell "SHELL=$(which bad-shell)"} nix-build ${expr nodes.client 1} 2> build-output", + "grep -q Hello build-output" + ) + builder1.succeed(f"test -e {out}") + + # And a parallel build. + paths = client.succeed(r'nix-store -r $(nix-instantiate ${expr nodes.client 2})\!out $(nix-instantiate ${expr nodes.client 3})\!out') + out1, out2 = paths.split() + builder1.succeed(f"test -e {out1} -o -e {out2}") + builder2.succeed(f"test -e {out1} -o -e {out2}") + + # And a failing build. + client.fail("nix-build ${expr nodes.client 5}") + + # Test whether the build hook automatically skips unavailable builders. + builder1.block() + client.succeed("nix-build ${expr nodes.client 4}") + ''; }; } diff --git a/tests/nixos/s3-binary-cache-store.nix b/tests/nixos/s3-binary-cache-store.nix index f8659b830cf..8e480866070 100644 --- a/tests/nixos/s3-binary-cache-store.nix +++ b/tests/nixos/s3-binary-cache-store.nix @@ -1,4 +1,9 @@ -{ lib, config, nixpkgs, ... }: +{ + lib, + config, + nixpkgs, + ... +}: let pkgs = config.nodes.client.nixpkgs.pkgs; @@ -12,71 +17,81 @@ let storeUrl = "s3://my-cache?endpoint=http://server:9000®ion=eu-west-1"; objectThatDoesNotExist = "s3://my-cache/foo-that-does-not-exist?endpoint=http://server:9000®ion=eu-west-1"; -in { +in +{ name = "s3-binary-cache-store"; - nodes = - { server = - { config, lib, pkgs, ... }: - { virtualisation.writableStore = true; - virtualisation.additionalPaths = [ pkgA ]; - environment.systemPackages = [ pkgs.minio-client ]; - nix.extraOptions = '' - experimental-features = nix-command - substituters = + nodes = { + server = + { + config, + lib, + pkgs, + ... + }: + { + virtualisation.writableStore = true; + virtualisation.additionalPaths = [ pkgA ]; + environment.systemPackages = [ pkgs.minio-client ]; + nix.extraOptions = '' + experimental-features = nix-command + substituters = + ''; + services.minio = { + enable = true; + region = "eu-west-1"; + rootCredentialsFile = pkgs.writeText "minio-credentials-full" '' + MINIO_ROOT_USER=${accessKey} + MINIO_ROOT_PASSWORD=${secretKey} ''; - services.minio = { - enable = true; - region = "eu-west-1"; - rootCredentialsFile = pkgs.writeText "minio-credentials-full" '' - MINIO_ROOT_USER=${accessKey} - MINIO_ROOT_PASSWORD=${secretKey} - ''; - }; - networking.firewall.allowedTCPPorts = [ 9000 ]; }; + networking.firewall.allowedTCPPorts = [ 9000 ]; + }; - client = - { config, pkgs, ... }: - { virtualisation.writableStore = true; - nix.extraOptions = '' - experimental-features = nix-command - substituters = - ''; - }; - }; + client = + { config, pkgs, ... }: + { + virtualisation.writableStore = true; + nix.extraOptions = '' + experimental-features = nix-command + substituters = + ''; + }; + }; - testScript = { nodes }: '' - # fmt: off - start_all() + testScript = + { nodes }: + '' + # fmt: off + start_all() - # Create a binary cache. - server.wait_for_unit("minio") - server.wait_for_unit("network-online.target") + # Create a binary cache. + server.wait_for_unit("minio") + server.wait_for_unit("network-online.target") - server.succeed("mc config host add minio http://localhost:9000 ${accessKey} ${secretKey} --api s3v4") - server.succeed("mc mb minio/my-cache") + server.succeed("mc config host add minio http://localhost:9000 ${accessKey} ${secretKey} --api s3v4") + server.succeed("mc mb minio/my-cache") - server.succeed("${env} nix copy --to '${storeUrl}' ${pkgA}") + server.succeed("${env} nix copy --to '${storeUrl}' ${pkgA}") - client.wait_for_unit("network-online.target") + client.wait_for_unit("network-online.target") - # Test fetchurl on s3:// URLs while we're at it. - client.succeed("${env} nix eval --impure --expr 'builtins.fetchurl { name = \"foo\"; url = \"s3://my-cache/nix-cache-info?endpoint=http://server:9000®ion=eu-west-1\"; }'") + # Test fetchurl on s3:// URLs while we're at it. + client.succeed("${env} nix eval --impure --expr 'builtins.fetchurl { name = \"foo\"; url = \"s3://my-cache/nix-cache-info?endpoint=http://server:9000®ion=eu-west-1\"; }'") - # Test that the format string in the error message is properly setup and won't display `%s` instead of the failed URI - msg = client.fail("${env} nix eval --impure --expr 'builtins.fetchurl { name = \"foo\"; url = \"${objectThatDoesNotExist}\"; }' 2>&1") - if "S3 object '${objectThatDoesNotExist}' does not exist" not in msg: - print(msg) # So that you can see the message that was improperly formatted - raise Exception("Error message formatting didn't work") + # Test that the format string in the error message is properly setup and won't display `%s` instead of the failed URI + msg = client.fail("${env} nix eval --impure --expr 'builtins.fetchurl { name = \"foo\"; url = \"${objectThatDoesNotExist}\"; }' 2>&1") + if "S3 object '${objectThatDoesNotExist}' does not exist" not in msg: + print(msg) # So that you can see the message that was improperly formatted + raise Exception("Error message formatting didn't work") - # Copy a package from the binary cache. - client.fail("nix path-info ${pkgA}") + # Copy a package from the binary cache. + client.fail("nix path-info ${pkgA}") - client.succeed("${env} nix store info --store '${storeUrl}' >&2") + client.succeed("${env} nix store info --store '${storeUrl}' >&2") - client.succeed("${env} nix copy --no-check-sigs --from '${storeUrl}' ${pkgA}") + client.succeed("${env} nix copy --no-check-sigs --from '${storeUrl}' ${pkgA}") - client.succeed("nix path-info ${pkgA}") - ''; + client.succeed("nix path-info ${pkgA}") + ''; } diff --git a/tests/nixos/setuid.nix b/tests/nixos/setuid.nix index 2b66320ddaf..dc368e38373 100644 --- a/tests/nixos/setuid.nix +++ b/tests/nixos/setuid.nix @@ -1,6 +1,11 @@ # Verify that Linux builds cannot create setuid or setgid binaries. -{ lib, config, nixpkgs, ... }: +{ + lib, + config, + nixpkgs, + ... +}: let pkgs = config.nodes.machine.nixpkgs.pkgs; @@ -10,116 +15,127 @@ in name = "setuid"; nodes.machine = - { config, lib, pkgs, ... }: - { virtualisation.writableStore = true; + { + config, + lib, + pkgs, + ... + }: + { + virtualisation.writableStore = true; nix.settings.substituters = lib.mkForce [ ]; nix.nixPath = [ "nixpkgs=${lib.cleanSource pkgs.path}" ]; - virtualisation.additionalPaths = [ pkgs.stdenvNoCC pkgs.pkgsi686Linux.stdenvNoCC ]; + virtualisation.additionalPaths = [ + pkgs.stdenvNoCC + pkgs.pkgsi686Linux.stdenvNoCC + ]; }; - testScript = { nodes }: '' - # fmt: off - start_all() - - # Copying to /tmp should succeed. - machine.succeed(r""" - nix-build --no-sandbox -E '(with import {}; runCommand "foo" {} " - mkdir -p $out - cp ${pkgs.coreutils}/bin/id /tmp/id - ")' - """.strip()) - - machine.succeed('[[ $(stat -c %a /tmp/id) = 555 ]]') - - machine.succeed("rm /tmp/id") - - # Creating a setuid binary should fail. - machine.fail(r""" - nix-build --no-sandbox -E '(with import {}; runCommand "foo" {} " - mkdir -p $out - cp ${pkgs.coreutils}/bin/id /tmp/id - chmod 4755 /tmp/id - ")' - """.strip()) - - machine.succeed('[[ $(stat -c %a /tmp/id) = 555 ]]') - - machine.succeed("rm /tmp/id") - - # Creating a setgid binary should fail. - machine.fail(r""" - nix-build --no-sandbox -E '(with import {}; runCommand "foo" {} " - mkdir -p $out - cp ${pkgs.coreutils}/bin/id /tmp/id - chmod 2755 /tmp/id - ")' - """.strip()) - - machine.succeed('[[ $(stat -c %a /tmp/id) = 555 ]]') - - machine.succeed("rm /tmp/id") - - # The checks should also work on 32-bit binaries. - machine.fail(r""" - nix-build --no-sandbox -E '(with import { system = "i686-linux"; }; runCommand "foo" {} " - mkdir -p $out - cp ${pkgs.coreutils}/bin/id /tmp/id - chmod 2755 /tmp/id - ")' - """.strip()) - - machine.succeed('[[ $(stat -c %a /tmp/id) = 555 ]]') - - machine.succeed("rm /tmp/id") - - # The tests above use fchmodat(). Test chmod() as well. - machine.succeed(r""" - nix-build --no-sandbox -E '(with import {}; runCommand "foo" { buildInputs = [ perl ]; } " - mkdir -p $out - cp ${pkgs.coreutils}/bin/id /tmp/id - perl -e \"chmod 0666, qw(/tmp/id) or die\" - ")' - """.strip()) - - machine.succeed('[[ $(stat -c %a /tmp/id) = 666 ]]') - - machine.succeed("rm /tmp/id") - - machine.fail(r""" - nix-build --no-sandbox -E '(with import {}; runCommand "foo" { buildInputs = [ perl ]; } " - mkdir -p $out - cp ${pkgs.coreutils}/bin/id /tmp/id - perl -e \"chmod 04755, qw(/tmp/id) or die\" - ")' - """.strip()) - - machine.succeed('[[ $(stat -c %a /tmp/id) = 555 ]]') - - machine.succeed("rm /tmp/id") - - # And test fchmod(). - machine.succeed(r""" - nix-build --no-sandbox -E '(with import {}; runCommand "foo" { buildInputs = [ perl ]; } " - mkdir -p $out - cp ${pkgs.coreutils}/bin/id /tmp/id - perl -e \"my \\\$x; open \\\$x, qw(/tmp/id); chmod 01750, \\\$x or die\" - ")' - """.strip()) - - machine.succeed('[[ $(stat -c %a /tmp/id) = 1750 ]]') - - machine.succeed("rm /tmp/id") - - machine.fail(r""" - nix-build --no-sandbox -E '(with import {}; runCommand "foo" { buildInputs = [ perl ]; } " - mkdir -p $out - cp ${pkgs.coreutils}/bin/id /tmp/id - perl -e \"my \\\$x; open \\\$x, qw(/tmp/id); chmod 04777, \\\$x or die\" - ")' - """.strip()) - - machine.succeed('[[ $(stat -c %a /tmp/id) = 555 ]]') - - machine.succeed("rm /tmp/id") - ''; + testScript = + { nodes }: + '' + # fmt: off + start_all() + + # Copying to /tmp should succeed. + machine.succeed(r""" + nix-build --no-sandbox -E '(with import {}; runCommand "foo" {} " + mkdir -p $out + cp ${pkgs.coreutils}/bin/id /tmp/id + ")' + """.strip()) + + machine.succeed('[[ $(stat -c %a /tmp/id) = 555 ]]') + + machine.succeed("rm /tmp/id") + + # Creating a setuid binary should fail. + machine.fail(r""" + nix-build --no-sandbox -E '(with import {}; runCommand "foo" {} " + mkdir -p $out + cp ${pkgs.coreutils}/bin/id /tmp/id + chmod 4755 /tmp/id + ")' + """.strip()) + + machine.succeed('[[ $(stat -c %a /tmp/id) = 555 ]]') + + machine.succeed("rm /tmp/id") + + # Creating a setgid binary should fail. + machine.fail(r""" + nix-build --no-sandbox -E '(with import {}; runCommand "foo" {} " + mkdir -p $out + cp ${pkgs.coreutils}/bin/id /tmp/id + chmod 2755 /tmp/id + ")' + """.strip()) + + machine.succeed('[[ $(stat -c %a /tmp/id) = 555 ]]') + + machine.succeed("rm /tmp/id") + + # The checks should also work on 32-bit binaries. + machine.fail(r""" + nix-build --no-sandbox -E '(with import { system = "i686-linux"; }; runCommand "foo" {} " + mkdir -p $out + cp ${pkgs.coreutils}/bin/id /tmp/id + chmod 2755 /tmp/id + ")' + """.strip()) + + machine.succeed('[[ $(stat -c %a /tmp/id) = 555 ]]') + + machine.succeed("rm /tmp/id") + + # The tests above use fchmodat(). Test chmod() as well. + machine.succeed(r""" + nix-build --no-sandbox -E '(with import {}; runCommand "foo" { buildInputs = [ perl ]; } " + mkdir -p $out + cp ${pkgs.coreutils}/bin/id /tmp/id + perl -e \"chmod 0666, qw(/tmp/id) or die\" + ")' + """.strip()) + + machine.succeed('[[ $(stat -c %a /tmp/id) = 666 ]]') + + machine.succeed("rm /tmp/id") + + machine.fail(r""" + nix-build --no-sandbox -E '(with import {}; runCommand "foo" { buildInputs = [ perl ]; } " + mkdir -p $out + cp ${pkgs.coreutils}/bin/id /tmp/id + perl -e \"chmod 04755, qw(/tmp/id) or die\" + ")' + """.strip()) + + machine.succeed('[[ $(stat -c %a /tmp/id) = 555 ]]') + + machine.succeed("rm /tmp/id") + + # And test fchmod(). + machine.succeed(r""" + nix-build --no-sandbox -E '(with import {}; runCommand "foo" { buildInputs = [ perl ]; } " + mkdir -p $out + cp ${pkgs.coreutils}/bin/id /tmp/id + perl -e \"my \\\$x; open \\\$x, qw(/tmp/id); chmod 01750, \\\$x or die\" + ")' + """.strip()) + + machine.succeed('[[ $(stat -c %a /tmp/id) = 1750 ]]') + + machine.succeed("rm /tmp/id") + + machine.fail(r""" + nix-build --no-sandbox -E '(with import {}; runCommand "foo" { buildInputs = [ perl ]; } " + mkdir -p $out + cp ${pkgs.coreutils}/bin/id /tmp/id + perl -e \"my \\\$x; open \\\$x, qw(/tmp/id); chmod 04777, \\\$x or die\" + ")' + """.strip()) + + machine.succeed('[[ $(stat -c %a /tmp/id) = 555 ]]') + + machine.succeed("rm /tmp/id") + ''; } diff --git a/tests/nixos/sourcehut-flakes.nix b/tests/nixos/sourcehut-flakes.nix index 2f469457aca..bb26b7ebbdc 100644 --- a/tests/nixos/sourcehut-flakes.nix +++ b/tests/nixos/sourcehut-flakes.nix @@ -1,22 +1,27 @@ -{ lib, config, hostPkgs, nixpkgs, ... }: +{ + lib, + config, + hostPkgs, + nixpkgs, + ... +}: let pkgs = config.nodes.sourcehut.nixpkgs.pkgs; # Generate a fake root CA and a fake git.sr.ht certificate. - cert = pkgs.runCommand "cert" { buildInputs = [ pkgs.openssl ]; } - '' - mkdir -p $out + cert = pkgs.runCommand "cert" { buildInputs = [ pkgs.openssl ]; } '' + mkdir -p $out - openssl genrsa -out ca.key 2048 - openssl req -new -x509 -days 36500 -key ca.key \ - -subj "/C=NL/ST=Denial/L=Springfield/O=Dis/CN=Root CA" -out $out/ca.crt + openssl genrsa -out ca.key 2048 + openssl req -new -x509 -days 36500 -key ca.key \ + -subj "/C=NL/ST=Denial/L=Springfield/O=Dis/CN=Root CA" -out $out/ca.crt - openssl req -newkey rsa:2048 -nodes -keyout $out/server.key \ - -subj "/C=CN/ST=Denial/L=Springfield/O=Dis/CN=git.sr.ht" -out server.csr - openssl x509 -req -extfile <(printf "subjectAltName=DNS:git.sr.ht") \ - -days 36500 -in server.csr -CA $out/ca.crt -CAkey ca.key -CAcreateserial -out $out/server.crt - ''; + openssl req -newkey rsa:2048 -nodes -keyout $out/server.key \ + -subj "/C=CN/ST=Denial/L=Springfield/O=Dis/CN=git.sr.ht" -out server.csr + openssl x509 -req -extfile <(printf "subjectAltName=DNS:git.sr.ht") \ + -days 36500 -in server.csr -CA $out/ca.crt -CAkey ca.key -CAcreateserial -out $out/server.crt + ''; registry = pkgs.writeTextFile { name = "registry"; @@ -41,80 +46,92 @@ let destination = "/flake-registry.json"; }; - nixpkgs-repo = pkgs.runCommand "nixpkgs-flake" { } - '' - dir=NixOS-nixpkgs-${nixpkgs.shortRev} - cp -prd ${nixpkgs} $dir + nixpkgs-repo = pkgs.runCommand "nixpkgs-flake" { } '' + dir=NixOS-nixpkgs-${nixpkgs.shortRev} + cp -prd ${nixpkgs} $dir - # Set the correct timestamp in the tarball. - find $dir -print0 | xargs -0 touch -h -t ${builtins.substring 0 12 nixpkgs.lastModifiedDate}.${builtins.substring 12 2 nixpkgs.lastModifiedDate} -- + # Set the correct timestamp in the tarball. + find $dir -print0 | xargs -0 touch -h -t ${builtins.substring 0 12 nixpkgs.lastModifiedDate}.${ + builtins.substring 12 2 nixpkgs.lastModifiedDate + } -- - mkdir -p $out/archive - tar cfz $out/archive/${nixpkgs.rev}.tar.gz $dir --hard-dereference + mkdir -p $out/archive + tar cfz $out/archive/${nixpkgs.rev}.tar.gz $dir --hard-dereference - echo 'ref: refs/heads/master' > $out/HEAD + echo 'ref: refs/heads/master' > $out/HEAD - mkdir -p $out/info - echo -e '${nixpkgs.rev}\trefs/heads/master\n${nixpkgs.rev}\trefs/tags/foo-bar' > $out/info/refs - ''; + mkdir -p $out/info + echo -e '${nixpkgs.rev}\trefs/heads/master\n${nixpkgs.rev}\trefs/tags/foo-bar' > $out/info/refs + ''; in - { - name = "sourcehut-flakes"; +{ + name = "sourcehut-flakes"; - nodes = + nodes = { + # Impersonate git.sr.ht + sourcehut = + { config, pkgs, ... }: { - # Impersonate git.sr.ht - sourcehut = - { config, pkgs, ... }: - { - networking.firewall.allowedTCPPorts = [ 80 443 ]; - - services.httpd.enable = true; - services.httpd.adminAddr = "foo@example.org"; - services.httpd.extraConfig = '' - ErrorLog syslog:local6 - ''; - services.httpd.virtualHosts."git.sr.ht" = - { - forceSSL = true; - sslServerKey = "${cert}/server.key"; - sslServerCert = "${cert}/server.crt"; - servedDirs = - [ - { - urlPath = "/~NixOS/nixpkgs"; - dir = nixpkgs-repo; - } - { - urlPath = "/~NixOS/flake-registry/blob/master"; - dir = registry; - } - ]; - }; - }; - - client = - { config, lib, pkgs, nodes, ... }: - { - virtualisation.writableStore = true; - virtualisation.diskSize = 2048; - virtualisation.additionalPaths = [ pkgs.hello pkgs.fuse ]; - virtualisation.memorySize = 4096; - nix.settings.substituters = lib.mkForce [ ]; - nix.extraOptions = '' - experimental-features = nix-command flakes - flake-registry = https://git.sr.ht/~NixOS/flake-registry/blob/master/flake-registry.json - ''; - environment.systemPackages = [ pkgs.jq ]; - networking.hosts.${(builtins.head nodes.sourcehut.networking.interfaces.eth1.ipv4.addresses).address} = - [ "git.sr.ht" ]; - security.pki.certificateFiles = [ "${cert}/ca.crt" ]; - }; + networking.firewall.allowedTCPPorts = [ + 80 + 443 + ]; + + services.httpd.enable = true; + services.httpd.adminAddr = "foo@example.org"; + services.httpd.extraConfig = '' + ErrorLog syslog:local6 + ''; + services.httpd.virtualHosts."git.sr.ht" = { + forceSSL = true; + sslServerKey = "${cert}/server.key"; + sslServerCert = "${cert}/server.crt"; + servedDirs = [ + { + urlPath = "/~NixOS/nixpkgs"; + dir = nixpkgs-repo; + } + { + urlPath = "/~NixOS/flake-registry/blob/master"; + dir = registry; + } + ]; + }; }; - testScript = { nodes }: '' + client = + { + config, + lib, + pkgs, + nodes, + ... + }: + { + virtualisation.writableStore = true; + virtualisation.diskSize = 2048; + virtualisation.additionalPaths = [ + pkgs.hello + pkgs.fuse + ]; + virtualisation.memorySize = 4096; + nix.settings.substituters = lib.mkForce [ ]; + nix.extraOptions = '' + experimental-features = nix-command flakes + flake-registry = https://git.sr.ht/~NixOS/flake-registry/blob/master/flake-registry.json + ''; + environment.systemPackages = [ pkgs.jq ]; + networking.hosts.${(builtins.head nodes.sourcehut.networking.interfaces.eth1.ipv4.addresses).address} = + [ "git.sr.ht" ]; + security.pki.certificateFiles = [ "${cert}/ca.crt" ]; + }; + }; + + testScript = + { nodes }: + '' # fmt: off import json import time diff --git a/tests/nixos/tarball-flakes.nix b/tests/nixos/tarball-flakes.nix index 84cf377ec5b..7b3638b64b8 100644 --- a/tests/nixos/tarball-flakes.nix +++ b/tests/nixos/tarball-flakes.nix @@ -1,94 +1,106 @@ -{ lib, config, nixpkgs, ... }: +{ + lib, + config, + nixpkgs, + ... +}: let pkgs = config.nodes.machine.nixpkgs.pkgs; - root = pkgs.runCommand "nixpkgs-flake" {} - '' - mkdir -p $out/{stable,tags} - - set -x - dir=nixpkgs-${nixpkgs.shortRev} - cp -prd ${nixpkgs} $dir - # Set the correct timestamp in the tarball. - find $dir -print0 | xargs -0 touch -h -t ${builtins.substring 0 12 nixpkgs.lastModifiedDate}.${builtins.substring 12 2 nixpkgs.lastModifiedDate} -- - tar cfz $out/stable/${nixpkgs.rev}.tar.gz $dir --hard-dereference - - # Set the "Link" header on the redirect but not the final response to - # simulate an S3-like serving environment where the final host cannot set - # arbitrary headers. - cat >$out/tags/.htaccess <; rel=\"immutable\"" - EOF - ''; + root = pkgs.runCommand "nixpkgs-flake" { } '' + mkdir -p $out/{stable,tags} + + set -x + dir=nixpkgs-${nixpkgs.shortRev} + cp -prd ${nixpkgs} $dir + # Set the correct timestamp in the tarball. + find $dir -print0 | xargs -0 touch -h -t ${builtins.substring 0 12 nixpkgs.lastModifiedDate}.${ + builtins.substring 12 2 nixpkgs.lastModifiedDate + } -- + tar cfz $out/stable/${nixpkgs.rev}.tar.gz $dir --hard-dereference + + # Set the "Link" header on the redirect but not the final response to + # simulate an S3-like serving environment where the final host cannot set + # arbitrary headers. + cat >$out/tags/.htaccess <; rel=\"immutable\"" + EOF + ''; in { name = "tarball-flakes"; - nodes = - { - machine = - { config, pkgs, ... }: - { networking.firewall.allowedTCPPorts = [ 80 ]; - - services.httpd.enable = true; - services.httpd.adminAddr = "foo@example.org"; - services.httpd.extraConfig = '' - ErrorLog syslog:local6 - ''; - services.httpd.virtualHosts."localhost" = - { servedDirs = - [ { urlPath = "/"; - dir = root; - } - ]; - }; - - virtualisation.writableStore = true; - virtualisation.diskSize = 2048; - virtualisation.additionalPaths = [ pkgs.hello pkgs.fuse ]; - virtualisation.memorySize = 4096; - nix.settings.substituters = lib.mkForce [ ]; - nix.extraOptions = "experimental-features = nix-command flakes"; + nodes = { + machine = + { config, pkgs, ... }: + { + networking.firewall.allowedTCPPorts = [ 80 ]; + + services.httpd.enable = true; + services.httpd.adminAddr = "foo@example.org"; + services.httpd.extraConfig = '' + ErrorLog syslog:local6 + ''; + services.httpd.virtualHosts."localhost" = { + servedDirs = [ + { + urlPath = "/"; + dir = root; + } + ]; }; - }; - testScript = { nodes }: '' - # fmt: off - import json + virtualisation.writableStore = true; + virtualisation.diskSize = 2048; + virtualisation.additionalPaths = [ + pkgs.hello + pkgs.fuse + ]; + virtualisation.memorySize = 4096; + nix.settings.substituters = lib.mkForce [ ]; + nix.extraOptions = "experimental-features = nix-command flakes"; + }; + }; + + testScript = + { nodes }: + '' + # fmt: off + import json - start_all() + start_all() - machine.wait_for_unit("httpd.service") + machine.wait_for_unit("httpd.service") - out = machine.succeed("nix flake metadata --json http://localhost/tags/latest.tar.gz") - print(out) - info = json.loads(out) + out = machine.succeed("nix flake metadata --json http://localhost/tags/latest.tar.gz") + print(out) + info = json.loads(out) - # Check that we got redirected to the immutable URL. - assert info["locked"]["url"] == "http://localhost/stable/${nixpkgs.rev}.tar.gz" + # Check that we got redirected to the immutable URL. + assert info["locked"]["url"] == "http://localhost/stable/${nixpkgs.rev}.tar.gz" - # Check that we got a fingerprint for caching. - assert info["fingerprint"] + # Check that we got a fingerprint for caching. + assert info["fingerprint"] - # Check that we got the rev and revCount attributes. - assert info["revision"] == "${nixpkgs.rev}" - assert info["revCount"] == 1234 + # Check that we got the rev and revCount attributes. + assert info["revision"] == "${nixpkgs.rev}" + assert info["revCount"] == 1234 - # Check that a 0-byte HTTP 304 "Not modified" result works. - machine.succeed("nix flake metadata --refresh --json http://localhost/tags/latest.tar.gz") + # Check that a 0-byte HTTP 304 "Not modified" result works. + machine.succeed("nix flake metadata --refresh --json http://localhost/tags/latest.tar.gz") - # Check that fetching with rev/revCount/narHash succeeds. - machine.succeed("nix flake metadata --json http://localhost/tags/latest.tar.gz?rev=" + info["revision"]) - machine.succeed("nix flake metadata --json http://localhost/tags/latest.tar.gz?revCount=" + str(info["revCount"])) - machine.succeed("nix flake metadata --json http://localhost/tags/latest.tar.gz?narHash=" + info["locked"]["narHash"]) + # Check that fetching with rev/revCount/narHash succeeds. + machine.succeed("nix flake metadata --json http://localhost/tags/latest.tar.gz?rev=" + info["revision"]) + machine.succeed("nix flake metadata --json http://localhost/tags/latest.tar.gz?revCount=" + str(info["revCount"])) + machine.succeed("nix flake metadata --json http://localhost/tags/latest.tar.gz?narHash=" + info["locked"]["narHash"]) - # Check that fetching fails if we provide incorrect attributes. - machine.fail("nix flake metadata --json http://localhost/tags/latest.tar.gz?rev=493300eb13ae6fb387fbd47bf54a85915acc31c0") - machine.fail("nix flake metadata --json http://localhost/tags/latest.tar.gz?revCount=789") - machine.fail("nix flake metadata --json http://localhost/tags/latest.tar.gz?narHash=sha256-tbudgBSg+bHWHiHnlteNzN8TUvI80ygS9IULh4rklEw=") - ''; + # Check that fetching fails if we provide incorrect attributes. + machine.fail("nix flake metadata --json http://localhost/tags/latest.tar.gz?rev=493300eb13ae6fb387fbd47bf54a85915acc31c0") + machine.fail("nix flake metadata --json http://localhost/tags/latest.tar.gz?revCount=789") + machine.fail("nix flake metadata --json http://localhost/tags/latest.tar.gz?narHash=sha256-tbudgBSg+bHWHiHnlteNzN8TUvI80ygS9IULh4rklEw=") + ''; } diff --git a/tests/nixos/user-sandboxing/default.nix b/tests/nixos/user-sandboxing/default.nix index 8a16f44e84d..028efd17f1c 100644 --- a/tests/nixos/user-sandboxing/default.nix +++ b/tests/nixos/user-sandboxing/default.nix @@ -3,12 +3,15 @@ let pkgs = config.nodes.machine.nixpkgs.pkgs; - attacker = pkgs.runCommandWith { - name = "attacker"; - stdenv = pkgs.pkgsStatic.stdenv; - } '' - $CC -static -o $out ${./attacker.c} - ''; + attacker = + pkgs.runCommandWith + { + name = "attacker"; + stdenv = pkgs.pkgsStatic.stdenv; + } + '' + $CC -static -o $out ${./attacker.c} + ''; try-open-build-dir = pkgs.writeScript "try-open-build-dir" '' export PATH=${pkgs.coreutils}/bin:$PATH @@ -55,75 +58,88 @@ in name = "sandbox-setuid-leak"; nodes.machine = - { config, lib, pkgs, ... }: - { virtualisation.writableStore = true; + { + config, + lib, + pkgs, + ... + }: + { + virtualisation.writableStore = true; nix.settings.substituters = lib.mkForce [ ]; nix.nrBuildUsers = 1; - virtualisation.additionalPaths = [ pkgs.busybox-sandbox-shell attacker try-open-build-dir create-hello-world pkgs.socat ]; + virtualisation.additionalPaths = [ + pkgs.busybox-sandbox-shell + attacker + try-open-build-dir + create-hello-world + pkgs.socat + ]; boot.kernelPackages = pkgs.linuxPackages_latest; users.users.alice = { isNormalUser = true; }; }; - testScript = { nodes }: '' - start_all() - - with subtest("A builder can't give access to its build directory"): - # Make sure that a builder can't change the permissions on its build - # directory to the point of opening it up to external users - - # A derivation whose builder tries to make its build directory as open - # as possible and wait for someone to hijack it - machine.succeed(r""" - nix-build -v -E ' - builtins.derivation { - name = "open-build-dir"; - system = builtins.currentSystem; - builder = "${pkgs.busybox-sandbox-shell}/bin/sh"; - args = [ (builtins.storePath "${try-open-build-dir}") ]; - }' >&2 & - """.strip()) - - # Wait for the build to be ready - # This is OK because it runs as root, so we can access everything - machine.wait_for_file("/tmp/nix-build-open-build-dir.drv-0/build/syncPoint") - - # But Alice shouldn't be able to access the build directory - machine.fail("su alice -c 'ls /tmp/nix-build-open-build-dir.drv-0/build'") - machine.fail("su alice -c 'touch /tmp/nix-build-open-build-dir.drv-0/build/bar'") - machine.fail("su alice -c 'cat /tmp/nix-build-open-build-dir.drv-0/build/foo'") - - # Tell the user to finish the build - machine.succeed("echo foo > /tmp/nix-build-open-build-dir.drv-0/build/syncPoint") - - with subtest("Being able to execute stuff as the build user doesn't give access to the build dir"): - machine.succeed(r""" - nix-build -E ' - builtins.derivation { - name = "innocent"; - system = builtins.currentSystem; - builder = "${pkgs.busybox-sandbox-shell}/bin/sh"; - args = [ (builtins.storePath "${create-hello-world}") ]; - }' >&2 & - """.strip()) - machine.wait_for_file("/tmp/nix-build-innocent.drv-0/build/syncPoint") - - # The build ran as `nixbld1` (which is the only build user on the - # machine), but a process running as `nixbld1` outside the sandbox - # shouldn't be able to touch the build directory regardless - machine.fail("su nixbld1 --shell ${pkgs.busybox-sandbox-shell}/bin/sh -c 'ls /tmp/nix-build-innocent.drv-0/build'") - machine.fail("su nixbld1 --shell ${pkgs.busybox-sandbox-shell}/bin/sh -c 'echo pwned > /tmp/nix-build-innocent.drv-0/build/result'") - - # Finish the build - machine.succeed("echo foo > /tmp/nix-build-innocent.drv-0/build/syncPoint") - - # Check that the build was not affected - machine.succeed(r""" - cat ./result - test "$(cat ./result)" = "hello, world" - """.strip()) - ''; + testScript = + { nodes }: + '' + start_all() + + with subtest("A builder can't give access to its build directory"): + # Make sure that a builder can't change the permissions on its build + # directory to the point of opening it up to external users + + # A derivation whose builder tries to make its build directory as open + # as possible and wait for someone to hijack it + machine.succeed(r""" + nix-build -v -E ' + builtins.derivation { + name = "open-build-dir"; + system = builtins.currentSystem; + builder = "${pkgs.busybox-sandbox-shell}/bin/sh"; + args = [ (builtins.storePath "${try-open-build-dir}") ]; + }' >&2 & + """.strip()) + + # Wait for the build to be ready + # This is OK because it runs as root, so we can access everything + machine.wait_for_file("/tmp/nix-build-open-build-dir.drv-0/build/syncPoint") + + # But Alice shouldn't be able to access the build directory + machine.fail("su alice -c 'ls /tmp/nix-build-open-build-dir.drv-0/build'") + machine.fail("su alice -c 'touch /tmp/nix-build-open-build-dir.drv-0/build/bar'") + machine.fail("su alice -c 'cat /tmp/nix-build-open-build-dir.drv-0/build/foo'") + + # Tell the user to finish the build + machine.succeed("echo foo > /tmp/nix-build-open-build-dir.drv-0/build/syncPoint") + + with subtest("Being able to execute stuff as the build user doesn't give access to the build dir"): + machine.succeed(r""" + nix-build -E ' + builtins.derivation { + name = "innocent"; + system = builtins.currentSystem; + builder = "${pkgs.busybox-sandbox-shell}/bin/sh"; + args = [ (builtins.storePath "${create-hello-world}") ]; + }' >&2 & + """.strip()) + machine.wait_for_file("/tmp/nix-build-innocent.drv-0/build/syncPoint") + + # The build ran as `nixbld1` (which is the only build user on the + # machine), but a process running as `nixbld1` outside the sandbox + # shouldn't be able to touch the build directory regardless + machine.fail("su nixbld1 --shell ${pkgs.busybox-sandbox-shell}/bin/sh -c 'ls /tmp/nix-build-innocent.drv-0/build'") + machine.fail("su nixbld1 --shell ${pkgs.busybox-sandbox-shell}/bin/sh -c 'echo pwned > /tmp/nix-build-innocent.drv-0/build/result'") + + # Finish the build + machine.succeed("echo foo > /tmp/nix-build-innocent.drv-0/build/syncPoint") + + # Check that the build was not affected + machine.succeed(r""" + cat ./result + test "$(cat ./result)" = "hello, world" + """.strip()) + ''; } - diff --git a/tests/repl-completion.nix b/tests/repl-completion.nix index 3ba198a9860..07406e969cd 100644 --- a/tests/repl-completion.nix +++ b/tests/repl-completion.nix @@ -1,40 +1,45 @@ -{ runCommand, nix, expect }: +{ + runCommand, + nix, + expect, +}: # We only use expect when necessary, e.g. for testing tab completion in nix repl. # See also tests/functional/repl.sh -runCommand "repl-completion" { - nativeBuildInputs = [ - expect - nix - ]; - expectScript = '' - # Regression https://github.com/NixOS/nix/pull/10778 - spawn nix repl --offline --extra-experimental-features nix-command - expect "nix-repl>" - send "foo = import ./does-not-exist.nix\n" - expect "nix-repl>" - send "foo.\t" - expect { - "nix-repl>" { - puts "Got another prompt. Good." +runCommand "repl-completion" + { + nativeBuildInputs = [ + expect + nix + ]; + expectScript = '' + # Regression https://github.com/NixOS/nix/pull/10778 + spawn nix repl --offline --extra-experimental-features nix-command + expect "nix-repl>" + send "foo = import ./does-not-exist.nix\n" + expect "nix-repl>" + send "foo.\t" + expect { + "nix-repl>" { + puts "Got another prompt. Good." + } + eof { + puts "Got EOF. Bad." + exit 1 + } } - eof { - puts "Got EOF. Bad." - exit 1 - } - } - exit 0 - ''; - passAsFile = [ "expectScript" ]; -} -'' - export NIX_STORE=$TMPDIR/store - export NIX_STATE_DIR=$TMPDIR/state - export HOME=$TMPDIR/home - mkdir $HOME + exit 0 + ''; + passAsFile = [ "expectScript" ]; + } + '' + export NIX_STORE=$TMPDIR/store + export NIX_STATE_DIR=$TMPDIR/state + export HOME=$TMPDIR/home + mkdir $HOME - nix-store --init - expect $expectScriptPath - touch $out -'' \ No newline at end of file + nix-store --init + expect $expectScriptPath + touch $out + '' From b04077c0ec0e5e08c259aff52520e876bd2423b6 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Fri, 24 Jan 2025 14:19:09 +0100 Subject: [PATCH 20/60] fix: Update shifted source positions after formatting Carefully reviewed... --- ...putDependencies-multi-elem-context.err.exp | 10 +-- ...putDependencies-wrong-element-kind.err.exp | 10 +-- ...al-fail-assert-equal-attrs-names-2.err.exp | 4 +- ...eval-fail-assert-equal-attrs-names.err.exp | 4 +- ...ail-assert-equal-derivations-extra.err.exp | 18 ++--- ...eval-fail-assert-equal-derivations.err.exp | 18 ++--- ...-fail-assert-equal-function-direct.err.exp | 4 +- ...eval-fail-assert-equal-list-length.err.exp | 4 +- .../lang/eval-fail-assert-nested-bool.err.exp | 76 ++++++++---------- .../functional/lang/eval-fail-assert.err.exp | 36 ++++----- .../lang/eval-fail-attr-name-type.err.exp | 14 ++-- ...fail-attrset-merge-drops-later-rec.err.exp | 9 ++- ...al-fail-bad-string-interpolation-4.err.exp | 8 +- .../lang/eval-fail-derivation-name.err.exp | 16 ++-- .../lang/eval-fail-dup-dynamic-attrs.err.exp | 16 ++-- .../lang/eval-fail-duplicate-traces.err.exp | 52 ++++++------ ...-fail-fetchurl-baseName-attrs-name.err.exp | 4 +- ...ake-ref-to-string-negative-integer.err.exp | 18 +++-- ...-foldlStrict-strict-op-application.err.exp | 44 +++++----- .../lang/eval-fail-hashfile-missing.err.exp | 10 +-- tests/functional/lang/eval-fail-list.err.exp | 6 +- .../lang/eval-fail-missing-arg.err.exp | 13 +-- .../lang/eval-fail-mutual-recursion.err.exp | 80 +++++++++---------- .../lang/eval-fail-nested-list-items.err.exp | 10 +-- .../lang/eval-fail-not-throws.err.exp | 12 +-- .../lang/eval-fail-overflowing-add.err.exp | 10 +-- .../lang/eval-fail-overflowing-div.err.exp | 30 +++---- .../lang/eval-fail-overflowing-mul.err.exp | 20 ++--- .../lang/eval-fail-overflowing-sub.err.exp | 10 +-- .../lang/eval-fail-recursion.err.exp | 18 +++-- .../functional/lang/eval-fail-remove.err.exp | 16 ++-- .../functional/lang/eval-fail-scope-5.err.exp | 36 ++++----- .../lang/eval-fail-undeclared-arg.err.exp | 8 +- .../eval-fail-using-set-as-attr-name.err.exp | 20 ++--- .../repl/doc-comment-curried-args.expected | 6 +- .../repl/doc-comment-formals.expected | 3 +- .../repl/doc-comment-function.expected | 3 +- tests/functional/repl/doc-compact.expected | 3 +- tests/functional/repl/doc-constant.expected | 33 ++++---- tests/functional/repl/doc-floatedIn.expected | 3 +- tests/functional/repl/doc-functor.expected | 52 ++++++------ .../repl/doc-lambda-flavors.expected | 12 ++- .../functional/repl/doc-measurement.expected | 3 +- .../functional/repl/doc-unambiguous.expected | 3 +- 44 files changed, 400 insertions(+), 385 deletions(-) diff --git a/tests/functional/lang/eval-fail-addDrvOutputDependencies-multi-elem-context.err.exp b/tests/functional/lang/eval-fail-addDrvOutputDependencies-multi-elem-context.err.exp index 6828e03c8e7..56fbffa1942 100644 --- a/tests/functional/lang/eval-fail-addDrvOutputDependencies-multi-elem-context.err.exp +++ b/tests/functional/lang/eval-fail-addDrvOutputDependencies-multi-elem-context.err.exp @@ -1,9 +1,9 @@ error: … while calling the 'addDrvOutputDependencies' builtin - at /pwd/lang/eval-fail-addDrvOutputDependencies-multi-elem-context.nix:18:4: - 17| - 18| in builtins.addDrvOutputDependencies combo-path - | ^ - 19| + at /pwd/lang/eval-fail-addDrvOutputDependencies-multi-elem-context.nix:25:1: + 24| in + 25| builtins.addDrvOutputDependencies combo-path + | ^ + 26| error: context of string '/nix/store/pg9yqs4yd85yhdm3f4i5dyaqp5jahrsz-fail.drv/nix/store/2dxd5frb715z451vbf7s8birlf3argbk-fail-2.drv' must have exactly one element, but has 2 diff --git a/tests/functional/lang/eval-fail-addDrvOutputDependencies-wrong-element-kind.err.exp b/tests/functional/lang/eval-fail-addDrvOutputDependencies-wrong-element-kind.err.exp index 72b5e636897..d8399380eb4 100644 --- a/tests/functional/lang/eval-fail-addDrvOutputDependencies-wrong-element-kind.err.exp +++ b/tests/functional/lang/eval-fail-addDrvOutputDependencies-wrong-element-kind.err.exp @@ -1,9 +1,9 @@ error: … while calling the 'addDrvOutputDependencies' builtin - at /pwd/lang/eval-fail-addDrvOutputDependencies-wrong-element-kind.nix:9:4: - 8| - 9| in builtins.addDrvOutputDependencies drv.outPath - | ^ - 10| + at /pwd/lang/eval-fail-addDrvOutputDependencies-wrong-element-kind.nix:13:1: + 12| in + 13| builtins.addDrvOutputDependencies drv.outPath + | ^ + 14| error: `addDrvOutputDependencies` can only act on derivations, not on a derivation output such as 'out' diff --git a/tests/functional/lang/eval-fail-assert-equal-attrs-names-2.err.exp b/tests/functional/lang/eval-fail-assert-equal-attrs-names-2.err.exp index 4b68d97c20c..5912e6b8c30 100644 --- a/tests/functional/lang/eval-fail-assert-equal-attrs-names-2.err.exp +++ b/tests/functional/lang/eval-fail-assert-equal-attrs-names-2.err.exp @@ -1,8 +1,8 @@ error: … while evaluating the condition of the assertion '({ a = true; } == { a = true; b = true; })' at /pwd/lang/eval-fail-assert-equal-attrs-names-2.nix:1:1: - 1| assert { a = true; } == { a = true; b = true; }; + 1| assert | ^ - 2| throw "unreachable" + 2| { error: attribute names of attribute set '{ a = true; }' differs from attribute set '{ a = true; b = true; }' diff --git a/tests/functional/lang/eval-fail-assert-equal-attrs-names.err.exp b/tests/functional/lang/eval-fail-assert-equal-attrs-names.err.exp index bc61ca63a27..a93b26324cc 100644 --- a/tests/functional/lang/eval-fail-assert-equal-attrs-names.err.exp +++ b/tests/functional/lang/eval-fail-assert-equal-attrs-names.err.exp @@ -1,8 +1,8 @@ error: … while evaluating the condition of the assertion '({ a = true; b = true; } == { a = true; })' at /pwd/lang/eval-fail-assert-equal-attrs-names.nix:1:1: - 1| assert { a = true; b = true; } == { a = true; }; + 1| assert | ^ - 2| throw "unreachable" + 2| { error: attribute names of attribute set '{ a = true; b = true; }' differs from attribute set '{ a = true; }' diff --git a/tests/functional/lang/eval-fail-assert-equal-derivations-extra.err.exp b/tests/functional/lang/eval-fail-assert-equal-derivations-extra.err.exp index 7f49240747c..9ccf5e4dc10 100644 --- a/tests/functional/lang/eval-fail-assert-equal-derivations-extra.err.exp +++ b/tests/functional/lang/eval-fail-assert-equal-derivations-extra.err.exp @@ -3,23 +3,23 @@ error: at /pwd/lang/eval-fail-assert-equal-derivations-extra.nix:1:1: 1| assert | ^ - 2| { foo = { type = "derivation"; outPath = "/nix/store/0"; }; } + 2| { … while comparing attribute 'foo' … where left hand side is - at /pwd/lang/eval-fail-assert-equal-derivations-extra.nix:2:5: - 1| assert - 2| { foo = { type = "derivation"; outPath = "/nix/store/0"; }; } + at /pwd/lang/eval-fail-assert-equal-derivations-extra.nix:3:5: + 2| { + 3| foo = { | ^ - 3| == + 4| type = "derivation"; … where right hand side is - at /pwd/lang/eval-fail-assert-equal-derivations-extra.nix:4:5: - 3| == - 4| { foo = { type = "derivation"; outPath = "/nix/store/1"; devious = true; }; }; + at /pwd/lang/eval-fail-assert-equal-derivations-extra.nix:8:5: + 7| } == { + 8| foo = { | ^ - 5| throw "unreachable" + 9| type = "derivation"; … while comparing a derivation by its 'outPath' attribute diff --git a/tests/functional/lang/eval-fail-assert-equal-derivations.err.exp b/tests/functional/lang/eval-fail-assert-equal-derivations.err.exp index d7f0face077..2be1f48583c 100644 --- a/tests/functional/lang/eval-fail-assert-equal-derivations.err.exp +++ b/tests/functional/lang/eval-fail-assert-equal-derivations.err.exp @@ -3,23 +3,23 @@ error: at /pwd/lang/eval-fail-assert-equal-derivations.nix:1:1: 1| assert | ^ - 2| { foo = { type = "derivation"; outPath = "/nix/store/0"; ignored = abort "not ignored"; }; } + 2| { … while comparing attribute 'foo' … where left hand side is - at /pwd/lang/eval-fail-assert-equal-derivations.nix:2:5: - 1| assert - 2| { foo = { type = "derivation"; outPath = "/nix/store/0"; ignored = abort "not ignored"; }; } + at /pwd/lang/eval-fail-assert-equal-derivations.nix:3:5: + 2| { + 3| foo = { | ^ - 3| == + 4| type = "derivation"; … where right hand side is - at /pwd/lang/eval-fail-assert-equal-derivations.nix:4:5: - 3| == - 4| { foo = { type = "derivation"; outPath = "/nix/store/1"; ignored = abort "not ignored"; }; }; + at /pwd/lang/eval-fail-assert-equal-derivations.nix:9:5: + 8| } == { + 9| foo = { | ^ - 5| throw "unreachable" + 10| type = "derivation"; … while comparing a derivation by its 'outPath' attribute diff --git a/tests/functional/lang/eval-fail-assert-equal-function-direct.err.exp b/tests/functional/lang/eval-fail-assert-equal-function-direct.err.exp index f06d796981b..93c88a80cd4 100644 --- a/tests/functional/lang/eval-fail-assert-equal-function-direct.err.exp +++ b/tests/functional/lang/eval-fail-assert-equal-function-direct.err.exp @@ -2,8 +2,8 @@ error: … while evaluating the condition of the assertion '((x: x) == (x: x))' at /pwd/lang/eval-fail-assert-equal-function-direct.nix:3:1: 2| # This only compares a direct comparison and makes no claims about functions in nested structures. - 3| assert + 3| assert (x: x) == (x: x); | ^ - 4| (x: x) + 4| abort "unreachable" error: distinct functions and immediate comparisons of identical functions compare as unequal diff --git a/tests/functional/lang/eval-fail-assert-equal-list-length.err.exp b/tests/functional/lang/eval-fail-assert-equal-list-length.err.exp index 90108552cf0..e82f3787517 100644 --- a/tests/functional/lang/eval-fail-assert-equal-list-length.err.exp +++ b/tests/functional/lang/eval-fail-assert-equal-list-length.err.exp @@ -1,8 +1,8 @@ error: … while evaluating the condition of the assertion '([ (1) (0) ] == [ (10) ])' at /pwd/lang/eval-fail-assert-equal-list-length.nix:1:1: - 1| assert [ 1 0 ] == [ 10 ]; + 1| assert | ^ - 2| throw "unreachable" + 2| [ error: list of size '2' is not equal to list of size '1', left hand side is '[ 1 0 ]', right hand side is '[ 10 ]' diff --git a/tests/functional/lang/eval-fail-assert-nested-bool.err.exp b/tests/functional/lang/eval-fail-assert-nested-bool.err.exp index 1debb668c98..fdc0818200b 100644 --- a/tests/functional/lang/eval-fail-assert-nested-bool.err.exp +++ b/tests/functional/lang/eval-fail-assert-nested-bool.err.exp @@ -1,74 +1,66 @@ error: … while evaluating the condition of the assertion '({ a = { b = [ ({ c = { d = true; }; }) ]; }; } == { a = { b = [ ({ c = { d = false; }; }) ]; }; })' at /pwd/lang/eval-fail-assert-nested-bool.nix:1:1: - 1| assert + 1| assert { a.b = [ { c.d = true; } ]; } == { a.b = [ { c.d = false; } ]; }; | ^ - 2| { a.b = [ { c.d = true; } ]; } + 2| … while comparing attribute 'a' … where left hand side is - at /pwd/lang/eval-fail-assert-nested-bool.nix:2:5: - 1| assert - 2| { a.b = [ { c.d = true; } ]; } - | ^ - 3| == + at /pwd/lang/eval-fail-assert-nested-bool.nix:1:10: + 1| assert { a.b = [ { c.d = true; } ]; } == { a.b = [ { c.d = false; } ]; }; + | ^ + 2| … where right hand side is - at /pwd/lang/eval-fail-assert-nested-bool.nix:4:5: - 3| == - 4| { a.b = [ { c.d = false; } ]; }; - | ^ - 5| + at /pwd/lang/eval-fail-assert-nested-bool.nix:1:44: + 1| assert { a.b = [ { c.d = true; } ]; } == { a.b = [ { c.d = false; } ]; }; + | ^ + 2| … while comparing attribute 'b' … where left hand side is - at /pwd/lang/eval-fail-assert-nested-bool.nix:2:5: - 1| assert - 2| { a.b = [ { c.d = true; } ]; } - | ^ - 3| == + at /pwd/lang/eval-fail-assert-nested-bool.nix:1:10: + 1| assert { a.b = [ { c.d = true; } ]; } == { a.b = [ { c.d = false; } ]; }; + | ^ + 2| … where right hand side is - at /pwd/lang/eval-fail-assert-nested-bool.nix:4:5: - 3| == - 4| { a.b = [ { c.d = false; } ]; }; - | ^ - 5| + at /pwd/lang/eval-fail-assert-nested-bool.nix:1:44: + 1| assert { a.b = [ { c.d = true; } ]; } == { a.b = [ { c.d = false; } ]; }; + | ^ + 2| … while comparing list element 0 … while comparing attribute 'c' … where left hand side is - at /pwd/lang/eval-fail-assert-nested-bool.nix:2:15: - 1| assert - 2| { a.b = [ { c.d = true; } ]; } - | ^ - 3| == + at /pwd/lang/eval-fail-assert-nested-bool.nix:1:20: + 1| assert { a.b = [ { c.d = true; } ]; } == { a.b = [ { c.d = false; } ]; }; + | ^ + 2| … where right hand side is - at /pwd/lang/eval-fail-assert-nested-bool.nix:4:15: - 3| == - 4| { a.b = [ { c.d = false; } ]; }; - | ^ - 5| + at /pwd/lang/eval-fail-assert-nested-bool.nix:1:54: + 1| assert { a.b = [ { c.d = true; } ]; } == { a.b = [ { c.d = false; } ]; }; + | ^ + 2| … while comparing attribute 'd' … where left hand side is - at /pwd/lang/eval-fail-assert-nested-bool.nix:2:15: - 1| assert - 2| { a.b = [ { c.d = true; } ]; } - | ^ - 3| == + at /pwd/lang/eval-fail-assert-nested-bool.nix:1:20: + 1| assert { a.b = [ { c.d = true; } ]; } == { a.b = [ { c.d = false; } ]; }; + | ^ + 2| … where right hand side is - at /pwd/lang/eval-fail-assert-nested-bool.nix:4:15: - 3| == - 4| { a.b = [ { c.d = false; } ]; }; - | ^ - 5| + at /pwd/lang/eval-fail-assert-nested-bool.nix:1:54: + 1| assert { a.b = [ { c.d = true; } ]; } == { a.b = [ { c.d = false; } ]; }; + | ^ + 2| error: boolean 'true' is not equal to boolean 'false' diff --git a/tests/functional/lang/eval-fail-assert.err.exp b/tests/functional/lang/eval-fail-assert.err.exp index 7be9e238797..5fffe79bf0d 100644 --- a/tests/functional/lang/eval-fail-assert.err.exp +++ b/tests/functional/lang/eval-fail-assert.err.exp @@ -1,30 +1,30 @@ error: … while evaluating the attribute 'body' - at /pwd/lang/eval-fail-assert.nix:4:3: - 3| - 4| body = x "x"; + at /pwd/lang/eval-fail-assert.nix:7:3: + 6| + 7| body = x "x"; | ^ - 5| } + 8| } … from call site - at /pwd/lang/eval-fail-assert.nix:4:10: - 3| - 4| body = x "x"; + at /pwd/lang/eval-fail-assert.nix:7:10: + 6| + 7| body = x "x"; | ^ - 5| } + 8| } … while calling 'x' - at /pwd/lang/eval-fail-assert.nix:2:7: - 1| let { - 2| x = arg: assert arg == "y"; 123; - | ^ - 3| + at /pwd/lang/eval-fail-assert.nix:3:5: + 2| x = + 3| arg: + | ^ + 4| assert arg == "y"; … while evaluating the condition of the assertion '(arg == "y")' - at /pwd/lang/eval-fail-assert.nix:2:12: - 1| let { - 2| x = arg: assert arg == "y"; 123; - | ^ - 3| + at /pwd/lang/eval-fail-assert.nix:4:5: + 3| arg: + 4| assert arg == "y"; + | ^ + 5| 123; error: string '"x"' is not equal to string '"y"' diff --git a/tests/functional/lang/eval-fail-attr-name-type.err.exp b/tests/functional/lang/eval-fail-attr-name-type.err.exp index 6848a35ed80..4ea209b130f 100644 --- a/tests/functional/lang/eval-fail-attr-name-type.err.exp +++ b/tests/functional/lang/eval-fail-attr-name-type.err.exp @@ -2,20 +2,20 @@ error: … while evaluating the attribute 'puppy."${key}"' at /pwd/lang/eval-fail-attr-name-type.nix:3:5: 2| attrs = { - 3| puppy.doggy = {}; + 3| puppy.doggy = { }; | ^ 4| }; … while evaluating an attribute name - at /pwd/lang/eval-fail-attr-name-type.nix:7:17: + at /pwd/lang/eval-fail-attr-name-type.nix:7:15: 6| in - 7| attrs.puppy.${key} - | ^ + 7| attrs.puppy.${key} + | ^ 8| error: expected a string but found an integer: 1 - at /pwd/lang/eval-fail-attr-name-type.nix:7:17: + at /pwd/lang/eval-fail-attr-name-type.nix:7:15: 6| in - 7| attrs.puppy.${key} - | ^ + 7| attrs.puppy.${key} + | ^ 8| diff --git a/tests/functional/lang/eval-fail-attrset-merge-drops-later-rec.err.exp b/tests/functional/lang/eval-fail-attrset-merge-drops-later-rec.err.exp index d1cdc7b769f..ba9185dce1c 100644 --- a/tests/functional/lang/eval-fail-attrset-merge-drops-later-rec.err.exp +++ b/tests/functional/lang/eval-fail-attrset-merge-drops-later-rec.err.exp @@ -1,5 +1,6 @@ error: undefined variable 'd' - at /pwd/lang/eval-fail-attrset-merge-drops-later-rec.nix:1:26: - 1| { a.b = 1; a = rec { c = d + 2; d = 3; }; }.c - | ^ - 2| + at /pwd/lang/eval-fail-attrset-merge-drops-later-rec.nix:4:9: + 3| a = rec { + 4| c = d + 2; + | ^ + 5| d = 3; diff --git a/tests/functional/lang/eval-fail-bad-string-interpolation-4.err.exp b/tests/functional/lang/eval-fail-bad-string-interpolation-4.err.exp index b262e814dbc..ea5910072c3 100644 --- a/tests/functional/lang/eval-fail-bad-string-interpolation-4.err.exp +++ b/tests/functional/lang/eval-fail-bad-string-interpolation-4.err.exp @@ -1,9 +1,9 @@ error: … while evaluating a path segment - at /pwd/lang/eval-fail-bad-string-interpolation-4.nix:9:3: - 8| # The error message should not be too long. - 9| ''${pkgs}'' + at /pwd/lang/eval-fail-bad-string-interpolation-4.nix:19:3: + 18| # The error message should not be too long. + 19| ''${pkgs}'' | ^ - 10| + 20| error: cannot coerce a set to a string: { a = { a = { a = { a = "ha"; b = "ha"; c = "ha"; d = "ha"; e = "ha"; f = "ha"; g = "ha"; h = "ha"; j = "ha"; }; «8 attributes elided» }; «8 attributes elided» }; «8 attributes elided» } diff --git a/tests/functional/lang/eval-fail-derivation-name.err.exp b/tests/functional/lang/eval-fail-derivation-name.err.exp index 0ef98674d81..017326c3490 100644 --- a/tests/functional/lang/eval-fail-derivation-name.err.exp +++ b/tests/functional/lang/eval-fail-derivation-name.err.exp @@ -1,17 +1,17 @@ error: … while evaluating the attribute 'outPath' at ::: - | value = commonAttrs // { - | outPath = builtins.getAttr outputName strict; - | ^ - | drvPath = strict.drvPath; + | value = commonAttrs // { + | outPath = builtins.getAttr outputName strict; + | ^ + | drvPath = strict.drvPath; … while calling the 'getAttr' builtin at ::: - | value = commonAttrs // { - | outPath = builtins.getAttr outputName strict; - | ^ - | drvPath = strict.drvPath; + | value = commonAttrs // { + | outPath = builtins.getAttr outputName strict; + | ^ + | drvPath = strict.drvPath; … while calling the 'derivationStrict' builtin at ::: diff --git a/tests/functional/lang/eval-fail-dup-dynamic-attrs.err.exp b/tests/functional/lang/eval-fail-dup-dynamic-attrs.err.exp index 834f9c67bc4..4eafe945b74 100644 --- a/tests/functional/lang/eval-fail-dup-dynamic-attrs.err.exp +++ b/tests/functional/lang/eval-fail-dup-dynamic-attrs.err.exp @@ -2,13 +2,13 @@ error: … while evaluating the attribute 'set' at /pwd/lang/eval-fail-dup-dynamic-attrs.nix:2:3: 1| { - 2| set = { "${"" + "b"}" = 1; }; + 2| set = { | ^ - 3| set = { "${"b" + ""}" = 2; }; + 3| "${"" + "b"}" = 1; - error: dynamic attribute 'b' already defined at /pwd/lang/eval-fail-dup-dynamic-attrs.nix:2:11 - at /pwd/lang/eval-fail-dup-dynamic-attrs.nix:3:11: - 2| set = { "${"" + "b"}" = 1; }; - 3| set = { "${"b" + ""}" = 2; }; - | ^ - 4| } + error: dynamic attribute 'b' already defined at /pwd/lang/eval-fail-dup-dynamic-attrs.nix:3:5 + at /pwd/lang/eval-fail-dup-dynamic-attrs.nix:6:5: + 5| set = { + 6| "${"b" + ""}" = 2; + | ^ + 7| }; diff --git a/tests/functional/lang/eval-fail-duplicate-traces.err.exp b/tests/functional/lang/eval-fail-duplicate-traces.err.exp index cedaebd3b58..e6ae60f3ca0 100644 --- a/tests/functional/lang/eval-fail-duplicate-traces.err.exp +++ b/tests/functional/lang/eval-fail-duplicate-traces.err.exp @@ -1,51 +1,51 @@ error: … from call site - at /pwd/lang/eval-fail-duplicate-traces.nix:9:3: - 8| in - 9| throwAfter 2 - | ^ - 10| + at /pwd/lang/eval-fail-duplicate-traces.nix:6:1: + 5| in + 6| throwAfter 2 + | ^ + 7| … while calling 'throwAfter' at /pwd/lang/eval-fail-duplicate-traces.nix:4:16: 3| let - 4| throwAfter = n: + 4| throwAfter = n: if n > 0 then throwAfter (n - 1) else throw "Uh oh!"; | ^ - 5| if n > 0 + 5| in … from call site - at /pwd/lang/eval-fail-duplicate-traces.nix:6:10: - 5| if n > 0 - 6| then throwAfter (n - 1) - | ^ - 7| else throw "Uh oh!"; + at /pwd/lang/eval-fail-duplicate-traces.nix:4:33: + 3| let + 4| throwAfter = n: if n > 0 then throwAfter (n - 1) else throw "Uh oh!"; + | ^ + 5| in … while calling 'throwAfter' at /pwd/lang/eval-fail-duplicate-traces.nix:4:16: 3| let - 4| throwAfter = n: + 4| throwAfter = n: if n > 0 then throwAfter (n - 1) else throw "Uh oh!"; | ^ - 5| if n > 0 + 5| in … from call site - at /pwd/lang/eval-fail-duplicate-traces.nix:6:10: - 5| if n > 0 - 6| then throwAfter (n - 1) - | ^ - 7| else throw "Uh oh!"; + at /pwd/lang/eval-fail-duplicate-traces.nix:4:33: + 3| let + 4| throwAfter = n: if n > 0 then throwAfter (n - 1) else throw "Uh oh!"; + | ^ + 5| in … while calling 'throwAfter' at /pwd/lang/eval-fail-duplicate-traces.nix:4:16: 3| let - 4| throwAfter = n: + 4| throwAfter = n: if n > 0 then throwAfter (n - 1) else throw "Uh oh!"; | ^ - 5| if n > 0 + 5| in … while calling the 'throw' builtin - at /pwd/lang/eval-fail-duplicate-traces.nix:7:10: - 6| then throwAfter (n - 1) - 7| else throw "Uh oh!"; - | ^ - 8| in + at /pwd/lang/eval-fail-duplicate-traces.nix:4:57: + 3| let + 4| throwAfter = n: if n > 0 then throwAfter (n - 1) else throw "Uh oh!"; + | ^ + 5| in error: Uh oh! diff --git a/tests/functional/lang/eval-fail-fetchurl-baseName-attrs-name.err.exp b/tests/functional/lang/eval-fail-fetchurl-baseName-attrs-name.err.exp index 30f8b6a3544..2cac02f5875 100644 --- a/tests/functional/lang/eval-fail-fetchurl-baseName-attrs-name.err.exp +++ b/tests/functional/lang/eval-fail-fetchurl-baseName-attrs-name.err.exp @@ -1,8 +1,8 @@ error: … while calling the 'fetchurl' builtin at /pwd/lang/eval-fail-fetchurl-baseName-attrs-name.nix:1:1: - 1| builtins.fetchurl { url = "https://example.com/foo.tar.gz"; name = "~wobble~"; } + 1| builtins.fetchurl { | ^ - 2| + 2| url = "https://example.com/foo.tar.gz"; error: invalid store path name when fetching URL 'https://example.com/foo.tar.gz': name '~wobble~' contains illegal character '~'. Please change the value for the 'name' attribute passed to 'fetchurl', so that it can create a valid store path. diff --git a/tests/functional/lang/eval-fail-flake-ref-to-string-negative-integer.err.exp b/tests/functional/lang/eval-fail-flake-ref-to-string-negative-integer.err.exp index 25c8d7eaaa8..2b56939c621 100644 --- a/tests/functional/lang/eval-fail-flake-ref-to-string-negative-integer.err.exp +++ b/tests/functional/lang/eval-fail-flake-ref-to-string-negative-integer.err.exp @@ -1,14 +1,16 @@ error: … while calling the 'seq' builtin - at /pwd/lang/eval-fail-flake-ref-to-string-negative-integer.nix:1:16: - 1| let n = -1; in builtins.seq n (builtins.flakeRefToString { - | ^ - 2| type = "github"; + at /pwd/lang/eval-fail-flake-ref-to-string-negative-integer.nix:4:1: + 3| in + 4| builtins.seq n ( + | ^ + 5| builtins.flakeRefToString { … while calling the 'flakeRefToString' builtin - at /pwd/lang/eval-fail-flake-ref-to-string-negative-integer.nix:1:32: - 1| let n = -1; in builtins.seq n (builtins.flakeRefToString { - | ^ - 2| type = "github"; + at /pwd/lang/eval-fail-flake-ref-to-string-negative-integer.nix:5:3: + 4| builtins.seq n ( + 5| builtins.flakeRefToString { + | ^ + 6| type = "github"; error: negative value given for flake ref attr repo: -1 diff --git a/tests/functional/lang/eval-fail-foldlStrict-strict-op-application.err.exp b/tests/functional/lang/eval-fail-foldlStrict-strict-op-application.err.exp index 4903bc82d54..bb02ecdcb8f 100644 --- a/tests/functional/lang/eval-fail-foldlStrict-strict-op-application.err.exp +++ b/tests/functional/lang/eval-fail-foldlStrict-strict-op-application.err.exp @@ -2,36 +2,36 @@ error: … while calling the 'foldl'' builtin at /pwd/lang/eval-fail-foldlStrict-strict-op-application.nix:2:1: 1| # Tests that the result of applying op is forced even if the value is never used - 2| builtins.foldl' + 2| builtins.foldl' (_: f: f null) null [ | ^ - 3| (_: f: f null) + 3| (_: throw "Not the final value, but is still forced!") … while calling anonymous lambda - at /pwd/lang/eval-fail-foldlStrict-strict-op-application.nix:3:7: - 2| builtins.foldl' - 3| (_: f: f null) - | ^ - 4| null + at /pwd/lang/eval-fail-foldlStrict-strict-op-application.nix:2:21: + 1| # Tests that the result of applying op is forced even if the value is never used + 2| builtins.foldl' (_: f: f null) null [ + | ^ + 3| (_: throw "Not the final value, but is still forced!") … from call site - at /pwd/lang/eval-fail-foldlStrict-strict-op-application.nix:3:10: - 2| builtins.foldl' - 3| (_: f: f null) - | ^ - 4| null + at /pwd/lang/eval-fail-foldlStrict-strict-op-application.nix:2:24: + 1| # Tests that the result of applying op is forced even if the value is never used + 2| builtins.foldl' (_: f: f null) null [ + | ^ + 3| (_: throw "Not the final value, but is still forced!") … while calling anonymous lambda - at /pwd/lang/eval-fail-foldlStrict-strict-op-application.nix:5:6: - 4| null - 5| [ (_: throw "Not the final value, but is still forced!") (_: 23) ] - | ^ - 6| + at /pwd/lang/eval-fail-foldlStrict-strict-op-application.nix:3:4: + 2| builtins.foldl' (_: f: f null) null [ + 3| (_: throw "Not the final value, but is still forced!") + | ^ + 4| (_: 23) … while calling the 'throw' builtin - at /pwd/lang/eval-fail-foldlStrict-strict-op-application.nix:5:9: - 4| null - 5| [ (_: throw "Not the final value, but is still forced!") (_: 23) ] - | ^ - 6| + at /pwd/lang/eval-fail-foldlStrict-strict-op-application.nix:3:7: + 2| builtins.foldl' (_: f: f null) null [ + 3| (_: throw "Not the final value, but is still forced!") + | ^ + 4| (_: 23) error: Not the final value, but is still forced! diff --git a/tests/functional/lang/eval-fail-hashfile-missing.err.exp b/tests/functional/lang/eval-fail-hashfile-missing.err.exp index 1e465392744..0d3747a6d57 100644 --- a/tests/functional/lang/eval-fail-hashfile-missing.err.exp +++ b/tests/functional/lang/eval-fail-hashfile-missing.err.exp @@ -1,10 +1,10 @@ error: … while calling the 'toString' builtin - at /pwd/lang/eval-fail-hashfile-missing.nix:4:3: - 3| in - 4| toString (builtins.concatLists (map (hash: map (builtins.hashFile hash) paths) ["md5" "sha1" "sha256" "sha512"])) - | ^ - 5| + at /pwd/lang/eval-fail-hashfile-missing.nix:7:1: + 6| in + 7| toString ( + | ^ + 8| builtins.concatLists ( … while evaluating the first argument passed to builtins.toString diff --git a/tests/functional/lang/eval-fail-list.err.exp b/tests/functional/lang/eval-fail-list.err.exp index d492f8bd2e4..8b21e9a3715 100644 --- a/tests/functional/lang/eval-fail-list.err.exp +++ b/tests/functional/lang/eval-fail-list.err.exp @@ -1,8 +1,8 @@ error: … while evaluating one of the elements to concatenate - at /pwd/lang/eval-fail-list.nix:1:2: - 1| 8++1 - | ^ + at /pwd/lang/eval-fail-list.nix:1:3: + 1| 8 ++ 1 + | ^ 2| error: expected a list but found an integer: 8 diff --git a/tests/functional/lang/eval-fail-missing-arg.err.exp b/tests/functional/lang/eval-fail-missing-arg.err.exp index 3b162fe1b60..d5a66d2c5ea 100644 --- a/tests/functional/lang/eval-fail-missing-arg.err.exp +++ b/tests/functional/lang/eval-fail-missing-arg.err.exp @@ -1,12 +1,13 @@ error: … from call site at /pwd/lang/eval-fail-missing-arg.nix:1:1: - 1| ({x, y, z}: x + y + z) {x = "foo"; z = "bar";} + 1| ( | ^ - 2| + 2| { error: function 'anonymous lambda' called without required argument 'y' - at /pwd/lang/eval-fail-missing-arg.nix:1:2: - 1| ({x, y, z}: x + y + z) {x = "foo"; z = "bar";} - | ^ - 2| + at /pwd/lang/eval-fail-missing-arg.nix:2:3: + 1| ( + 2| { + | ^ + 3| x, diff --git a/tests/functional/lang/eval-fail-mutual-recursion.err.exp b/tests/functional/lang/eval-fail-mutual-recursion.err.exp index c034afcd5e0..9d84aa43f0f 100644 --- a/tests/functional/lang/eval-fail-mutual-recursion.err.exp +++ b/tests/functional/lang/eval-fail-mutual-recursion.err.exp @@ -1,64 +1,64 @@ error: … from call site - at /pwd/lang/eval-fail-mutual-recursion.nix:36:3: - 35| in - 36| throwAfterA true 10 - | ^ - 37| + at /pwd/lang/eval-fail-mutual-recursion.nix:40:1: + 39| in + 40| throwAfterA true 10 + | ^ + 41| … while calling 'throwAfterA' - at /pwd/lang/eval-fail-mutual-recursion.nix:29:26: - 28| - 29| throwAfterA = recurse: n: - | ^ - 30| if n > 0 + at /pwd/lang/eval-fail-mutual-recursion.nix:32:14: + 31| throwAfterA = + 32| recurse: n: + | ^ + 33| if n > 0 then … from call site - at /pwd/lang/eval-fail-mutual-recursion.nix:31:10: - 30| if n > 0 - 31| then throwAfterA recurse (n - 1) - | ^ - 32| else if recurse + at /pwd/lang/eval-fail-mutual-recursion.nix:34:7: + 33| if n > 0 then + 34| throwAfterA recurse (n - 1) + | ^ + 35| else if recurse then (19 duplicate frames omitted) … from call site - at /pwd/lang/eval-fail-mutual-recursion.nix:33:10: - 32| else if recurse - 33| then throwAfterB true 10 - | ^ - 34| else throw "Uh oh!"; + at /pwd/lang/eval-fail-mutual-recursion.nix:36:7: + 35| else if recurse then + 36| throwAfterB true 10 + | ^ + 37| else … while calling 'throwAfterB' - at /pwd/lang/eval-fail-mutual-recursion.nix:22:26: - 21| let - 22| throwAfterB = recurse: n: - | ^ - 23| if n > 0 + at /pwd/lang/eval-fail-mutual-recursion.nix:23:14: + 22| throwAfterB = + 23| recurse: n: + | ^ + 24| if n > 0 then … from call site - at /pwd/lang/eval-fail-mutual-recursion.nix:24:10: - 23| if n > 0 - 24| then throwAfterB recurse (n - 1) - | ^ - 25| else if recurse + at /pwd/lang/eval-fail-mutual-recursion.nix:25:7: + 24| if n > 0 then + 25| throwAfterB recurse (n - 1) + | ^ + 26| else if recurse then (19 duplicate frames omitted) … from call site - at /pwd/lang/eval-fail-mutual-recursion.nix:26:10: - 25| else if recurse - 26| then throwAfterA false 10 - | ^ - 27| else throw "Uh oh!"; + at /pwd/lang/eval-fail-mutual-recursion.nix:27:7: + 26| else if recurse then + 27| throwAfterA false 10 + | ^ + 28| else (21 duplicate frames omitted) … while calling the 'throw' builtin - at /pwd/lang/eval-fail-mutual-recursion.nix:34:10: - 33| then throwAfterB true 10 - 34| else throw "Uh oh!"; - | ^ - 35| in + at /pwd/lang/eval-fail-mutual-recursion.nix:38:7: + 37| else + 38| throw "Uh oh!"; + | ^ + 39| in error: Uh oh! diff --git a/tests/functional/lang/eval-fail-nested-list-items.err.exp b/tests/functional/lang/eval-fail-nested-list-items.err.exp index 90d43906165..1169b8326ca 100644 --- a/tests/functional/lang/eval-fail-nested-list-items.err.exp +++ b/tests/functional/lang/eval-fail-nested-list-items.err.exp @@ -1,9 +1,9 @@ error: … while evaluating a path segment - at /pwd/lang/eval-fail-nested-list-items.nix:11:6: - 10| - 11| "" + (let v = [ [ 1 2 3 4 5 6 7 8 ] [1 2 3 4]]; in builtins.deepSeq v v) - | ^ - 12| + at /pwd/lang/eval-fail-nested-list-items.nix:12:3: + 11| "" + 12| + ( + | ^ + 13| let error: cannot coerce a list to a string: [ [ 1 2 3 4 5 6 7 8 ] [ 1 «3 items elided» ] ] diff --git a/tests/functional/lang/eval-fail-not-throws.err.exp b/tests/functional/lang/eval-fail-not-throws.err.exp index fc81f7277e1..b49ed7b0048 100644 --- a/tests/functional/lang/eval-fail-not-throws.err.exp +++ b/tests/functional/lang/eval-fail-not-throws.err.exp @@ -1,14 +1,14 @@ error: … in the argument of the not operator - at /pwd/lang/eval-fail-not-throws.nix:1:4: - 1| ! (throw "uh oh!") - | ^ + at /pwd/lang/eval-fail-not-throws.nix:1:3: + 1| !(throw "uh oh!") + | ^ 2| … while calling the 'throw' builtin - at /pwd/lang/eval-fail-not-throws.nix:1:4: - 1| ! (throw "uh oh!") - | ^ + at /pwd/lang/eval-fail-not-throws.nix:1:3: + 1| !(throw "uh oh!") + | ^ 2| error: uh oh! diff --git a/tests/functional/lang/eval-fail-overflowing-add.err.exp b/tests/functional/lang/eval-fail-overflowing-add.err.exp index 6458cf1c933..5a77e9c9d97 100644 --- a/tests/functional/lang/eval-fail-overflowing-add.err.exp +++ b/tests/functional/lang/eval-fail-overflowing-add.err.exp @@ -1,6 +1,6 @@ error: integer overflow in adding 9223372036854775807 + 1 - at /pwd/lang/eval-fail-overflowing-add.nix:4:8: - 3| b = 1; - 4| in a + b - | ^ - 5| + at /pwd/lang/eval-fail-overflowing-add.nix:5:5: + 4| in + 5| a + b + | ^ + 6| diff --git a/tests/functional/lang/eval-fail-overflowing-div.err.exp b/tests/functional/lang/eval-fail-overflowing-div.err.exp index 8ce07d4d662..812c6056b76 100644 --- a/tests/functional/lang/eval-fail-overflowing-div.err.exp +++ b/tests/functional/lang/eval-fail-overflowing-div.err.exp @@ -1,23 +1,23 @@ error: … while calling the 'seq' builtin - at /pwd/lang/eval-fail-overflowing-div.nix:7:4: - 6| b = -1; - 7| in builtins.seq intMin (builtins.seq b (intMin / b)) - | ^ - 8| + at /pwd/lang/eval-fail-overflowing-div.nix:8:1: + 7| in + 8| builtins.seq intMin (builtins.seq b (intMin / b)) + | ^ + 9| … while calling the 'seq' builtin - at /pwd/lang/eval-fail-overflowing-div.nix:7:25: - 6| b = -1; - 7| in builtins.seq intMin (builtins.seq b (intMin / b)) - | ^ - 8| + at /pwd/lang/eval-fail-overflowing-div.nix:8:22: + 7| in + 8| builtins.seq intMin (builtins.seq b (intMin / b)) + | ^ + 9| … while calling the 'div' builtin - at /pwd/lang/eval-fail-overflowing-div.nix:7:48: - 6| b = -1; - 7| in builtins.seq intMin (builtins.seq b (intMin / b)) - | ^ - 8| + at /pwd/lang/eval-fail-overflowing-div.nix:8:45: + 7| in + 8| builtins.seq intMin (builtins.seq b (intMin / b)) + | ^ + 9| error: integer overflow in dividing -9223372036854775808 / -1 diff --git a/tests/functional/lang/eval-fail-overflowing-mul.err.exp b/tests/functional/lang/eval-fail-overflowing-mul.err.exp index f42b39d4db9..aaae4b7bd86 100644 --- a/tests/functional/lang/eval-fail-overflowing-mul.err.exp +++ b/tests/functional/lang/eval-fail-overflowing-mul.err.exp @@ -1,16 +1,16 @@ error: … while calling the 'mul' builtin - at /pwd/lang/eval-fail-overflowing-mul.nix:3:10: - 2| a = 4294967297; - 3| in a * a * a - | ^ - 4| + at /pwd/lang/eval-fail-overflowing-mul.nix:4:7: + 3| in + 4| a * a * a + | ^ + 5| … while calling the 'mul' builtin - at /pwd/lang/eval-fail-overflowing-mul.nix:3:6: - 2| a = 4294967297; - 3| in a * a * a - | ^ - 4| + at /pwd/lang/eval-fail-overflowing-mul.nix:4:3: + 3| in + 4| a * a * a + | ^ + 5| error: integer overflow in multiplying 4294967297 * 4294967297 diff --git a/tests/functional/lang/eval-fail-overflowing-sub.err.exp b/tests/functional/lang/eval-fail-overflowing-sub.err.exp index 66a3a03f885..5904c8dcc9d 100644 --- a/tests/functional/lang/eval-fail-overflowing-sub.err.exp +++ b/tests/functional/lang/eval-fail-overflowing-sub.err.exp @@ -1,9 +1,9 @@ error: … while calling the 'sub' builtin - at /pwd/lang/eval-fail-overflowing-sub.nix:4:6: - 3| b = 2; - 4| in a - b - | ^ - 5| + at /pwd/lang/eval-fail-overflowing-sub.nix:5:3: + 4| in + 5| a - b + | ^ + 6| error: integer overflow in subtracting -9223372036854775807 - 2 diff --git a/tests/functional/lang/eval-fail-recursion.err.exp b/tests/functional/lang/eval-fail-recursion.err.exp index 19380dc6536..8bfb4e12e47 100644 --- a/tests/functional/lang/eval-fail-recursion.err.exp +++ b/tests/functional/lang/eval-fail-recursion.err.exp @@ -1,12 +1,14 @@ error: … in the right operand of the update (//) operator - at /pwd/lang/eval-fail-recursion.nix:1:12: - 1| let a = {} // a; in a.foo - | ^ - 2| + at /pwd/lang/eval-fail-recursion.nix:2:11: + 1| let + 2| a = { } // a; + | ^ + 3| in error: infinite recursion encountered - at /pwd/lang/eval-fail-recursion.nix:1:15: - 1| let a = {} // a; in a.foo - | ^ - 2| + at /pwd/lang/eval-fail-recursion.nix:2:14: + 1| let + 2| a = { } // a; + | ^ + 3| in diff --git a/tests/functional/lang/eval-fail-remove.err.exp b/tests/functional/lang/eval-fail-remove.err.exp index 292b3c3f33a..0e087688a25 100644 --- a/tests/functional/lang/eval-fail-remove.err.exp +++ b/tests/functional/lang/eval-fail-remove.err.exp @@ -1,15 +1,15 @@ error: … while evaluating the attribute 'body' - at /pwd/lang/eval-fail-remove.nix:4:3: - 3| - 4| body = (removeAttrs attrs ["x"]).x; + at /pwd/lang/eval-fail-remove.nix:7:3: + 6| + 7| body = (removeAttrs attrs [ "x" ]).x; | ^ - 5| } + 8| } error: attribute 'x' missing - at /pwd/lang/eval-fail-remove.nix:4:10: - 3| - 4| body = (removeAttrs attrs ["x"]).x; + at /pwd/lang/eval-fail-remove.nix:7:10: + 6| + 7| body = (removeAttrs attrs [ "x" ]).x; | ^ - 5| } + 8| } Did you mean y? diff --git a/tests/functional/lang/eval-fail-scope-5.err.exp b/tests/functional/lang/eval-fail-scope-5.err.exp index b0b05cad737..6edc85f4f16 100644 --- a/tests/functional/lang/eval-fail-scope-5.err.exp +++ b/tests/functional/lang/eval-fail-scope-5.err.exp @@ -1,28 +1,28 @@ error: … while evaluating the attribute 'body' - at /pwd/lang/eval-fail-scope-5.nix:8:3: - 7| - 8| body = f {}; + at /pwd/lang/eval-fail-scope-5.nix:13:3: + 12| + 13| body = f { }; | ^ - 9| + 14| … from call site - at /pwd/lang/eval-fail-scope-5.nix:8:10: - 7| - 8| body = f {}; + at /pwd/lang/eval-fail-scope-5.nix:13:10: + 12| + 13| body = f { }; | ^ - 9| + 14| … while calling 'f' - at /pwd/lang/eval-fail-scope-5.nix:6:7: - 5| - 6| f = {x ? y, y ? x}: x + y; - | ^ - 7| + at /pwd/lang/eval-fail-scope-5.nix:7:5: + 6| f = + 7| { + | ^ + 8| x ? y, error: infinite recursion encountered - at /pwd/lang/eval-fail-scope-5.nix:6:12: - 5| - 6| f = {x ? y, y ? x}: x + y; - | ^ - 7| + at /pwd/lang/eval-fail-scope-5.nix:8:11: + 7| { + 8| x ? y, + | ^ + 9| y ? x, diff --git a/tests/functional/lang/eval-fail-undeclared-arg.err.exp b/tests/functional/lang/eval-fail-undeclared-arg.err.exp index 6e13a138eb7..353894d01e6 100644 --- a/tests/functional/lang/eval-fail-undeclared-arg.err.exp +++ b/tests/functional/lang/eval-fail-undeclared-arg.err.exp @@ -1,13 +1,13 @@ error: … from call site at /pwd/lang/eval-fail-undeclared-arg.nix:1:1: - 1| ({x, z}: x + z) {x = "foo"; y = "bla"; z = "bar";} + 1| ({ x, z }: x + z) { | ^ - 2| + 2| x = "foo"; error: function 'anonymous lambda' called with unexpected argument 'y' at /pwd/lang/eval-fail-undeclared-arg.nix:1:2: - 1| ({x, z}: x + z) {x = "foo"; y = "bla"; z = "bar";} + 1| ({ x, z }: x + z) { | ^ - 2| + 2| x = "foo"; Did you mean one of x or z? diff --git a/tests/functional/lang/eval-fail-using-set-as-attr-name.err.exp b/tests/functional/lang/eval-fail-using-set-as-attr-name.err.exp index 4326c965008..9a59f37f35e 100644 --- a/tests/functional/lang/eval-fail-using-set-as-attr-name.err.exp +++ b/tests/functional/lang/eval-fail-using-set-as-attr-name.err.exp @@ -1,14 +1,14 @@ error: … while evaluating an attribute name - at /pwd/lang/eval-fail-using-set-as-attr-name.nix:5:10: - 4| in - 5| attr.${key} - | ^ - 6| + at /pwd/lang/eval-fail-using-set-as-attr-name.nix:7:8: + 6| in + 7| attr.${key} + | ^ + 8| error: expected a string but found a set: { } - at /pwd/lang/eval-fail-using-set-as-attr-name.nix:5:10: - 4| in - 5| attr.${key} - | ^ - 6| + at /pwd/lang/eval-fail-using-set-as-attr-name.nix:7:8: + 6| in + 7| attr.${key} + | ^ + 8| diff --git a/tests/functional/repl/doc-comment-curried-args.expected b/tests/functional/repl/doc-comment-curried-args.expected index 56607e911e8..d2a5bf32853 100644 --- a/tests/functional/repl/doc-comment-curried-args.expected +++ b/tests/functional/repl/doc-comment-curried-args.expected @@ -6,7 +6,8 @@ Added variables. nix-repl> :doc curriedArgs Function `curriedArgs`\ - … defined at /path/to/tests/functional/repl/doc-comments.nix:48:5 + … defined at /path/to/tests/functional/repl/doc-comments.nix:87:5 + A documented function. @@ -17,7 +18,8 @@ nix-repl> "Note that users may not expect this to behave as it currently does" nix-repl> :doc x Function `curriedArgs`\ - … defined at /path/to/tests/functional/repl/doc-comments.nix:50:5 + … defined at /path/to/tests/functional/repl/doc-comments.nix:91:5 + The function returned by applying once diff --git a/tests/functional/repl/doc-comment-formals.expected b/tests/functional/repl/doc-comment-formals.expected index 1024919f4b9..357cf998680 100644 --- a/tests/functional/repl/doc-comment-formals.expected +++ b/tests/functional/repl/doc-comment-formals.expected @@ -9,6 +9,7 @@ nix-repl> "Note that this is not yet complete" nix-repl> :doc documentedFormals Function `documentedFormals`\ - … defined at /path/to/tests/functional/repl/doc-comments.nix:57:5 + … defined at /path/to/tests/functional/repl/doc-comments.nix:104:5 + Finds x diff --git a/tests/functional/repl/doc-comment-function.expected b/tests/functional/repl/doc-comment-function.expected index 3889c4f7860..030cfc3265a 100644 --- a/tests/functional/repl/doc-comment-function.expected +++ b/tests/functional/repl/doc-comment-function.expected @@ -2,6 +2,7 @@ Nix Type :? for help. nix-repl> :doc import ./doc-comment-function.nix -Function defined at /path/to/tests/functional/repl/doc-comment-function.nix:2:1 +Function defined at /path/to/tests/functional/repl/doc-comment-function.nix:4:1 + A doc comment for a file that only contains a function diff --git a/tests/functional/repl/doc-compact.expected b/tests/functional/repl/doc-compact.expected index 79f1fd44f59..276de2e60b5 100644 --- a/tests/functional/repl/doc-compact.expected +++ b/tests/functional/repl/doc-compact.expected @@ -6,6 +6,7 @@ Added variables. nix-repl> :doc compact Function `compact`\ - … defined at /path/to/tests/functional/repl/doc-comments.nix:18:20 + … defined at /path/to/tests/functional/repl/doc-comments.nix:27:5 + boom diff --git a/tests/functional/repl/doc-constant.expected b/tests/functional/repl/doc-constant.expected index 5787e04dc19..a68188b25ab 100644 --- a/tests/functional/repl/doc-constant.expected +++ b/tests/functional/repl/doc-constant.expected @@ -10,25 +10,27 @@ error: value does not have documentation nix-repl> :doc lib.version Attribute `version` - … defined at /path/to/tests/functional/repl/doc-comments.nix:30:3 + … defined at /path/to/tests/functional/repl/doc-comments.nix:47:3 + Immovably fixed. nix-repl> :doc lib.attr.empty Attribute `empty` - … defined at /path/to/tests/functional/repl/doc-comments.nix:33:3 + … defined at /path/to/tests/functional/repl/doc-comments.nix:52:3 + Unchangeably constant. nix-repl> :doc lib.attr.undocument error: … while evaluating the attribute 'attr.undocument' - at /path/to/tests/functional/repl/doc-comments.nix:33:3: - 32| /** Unchangeably constant. */ - 33| lib.attr.empty = { }; + at /path/to/tests/functional/repl/doc-comments.nix:52:3: + 51| */ + 52| lib.attr.empty = { }; | ^ - 34| + 53| error: attribute 'undocument' missing at «string»:1:1: @@ -39,28 +41,31 @@ error: nix-repl> :doc (import ./doc-comments.nix).constant Attribute `constant` - … defined at /path/to/tests/functional/repl/doc-comments.nix:27:3 + … defined at /path/to/tests/functional/repl/doc-comments.nix:42:3 + Firmly rigid. nix-repl> :doc (import ./doc-comments.nix).lib.version Attribute `version` - … defined at /path/to/tests/functional/repl/doc-comments.nix:30:3 + … defined at /path/to/tests/functional/repl/doc-comments.nix:47:3 + Immovably fixed. nix-repl> :doc (import ./doc-comments.nix).lib.attr.empty Attribute `empty` - … defined at /path/to/tests/functional/repl/doc-comments.nix:33:3 + … defined at /path/to/tests/functional/repl/doc-comments.nix:52:3 + Unchangeably constant. nix-repl> :doc (import ./doc-comments.nix).lib.attr.undocumented Attribute `undocumented` - … defined at /path/to/tests/functional/repl/doc-comments.nix:35:3 + … defined at /path/to/tests/functional/repl/doc-comments.nix:54:3 No documentation found. @@ -97,11 +102,11 @@ error: attribute 'missing' missing nix-repl> :doc lib.attr.undocumental error: … while evaluating the attribute 'attr.undocumental' - at /path/to/tests/functional/repl/doc-comments.nix:33:3: - 32| /** Unchangeably constant. */ - 33| lib.attr.empty = { }; + at /path/to/tests/functional/repl/doc-comments.nix:52:3: + 51| */ + 52| lib.attr.empty = { }; | ^ - 34| + 53| error: attribute 'undocumental' missing at «string»:1:1: diff --git a/tests/functional/repl/doc-floatedIn.expected b/tests/functional/repl/doc-floatedIn.expected index 82bb80b9501..3bf1c40715b 100644 --- a/tests/functional/repl/doc-floatedIn.expected +++ b/tests/functional/repl/doc-floatedIn.expected @@ -6,6 +6,7 @@ Added variables. nix-repl> :doc floatedIn Function `floatedIn`\ - … defined at /path/to/tests/functional/repl/doc-comments.nix:16:5 + … defined at /path/to/tests/functional/repl/doc-comments.nix:21:5 + This also works. diff --git a/tests/functional/repl/doc-functor.expected b/tests/functional/repl/doc-functor.expected index 8cb2706ef0f..503fb807368 100644 --- a/tests/functional/repl/doc-functor.expected +++ b/tests/functional/repl/doc-functor.expected @@ -20,7 +20,7 @@ Look, it's just like a function! nix-repl> :doc recursive Function `__functor`\ - … defined at /path/to/tests/functional/repl/doc-functor.nix:77:23 + … defined at /path/to/tests/functional/repl/doc-functor.nix:82:23 This looks bad, but the docs are ok because of the eta expansion. @@ -30,27 +30,27 @@ error: … while partially calling '__functor' to retrieve documentation … while calling '__functor' - at /path/to/tests/functional/repl/doc-functor.nix:85:17: - 84| */ - 85| __functor = self: self.__functor self; + at /path/to/tests/functional/repl/doc-functor.nix:90:17: + 89| */ + 90| __functor = self: self.__functor self; | ^ - 86| }; + 91| }; … from call site - at /path/to/tests/functional/repl/doc-functor.nix:85:23: - 84| */ - 85| __functor = self: self.__functor self; + at /path/to/tests/functional/repl/doc-functor.nix:90:23: + 89| */ + 90| __functor = self: self.__functor self; | ^ - 86| }; + 91| }; (19999 duplicate frames omitted) error: stack overflow; max-call-depth exceeded - at /path/to/tests/functional/repl/doc-functor.nix:85:23: - 84| */ - 85| __functor = self: self.__functor self; + at /path/to/tests/functional/repl/doc-functor.nix:90:23: + 89| */ + 90| __functor = self: self.__functor self; | ^ - 86| }; + 91| }; nix-repl> :doc diverging error: @@ -59,18 +59,18 @@ error: (10000 duplicate frames omitted) … while calling '__functor' - at /path/to/tests/functional/repl/doc-functor.nix:97:19: - 96| f = x: { - 97| __functor = self: (f (x + 1)); - | ^ - 98| }; + at /path/to/tests/functional/repl/doc-functor.nix:103:21: + 102| f = x: { + 103| __functor = self: (f (x + 1)); + | ^ + 104| }; error: stack overflow; max-call-depth exceeded - at /path/to/tests/functional/repl/doc-functor.nix:97:26: - 96| f = x: { - 97| __functor = self: (f (x + 1)); - | ^ - 98| }; + at /path/to/tests/functional/repl/doc-functor.nix:103:28: + 102| f = x: { + 103| __functor = self: (f (x + 1)); + | ^ + 104| }; nix-repl> :doc helper Function `square`\ @@ -81,21 +81,21 @@ Compute x^2 nix-repl> :doc helper2 Function `__functor`\ - … defined at /path/to/tests/functional/repl/doc-functor.nix:45:23 + … defined at /path/to/tests/functional/repl/doc-functor.nix:46:13 This is a function that can be overridden. nix-repl> :doc lib.helper3 Function `__functor`\ - … defined at /path/to/tests/functional/repl/doc-functor.nix:45:23 + … defined at /path/to/tests/functional/repl/doc-functor.nix:46:13 This is a function that can be overridden. nix-repl> :doc helper3 Function `__functor`\ - … defined at /path/to/tests/functional/repl/doc-functor.nix:45:23 + … defined at /path/to/tests/functional/repl/doc-functor.nix:46:13 This is a function that can be overridden. diff --git a/tests/functional/repl/doc-lambda-flavors.expected b/tests/functional/repl/doc-lambda-flavors.expected index ab5c956390f..437c09d2b31 100644 --- a/tests/functional/repl/doc-lambda-flavors.expected +++ b/tests/functional/repl/doc-lambda-flavors.expected @@ -6,24 +6,28 @@ Added variables. nix-repl> :doc nonStrict Function `nonStrict`\ - … defined at /path/to/tests/functional/repl/doc-comments.nix:37:70 + … defined at /path/to/tests/functional/repl/doc-comments.nix:60:5 + My syntax is not strict, but I'm strict anyway. nix-repl> :doc strict Function `strict`\ - … defined at /path/to/tests/functional/repl/doc-comments.nix:38:63 + … defined at /path/to/tests/functional/repl/doc-comments.nix:65:5 + I don't have to be strict, but I am anyway. nix-repl> :doc strictPre Function `strictPre`\ - … defined at /path/to/tests/functional/repl/doc-comments.nix:40:48 + … defined at /path/to/tests/functional/repl/doc-comments.nix:71:5 + Here's one way to do this nix-repl> :doc strictPost Function `strictPost`\ - … defined at /path/to/tests/functional/repl/doc-comments.nix:41:53 + … defined at /path/to/tests/functional/repl/doc-comments.nix:76:5 + Here's another way to do this diff --git a/tests/functional/repl/doc-measurement.expected b/tests/functional/repl/doc-measurement.expected index 555cac9a2a0..862697613be 100644 --- a/tests/functional/repl/doc-measurement.expected +++ b/tests/functional/repl/doc-measurement.expected @@ -6,6 +6,7 @@ Added variables. nix-repl> :doc measurement Function `measurement`\ - … defined at /path/to/tests/functional/repl/doc-comments.nix:13:17 + … defined at /path/to/tests/functional/repl/doc-comments.nix:15:17 + 👈 precisely this wide 👉 diff --git a/tests/functional/repl/doc-unambiguous.expected b/tests/functional/repl/doc-unambiguous.expected index 0db5505d781..32ca9aef22a 100644 --- a/tests/functional/repl/doc-unambiguous.expected +++ b/tests/functional/repl/doc-unambiguous.expected @@ -6,6 +6,7 @@ Added variables. nix-repl> :doc unambiguous Function `unambiguous`\ - … defined at /path/to/tests/functional/repl/doc-comments.nix:24:5 + … defined at /path/to/tests/functional/repl/doc-comments.nix:37:5 + Very close From 4e5d1b281e503641d649ddba22d49361e6295e2e Mon Sep 17 00:00:00 2001 From: Ben Millwood Date: Thu, 10 Oct 2024 16:05:50 +0100 Subject: [PATCH 21/60] Improve "illegal path references in fixed output derivation" error The main improvement is that the new message gives an example of a path that is referenced, which should make it easier to track down. While there, I also clarified the wording, saying exactly why the paths in question were illegal. --- src/libstore/unix/build/local-derivation-goal.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libstore/unix/build/local-derivation-goal.cc b/src/libstore/unix/build/local-derivation-goal.cc index ceb0b353927..9d26c0b0578 100644 --- a/src/libstore/unix/build/local-derivation-goal.cc +++ b/src/libstore/unix/build/local-derivation-goal.cc @@ -2657,10 +2657,14 @@ SingleDrvOutputs LocalDerivationGoal::registerOutputs() wanted.to_string(HashFormat::SRI, true), got.to_string(HashFormat::SRI, true))); } - if (!newInfo0.references.empty()) + if (!newInfo0.references.empty()) { + auto numViolations = newInfo.references.size(); delayedException = std::make_exception_ptr( - BuildError("illegal path references in fixed-output derivation '%s'", - worker.store.printStorePath(drvPath))); + BuildError("fixed-output derivations must not reference store paths: '%s' references %d distinct paths, e.g. '%s'", + worker.store.printStorePath(drvPath), + numViolations, + worker.store.printStorePath(*newInfo.references.begin()))); + } return newInfo0; }, From 7465fbe9264e46c556b456226e8fb980fcfd7e66 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Mon, 27 Jan 2025 12:32:46 +0100 Subject: [PATCH 22/60] refactor: Extract EvalState::realiseString --- src/libexpr-c/nix_api_value.cc | 6 +----- src/libexpr/eval.hh | 9 +++++++++ src/libexpr/primops.cc | 9 +++++++++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/libexpr-c/nix_api_value.cc b/src/libexpr-c/nix_api_value.cc index bae078d312f..448f4a58a78 100644 --- a/src/libexpr-c/nix_api_value.cc +++ b/src/libexpr-c/nix_api_value.cc @@ -613,12 +613,8 @@ nix_realised_string * nix_string_realise(nix_c_context * context, EvalState * st context->last_err_code = NIX_OK; try { auto & v = check_value_in(value); - nix::NixStringContext stringContext; - auto rawStr = state->state.coerceToString(nix::noPos, v, stringContext, "while realising a string").toOwned(); nix::StorePathSet storePaths; - auto rewrites = state->state.realiseContext(stringContext, &storePaths); - - auto s = nix::rewriteStrings(rawStr, rewrites); + auto s = state->state.realiseString(v, &storePaths, isIFD); // Convert to the C API StorePath type and convert to vector for index-based access std::vector vec; diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 84b7d823c36..767578343d9 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -820,6 +820,15 @@ public: */ [[nodiscard]] StringMap realiseContext(const NixStringContext & context, StorePathSet * maybePaths = nullptr, bool isIFD = true); + /** + * Realise the given string with context, and return the string with outputs instead of downstream output placeholders. + * @param[in] str the string to realise + * @param[out] paths all referenced store paths will be added to this set + * @return the realised string + * @throw EvalError if the value is not a string, path or derivation (see `coerceToString`) + */ + std::string realiseString(Value & str, StorePathSet * storePathsOutMaybe, bool isIFD = true, const PosIdx pos = noPos); + /* Call the binary path filter predicate used builtins.path etc. */ bool callPathFilter( Value * filterFun, diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index a0e2753b5ec..e6f6f1dda24 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -47,6 +47,15 @@ static inline Value * mkString(EvalState & state, const std::csub_match & match) return v; } +std::string EvalState::realiseString(Value & s, StorePathSet * storePathsOutMaybe, bool isIFD, const PosIdx pos) +{ + nix::NixStringContext stringContext; + auto rawStr = coerceToString(pos, s, stringContext, "while realising a string").toOwned(); + auto rewrites = realiseContext(stringContext, storePathsOutMaybe, isIFD); + + return nix::rewriteStrings(rawStr, rewrites); +} + StringMap EvalState::realiseContext(const NixStringContext & context, StorePathSet * maybePathsOut, bool isIFD) { std::vector drvs; From 0d7418b4feebcfb3e0e66798398d3ecf618c1e58 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Mon, 27 Jan 2025 14:25:35 +0100 Subject: [PATCH 23/60] packages.default: Add meta.mainProgram --- packaging/everything.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/packaging/everything.nix b/packaging/everything.nix index 2b47c31bbf5..0974a34df50 100644 --- a/packaging/everything.nix +++ b/packaging/everything.nix @@ -93,6 +93,7 @@ let libs = throw "`nix.dev.libs` is not meant to be used; use `nix.libs` instead."; }; meta = { + mainProgram = "nix"; pkgConfigModules = [ "nix-cmd" "nix-expr" From 850329dea59358db6e8ea572d769eb706715c508 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Mon, 27 Jan 2025 14:26:05 +0100 Subject: [PATCH 24/60] packages.nix-cli: Add meta.mainProgram --- src/nix/package.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nix/package.nix b/src/nix/package.nix index 89c52c3bb05..6e59adc3800 100644 --- a/src/nix/package.nix +++ b/src/nix/package.nix @@ -103,6 +103,7 @@ mkMesonExecutable (finalAttrs: { ]; meta = { + mainProgram = "nix"; platforms = lib.platforms.unix ++ lib.platforms.windows; }; From a5de2dd27457a9dd3d121b402b9445ef86aad262 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Fri, 24 Jan 2025 16:39:56 +0100 Subject: [PATCH 25/60] tests/functional/characterisation/framework: Log to stderr It seems that `meson test --print-errorlogs` only captures stderr, so this makes it forward the logs as intended. We might want to redirect stdout in our common setup script instead. --- .../functional/characterisation/framework.sh | 42 +++++++++++-------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/tests/functional/characterisation/framework.sh b/tests/functional/characterisation/framework.sh index 5ca125ab5bc..d2c2155db80 100644 --- a/tests/functional/characterisation/framework.sh +++ b/tests/functional/characterisation/framework.sh @@ -1,5 +1,7 @@ # shellcheck shell=bash +badTestNames=() + # Golden test support # # Test that the output of the given test matches what is expected. If @@ -18,10 +20,11 @@ function diffAndAcceptInner() { fi # Diff so we get a nice message - if ! diff --color=always --unified "$expectedOrEmpty" "$got"; then - echo "FAIL: evaluation result of $testName not as expected" + if ! diff >&2 --color=always --unified "$expectedOrEmpty" "$got"; then + echo >&2 "FAIL: evaluation result of $testName not as expected" # shellcheck disable=SC2034 badDiff=1 + badTestNames+=("$testName") fi # Update expected if `_NIX_TEST_ACCEPT` is non-empty. @@ -42,14 +45,14 @@ function characterisationTestExit() { if test -n "${_NIX_TEST_ACCEPT-}"; then if (( "$badDiff" )); then set +x - echo 'Output did mot match, but accepted output as the persisted expected output.' - echo 'That means the next time the tests are run, they should pass.' + echo >&2 'Output did mot match, but accepted output as the persisted expected output.' + echo >&2 'That means the next time the tests are run, they should pass.' set -x else set +x - echo 'NOTE: Environment variable _NIX_TEST_ACCEPT is defined,' - echo 'indicating the unexpected output should be accepted as the expected output going forward,' - echo 'but no tests had unexpected output so there was no expected output to update.' + echo >&2 'NOTE: Environment variable _NIX_TEST_ACCEPT is defined,' + echo >&2 'indicating the unexpected output should be accepted as the expected output going forward,' + echo >&2 'but no tests had unexpected output so there was no expected output to update.' set -x fi if (( "$badExitCode" )); then @@ -60,16 +63,21 @@ function characterisationTestExit() { else if (( "$badDiff" )); then set +x - echo '' - echo 'You can rerun this test with:' - echo '' - echo " _NIX_TEST_ACCEPT=1 make tests/functional/${TEST_NAME}.sh.test" - echo '' - echo 'to regenerate the files containing the expected output,' - echo 'and then view the git diff to decide whether a change is' - echo 'good/intentional or bad/unintentional.' - echo 'If the diff contains arbitrary or impure information,' - echo 'please improve the normalization that the test applies to the output.' + echo >&2 '' + echo >&2 'The following tests had unexpected output:' + for testName in "${badTestNames[@]}"; do + echo >&2 " $testName" + done + echo >&2 '' + echo >&2 'You can rerun this test with:' + echo >&2 '' + echo >&2 " _NIX_TEST_ACCEPT=1 meson test ${TEST_NAME}" + echo >&2 '' + echo >&2 'to regenerate the files containing the expected output,' + echo >&2 'and then view the git diff to decide whether a change is' + echo >&2 'good/intentional or bad/unintentional.' + echo >&2 'If the diff contains arbitrary or impure information,' + echo >&2 'please improve the normalization that the test applies to the output.' set -x fi exit $(( "$badExitCode" + "$badDiff" )) From fa87ad6a7ca97c4bd45ddec284be4209495bb1eb Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 29 Jan 2025 15:34:49 +0100 Subject: [PATCH 26/60] Fix shellcheck warnings --- tests/functional/git-hashing/fixed.sh | 2 ++ tests/functional/help.sh | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/functional/git-hashing/fixed.sh b/tests/functional/git-hashing/fixed.sh index 1962472a876..f33d95cfa92 100644 --- a/tests/functional/git-hashing/fixed.sh +++ b/tests/functional/git-hashing/fixed.sh @@ -1,3 +1,5 @@ +#!/usr/bin/env bash + source common.sh # Store layer needs bugfix diff --git a/tests/functional/help.sh b/tests/functional/help.sh index 2d64c465db0..efacaba5922 100755 --- a/tests/functional/help.sh +++ b/tests/functional/help.sh @@ -25,7 +25,7 @@ done # FIXME: we don't know whether we built the manpages, so we can't # reliably test them here. -exit 0 +if false; then # test help output @@ -74,3 +74,5 @@ nix-daemon --help nix-hash --help nix-instantiate --help nix-prefetch-url --help + +fi From 102d90ebf07b1f268a3551daf5457131ae063d4a Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 30 Jan 2025 11:27:24 +0100 Subject: [PATCH 27/60] Fix duplicate setPathDisplay() Fixes messages like 'copying /tmp/repo/tmp/repo to the store'. The PosixSourceAccessor already sets the prefix. Setting the prefix twice shouldn't be a problem, but GitRepoImpl::getAccessor() returns a wrapped accessor so it's not actually idempotent. --- src/libfetchers/git.cc | 2 -- tests/functional/fetchGit.sh | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libfetchers/git.cc b/src/libfetchers/git.cc index b411e112f5f..e8698709af2 100644 --- a/src/libfetchers/git.cc +++ b/src/libfetchers/git.cc @@ -737,8 +737,6 @@ struct GitInputScheme : InputScheme exportIgnore, makeNotAllowedError(repoInfo.locationToArg())); - accessor->setPathDisplay(repoInfo.locationToArg()); - /* If the repo has submodules, return a mounted input accessor consisting of the accessor for the top-level repo and the accessors for the submodule workdirs. */ diff --git a/tests/functional/fetchGit.sh b/tests/functional/fetchGit.sh index 78925b5cdd6..f3eda54dcdf 100755 --- a/tests/functional/fetchGit.sh +++ b/tests/functional/fetchGit.sh @@ -37,6 +37,7 @@ nix-instantiate --eval -E "builtins.readFile ((builtins.fetchGit file://$TEST_RO # Fetch a worktree. unset _NIX_FORCE_HTTP +expectStderr 0 nix eval -vvvv --impure --raw --expr "(builtins.fetchGit file://$TEST_ROOT/worktree).outPath" | grepQuiet "copying '$TEST_ROOT/worktree/' to the store" path0=$(nix eval --impure --raw --expr "(builtins.fetchGit file://$TEST_ROOT/worktree).outPath") path0_=$(nix eval --impure --raw --expr "(builtins.fetchTree { type = \"git\"; url = file://$TEST_ROOT/worktree; }).outPath") [[ $path0 = $path0_ ]] From 3032512425a09fc58f2d658442043894e0aab256 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 30 Jan 2025 12:41:02 +0100 Subject: [PATCH 28/60] =?UTF-8?q?GitExportIgnoreSourceAccessor:=20Don't=20?= =?UTF-8?q?show=20=C2=ABunknown=C2=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In general we should set the path display prefix on the inner accessor, so we now pass the display prefix to getAccessor(). --- src/libfetchers/git-utils.cc | 21 +++++++++++++-------- src/libfetchers/git-utils.hh | 5 ++++- src/libfetchers/git.cc | 4 +--- src/libfetchers/github.cc | 7 ++++--- src/libfetchers/tarball.cc | 12 +++++++----- 5 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src/libfetchers/git-utils.cc b/src/libfetchers/git-utils.cc index 6a75daf6124..a6b13fb31c8 100644 --- a/src/libfetchers/git-utils.cc +++ b/src/libfetchers/git-utils.cc @@ -508,7 +508,10 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this */ ref getRawAccessor(const Hash & rev); - ref getAccessor(const Hash & rev, bool exportIgnore) override; + ref getAccessor( + const Hash & rev, + bool exportIgnore, + std::string displayPrefix) override; ref getAccessor(const WorkdirInfo & wd, bool exportIgnore, MakeNotAllowedError e) override; @@ -627,7 +630,7 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this Hash treeHashToNarHash(const Hash & treeHash) override { - auto accessor = getAccessor(treeHash, false); + auto accessor = getAccessor(treeHash, false, ""); fetchers::Cache::Key cacheKey{"treeHashToNarHash", {{"treeHash", treeHash.gitRev()}}}; @@ -1194,16 +1197,18 @@ ref GitRepoImpl::getRawAccessor(const Hash & rev) return make_ref(self, rev); } -ref GitRepoImpl::getAccessor(const Hash & rev, bool exportIgnore) +ref GitRepoImpl::getAccessor( + const Hash & rev, + bool exportIgnore, + std::string displayPrefix) { auto self = ref(shared_from_this()); ref rawGitAccessor = getRawAccessor(rev); - if (exportIgnore) { + rawGitAccessor->setPathDisplay(std::move(displayPrefix)); + if (exportIgnore) return make_ref(self, rawGitAccessor, rev); - } - else { + else return rawGitAccessor; - } } ref GitRepoImpl::getAccessor(const WorkdirInfo & wd, bool exportIgnore, MakeNotAllowedError makeNotAllowedError) @@ -1236,7 +1241,7 @@ std::vector> GitRepoImpl::getSubmodules /* Read the .gitmodules files from this revision. */ CanonPath modulesFile(".gitmodules"); - auto accessor = getAccessor(rev, exportIgnore); + auto accessor = getAccessor(rev, exportIgnore, ""); if (!accessor->pathExists(modulesFile)) return {}; /* Parse it and get the revision of each submodule. */ diff --git a/src/libfetchers/git-utils.hh b/src/libfetchers/git-utils.hh index ff115143fc7..9677f507923 100644 --- a/src/libfetchers/git-utils.hh +++ b/src/libfetchers/git-utils.hh @@ -86,7 +86,10 @@ struct GitRepo virtual bool hasObject(const Hash & oid) = 0; - virtual ref getAccessor(const Hash & rev, bool exportIgnore) = 0; + virtual ref getAccessor( + const Hash & rev, + bool exportIgnore, + std::string displayPrefix) = 0; virtual ref getAccessor(const WorkdirInfo & wd, bool exportIgnore, MakeNotAllowedError makeNotAllowedError) = 0; diff --git a/src/libfetchers/git.cc b/src/libfetchers/git.cc index e8698709af2..e40afb865eb 100644 --- a/src/libfetchers/git.cc +++ b/src/libfetchers/git.cc @@ -672,9 +672,7 @@ struct GitInputScheme : InputScheme verifyCommit(input, repo); bool exportIgnore = getExportIgnoreAttr(input); - auto accessor = repo->getAccessor(rev, exportIgnore); - - accessor->setPathDisplay("«" + input.to_string() + "»"); + auto accessor = repo->getAccessor(rev, exportIgnore, "«" + input.to_string() + "»"); /* If the repo has submodules, fetch them and return a mounted input accessor consisting of the accessor for the top-level diff --git a/src/libfetchers/github.cc b/src/libfetchers/github.cc index 18594198847..ec469df7cd3 100644 --- a/src/libfetchers/github.cc +++ b/src/libfetchers/github.cc @@ -294,9 +294,10 @@ struct GitArchiveInputScheme : InputScheme #endif input.attrs.insert_or_assign("lastModified", uint64_t(tarballInfo.lastModified)); - auto accessor = getTarballCache()->getAccessor(tarballInfo.treeHash, false); - - accessor->setPathDisplay("«" + input.to_string() + "»"); + auto accessor = getTarballCache()->getAccessor( + tarballInfo.treeHash, + false, + "«" + input.to_string() + "»"); return {accessor, input}; } diff --git a/src/libfetchers/tarball.cc b/src/libfetchers/tarball.cc index 28574e7b1e7..699612e250c 100644 --- a/src/libfetchers/tarball.cc +++ b/src/libfetchers/tarball.cc @@ -105,7 +105,8 @@ DownloadFileResult downloadFile( static DownloadTarballResult downloadTarball_( const std::string & url, - const Headers & headers) + const Headers & headers, + const std::string & displayPrefix) { Cache::Key cacheKey{"tarball", {{"url", url}}}; @@ -118,7 +119,7 @@ static DownloadTarballResult downloadTarball_( .treeHash = treeHash, .lastModified = (time_t) getIntAttr(infoAttrs, "lastModified"), .immutableUrl = maybeGetStrAttr(infoAttrs, "immutableUrl"), - .accessor = getTarballCache()->getAccessor(treeHash, false), + .accessor = getTarballCache()->getAccessor(treeHash, false, displayPrefix), }; }; @@ -371,9 +372,10 @@ struct TarballInputScheme : CurlInputScheme { auto input(_input); - auto result = downloadTarball_(getStrAttr(input.attrs, "url"), {}); - - result.accessor->setPathDisplay("«" + input.to_string() + "»"); + auto result = downloadTarball_( + getStrAttr(input.attrs, "url"), + {}, + "«" + input.to_string() + "»"); if (result.immutableUrl) { auto immutableInput = Input::fromURL(*input.settings, *result.immutableUrl); From 9f72d5bce9205c9f45dcb0e06b9573ccca5724ac Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 30 Jan 2025 11:47:41 +0100 Subject: [PATCH 29/60] Git fetcher: Don't pass URL query parameters for file:// URLs Git interprets them as part of the file name, so passing parameters like 'rev' breaks. Only relevant for testing (when _NIX_FORCE_HTTP is set) and local bare repos. --- src/libfetchers/git.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libfetchers/git.cc b/src/libfetchers/git.cc index b411e112f5f..7713a6e0c11 100644 --- a/src/libfetchers/git.cc +++ b/src/libfetchers/git.cc @@ -459,8 +459,14 @@ struct GitInputScheme : InputScheme url); } repoInfo.location = std::filesystem::absolute(url.path); - } else + } else { + if (url.scheme == "file") + /* Query parameters are meaningless for file://, but + Git interprets them as part of the file name. So get + rid of them. */ + url.query.clear(); repoInfo.location = url; + } // If this is a local directory and no ref or revision is // given, then allow the use of an unclean working tree. From ee9fa0d3603165631e65c8e694a033c47872267a Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 30 Jan 2025 18:23:27 +0100 Subject: [PATCH 30/60] Git fetcher: Don't use refspec : This causes Git to create a local ref named refs/head/, e.g. $ git -C ~/.cache/nix/gitv3/11irpim06vj4h6c0w8yls6kx4hvl0qd0gr1fvk47n76g6wf1s1vk ls-remote --symref . 5c4410e3b9891c05ab40d723de78c6f0be45ad30 refs/heads/5c4410e3b9891c05ab40d723de78c6f0be45ad30 7f6bde8a20de4cccc2256f088bc5af9dbe38881d refs/heads/7f6bde8a20de4cccc2256f088bc5af9dbe38881d which confuses readHead(), leading to errors like fatal: Refusing to point HEAD outside of refs/ warning: could not update cached head 'd275d93aa0bb8a004939b2f1e87f559f989453be' for 'file:///tmp/repo' --- src/libfetchers/git.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libfetchers/git.cc b/src/libfetchers/git.cc index 7713a6e0c11..004123e27ab 100644 --- a/src/libfetchers/git.cc +++ b/src/libfetchers/git.cc @@ -611,16 +611,16 @@ struct GitInputScheme : InputScheme try { auto fetchRef = getAllRefsAttr(input) - ? "refs/*" + ? "refs/*:refs/*" : input.getRev() ? input.getRev()->gitRev() : ref.compare(0, 5, "refs/") == 0 - ? ref + ? fmt("%1%:%1%", ref) : ref == "HEAD" ? ref - : "refs/heads/" + ref; + : fmt("%1%:%1%", "refs/heads/" + ref); - repo->fetch(repoUrl.to_string(), fmt("%s:%s", fetchRef, fetchRef), getShallowAttr(input)); + repo->fetch(repoUrl.to_string(), fetchRef, getShallowAttr(input)); } catch (Error & e) { if (!std::filesystem::exists(localRefFile)) throw; logError(e.info()); From c8b22643ba13b12f493e8b90dfa4b416bf267553 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 30 Jan 2025 18:57:43 +0100 Subject: [PATCH 31/60] readHead(): Make sure we're returning the HEAD ref line If we previously fetched by revision, the output of "git ls-remote" won't start with the expected line like ref: refs/heads/master HEAD but will be something like 5c4410e3b9891c05ab40d723de78c6f0be45ad30 refs/heads/5c4410e3b9891c05ab40d723de78c6f0be45ad30 This then causes Nix to treat that revision as a refname, which then leads to warnings like warning: could not update cached head '5c4410e3b9891c05ab40d723de78c6f0be45ad30' for 'file:///tmp/repo' --- src/libfetchers/git.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libfetchers/git.cc b/src/libfetchers/git.cc index 004123e27ab..46b6232de09 100644 --- a/src/libfetchers/git.cc +++ b/src/libfetchers/git.cc @@ -69,7 +69,7 @@ std::optional readHead(const Path & path) std::string_view line = output; line = line.substr(0, line.find("\n")); - if (const auto parseResult = git::parseLsRemoteLine(line)) { + if (const auto parseResult = git::parseLsRemoteLine(line); parseResult && parseResult->reference == "HEAD") { switch (parseResult->kind) { case git::LsRemoteRefLine::Kind::Symbolic: debug("resolved HEAD ref '%s' for repo '%s'", parseResult->target, path); From 7c8c71f8e9319b17e85c0f510bfd0d0558361ac2 Mon Sep 17 00:00:00 2001 From: Brian McKenna Date: Fri, 31 Jan 2025 21:11:45 +1100 Subject: [PATCH 32/60] Totally exclude nix::setStackSize on Windows --- src/libutil/current-process.cc | 4 ++-- src/libutil/current-process.hh | 3 +++ src/nix/main.cc | 2 ++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libutil/current-process.cc b/src/libutil/current-process.cc index 46e72b63ad1..255ae2cf561 100644 --- a/src/libutil/current-process.cc +++ b/src/libutil/current-process.cc @@ -51,11 +51,11 @@ unsigned int getMaxCPU() ////////////////////////////////////////////////////////////////////// +#ifndef _WIN32 size_t savedStackSize = 0; void setStackSize(size_t stackSize) { - #ifndef _WIN32 struct rlimit limit; if (getrlimit(RLIMIT_STACK, &limit) == 0 && limit.rlim_cur < stackSize) { savedStackSize = limit.rlim_cur; @@ -73,8 +73,8 @@ void setStackSize(size_t stackSize) ); } } - #endif } +#endif void restoreProcessContext(bool restoreMounts) { diff --git a/src/libutil/current-process.hh b/src/libutil/current-process.hh index 8286bf89d66..660dcfe0ba3 100644 --- a/src/libutil/current-process.hh +++ b/src/libutil/current-process.hh @@ -17,10 +17,13 @@ namespace nix { */ unsigned int getMaxCPU(); +// It does not seem possible to dynamically change stack size on Windows. +#ifndef _WIN32 /** * Change the stack size. */ void setStackSize(size_t stackSize); +#endif /** * Restore the original inherited Unix process context (such as signal diff --git a/src/nix/main.cc b/src/nix/main.cc index b0e26e093f1..80ef53084a4 100644 --- a/src/nix/main.cc +++ b/src/nix/main.cc @@ -557,9 +557,11 @@ void mainWrapped(int argc, char * * argv) int main(int argc, char * * argv) { +#ifndef _WIN32 // Increase the default stack size for the evaluator and for // libstdc++'s std::regex. nix::setStackSize(64 * 1024 * 1024); +#endif return nix::handleExceptions(argv[0], [&]() { nix::mainWrapped(argc, argv); From 26539a087f7e0ff95c82e6fcd16f0017f4243e7e Mon Sep 17 00:00:00 2001 From: Brian McKenna Date: Fri, 31 Jan 2025 22:52:57 +1100 Subject: [PATCH 33/60] Add mbig-obj flag to allow cross-compiling libexpr to mingw32 --- nix-meson-build-support/big-objs/meson.build | 4 ++++ src/libexpr/meson.build | 1 + 2 files changed, 5 insertions(+) create mode 100644 nix-meson-build-support/big-objs/meson.build diff --git a/nix-meson-build-support/big-objs/meson.build b/nix-meson-build-support/big-objs/meson.build new file mode 100644 index 00000000000..f5abd8bd8d2 --- /dev/null +++ b/nix-meson-build-support/big-objs/meson.build @@ -0,0 +1,4 @@ +# libexpr's primops creates a large object +# Without the following flag, we'll get errors when cross-compiling to mingw32: +# Fatal error: can't write 66 bytes to section .text of src/libexpr/libnixexpr.dll.p/primops.cc.obj: 'file too big' +add_project_arguments([ '-Wa,-mbig-obj' ], language: 'cpp') diff --git a/src/libexpr/meson.build b/src/libexpr/meson.build index b33aebc86a5..987300d58c1 100644 --- a/src/libexpr/meson.build +++ b/src/libexpr/meson.build @@ -24,6 +24,7 @@ deps_public_maybe_subproject = [ dependency('nix-fetchers'), ] subdir('nix-meson-build-support/subprojects') +subdir('nix-meson-build-support/big-objs') boost = dependency( 'boost', From 5f6658b9c909894a89da74c3f34b1ebe1434b8e7 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 28 Jan 2025 15:32:06 +0100 Subject: [PATCH 34/60] fetchTree: Distinguish between fetchGit and fetchTree consistently --- src/libexpr/primops/fetchTree.cc | 31 +++++++++---------- tests/functional/fetchGit.sh | 2 +- .../lang/eval-fail-fetchTree-negative.err.exp | 2 +- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index fe42b88f129..8c2d9ed06ad 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -90,24 +90,26 @@ static void fetchTree( fetchers::Input input { state.fetchSettings }; NixStringContext context; std::optional type; + auto fetcher = params.isFetchGit ? "fetchGit" : "fetchTree"; if (params.isFetchGit) type = "git"; state.forceValue(*args[0], pos); if (args[0]->type() == nAttrs) { - state.forceAttrs(*args[0], pos, "while evaluating the argument passed to builtins.fetchTree"); + state.forceAttrs(*args[0], pos, fmt("while evaluating the argument passed to '%s'", fetcher)); fetchers::Attrs attrs; if (auto aType = args[0]->attrs()->get(state.sType)) { if (type) state.error( - "unexpected attribute 'type'" + "unexpected argument 'type'" ).atPos(pos).debugThrow(); - type = state.forceStringNoCtx(*aType->value, aType->pos, "while evaluating the `type` attribute passed to builtins.fetchTree"); + type = state.forceStringNoCtx(*aType->value, aType->pos, + fmt("while evaluating the `type` argument passed to '%s'", fetcher)); } else if (!type) state.error( - "attribute 'type' is missing in call to 'fetchTree'" + "argument 'type' is missing in call to '%s'", fetcher ).atPos(pos).debugThrow(); attrs.emplace("type", type.value()); @@ -127,9 +129,8 @@ static void fetchTree( else if (attr.value->type() == nInt) { auto intValue = attr.value->integer().value; - if (intValue < 0) { - state.error("negative value given for fetchTree attr %1%: %2%", state.symbols[attr.name], intValue).atPos(pos).debugThrow(); - } + if (intValue < 0) + state.error("negative value given for '%s' argument '%s': %d", fetcher, state.symbols[attr.name], intValue).atPos(pos).debugThrow(); attrs.emplace(state.symbols[attr.name], uint64_t(intValue)); } else if (state.symbols[attr.name] == "publicKeys") { @@ -137,8 +138,8 @@ static void fetchTree( attrs.emplace(state.symbols[attr.name], printValueAsJSON(state, true, *attr.value, pos, context).dump()); } else - state.error("fetchTree argument '%s' is %s while a string, Boolean or integer is expected", - state.symbols[attr.name], showType(*attr.value)).debugThrow(); + state.error("argument '%s' to '%s' is %s while a string, Boolean or integer is expected", + state.symbols[attr.name], fetcher, showType(*attr.value)).debugThrow(); } if (params.isFetchGit && !attrs.contains("exportIgnore") && (!attrs.contains("submodules") || !*fetchers::maybeGetBoolAttr(attrs, "submodules"))) { @@ -153,14 +154,14 @@ static void fetchTree( if (!params.allowNameArgument) if (auto nameIter = attrs.find("name"); nameIter != attrs.end()) state.error( - "attribute 'name' isn’t supported in call to 'fetchTree'" + "argument 'name' isn’t supported in call to '%s'", fetcher ).atPos(pos).debugThrow(); input = fetchers::Input::fromAttrs(state.fetchSettings, std::move(attrs)); } else { auto url = state.coerceToString(pos, *args[0], context, - "while evaluating the first argument passed to the fetcher", - false, false).toOwned(); + fmt("while evaluating the first argument passed to '%s'", fetcher), + false, false).toOwned(); if (params.isFetchGit) { fetchers::Attrs attrs; @@ -173,7 +174,7 @@ static void fetchTree( } else { if (!experimentalFeatureSettings.isEnabled(Xp::Flakes)) state.error( - "passing a string argument to 'fetchTree' requires the 'flakes' experimental feature" + "passing a string argument to '%s' requires the 'flakes' experimental feature", fetcher ).atPos(pos).debugThrow(); input = fetchers::Input::fromURL(state.fetchSettings, url); } @@ -183,10 +184,6 @@ static void fetchTree( input = lookupInRegistries(state.store, input).first; if (state.settings.pureEval && !input.isConsideredLocked(state.fetchSettings)) { - auto fetcher = "fetchTree"; - if (params.isFetchGit) - fetcher = "fetchGit"; - state.error( "in pure evaluation mode, '%s' will not fetch unlocked input '%s'", fetcher, input.to_string() diff --git a/tests/functional/fetchGit.sh b/tests/functional/fetchGit.sh index 78925b5cdd6..2056117cea5 100755 --- a/tests/functional/fetchGit.sh +++ b/tests/functional/fetchGit.sh @@ -79,7 +79,7 @@ path2=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$repo; rev = \" # In pure eval mode, fetchGit with a revision should succeed. [[ $(nix eval --raw --expr "builtins.readFile (fetchGit { url = file://$repo; rev = \"$rev2\"; } + \"/hello\")") = world ]] -# But without a hash, it fails +# But without a hash, it fails. expectStderr 1 nix eval --expr 'builtins.fetchGit "file:///foo"' | grepQuiet "'fetchGit' will not fetch unlocked input" # Fetch again. This should be cached. diff --git a/tests/functional/lang/eval-fail-fetchTree-negative.err.exp b/tests/functional/lang/eval-fail-fetchTree-negative.err.exp index d9ba1f0b2f8..423123ca0a7 100644 --- a/tests/functional/lang/eval-fail-fetchTree-negative.err.exp +++ b/tests/functional/lang/eval-fail-fetchTree-negative.err.exp @@ -5,4 +5,4 @@ error: | ^ 2| type = "file"; - error: negative value given for fetchTree attr owner: -1 + error: negative value given for 'fetchTree' argument 'owner': -1 From a142803c282a68c1ba21390bcaf0cef0310271a0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 28 Jan 2025 21:39:32 +0100 Subject: [PATCH 35/60] tests/functional/fetchGit.sh: Drop unnecessary --impure flags --- tests/functional/fetchGit.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/functional/fetchGit.sh b/tests/functional/fetchGit.sh index 2056117cea5..6c86b20aaab 100755 --- a/tests/functional/fetchGit.sh +++ b/tests/functional/fetchGit.sh @@ -64,7 +64,7 @@ git -C $repo add differentbranch git -C $repo commit -m 'Test2' git -C $repo checkout master devrev=$(git -C $repo rev-parse devtest) -nix eval --impure --raw --expr "builtins.fetchGit { url = file://$repo; rev = \"$devrev\"; }" +nix eval --raw --expr "builtins.fetchGit { url = file://$repo; rev = \"$devrev\"; }" [[ $(nix eval --raw --expr "builtins.readFile (builtins.fetchGit { url = file://$repo; rev = \"$devrev\"; allRefs = true; } + \"/differentbranch\")") = 'different file' ]] @@ -142,10 +142,10 @@ path4=$(nix eval --impure --refresh --raw --expr "(builtins.fetchGit file://$rep [[ $(nix eval --impure --expr "builtins.hasAttr \"dirtyShortRev\" (builtins.fetchGit $repo)") == "false" ]] status=0 -nix eval --impure --raw --expr "(builtins.fetchGit { url = $repo; rev = \"$rev2\"; narHash = \"sha256-B5yIPHhEm0eysJKEsO7nqxprh9vcblFxpJG11gXJus1=\"; }).outPath" || status=$? +nix eval --raw --expr "(builtins.fetchGit { url = $repo; rev = \"$rev2\"; narHash = \"sha256-B5yIPHhEm0eysJKEsO7nqxprh9vcblFxpJG11gXJus1=\"; }).outPath" || status=$? [[ "$status" = "102" ]] -path5=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = $repo; rev = \"$rev2\"; narHash = \"sha256-Hr8g6AqANb3xqX28eu1XnjK/3ab8Gv6TJSnkb1LezG9=\"; }).outPath") +path5=$(nix eval --raw --expr "(builtins.fetchGit { url = $repo; rev = \"$rev2\"; narHash = \"sha256-Hr8g6AqANb3xqX28eu1XnjK/3ab8Gv6TJSnkb1LezG9=\"; }).outPath") [[ $path = $path5 ]] # tarball-ttl should be ignored if we specify a rev @@ -255,7 +255,7 @@ echo "/exported-wonky export-ignore=wonk" >> $repo/.gitattributes git -C $repo add not-exported-file exported-wonky .gitattributes git -C $repo commit -m 'Bla6' rev5=$(git -C $repo rev-parse HEAD) -path12=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = file://$repo; rev = \"$rev5\"; }).outPath") +path12=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$repo; rev = \"$rev5\"; }).outPath") [[ ! -e $path12/not-exported-file ]] [[ -e $path12/exported-wonky ]] From 5dec1dc086aa173c74644c4e3b46e97620f61dce Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 28 Jan 2025 21:53:57 +0100 Subject: [PATCH 36/60] fetchGit/fetchTree: Allow fetching using only a NAR hash Fixes #12027. --- src/libexpr/primops/fetchTree.cc | 13 +++++++++---- tests/functional/fetchGit.sh | 7 ++++--- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index 8c2d9ed06ad..ddbd899e724 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -184,10 +184,15 @@ static void fetchTree( input = lookupInRegistries(state.store, input).first; if (state.settings.pureEval && !input.isConsideredLocked(state.fetchSettings)) { - state.error( - "in pure evaluation mode, '%s' will not fetch unlocked input '%s'", - fetcher, input.to_string() - ).atPos(pos).debugThrow(); + if (input.getNarHash()) + warn( + "Input '%s' is unlocked (e.g. lacks a Git revision) but does have a NAR hash. " + "This is deprecated since such inputs are verifiable but may not be reproducible.", + input.to_string()); + else + state.error( + "in pure evaluation mode, '%s' will not fetch unlocked input '%s'", + fetcher, input.to_string()).atPos(pos).debugThrow(); } state.checkURI(input.toURLString()); diff --git a/tests/functional/fetchGit.sh b/tests/functional/fetchGit.sh index 6c86b20aaab..3bd4dcaa6b2 100755 --- a/tests/functional/fetchGit.sh +++ b/tests/functional/fetchGit.sh @@ -141,13 +141,14 @@ path4=$(nix eval --impure --refresh --raw --expr "(builtins.fetchGit file://$rep [[ $(nix eval --impure --expr "builtins.hasAttr \"dirtyRev\" (builtins.fetchGit $repo)") == "false" ]] [[ $(nix eval --impure --expr "builtins.hasAttr \"dirtyShortRev\" (builtins.fetchGit $repo)") == "false" ]] -status=0 -nix eval --raw --expr "(builtins.fetchGit { url = $repo; rev = \"$rev2\"; narHash = \"sha256-B5yIPHhEm0eysJKEsO7nqxprh9vcblFxpJG11gXJus1=\"; }).outPath" || status=$? -[[ "$status" = "102" ]] +expect 102 nix eval --raw --expr "(builtins.fetchGit { url = $repo; rev = \"$rev2\"; narHash = \"sha256-B5yIPHhEm0eysJKEsO7nqxprh9vcblFxpJG11gXJus1=\"; }).outPath" path5=$(nix eval --raw --expr "(builtins.fetchGit { url = $repo; rev = \"$rev2\"; narHash = \"sha256-Hr8g6AqANb3xqX28eu1XnjK/3ab8Gv6TJSnkb1LezG9=\"; }).outPath") [[ $path = $path5 ]] +# It's allowed to use only a narHash, but you should get a warning. +expectStderr 0 nix eval --raw --expr "(builtins.fetchGit { url = $repo; ref = \"tag2\"; narHash = \"sha256-Hr8g6AqANb3xqX28eu1XnjK/3ab8Gv6TJSnkb1LezG9=\"; }).outPath" | grepQuiet "warning: Input .* is unlocked" + # tarball-ttl should be ignored if we specify a rev echo delft > $repo/hello git -C $repo add hello From 4113fdf2f05b5145d5f649f4393758606e2e2c97 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 28 Jan 2025 22:07:50 +0100 Subject: [PATCH 37/60] Allow use of lock files with unlocked entries as long as they have a NAR hash Fixes #12364. --- src/libflake/flake/lockfile.cc | 13 ++++++++++--- tests/functional/flakes/unlocked-override.sh | 8 ++++---- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/libflake/flake/lockfile.cc b/src/libflake/flake/lockfile.cc index 25e7299f0a0..e3bf22c21df 100644 --- a/src/libflake/flake/lockfile.cc +++ b/src/libflake/flake/lockfile.cc @@ -45,9 +45,16 @@ LockedNode::LockedNode( , isFlake(json.find("flake") != json.end() ? (bool) json["flake"] : true) , parentInputAttrPath(json.find("parent") != json.end() ? (std::optional) json["parent"] : std::nullopt) { - if (!lockedRef.input.isConsideredLocked(fetchSettings) && !lockedRef.input.isRelative()) - throw Error("Lock file contains unlocked input '%s'. Use '--allow-dirty-locks' to accept this lock file.", - fetchers::attrsToJSON(lockedRef.input.toAttrs())); + if (!lockedRef.input.isLocked() && !lockedRef.input.isRelative()) { + if (lockedRef.input.getNarHash()) + warn( + "Lock file entry '%s' is unlocked (e.g. lacks a Git revision) but does have a NAR hash. " + "This is deprecated since such inputs are verifiable but may not be reproducible.", + lockedRef.to_string()); + else + throw Error("Lock file contains unlocked input '%s'. Use '--allow-dirty-locks' to accept this lock file.", + fetchers::attrsToJSON(lockedRef.input.toAttrs())); + } // For backward compatibility, lock file entries are implicitly final. assert(!lockedRef.input.attrs.contains("__final")); diff --git a/tests/functional/flakes/unlocked-override.sh b/tests/functional/flakes/unlocked-override.sh index dcb427a8fcc..512aca401d3 100755 --- a/tests/functional/flakes/unlocked-override.sh +++ b/tests/functional/flakes/unlocked-override.sh @@ -37,8 +37,8 @@ expectStderr 1 nix flake lock "$flake2Dir" --override-input flake1 "$TEST_ROOT/f nix flake lock "$flake2Dir" --override-input flake1 "$TEST_ROOT/flake1" --allow-dirty-locks -# Using a lock file with a dirty lock requires --allow-dirty-locks as well. -expectStderr 1 nix eval "$flake2Dir#x" | - grepQuiet "Lock file contains unlocked input" +# Using a lock file with a dirty lock does not require --allow-dirty-locks, but should print a warning. +expectStderr 0 nix eval "$flake2Dir#x" | + grepQuiet "warning: Lock file entry .* is unlocked" -[[ $(nix eval "$flake2Dir#x" --allow-dirty-locks) = 456 ]] +[[ $(nix eval "$flake2Dir#x") = 456 ]] From 9e240eccede1b9444cb63ca00814af4235956024 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 28 Jan 2025 22:14:49 +0100 Subject: [PATCH 38/60] Remove isConsideredLocked() --- src/libexpr/primops/fetchTree.cc | 2 +- src/libfetchers/fetchers.cc | 6 ------ src/libfetchers/fetchers.hh | 9 --------- src/libflake/flake/lockfile.cc | 16 +++++++++++++--- 4 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index ddbd899e724..c4b8b2999c5 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -183,7 +183,7 @@ static void fetchTree( if (!state.settings.pureEval && !input.isDirect() && experimentalFeatureSettings.isEnabled(Xp::Flakes)) input = lookupInRegistries(state.store, input).first; - if (state.settings.pureEval && !input.isConsideredLocked(state.fetchSettings)) { + if (state.settings.pureEval && !input.isLocked()) { if (input.getNarHash()) warn( "Input '%s' is unlocked (e.g. lacks a Git revision) but does have a NAR hash. " diff --git a/src/libfetchers/fetchers.cc b/src/libfetchers/fetchers.cc index 9459db087ff..aadeecba226 100644 --- a/src/libfetchers/fetchers.cc +++ b/src/libfetchers/fetchers.cc @@ -155,12 +155,6 @@ bool Input::isLocked() const return scheme && scheme->isLocked(*this); } -bool Input::isConsideredLocked( - const Settings & settings) const -{ - return isLocked() || (settings.allowDirtyLocks && getNarHash()); -} - bool Input::isFinal() const { return maybeGetBoolAttr(attrs, "__final").value_or(false); diff --git a/src/libfetchers/fetchers.hh b/src/libfetchers/fetchers.hh index 644c267c17f..37de1f507d9 100644 --- a/src/libfetchers/fetchers.hh +++ b/src/libfetchers/fetchers.hh @@ -90,15 +90,6 @@ public: */ bool isLocked() const; - /** - * Return whether the input is either locked, or, if - * `allow-dirty-locks` is enabled, it has a NAR hash. In the - * latter case, we can verify the input but we may not be able to - * fetch it from anywhere. - */ - bool isConsideredLocked( - const Settings & settings) const; - /** * Only for relative path flakes, i.e. 'path:./foo', returns the * relative path, i.e. './foo'. diff --git a/src/libflake/flake/lockfile.cc b/src/libflake/flake/lockfile.cc index e3bf22c21df..b0971a6969a 100644 --- a/src/libflake/flake/lockfile.cc +++ b/src/libflake/flake/lockfile.cc @@ -1,7 +1,10 @@ #include +#include "fetch-settings.hh" +#include "flake/settings.hh" #include "lockfile.hh" #include "store-api.hh" +#include "strings.hh" #include #include @@ -9,8 +12,6 @@ #include #include -#include "strings.hh" -#include "flake/settings.hh" namespace nix::flake { @@ -255,11 +256,20 @@ std::optional LockFile::isUnlocked(const fetchers::Settings & fetchSet visit(root); + /* Return whether the input is either locked, or, if + `allow-dirty-locks` is enabled, it has a NAR hash. In the + latter case, we can verify the input but we may not be able to + fetch it from anywhere. */ + auto isConsideredLocked = [&](const fetchers::Input & input) + { + return input.isLocked() || (fetchSettings.allowDirtyLocks && input.getNarHash()); + }; + for (auto & i : nodes) { if (i == ref(root)) continue; auto node = i.dynamic_pointer_cast(); if (node - && (!node->lockedRef.input.isConsideredLocked(fetchSettings) + && (!isConsideredLocked(node->lockedRef.input) || !node->lockedRef.input.isFinal()) && !node->lockedRef.input.isRelative()) return node->lockedRef; From 8006196c55362685e576cda6b61513424daaaf33 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 29 Jan 2025 12:47:11 +0100 Subject: [PATCH 39/60] tests/functional/fetchGit.sh: Add a test for NAR hash mismatches --- tests/functional/fetchGit.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/functional/fetchGit.sh b/tests/functional/fetchGit.sh index 3bd4dcaa6b2..54be96da982 100755 --- a/tests/functional/fetchGit.sh +++ b/tests/functional/fetchGit.sh @@ -146,6 +146,9 @@ expect 102 nix eval --raw --expr "(builtins.fetchGit { url = $repo; rev = \"$rev path5=$(nix eval --raw --expr "(builtins.fetchGit { url = $repo; rev = \"$rev2\"; narHash = \"sha256-Hr8g6AqANb3xqX28eu1XnjK/3ab8Gv6TJSnkb1LezG9=\"; }).outPath") [[ $path = $path5 ]] +# Ensure that NAR hashes are checked. +expectStderr 102 nix eval --raw --expr "(builtins.fetchGit { url = $repo; rev = \"$rev2\"; narHash = \"sha256-Hr8g6AqANb4xqX28eu1XnjK/3ab8Gv6TJSnkb1LezG9=\"; }).outPath" | grepQuiet "error: NAR hash mismatch" + # It's allowed to use only a narHash, but you should get a warning. expectStderr 0 nix eval --raw --expr "(builtins.fetchGit { url = $repo; ref = \"tag2\"; narHash = \"sha256-Hr8g6AqANb3xqX28eu1XnjK/3ab8Gv6TJSnkb1LezG9=\"; }).outPath" | grepQuiet "warning: Input .* is unlocked" From f62a28716301a1176aa5d6b6c6a13f11d0f4f99f Mon Sep 17 00:00:00 2001 From: Brian McKenna Date: Sat, 1 Feb 2025 21:36:50 +1100 Subject: [PATCH 40/60] Only enable big-obj on Windows --- nix-meson-build-support/big-objs/meson.build | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/nix-meson-build-support/big-objs/meson.build b/nix-meson-build-support/big-objs/meson.build index f5abd8bd8d2..7e422abd86e 100644 --- a/nix-meson-build-support/big-objs/meson.build +++ b/nix-meson-build-support/big-objs/meson.build @@ -1,4 +1,6 @@ -# libexpr's primops creates a large object -# Without the following flag, we'll get errors when cross-compiling to mingw32: -# Fatal error: can't write 66 bytes to section .text of src/libexpr/libnixexpr.dll.p/primops.cc.obj: 'file too big' -add_project_arguments([ '-Wa,-mbig-obj' ], language: 'cpp') +if host_machine.system() == 'windows' + # libexpr's primops creates a large object + # Without the following flag, we'll get errors when cross-compiling to mingw32: + # Fatal error: can't write 66 bytes to section .text of src/libexpr/libnixexpr.dll.p/primops.cc.obj: 'file too big' + add_project_arguments([ '-Wa,-mbig-obj' ], language: 'cpp') +endif From 453e8dc067e77d5d81cad5a533f99fdc33bcf2a1 Mon Sep 17 00:00:00 2001 From: Steve Walker <65963536+etherswangel@users.noreply.github.com> Date: Fri, 17 Jan 2025 22:17:39 +0800 Subject: [PATCH 41/60] Fix flakes follow symlinks Co-authored-by: Jan Christoph Bischko --- src/libflake/flake/flakeref.cc | 2 +- tests/functional/flakes/meson.build | 1 + tests/functional/flakes/symlink-paths.sh | 75 ++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 tests/functional/flakes/symlink-paths.sh diff --git a/src/libflake/flake/flakeref.cc b/src/libflake/flake/flakeref.cc index 720f771ab09..fbe61c294dc 100644 --- a/src/libflake/flake/flakeref.cc +++ b/src/libflake/flake/flakeref.cc @@ -107,7 +107,7 @@ std::pair parsePathFlakeRefWithFragment( to 'baseDir'). If so, search upward to the root of the repo (i.e. the directory containing .git). */ - path = absPath(path, baseDir); + path = absPath(path, baseDir, true); if (isFlake) { diff --git a/tests/functional/flakes/meson.build b/tests/functional/flakes/meson.build index cc65dc306a1..af7fb304b7a 100644 --- a/tests/functional/flakes/meson.build +++ b/tests/functional/flakes/meson.build @@ -28,6 +28,7 @@ suites += { 'commit-lock-file-summary.sh', 'non-flake-inputs.sh', 'relative-paths.sh', + 'symlink-paths.sh' ], 'workdir': meson.current_source_dir(), } diff --git a/tests/functional/flakes/symlink-paths.sh b/tests/functional/flakes/symlink-paths.sh new file mode 100644 index 00000000000..2559e81073a --- /dev/null +++ b/tests/functional/flakes/symlink-paths.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash + +source ./common.sh + +requireGit + +create_flake() { + local flakeDir="$1" + createGitRepo $flakeDir + cat > $flakeDir/flake.nix < $repoDir/subdir/flake.nix < $repoDir/file + mkdir $repoDir/subdir + cat > $repoDir/subdir/flake.nix < $repo2Dir/file + git -C "$repo2Dir" add flake1_sym file + git -C "$repo2Dir" commit -m Initial + [[ $(nix eval "$repo2Dir/flake1_sym#x") == \"Hello\\n\" ]] + rm -rf "$TEST_ROOT/repo1" "$TEST_ROOT/repo2" +} +test_symlink_from_repo_to_another From 803fb83f7ffb3bd5e2e1ee3bb9ce3ea3001bec2c Mon Sep 17 00:00:00 2001 From: Illia Bobyr Date: Mon, 13 Jan 2025 18:19:16 -0800 Subject: [PATCH 42/60] nix-profile.fish: Typo NIX_SS{H => L}_CERT_FILE --- scripts/nix-profile.fish.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/nix-profile.fish.in b/scripts/nix-profile.fish.in index dd2fbe2090f..53ad8efd056 100644 --- a/scripts/nix-profile.fish.in +++ b/scripts/nix-profile.fish.in @@ -39,7 +39,7 @@ else end # Set $NIX_SSL_CERT_FILE so that Nixpkgs applications like curl work. -if test -n "$NIX_SSH_CERT_FILE" +if test -n "$NIX_SSL_CERT_FILE" : # Allow users to override the NIX_SSL_CERT_FILE else if test -e /etc/ssl/certs/ca-certificates.crt # NixOS, Ubuntu, Debian, Gentoo, Arch set --export NIX_SSL_CERT_FILE /etc/ssl/certs/ca-certificates.crt From 243467e14bf7afc5c40284c7e1209a3cd0e617a7 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Mon, 3 Feb 2025 10:05:56 -0500 Subject: [PATCH 43/60] More debugging documentation There are a few things I think people should know, post-Meson. --- doc/manual/source/development/building.md | 20 +++++------------ doc/manual/source/development/debugging.md | 11 +++++++++ doc/manual/source/development/testing.md | 26 +++++++++++++++++++--- 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/doc/manual/source/development/building.md b/doc/manual/source/development/building.md index a60543f4de2..c5a173dc744 100644 --- a/doc/manual/source/development/building.md +++ b/doc/manual/source/development/building.md @@ -167,24 +167,18 @@ It is useful to perform multiple cross and native builds on the same source tree for example to ensure that better support for one platform doesn't break the build for another. Meson thankfully makes this very easy by confining all build products to the build directory --- one simple shares the source directory between multiple build directories, each of which contains the build for Nix to a different platform. -Nixpkgs's `configurePhase` always chooses `build` in the current directory as the name and location of the build. -This makes having multiple build directories slightly more inconvenient. -The good news is that Meson/Ninja seem to cope well with relocating the build directory after it is created. +Here's how to do that: -Here's how to do that - -1. Configure as usual +1. Instruct Nixpkgs's infra where we want Meson to put its build directory ```bash - configurePhase + mesonBuildDir=build-my-variant-name ``` -2. Rename the build directory +1. Configure as usual ```bash - cd .. # since `configurePhase` cd'd inside - mv build build-linux # or whatever name we want - cd build-linux + configurePhase ``` 3. Build as usual @@ -193,10 +187,6 @@ Here's how to do that buildPhase ``` -> **N.B.** -> [`nixpkgs#335818`](https://github.com/NixOS/nixpkgs/issues/335818) tracks giving `mesonConfigurePhase` proper support for custom build directories. -> When it is fixed, we can simplify these instructions and then remove this notice. - ## System type Nix uses a string with the following format to identify the *system type* or *platform* it runs on: diff --git a/doc/manual/source/development/debugging.md b/doc/manual/source/development/debugging.md index ce623110b36..98456841af1 100644 --- a/doc/manual/source/development/debugging.md +++ b/doc/manual/source/development/debugging.md @@ -2,6 +2,8 @@ This section shows how to build and debug Nix with debug symbols enabled. +Additionally, see [Testing Nix](./testing.md) for further instructions on how to debug Nix in the context of a unit test or functional test. + ## Building Nix with Debug Symbols In the development shell, set the `mesonBuildType` environment variable to `debug` before configuring the build: @@ -13,6 +15,15 @@ In the development shell, set the `mesonBuildType` environment variable to `debu Then, proceed to build Nix as described in [Building Nix](./building.md). This will build Nix with debug symbols, which are essential for effective debugging. +It is also possible to build without debugging for faster build: + +```console +[nix-shell]$ NIX_HARDENING_ENABLE=$(printLines $NIX_HARDENING_ENABLE | grep -v fortify) +[nix-shell]$ export mesonBuildType=debug +``` + +(The first line is needed because `fortify` hardening requires at least some optimization.) + ## Debugging the Nix Binary Obtain your preferred debugger within the development shell: diff --git a/doc/manual/source/development/testing.md b/doc/manual/source/development/testing.md index d582ce4b413..7d8a9cb18e8 100644 --- a/doc/manual/source/development/testing.md +++ b/doc/manual/source/development/testing.md @@ -87,7 +87,11 @@ A environment variables that Google Test accepts are also worth knowing: This is used to avoid logging passing tests. -Putting the two together, one might run +3. [`GTEST_BREAK_ON_FAILURE`](https://google.github.io/googletest/advanced.html#turning-assertion-failures-into-break-points) + + This is used to create a debugger breakpoint when an assertion failure occurs. + +Putting the first two together, one might run ```bash GTEST_BRIEF=1 GTEST_FILTER='ErrorTraceTest.*' meson test nix-expr-tests -v @@ -95,6 +99,22 @@ GTEST_BRIEF=1 GTEST_FILTER='ErrorTraceTest.*' meson test nix-expr-tests -v for short but comprensive output. +### Debugging tests + +For debugging, it is useful to combine the third option above with Meson's [`--gdb`](https://mesonbuild.com/Unit-tests.html#other-test-options) flag: + +```bash +GTEST_BRIEF=1 GTEST_FILTER='Group.my-failing-test' meson test nix-expr-tests --gdb +``` + +This will: + +1. Run the unit test with GDB + +2. Run just `Group.my-failing-test` + +3. Stop the program when the test fails, allowing the user to then issue arbitrary commands to GDB. + ### Characterisation testing { #characaterisation-testing-unit } See [functional characterisation testing](#characterisation-testing-functional) for a broader discussion of characterisation testing. @@ -213,10 +233,10 @@ edit it like so: bar ``` -Then, running the test with `./mk/debug-test.sh` will drop you into GDB once the script reaches that point: +Then, running the test with [`--interactive`](https://mesonbuild.com/Unit-tests.html#other-test-options) will prevent Meson from hijacking the terminal so you can drop you into GDB once the script reaches that point: ```shell-session -$ ./mk/debug-test.sh tests/functional/${testName}.sh +$ meson test ${testName} --interactive ... + gdb blash blub GNU gdb (GDB) 12.1 From 53946fe0171cc30259940b2ac83a6e03782b3bf5 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sat, 1 Feb 2025 18:33:00 -0500 Subject: [PATCH 44/60] Narrow scope on some local variables --- src/libstore/build/derivation-goal.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libstore/build/derivation-goal.cc b/src/libstore/build/derivation-goal.cc index 4d97250d3af..401e2cda1e4 100644 --- a/src/libstore/build/derivation-goal.cc +++ b/src/libstore/build/derivation-goal.cc @@ -235,12 +235,14 @@ Goal::Co DerivationGoal::haveDerivation() } }); - /* Check what outputs paths are not already valid. */ - auto [allValid, validOutputs] = checkPathValidity(); + { + /* Check what outputs paths are not already valid. */ + auto [allValid, validOutputs] = checkPathValidity(); - /* If they are all valid, then we're done. */ - if (allValid && buildMode == bmNormal) { - co_return done(BuildResult::AlreadyValid, std::move(validOutputs)); + /* If they are all valid, then we're done. */ + if (allValid && buildMode == bmNormal) { + co_return done(BuildResult::AlreadyValid, std::move(validOutputs)); + } } /* We are first going to try to create the invalid output paths From 41274f3c3e82d3b7f13147f1828890c1e0e8d141 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sat, 1 Feb 2025 18:33:58 -0500 Subject: [PATCH 45/60] Inline `outputsSubstitutionTried` --- src/libstore/build/derivation-goal.cc | 5 ----- src/libstore/build/derivation-goal.hh | 1 - 2 files changed, 6 deletions(-) diff --git a/src/libstore/build/derivation-goal.cc b/src/libstore/build/derivation-goal.cc index 401e2cda1e4..2993333fd5a 100644 --- a/src/libstore/build/derivation-goal.cc +++ b/src/libstore/build/derivation-goal.cc @@ -270,12 +270,7 @@ Goal::Co DerivationGoal::haveDerivation() } if (!waitees.empty()) co_await Suspend{}; /* to prevent hang (no wake-up event) */ - co_return outputsSubstitutionTried(); -} - -Goal::Co DerivationGoal::outputsSubstitutionTried() -{ trace("all outputs substituted (maybe)"); assert(!drv->type().isImpure()); diff --git a/src/libstore/build/derivation-goal.hh b/src/libstore/build/derivation-goal.hh index ad3d9ca2acf..82fee353909 100644 --- a/src/libstore/build/derivation-goal.hh +++ b/src/libstore/build/derivation-goal.hh @@ -236,7 +236,6 @@ struct DerivationGoal : public Goal Co getDerivation(); Co loadDerivation(); Co haveDerivation(); - Co outputsSubstitutionTried(); Co gaveUpOnSubstitution(); Co closureRepaired(); Co inputsRealised(); From 57463ab910bf5ca31342e73f8f413d67128fb957 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sat, 1 Feb 2025 18:36:58 -0500 Subject: [PATCH 46/60] Inline `closureRepaired` --- src/libstore/build/derivation-goal.cc | 17 ++++++----------- src/libstore/build/derivation-goal.hh | 1 - 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/libstore/build/derivation-goal.cc b/src/libstore/build/derivation-goal.cc index 2993333fd5a..4d0a7ebc78d 100644 --- a/src/libstore/build/derivation-goal.cc +++ b/src/libstore/build/derivation-goal.cc @@ -457,18 +457,13 @@ Goal::Co DerivationGoal::repairClosure() co_return done(BuildResult::AlreadyValid, assertPathValidity()); } else { co_await Suspend{}; - co_return closureRepaired(); - } -} - -Goal::Co DerivationGoal::closureRepaired() -{ - trace("closure repaired"); - if (nrFailed > 0) - throw Error("some paths in the output closure of derivation '%s' could not be repaired", - worker.store.printStorePath(drvPath)); - co_return done(BuildResult::AlreadyValid, assertPathValidity()); + trace("closure repaired"); + if (nrFailed > 0) + throw Error("some paths in the output closure of derivation '%s' could not be repaired", + worker.store.printStorePath(drvPath)); + co_return done(BuildResult::AlreadyValid, assertPathValidity()); + } } diff --git a/src/libstore/build/derivation-goal.hh b/src/libstore/build/derivation-goal.hh index 82fee353909..c21a12e4aab 100644 --- a/src/libstore/build/derivation-goal.hh +++ b/src/libstore/build/derivation-goal.hh @@ -237,7 +237,6 @@ struct DerivationGoal : public Goal Co loadDerivation(); Co haveDerivation(); Co gaveUpOnSubstitution(); - Co closureRepaired(); Co inputsRealised(); Co tryToBuild(); virtual Co tryLocalBuild(); From 2297cc0daba549a1b8d2278ffb02bb3edd734f38 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sat, 1 Feb 2025 18:56:42 -0500 Subject: [PATCH 47/60] Inline `getDerivation` and `loadDerivation` --- src/libstore/build/derivation-goal.cc | 68 +++++++++++---------------- src/libstore/build/derivation-goal.hh | 2 - 2 files changed, 27 insertions(+), 43 deletions(-) diff --git a/src/libstore/build/derivation-goal.cc b/src/libstore/build/derivation-goal.cc index 4d0a7ebc78d..70d2d30b192 100644 --- a/src/libstore/build/derivation-goal.cc +++ b/src/libstore/build/derivation-goal.cc @@ -36,14 +36,6 @@ namespace nix { -Goal::Co DerivationGoal::init() { - if (useDerivation) { - co_return getDerivation(); - } else { - co_return haveDerivation(); - } -} - DerivationGoal::DerivationGoal(const StorePath & drvPath, const OutputsSpec & wantedOutputs, Worker & worker, BuildMode buildMode) : Goal(worker, DerivedPath::Built { .drvPath = makeConstantStorePathRef(drvPath), .outputs = wantedOutputs }) @@ -141,50 +133,44 @@ void DerivationGoal::addWantedOutputs(const OutputsSpec & outputs) } -Goal::Co DerivationGoal::getDerivation() -{ +Goal::Co DerivationGoal::init() { trace("init"); - /* The first thing to do is to make sure that the derivation - exists. If it doesn't, it may be created through a - substitute. */ - if (buildMode == bmNormal && worker.evalStore.isValidPath(drvPath)) { - co_return loadDerivation(); - } - - addWaitee(upcast_goal(worker.makePathSubstitutionGoal(drvPath))); - - co_await Suspend{}; - co_return loadDerivation(); -} + if (useDerivation) { + /* The first thing to do is to make sure that the derivation + exists. If it doesn't, it may be created through a + substitute. */ + if (buildMode != bmNormal || !worker.evalStore.isValidPath(drvPath)) { + addWaitee(upcast_goal(worker.makePathSubstitutionGoal(drvPath))); + co_await Suspend{}; + } -Goal::Co DerivationGoal::loadDerivation() -{ - trace("loading derivation"); + trace("loading derivation"); - if (nrFailed != 0) { - co_return done(BuildResult::MiscFailure, {}, Error("cannot build missing derivation '%s'", worker.store.printStorePath(drvPath))); - } + if (nrFailed != 0) { + co_return done(BuildResult::MiscFailure, {}, Error("cannot build missing derivation '%s'", worker.store.printStorePath(drvPath))); + } - /* `drvPath' should already be a root, but let's be on the safe - side: if the user forgot to make it a root, we wouldn't want - things being garbage collected while we're busy. */ - worker.evalStore.addTempRoot(drvPath); + /* `drvPath' should already be a root, but let's be on the safe + side: if the user forgot to make it a root, we wouldn't want + things being garbage collected while we're busy. */ + worker.evalStore.addTempRoot(drvPath); - /* Get the derivation. It is probably in the eval store, but it might be inthe main store: + /* Get the derivation. It is probably in the eval store, but it might be inthe main store: - - Resolved derivation are resolved against main store realisations, and so must be stored there. + - Resolved derivation are resolved against main store realisations, and so must be stored there. - - Dynamic derivations are built, and so are found in the main store. - */ - for (auto * drvStore : { &worker.evalStore, &worker.store }) { - if (drvStore->isValidPath(drvPath)) { - drv = std::make_unique(drvStore->readDerivation(drvPath)); - break; + - Dynamic derivations are built, and so are found in the main store. + */ + for (auto * drvStore : { &worker.evalStore, &worker.store }) { + if (drvStore->isValidPath(drvPath)) { + drv = std::make_unique(drvStore->readDerivation(drvPath)); + break; + } } + assert(drv); } - assert(drv); co_return haveDerivation(); } diff --git a/src/libstore/build/derivation-goal.hh b/src/libstore/build/derivation-goal.hh index c21a12e4aab..652fca0352a 100644 --- a/src/libstore/build/derivation-goal.hh +++ b/src/libstore/build/derivation-goal.hh @@ -233,8 +233,6 @@ struct DerivationGoal : public Goal * The states. */ Co init() override; - Co getDerivation(); - Co loadDerivation(); Co haveDerivation(); Co gaveUpOnSubstitution(); Co inputsRealised(); From 4b1753e66164297b4930046200e71e26e4ac2728 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sat, 1 Feb 2025 18:37:54 -0500 Subject: [PATCH 48/60] Move `repairClosure` This is necessary in order to inline `inputsRealised` in the next commit by combing it with its adjacent function (i.e. with a small diff). --- src/libstore/build/derivation-goal.cc | 134 +++++++++++++------------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/src/libstore/build/derivation-goal.cc b/src/libstore/build/derivation-goal.cc index 70d2d30b192..344b2b5a7ae 100644 --- a/src/libstore/build/derivation-goal.cc +++ b/src/libstore/build/derivation-goal.cc @@ -386,73 +386,6 @@ Goal::Co DerivationGoal::gaveUpOnSubstitution() } -Goal::Co DerivationGoal::repairClosure() -{ - assert(!drv->type().isImpure()); - - /* If we're repairing, we now know that our own outputs are valid. - Now check whether the other paths in the outputs closure are - good. If not, then start derivation goals for the derivations - that produced those outputs. */ - - /* Get the output closure. */ - auto outputs = queryDerivationOutputMap(); - StorePathSet outputClosure; - for (auto & i : outputs) { - if (!wantedOutputs.contains(i.first)) continue; - worker.store.computeFSClosure(i.second, outputClosure); - } - - /* Filter out our own outputs (which we have already checked). */ - for (auto & i : outputs) - outputClosure.erase(i.second); - - /* Get all dependencies of this derivation so that we know which - derivation is responsible for which path in the output - closure. */ - StorePathSet inputClosure; - if (useDerivation) worker.store.computeFSClosure(drvPath, inputClosure); - std::map outputsToDrv; - for (auto & i : inputClosure) - if (i.isDerivation()) { - auto depOutputs = worker.store.queryPartialDerivationOutputMap(i, &worker.evalStore); - for (auto & j : depOutputs) - if (j.second) - outputsToDrv.insert_or_assign(*j.second, i); - } - - /* Check each path (slow!). */ - for (auto & i : outputClosure) { - if (worker.pathContentsGood(i)) continue; - printError( - "found corrupted or missing path '%s' in the output closure of '%s'", - worker.store.printStorePath(i), worker.store.printStorePath(drvPath)); - auto drvPath2 = outputsToDrv.find(i); - if (drvPath2 == outputsToDrv.end()) - addWaitee(upcast_goal(worker.makePathSubstitutionGoal(i, Repair))); - else - addWaitee(worker.makeGoal( - DerivedPath::Built { - .drvPath = makeConstantStorePathRef(drvPath2->second), - .outputs = OutputsSpec::All { }, - }, - bmRepair)); - } - - if (waitees.empty()) { - co_return done(BuildResult::AlreadyValid, assertPathValidity()); - } else { - co_await Suspend{}; - - trace("closure repaired"); - if (nrFailed > 0) - throw Error("some paths in the output closure of derivation '%s' could not be repaired", - worker.store.printStorePath(drvPath)); - co_return done(BuildResult::AlreadyValid, assertPathValidity()); - } -} - - Goal::Co DerivationGoal::inputsRealised() { trace("all inputs realised"); @@ -744,6 +677,73 @@ Goal::Co DerivationGoal::tryLocalBuild() { } +Goal::Co DerivationGoal::repairClosure() +{ + assert(!drv->type().isImpure()); + + /* If we're repairing, we now know that our own outputs are valid. + Now check whether the other paths in the outputs closure are + good. If not, then start derivation goals for the derivations + that produced those outputs. */ + + /* Get the output closure. */ + auto outputs = queryDerivationOutputMap(); + StorePathSet outputClosure; + for (auto & i : outputs) { + if (!wantedOutputs.contains(i.first)) continue; + worker.store.computeFSClosure(i.second, outputClosure); + } + + /* Filter out our own outputs (which we have already checked). */ + for (auto & i : outputs) + outputClosure.erase(i.second); + + /* Get all dependencies of this derivation so that we know which + derivation is responsible for which path in the output + closure. */ + StorePathSet inputClosure; + if (useDerivation) worker.store.computeFSClosure(drvPath, inputClosure); + std::map outputsToDrv; + for (auto & i : inputClosure) + if (i.isDerivation()) { + auto depOutputs = worker.store.queryPartialDerivationOutputMap(i, &worker.evalStore); + for (auto & j : depOutputs) + if (j.second) + outputsToDrv.insert_or_assign(*j.second, i); + } + + /* Check each path (slow!). */ + for (auto & i : outputClosure) { + if (worker.pathContentsGood(i)) continue; + printError( + "found corrupted or missing path '%s' in the output closure of '%s'", + worker.store.printStorePath(i), worker.store.printStorePath(drvPath)); + auto drvPath2 = outputsToDrv.find(i); + if (drvPath2 == outputsToDrv.end()) + addWaitee(upcast_goal(worker.makePathSubstitutionGoal(i, Repair))); + else + addWaitee(worker.makeGoal( + DerivedPath::Built { + .drvPath = makeConstantStorePathRef(drvPath2->second), + .outputs = OutputsSpec::All { }, + }, + bmRepair)); + } + + if (waitees.empty()) { + co_return done(BuildResult::AlreadyValid, assertPathValidity()); + } else { + co_await Suspend{}; + + trace("closure repaired"); + if (nrFailed > 0) + throw Error("some paths in the output closure of derivation '%s' could not be repaired", + worker.store.printStorePath(drvPath)); + co_return done(BuildResult::AlreadyValid, assertPathValidity()); + } +} + + static void chmod_(const Path & path, mode_t mode) { if (chmod(path.c_str(), mode) == -1) From b3b741973ec499607ae2ab2719e1b69024a8b8b7 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sat, 1 Feb 2025 18:37:54 -0500 Subject: [PATCH 49/60] Inline `inputsRealised` --- src/libstore/build/derivation-goal.cc | 5 ----- src/libstore/build/derivation-goal.hh | 3 +-- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/libstore/build/derivation-goal.cc b/src/libstore/build/derivation-goal.cc index 344b2b5a7ae..0d16f09750b 100644 --- a/src/libstore/build/derivation-goal.cc +++ b/src/libstore/build/derivation-goal.cc @@ -382,12 +382,7 @@ Goal::Co DerivationGoal::gaveUpOnSubstitution() } if (!waitees.empty()) co_await Suspend{}; /* to prevent hang (no wake-up event) */ - co_return inputsRealised(); -} - -Goal::Co DerivationGoal::inputsRealised() -{ trace("all inputs realised"); if (nrFailed != 0) { diff --git a/src/libstore/build/derivation-goal.hh b/src/libstore/build/derivation-goal.hh index 652fca0352a..4e9c1451901 100644 --- a/src/libstore/build/derivation-goal.hh +++ b/src/libstore/build/derivation-goal.hh @@ -80,7 +80,7 @@ struct DerivationGoal : public Goal /** * Mapping from input derivations + output names to actual store * paths. This is filled in by waiteeDone() as each dependency - * finishes, before inputsRealised() is reached. + * finishes, before `trace("all inputs realised")` is reached. */ std::map, StorePath> inputDrvOutputs; @@ -235,7 +235,6 @@ struct DerivationGoal : public Goal Co init() override; Co haveDerivation(); Co gaveUpOnSubstitution(); - Co inputsRealised(); Co tryToBuild(); virtual Co tryLocalBuild(); Co buildDone(); From 85aa624126a93ca37364c1c2f196d9bdaeefedb2 Mon Sep 17 00:00:00 2001 From: Illia Bobyr Date: Mon, 13 Jan 2025 19:09:36 -0800 Subject: [PATCH 50/60] nix-profile-daemon.fish: XDG_DATA_DIRS: .profile/share It seems reasonable to add the `share` folder from the user profile into `$XDG_DATA_DIRS` both for daemon and profile execution. Nix could add package shared files into this folder regardless of how the nix daemon itself is running. --- scripts/nix-profile-daemon.fish.in | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/scripts/nix-profile-daemon.fish.in b/scripts/nix-profile-daemon.fish.in index 3d193412a3c..21a26da7cb6 100644 --- a/scripts/nix-profile-daemon.fish.in +++ b/scripts/nix-profile-daemon.fish.in @@ -21,14 +21,21 @@ function add_path --argument-names new_path end # Main configuration + +# Set up the per-user profile. + +set NIX_LINK $HOME/.nix-profile + +# Set up environment. +# This part should be kept in sync with nixpkgs:nixos/modules/programs/environment.nix set --export NIX_PROFILES "@localstatedir@/nix/profiles/default $HOME/.nix-profile" # Populate bash completions, .desktop files, etc if test -z "$XDG_DATA_DIRS" # According to XDG spec the default is /usr/local/share:/usr/share, don't set something that prevents that default - set --export XDG_DATA_DIRS "/usr/local/share:/usr/share:/nix/var/nix/profiles/default/share" + set --export XDG_DATA_DIRS "/usr/local/share:/usr/share:$NIX_LINK/share:/nix/var/nix/profiles/default/share" else - set --export XDG_DATA_DIRS "$XDG_DATA_DIRS:/nix/var/nix/profiles/default/share" + set --export XDG_DATA_DIRS "$XDG_DATA_DIRS:$NIX_LINK/share:/nix/var/nix/profiles/default/share" end # Set $NIX_SSL_CERT_FILE so that Nixpkgs applications like curl work. @@ -56,7 +63,8 @@ else end add_path "@localstatedir@/nix/profiles/default/bin" -add_path "$HOME/.nix-profile/bin" +add_path "$NIX_LINK/bin" +set --erase NIX_LINK # Cleanup From 137ba71f02366e138e8a130f1bfd3be687aaa6b0 Mon Sep 17 00:00:00 2001 From: silvanshade Date: Mon, 3 Feb 2025 17:47:37 -0700 Subject: [PATCH 51/60] Fix shellcheck lints --- tests/functional/flakes/symlink-paths.sh | 32 ++++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/functional/flakes/symlink-paths.sh b/tests/functional/flakes/symlink-paths.sh index 2559e81073a..8f3dafd2952 100644 --- a/tests/functional/flakes/symlink-paths.sh +++ b/tests/functional/flakes/symlink-paths.sh @@ -6,14 +6,14 @@ requireGit create_flake() { local flakeDir="$1" - createGitRepo $flakeDir - cat > $flakeDir/flake.nix < "$flakeDir/flake.nix" < $repoDir/subdir/flake.nix < "$repoDir/subdir/flake.nix" < $repoDir/file - mkdir $repoDir/subdir - cat > $repoDir/subdir/flake.nix < "$repoDir/file" + mkdir "$repoDir/subdir" + cat > "$repoDir/subdir/flake.nix" < $repo2Dir/file + echo "World" > "$repo2Dir/file" git -C "$repo2Dir" add flake1_sym file git -C "$repo2Dir" commit -m Initial [[ $(nix eval "$repo2Dir/flake1_sym#x") == \"Hello\\n\" ]] From f90ba3a7c1304c067581100cfad10d18f2fcb72c Mon Sep 17 00:00:00 2001 From: John Ericson Date: Tue, 4 Feb 2025 11:25:14 -0500 Subject: [PATCH 52/60] Update tests/functional/flakes/symlink-paths.sh --- tests/functional/flakes/symlink-paths.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/functional/flakes/symlink-paths.sh b/tests/functional/flakes/symlink-paths.sh index 8f3dafd2952..d93accc5405 100644 --- a/tests/functional/flakes/symlink-paths.sh +++ b/tests/functional/flakes/symlink-paths.sh @@ -51,7 +51,7 @@ test_symlink_points_to_dir_in_repo test_symlink_from_repo_to_another() { local repoDir="$TEST_ROOT/repo1" - createGitRepo "{$repoDir}" + createGitRepo "$repoDir" echo "Hello" > "$repoDir/file" mkdir "$repoDir/subdir" cat > "$repoDir/subdir/flake.nix" < Date: Mon, 13 Jan 2025 19:12:24 -0800 Subject: [PATCH 53/60] nix-profile.fish: set --local NIX_LINK Using `set --local` is better than using `set`/`set --erase`. `--local` will preserve any existing `NIX_LINK` value. And the local variable is automatically removed for any execution path. --- scripts/nix-profile-daemon.fish.in | 3 +-- scripts/nix-profile.fish.in | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/scripts/nix-profile-daemon.fish.in b/scripts/nix-profile-daemon.fish.in index 21a26da7cb6..2ecab007766 100644 --- a/scripts/nix-profile-daemon.fish.in +++ b/scripts/nix-profile-daemon.fish.in @@ -24,7 +24,7 @@ end # Set up the per-user profile. -set NIX_LINK $HOME/.nix-profile +set --local NIX_LINK $HOME/.nix-profile # Set up environment. # This part should be kept in sync with nixpkgs:nixos/modules/programs/environment.nix @@ -64,7 +64,6 @@ end add_path "@localstatedir@/nix/profiles/default/bin" add_path "$NIX_LINK/bin" -set --erase NIX_LINK # Cleanup diff --git a/scripts/nix-profile.fish.in b/scripts/nix-profile.fish.in index 53ad8efd056..05d9a187de3 100644 --- a/scripts/nix-profile.fish.in +++ b/scripts/nix-profile.fish.in @@ -24,7 +24,7 @@ end # Set up the per-user profile. -set NIX_LINK $HOME/.nix-profile +set --local NIX_LINK $HOME/.nix-profile # Set up environment. # This part should be kept in sync with nixpkgs:nixos/modules/programs/environment.nix @@ -63,7 +63,6 @@ if set --query MANPATH end add_path "$NIX_LINK/bin" -set --erase NIX_LINK # Cleanup From 1f56ea4c7204a5b014bf96953a7f7c1e44cc66f3 Mon Sep 17 00:00:00 2001 From: silvanshade Date: Wed, 29 Jan 2025 12:24:37 -0700 Subject: [PATCH 54/60] Add BLAKE3 hashing algorithm This uses the single-threaded C-based routines from libblake3. This is not optimal performance-wise but should be a good starting point for nix compatibility with BLAKE3 hashing until a more performant implementation based on the multi-threaded BLAKE3 routines (written in Rust) can be developed. --- src/libcmd/misc-store-flags.cc | 4 +-- src/libexpr-tests/error_traces.cc | 2 +- src/libutil-tests/hash.cc | 42 ++++++++++++++++++++++++++++ src/libutil/experimental-features.cc | 10 ++++++- src/libutil/experimental-features.hh | 1 + src/libutil/hash.cc | 31 +++++++++++++------- src/libutil/hash.hh | 9 +++--- src/libutil/meson.build | 6 ++++ src/libutil/package.nix | 2 ++ 9 files changed, 89 insertions(+), 18 deletions(-) diff --git a/src/libcmd/misc-store-flags.cc b/src/libcmd/misc-store-flags.cc index 06552c03223..242bd4483e2 100644 --- a/src/libcmd/misc-store-flags.cc +++ b/src/libcmd/misc-store-flags.cc @@ -50,7 +50,7 @@ Args::Flag hashAlgo(std::string && longName, HashAlgorithm * ha) { return Args::Flag { .longName = std::move(longName), - .description = "Hash algorithm (`md5`, `sha1`, `sha256`, or `sha512`).", + .description = "Hash algorithm (`blake3`, `md5`, `sha1`, `sha256`, or `sha512`).", .labels = {"hash-algo"}, .handler = {[ha](std::string s) { *ha = parseHashAlgo(s); @@ -63,7 +63,7 @@ Args::Flag hashAlgoOpt(std::string && longName, std::optional * o { return Args::Flag { .longName = std::move(longName), - .description = "Hash algorithm (`md5`, `sha1`, `sha256`, or `sha512`). Can be omitted for SRI hashes.", + .description = "Hash algorithm (`blake3`, `md5`, `sha1`, `sha256`, or `sha512`). Can be omitted for SRI hashes.", .labels = {"hash-algo"}, .handler = {[oha](std::string s) { *oha = std::optional{parseHashAlgo(s)}; diff --git a/src/libexpr-tests/error_traces.cc b/src/libexpr-tests/error_traces.cc index 2aa13cf62de..53013a34a36 100644 --- a/src/libexpr-tests/error_traces.cc +++ b/src/libexpr-tests/error_traces.cc @@ -1152,7 +1152,7 @@ namespace nix { ASSERT_TRACE1("hashString \"foo\" \"content\"", UsageError, - HintFmt("unknown hash algorithm '%s', expect 'md5', 'sha1', 'sha256', or 'sha512'", "foo")); + HintFmt("unknown hash algorithm '%s', expect 'blake3', 'md5', 'sha1', 'sha256', or 'sha512'", "foo")); ASSERT_TRACE2("hashString \"sha256\" {}", TypeError, diff --git a/src/libutil-tests/hash.cc b/src/libutil-tests/hash.cc index a88994d0bc8..3a639aef92f 100644 --- a/src/libutil-tests/hash.cc +++ b/src/libutil-tests/hash.cc @@ -6,10 +6,52 @@ namespace nix { +class BLAKE3HashTest : public virtual ::testing::Test +{ +public: + + /** + * We set these in tests rather than the regular globals so we don't have + * to worry about race conditions if the tests run concurrently. + */ + ExperimentalFeatureSettings mockXpSettings; + +private: + + void SetUp() override + { + mockXpSettings.set("experimental-features", "blake3-hashes"); + } +}; + /* ---------------------------------------------------------------------------- * hashString * --------------------------------------------------------------------------*/ + TEST_F(BLAKE3HashTest, testKnownBLAKE3Hashes1) { + // values taken from: https://tools.ietf.org/html/rfc4634 + auto s = "abc"; + auto hash = hashString(HashAlgorithm::BLAKE3, s, mockXpSettings); + ASSERT_EQ(hash.to_string(HashFormat::Base16, true), + "blake3:6437b3ac38465133ffb63b75273a8db548c558465d79db03fd359c6cd5bd9d85"); + } + + TEST_F(BLAKE3HashTest, testKnownBLAKE3Hashes2) { + // values taken from: https://tools.ietf.org/html/rfc4634 + auto s = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; + auto hash = hashString(HashAlgorithm::BLAKE3, s, mockXpSettings); + ASSERT_EQ(hash.to_string(HashFormat::Base16, true), + "blake3:c19012cc2aaf0dc3d8e5c45a1b79114d2df42abb2a410bf54be09e891af06ff8"); + } + + TEST_F(BLAKE3HashTest, testKnownBLAKE3Hashes3) { + // values taken from: https://www.ietf.org/archive/id/draft-aumasson-blake3-00.txt + auto s = "IETF"; + auto hash = hashString(HashAlgorithm::BLAKE3, s, mockXpSettings); + ASSERT_EQ(hash.to_string(HashFormat::Base16, true), + "blake3:83a2de1ee6f4e6ab686889248f4ec0cf4cc5709446a682ffd1cbb4d6165181e2"); + } + TEST(hashString, testKnownMD5Hashes1) { // values taken from: https://tools.ietf.org/html/rfc1321 auto s1 = ""; diff --git a/src/libutil/experimental-features.cc b/src/libutil/experimental-features.cc index a0c955816e9..dba5893a824 100644 --- a/src/libutil/experimental-features.cc +++ b/src/libutil/experimental-features.cc @@ -24,7 +24,7 @@ struct ExperimentalFeatureDetails * feature, we either have no issue at all if few features are not added * at the end of the list, or a proper merge conflict if they are. */ -constexpr size_t numXpFeatures = 1 + static_cast(Xp::PipeOperators); +constexpr size_t numXpFeatures = 1 + static_cast(Xp::BLAKE3Hashes); constexpr std::array xpFeatureDetails = {{ { @@ -302,6 +302,14 @@ constexpr std::array xpFeatureDetails )", .trackingUrl = "https://github.com/NixOS/nix/milestone/55", }, + { + .tag = Xp::BLAKE3Hashes, + .name = "blake3-hashes", + .description = R"( + Enables support for BLAKE3 hashes. + )", + .trackingUrl = "", + }, }}; static_assert( diff --git a/src/libutil/experimental-features.hh b/src/libutil/experimental-features.hh index 412bf08864d..1d02ba94d2c 100644 --- a/src/libutil/experimental-features.hh +++ b/src/libutil/experimental-features.hh @@ -37,6 +37,7 @@ enum struct ExperimentalFeature MountedSSHStore, VerifiedFetches, PipeOperators, + BLAKE3Hashes, }; /** diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc index b69dec685f5..6a7a8b0920a 100644 --- a/src/libutil/hash.cc +++ b/src/libutil/hash.cc @@ -1,6 +1,7 @@ #include #include +#include #include #include #include @@ -8,6 +9,7 @@ #include "args.hh" #include "hash.hh" #include "archive.hh" +#include "config.hh" #include "split.hh" #include @@ -20,6 +22,7 @@ namespace nix { static size_t regularHashSize(HashAlgorithm type) { switch (type) { + case HashAlgorithm::BLAKE3: return blake3HashSize; case HashAlgorithm::MD5: return md5HashSize; case HashAlgorithm::SHA1: return sha1HashSize; case HashAlgorithm::SHA256: return sha256HashSize; @@ -29,12 +32,15 @@ static size_t regularHashSize(HashAlgorithm type) { } -const std::set hashAlgorithms = {"md5", "sha1", "sha256", "sha512" }; +const std::set hashAlgorithms = {"blake3", "md5", "sha1", "sha256", "sha512" }; const std::set hashFormats = {"base64", "nix32", "base16", "sri" }; -Hash::Hash(HashAlgorithm algo) : algo(algo) +Hash::Hash(HashAlgorithm algo, const ExperimentalFeatureSettings & xpSettings) : algo(algo) { + if (algo == HashAlgorithm::BLAKE3) { + xpSettings.require(Xp::BLAKE3Hashes); + } hashSize = regularHashSize(algo); assert(hashSize <= maxHashSize); memset(hash, 0, maxHashSize); @@ -284,6 +290,7 @@ Hash newHashAllowEmpty(std::string_view hashStr, std::optional ha union Ctx { + blake3_hasher blake3; MD5_CTX md5; SHA_CTX sha1; SHA256_CTX sha256; @@ -293,7 +300,8 @@ union Ctx static void start(HashAlgorithm ha, Ctx & ctx) { - if (ha == HashAlgorithm::MD5) MD5_Init(&ctx.md5); + if (ha == HashAlgorithm::BLAKE3) blake3_hasher_init(&ctx.blake3); + else if (ha == HashAlgorithm::MD5) MD5_Init(&ctx.md5); else if (ha == HashAlgorithm::SHA1) SHA1_Init(&ctx.sha1); else if (ha == HashAlgorithm::SHA256) SHA256_Init(&ctx.sha256); else if (ha == HashAlgorithm::SHA512) SHA512_Init(&ctx.sha512); @@ -303,7 +311,8 @@ static void start(HashAlgorithm ha, Ctx & ctx) static void update(HashAlgorithm ha, Ctx & ctx, std::string_view data) { - if (ha == HashAlgorithm::MD5) MD5_Update(&ctx.md5, data.data(), data.size()); + if (ha == HashAlgorithm::BLAKE3) blake3_hasher_update(&ctx.blake3, data.data(), data.size()); + else if (ha == HashAlgorithm::MD5) MD5_Update(&ctx.md5, data.data(), data.size()); else if (ha == HashAlgorithm::SHA1) SHA1_Update(&ctx.sha1, data.data(), data.size()); else if (ha == HashAlgorithm::SHA256) SHA256_Update(&ctx.sha256, data.data(), data.size()); else if (ha == HashAlgorithm::SHA512) SHA512_Update(&ctx.sha512, data.data(), data.size()); @@ -312,24 +321,24 @@ static void update(HashAlgorithm ha, Ctx & ctx, static void finish(HashAlgorithm ha, Ctx & ctx, unsigned char * hash) { - if (ha == HashAlgorithm::MD5) MD5_Final(hash, &ctx.md5); + if (ha == HashAlgorithm::BLAKE3) blake3_hasher_finalize(&ctx.blake3, hash, BLAKE3_OUT_LEN); + else if (ha == HashAlgorithm::MD5) MD5_Final(hash, &ctx.md5); else if (ha == HashAlgorithm::SHA1) SHA1_Final(hash, &ctx.sha1); else if (ha == HashAlgorithm::SHA256) SHA256_Final(hash, &ctx.sha256); else if (ha == HashAlgorithm::SHA512) SHA512_Final(hash, &ctx.sha512); } - -Hash hashString(HashAlgorithm ha, std::string_view s) +Hash hashString( + HashAlgorithm ha, std::string_view s, const ExperimentalFeatureSettings & xpSettings) { Ctx ctx; - Hash hash(ha); + Hash hash(ha, xpSettings); start(ha, ctx); update(ha, ctx, s); finish(ha, ctx, hash.hash); return hash; } - Hash hashFile(HashAlgorithm ha, const Path & path) { HashSink sink(ha); @@ -426,6 +435,7 @@ std::string_view printHashFormat(HashFormat HashFormat) std::optional parseHashAlgoOpt(std::string_view s) { + if (s == "blake3") return HashAlgorithm::BLAKE3; if (s == "md5") return HashAlgorithm::MD5; if (s == "sha1") return HashAlgorithm::SHA1; if (s == "sha256") return HashAlgorithm::SHA256; @@ -439,12 +449,13 @@ HashAlgorithm parseHashAlgo(std::string_view s) if (opt_h) return *opt_h; else - throw UsageError("unknown hash algorithm '%1%', expect 'md5', 'sha1', 'sha256', or 'sha512'", s); + throw UsageError("unknown hash algorithm '%1%', expect 'blake3', 'md5', 'sha1', 'sha256', or 'sha512'", s); } std::string_view printHashAlgo(HashAlgorithm ha) { switch (ha) { + case HashAlgorithm::BLAKE3: return "blake3"; case HashAlgorithm::MD5: return "md5"; case HashAlgorithm::SHA1: return "sha1"; case HashAlgorithm::SHA256: return "sha256"; diff --git a/src/libutil/hash.hh b/src/libutil/hash.hh index dc95b9f2f9b..13d526f42cf 100644 --- a/src/libutil/hash.hh +++ b/src/libutil/hash.hh @@ -1,6 +1,7 @@ #pragma once ///@file +#include "config.hh" #include "types.hh" #include "serialise.hh" #include "file-system.hh" @@ -11,9 +12,9 @@ namespace nix { MakeError(BadHash, Error); -enum struct HashAlgorithm : char { MD5 = 42, SHA1, SHA256, SHA512 }; - +enum struct HashAlgorithm : char { MD5 = 42, SHA1, SHA256, SHA512, BLAKE3 }; +const int blake3HashSize = 32; const int md5HashSize = 16; const int sha1HashSize = 20; const int sha256HashSize = 32; @@ -52,7 +53,7 @@ struct Hash /** * Create a zero-filled hash object. */ - explicit Hash(HashAlgorithm algo); + explicit Hash(HashAlgorithm algo, const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings); /** * Parse the hash from a string representation in the format @@ -157,7 +158,7 @@ std::string printHash16or32(const Hash & hash); /** * Compute the hash of the given string. */ -Hash hashString(HashAlgorithm ha, std::string_view s); +Hash hashString(HashAlgorithm ha, std::string_view s, const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings); /** * Compute the hash of the given file, hashing its contents directly. diff --git a/src/libutil/meson.build b/src/libutil/meson.build index ac701d8fd3b..9ee3770de2c 100644 --- a/src/libutil/meson.build +++ b/src/libutil/meson.build @@ -62,6 +62,12 @@ elif host_machine.system() == 'sunos' deps_other += [socket, network_service_library] endif +blake3 = dependency( + 'libblake3', + version: '>= 1.5.5', +) +deps_private += blake3 + boost = dependency( 'boost', modules : ['context', 'coroutine'], diff --git a/src/libutil/package.nix b/src/libutil/package.nix index 586119a6e5d..2f19b5822f7 100644 --- a/src/libutil/package.nix +++ b/src/libutil/package.nix @@ -6,6 +6,7 @@ boost, brotli, libarchive, + libblake3, libcpuid, libsodium, nlohmann_json, @@ -42,6 +43,7 @@ mkMesonLibrary (finalAttrs: { buildInputs = [ brotli + libblake3 libsodium openssl ] ++ lib.optional stdenv.hostPlatform.isx86_64 libcpuid; From 7fd2125573958fe91ee8944bd2e80bee3e45f6be Mon Sep 17 00:00:00 2001 From: silvanshade Date: Wed, 5 Feb 2025 17:29:55 -0700 Subject: [PATCH 55/60] Add BLAKE3 to documentation --- doc/manual/source/command-ref/nix-hash.md | 2 +- doc/manual/source/command-ref/nix-prefetch-url.md | 2 +- doc/manual/source/language/advanced-attributes.md | 2 +- doc/manual/source/protocols/json/derivation.md | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/manual/source/command-ref/nix-hash.md b/doc/manual/source/command-ref/nix-hash.md index f249c2b84d6..0860f312d94 100644 --- a/doc/manual/source/command-ref/nix-hash.md +++ b/doc/manual/source/command-ref/nix-hash.md @@ -67,7 +67,7 @@ md5sum`. - `--type` *hashAlgo* Use the specified cryptographic hash algorithm, which can be one of - `md5`, `sha1`, `sha256`, and `sha512`. + `blake3`, `md5`, `sha1`, `sha256`, and `sha512`. - `--to-base16` diff --git a/doc/manual/source/command-ref/nix-prefetch-url.md b/doc/manual/source/command-ref/nix-prefetch-url.md index ffab94b8afa..19322ec8e04 100644 --- a/doc/manual/source/command-ref/nix-prefetch-url.md +++ b/doc/manual/source/command-ref/nix-prefetch-url.md @@ -42,7 +42,7 @@ the path of the downloaded file in the Nix store is also printed. - `--type` *hashAlgo* Use the specified cryptographic hash algorithm, - which can be one of `md5`, `sha1`, `sha256`, and `sha512`. + which can be one of `blake3`, `md5`, `sha1`, `sha256`, and `sha512`. The default is `sha256`. - `--print-path` diff --git a/doc/manual/source/language/advanced-attributes.md b/doc/manual/source/language/advanced-attributes.md index 51b83fc8acc..c384e956af6 100644 --- a/doc/manual/source/language/advanced-attributes.md +++ b/doc/manual/source/language/advanced-attributes.md @@ -192,7 +192,7 @@ Derivations can declare some infrequently used optional attributes. The [`convertHash`](@docroot@/language/builtins.md#builtins-convertHash) function shows how to convert between different encodings, and the [`nix-hash` command](../command-ref/nix-hash.md) has information about obtaining the hash for some contents, as well as converting to and from encodings. The `outputHashAlgo` attribute specifies the hash algorithm used to compute the hash. - It can currently be `"sha1"`, `"sha256"`, `"sha512"`, or `null`. + It can currently be `"blake3", "sha1"`, `"sha256"`, `"sha512"`, or `null`. `outputHashAlgo` can only be `null` when `outputHash` follows the SRI format. The `outputHashMode` attribute determines how the hash is computed. diff --git a/doc/manual/source/protocols/json/derivation.md b/doc/manual/source/protocols/json/derivation.md index 2f85340d6c5..3845f120029 100644 --- a/doc/manual/source/protocols/json/derivation.md +++ b/doc/manual/source/protocols/json/derivation.md @@ -38,6 +38,7 @@ is a JSON object with the following fields: For an output which will be [content addresed], the name of the hash algorithm used. Valid algorithm strings are: + - `blake3` - `md5` - `sha1` - `sha256` From 73060b49720ce165bd7d0a087ecae98ad104e25a Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Fri, 24 Jan 2025 16:37:09 +0100 Subject: [PATCH 56/60] pre-commit/check-merge-conflicts-2: fix use outside dev shell Note that this is just a script that is meant to run outside a derivation (but also can be called by a derivation builder). `touch $out` does not belong in it. `touch $out` worked accidentally in the derivation-based check, and also in the dev shell, but if pre-commit is invoked without the dev shell it would fail. --- maintainers/flake-module.nix | 1 - 1 file changed, 1 deletion(-) diff --git a/maintainers/flake-module.nix b/maintainers/flake-module.nix index c44e5134c8a..208296194a1 100644 --- a/maintainers/flake-module.nix +++ b/maintainers/flake-module.nix @@ -35,7 +35,6 @@ echo "ERROR: found merge/patch conflicts in files" exit 1 fi - touch $out ''}"; }; nixfmt-rfc-style = { From 77a83860223bbcfd53b2cae3ad3e650a9cc7c157 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Wed, 29 Jan 2025 21:53:12 +0100 Subject: [PATCH 57/60] test: Fix shellcheck by giving git-hashing scripts shebangs This seems to be the way to do it now, even though I can't run them without setting at least one env var. I'll only fix shellcheck for now. Don't shoot the messenger. It isn't quite clear to me why the previous commit masked this problem, but I'm glad shellcheck has an effect or more effect now. --- tests/functional/git-hashing/fixed.sh | 0 tests/functional/git-hashing/simple.sh | 2 ++ 2 files changed, 2 insertions(+) mode change 100644 => 100755 tests/functional/git-hashing/fixed.sh mode change 100644 => 100755 tests/functional/git-hashing/simple.sh diff --git a/tests/functional/git-hashing/fixed.sh b/tests/functional/git-hashing/fixed.sh old mode 100644 new mode 100755 diff --git a/tests/functional/git-hashing/simple.sh b/tests/functional/git-hashing/simple.sh old mode 100644 new mode 100755 index f43168eb214..e02d8b29761 --- a/tests/functional/git-hashing/simple.sh +++ b/tests/functional/git-hashing/simple.sh @@ -1,3 +1,5 @@ +#!/usr/bin/env bash + source common.sh repo="$TEST_ROOT/scratch" From 414c346560de1235119bce25da60fd68353d5ebf Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Wed, 29 Jan 2025 22:01:17 +0100 Subject: [PATCH 58/60] test: Use skipTest instead of exit 0 This way shellcheck is ok with it, and it conveys that a significant chunk of the test is skipped. --- tests/functional/help.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/functional/help.sh b/tests/functional/help.sh index efacaba5922..e1ef75c41f4 100755 --- a/tests/functional/help.sh +++ b/tests/functional/help.sh @@ -25,7 +25,7 @@ done # FIXME: we don't know whether we built the manpages, so we can't # reliably test them here. -if false; then +skipTest "we don't know whether we built the manpages, so we can't reliably test them here." # test help output @@ -74,5 +74,3 @@ nix-daemon --help nix-hash --help nix-instantiate --help nix-prefetch-url --help - -fi From e80d333777e583c6d786479c398df161f77ec0e8 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sun, 9 Feb 2025 20:30:07 -0500 Subject: [PATCH 59/60] Document Store Derivations and Deriving Paths (#12290) This is a big step documenting the store layer on its own, separately from the evaluator (and `builtins.derivation`). Co-authored-by: Robert Hensing --- doc/manual/redirects.js | 3 + doc/manual/source/SUMMARY.md.in | 2 + .../source/architecture/architecture.md | 2 +- .../source/command-ref/nix-env/install.md | 12 +- .../source/command-ref/nix-env/query.md | 5 +- .../source/command-ref/nix-instantiate.md | 4 +- doc/manual/source/glossary.md | 53 +-- doc/manual/source/language/derivations.md | 96 +----- .../source/language/import-from-derivation.md | 5 +- .../source/language/string-interpolation.md | 6 +- .../source/protocols/derivation-aterm.md | 21 +- .../protocols/json/store-object-info.md | 4 +- doc/manual/source/release-notes/rl-0.8.md | 48 +-- doc/manual/source/release-notes/rl-2.0.md | 144 ++++---- doc/manual/source/store/building.md | 97 ++++++ doc/manual/source/store/drv.md | 310 ++++++++++++++++++ src/libcmd/misc-store-flags.cc | 2 +- src/libexpr/primops.cc | 23 +- src/libstore/globals.hh | 4 +- src/nix/derivation-show.cc | 4 +- src/nix/search.md | 7 +- 21 files changed, 611 insertions(+), 241 deletions(-) create mode 100644 doc/manual/source/store/building.md create mode 100644 doc/manual/source/store/drv.md diff --git a/doc/manual/redirects.js b/doc/manual/redirects.js index dea141391df..a1d30d9e81c 100644 --- a/doc/manual/redirects.js +++ b/doc/manual/redirects.js @@ -346,6 +346,9 @@ const redirects = { "scoping-rules": "scoping.html", "string-literal": "string-literals.html", }, + "language/derivations.md": { + "builder-execution": "store/drv/building.md#builder-execution", + }, "installation/installing-binary.html": { "linux": "uninstall.html#linux", "macos": "uninstall.html#macos", diff --git a/doc/manual/source/SUMMARY.md.in b/doc/manual/source/SUMMARY.md.in index a92bca42f4d..0abe691cc25 100644 --- a/doc/manual/source/SUMMARY.md.in +++ b/doc/manual/source/SUMMARY.md.in @@ -22,6 +22,8 @@ - [Store Object](store/store-object.md) - [Content-Addressing Store Objects](store/store-object/content-address.md) - [Store Path](store/store-path.md) + - [Store Derivation and Deriving Path](store/drv.md) + - [Building](store/building.md) - [Store Types](store/types/index.md) {{#include ./store/types/SUMMARY.md}} - [Nix Language](language/index.md) diff --git a/doc/manual/source/architecture/architecture.md b/doc/manual/source/architecture/architecture.md index 867a9c992d3..cbc469355f8 100644 --- a/doc/manual/source/architecture/architecture.md +++ b/doc/manual/source/architecture/architecture.md @@ -69,7 +69,7 @@ It can also execute build plans to produce new data, which are made available to A build plan itself is a series of *build tasks*, together with their build inputs. > **Important** -> A build task in Nix is called [derivation](@docroot@/glossary.md#gloss-derivation). +> A build task in Nix is called [store derivation](@docroot@/glossary.md#gloss-store-derivation). Each build task has a special build input executed as *build instructions* in order to perform the build. The result of a build task can be input to another build task. diff --git a/doc/manual/source/command-ref/nix-env/install.md b/doc/manual/source/command-ref/nix-env/install.md index aa5c2fbba83..527fd8f90d8 100644 --- a/doc/manual/source/command-ref/nix-env/install.md +++ b/doc/manual/source/command-ref/nix-env/install.md @@ -22,11 +22,11 @@ It is based on the current generation of the active [profile](@docroot@/command- The arguments *args* map to store paths in a number of possible ways: -- By default, *args* is a set of [derivation] names denoting derivations in the [default Nix expression]. +- By default, *args* is a set of names denoting derivations in the [default Nix expression]. These are [realised], and the resulting output paths are installed. Currently installed derivations with a name equal to the name of a derivation being added are removed unless the option `--preserve-installed` is specified. - [derivation]: @docroot@/glossary.md#gloss-derivation + [derivation expression]: @docroot@/glossary.md#gloss-derivation-expression [default Nix expression]: @docroot@/command-ref/files/default-nix-expression.md [realised]: @docroot@/glossary.md#gloss-realise @@ -66,11 +66,11 @@ The arguments *args* map to store paths in a number of possible ways: This can be used to override the priority of the derivations being installed. This is useful if *args* are [store paths], which don't have any priority information. -- If *args* are [store derivations](@docroot@/glossary.md#gloss-store-derivation), then these are [realised], and the resulting output paths are installed. +- If *args* are [store paths] that point to [store derivations][store derivation], then those store derivations are [realised], and the resulting output paths are installed. -- If *args* are [store paths] that are not store derivations, then these are [realised] and installed. +- If *args* are [store paths] that do not point to store derivations, then these are [realised] and installed. -- By default all [outputs](@docroot@/language/derivations.md#attr-outputs) are installed for each [derivation]. +- By default all [outputs](@docroot@/language/derivations.md#attr-outputs) are installed for each [store derivation]. This can be overridden by adding a `meta.outputsToInstall` attribute on the derivation listing a subset of the output names. Example: @@ -122,6 +122,8 @@ The arguments *args* map to store paths in a number of possible ways: manifest.nix ``` +[store derivation]: @docroot@/glossary.md#gloss-store-derivation + # Options - `--prebuilt-only` / `-b` diff --git a/doc/manual/source/command-ref/nix-env/query.md b/doc/manual/source/command-ref/nix-env/query.md index c67794ed58e..bde9b38202c 100644 --- a/doc/manual/source/command-ref/nix-env/query.md +++ b/doc/manual/source/command-ref/nix-env/query.md @@ -125,7 +125,10 @@ derivation is shown unless `--no-name` is specified. - `--drv-path` - Print the path of the [store derivation](@docroot@/glossary.md#gloss-store-derivation). + Print the [store path] to the [store derivation]. + + [store path]: @docroot@/glossary.md#gloss-store-path + [store derivation]: @docroot@/glossary.md#gloss-derivation - `--out-path` diff --git a/doc/manual/source/command-ref/nix-instantiate.md b/doc/manual/source/command-ref/nix-instantiate.md index 487ef8f102f..38454515d57 100644 --- a/doc/manual/source/command-ref/nix-instantiate.md +++ b/doc/manual/source/command-ref/nix-instantiate.md @@ -42,8 +42,8 @@ standard input. - `--eval` Just parse and evaluate the input files, and print the resulting - values on standard output. No instantiation of store derivations - takes place. + values on standard output. + Store derivations are not serialized and written to the store, but instead just hashed and discarded. > **Warning** > diff --git a/doc/manual/source/glossary.md b/doc/manual/source/glossary.md index fa357ece3d6..772116e9886 100644 --- a/doc/manual/source/glossary.md +++ b/doc/manual/source/glossary.md @@ -19,31 +19,35 @@ Besides content addressing, the Nix store also uses [input addressing](#gloss-input-addressed-store-object). -- [derivation]{#gloss-derivation} +- [store derivation]{#gloss-store-derivation} - A description of a build task. The result of a derivation is a - store object. Derivations declared in Nix expressions are specified - using the [`derivation` primitive](./language/derivations.md). These are - translated into low-level *store derivations* (implicitly by - `nix-build`, or explicitly by `nix-instantiate`). + A single build task. + See [Store Derivation](@docroot@/store/drv.md#store-derivation) for details. - [derivation]: #gloss-derivation + [store derivation]: #gloss-store-derivation -- [store derivation]{#gloss-store-derivation} +- [derivation path]{#gloss-derivation-path} - A [derivation] represented as a `.drv` file in the [store]. - It has a [store path], like any [store object]. - It is the [instantiated][instantiate] form of a derivation. + A [store path] which uniquely identifies a [store derivation]. - Example: `/nix/store/g946hcz4c8mdvq2g8vxx42z51qb71rvp-git-2.38.1.drv` + See [Referencing Store Derivations](@docroot@/store/drv.md#derivation-path) for details. - See [`nix derivation show`](./command-ref/new-cli/nix3-derivation-show.md) (experimental) for displaying the contents of store derivations. + Not to be confused with [deriving path]. - [store derivation]: #gloss-store-derivation + [derivation path]: #gloss-derivation-path + +- [derivation expression]{#gloss-derivation-expression} + + A description of a [store derivation] in the Nix language. + The output(s) of a derivation are store objects. + Derivations are typically specified in Nix expressions using the [`derivation` primitive](./language/derivations.md). + These are translated into store layer *derivations* (implicitly by `nix-env` and `nix-build`, or explicitly by `nix-instantiate`). + + [derivation expression]: #gloss-derivation-expression - [instantiate]{#gloss-instantiate}, instantiation - Save an evaluated [derivation] as a [store derivation] in the Nix [store]. + Translate a [derivation expression] into a [store derivation]. See [`nix-instantiate`](./command-ref/nix-instantiate.md), which produces a store derivation from a Nix expression that evaluates to a derivation. @@ -55,7 +59,7 @@ This can be achieved by: - Fetching a pre-built [store object] from a [substituter] - - Running the [`builder`](@docroot@/language/derivations.md#attr-builder) executable as specified in the corresponding [derivation] + - Running the [`builder`](@docroot@/language/derivations.md#attr-builder) executable as specified in the corresponding [store derivation] - Delegating to a [remote machine](@docroot@/command-ref/conf-file.md#conf-builders) and retrieving the outputs @@ -73,7 +77,7 @@ - [fixed-output derivation]{#gloss-fixed-output-derivation} (FOD) - A [derivation] where a cryptographic hash of the [output] is determined in advance using the [`outputHash`](./language/advanced-attributes.md#adv-attr-outputHash) attribute, and where the [`builder`](@docroot@/language/derivations.md#attr-builder) executable has access to the network. + A [store derivation] where a cryptographic hash of the [output] is determined in advance using the [`outputHash`](./language/advanced-attributes.md#adv-attr-outputHash) attribute, and where the [`builder`](@docroot@/language/derivations.md#attr-builder) executable has access to the network. - [store]{#gloss-store} @@ -188,7 +192,7 @@ > > The contents of a `.nix` file form a Nix expression. - Nix expressions specify [derivations][derivation], which are [instantiated][instantiate] into the Nix store as [store derivations][store derivation]. + Nix expressions specify [derivation expressions][derivation expression], which are [instantiated][instantiate] into the Nix store as [store derivations][store derivation]. These derivations can then be [realised][realise] to produce [outputs][output]. > **Example** @@ -230,14 +234,14 @@ - [output]{#gloss-output} - A [store object] produced by a [derivation]. + A [store object] produced by a [store derivation]. See [the `outputs` argument to the `derivation` function](@docroot@/language/derivations.md#attr-outputs) for details. [output]: #gloss-output - [output path]{#gloss-output-path} - The [store path] to the [output] of a [derivation]. + The [store path] to the [output] of a [store derivation]. [output path]: #gloss-output-path @@ -246,14 +250,11 @@ - [deriving path]{#gloss-deriving-path} - Deriving paths are a way to refer to [store objects][store object] that ar not yet [realised][realise]. - This is necessary because, in general and particularly for [content-addressed derivations][content-addressed derivation], the [output path] of an [output] is not known in advance. - There are two forms: + Deriving paths are a way to refer to [store objects][store object] that might not yet be [realised][realise]. - - *constant*: just a [store path] - It can be made [valid][validity] by copying it into the store: from the evaluator, command line interface or another store. + See [Deriving Path](./store/drv.md#deriving-path) for details. - - *output*: a pair of a [store path] to a [derivation] and an [output] name. + Not to be confused with [derivation path]. - [deriver]{#gloss-deriver} diff --git a/doc/manual/source/language/derivations.md b/doc/manual/source/language/derivations.md index 771b2bd9130..0f9284e9844 100644 --- a/doc/manual/source/language/derivations.md +++ b/doc/manual/source/language/derivations.md @@ -1,9 +1,10 @@ # Derivations -The most important built-in function is `derivation`, which is used to describe a single derivation: -a specification for running an executable on precisely defined input files to repeatably produce output files at uniquely determined file system paths. +The most important built-in function is `derivation`, which is used to describe a single store-layer [store derivation]. +Consult the [store chapter](@docroot@/store/drv.md) for what a store derivation is; +this section just concerns how to create one from the Nix language. -It takes as input an attribute set, the attributes of which specify the inputs to the process. +This builtin function takes as input an attribute set, the attributes of which specify the inputs to the process. It outputs an attribute set, and produces a [store derivation] as a side effect of evaluation. [store derivation]: @docroot@/glossary.md#gloss-store-derivation @@ -15,7 +16,7 @@ It outputs an attribute set, and produces a [store derivation] as a side effect - [`name`]{#attr-name} ([String](@docroot@/language/types.md#type-string)) A symbolic name for the derivation. - It is added to the [store path] of the corresponding [store derivation] as well as to its [output paths](@docroot@/glossary.md#gloss-output-path). + See [derivation outputs](@docroot@/store/drv.md#outputs) for what this is affects. [store path]: @docroot@/store/store-path.md @@ -28,17 +29,12 @@ It outputs an attribute set, and produces a [store derivation] as a side effect > } > ``` > - > The store derivation's path will be `/nix/store/-hello.drv`. + > The derivation's path will be `/nix/store/-hello.drv`. > The [output](#attr-outputs) paths will be of the form `/nix/store/-hello[-]` - [`system`]{#attr-system} ([String](@docroot@/language/types.md#type-string)) - The system type on which the [`builder`](#attr-builder) executable is meant to be run. - - A necessary condition for Nix to build derivations locally is that the `system` attribute matches the current [`system` configuration option]. - It can automatically [build on other platforms](@docroot@/language/derivations.md#attr-builder) by forwarding build requests to other machines. - - [`system` configuration option]: @docroot@/command-ref/conf-file.md#conf-system + See [system](@docroot@/store/drv.md#system). > **Example** > @@ -68,7 +64,7 @@ It outputs an attribute set, and produces a [store derivation] as a side effect - [`builder`]{#attr-builder} ([Path](@docroot@/language/types.md#type-path) | [String](@docroot@/language/types.md#type-string)) - Path to an executable that will perform the build. + See [builder](@docroot@/store/drv.md#builder). > **Example** > @@ -117,7 +113,7 @@ It outputs an attribute set, and produces a [store derivation] as a side effect Default: `[ ]` - Command-line arguments to be passed to the [`builder`](#attr-builder) executable. + See [args](@docroot@/store/drv.md#args). > **Example** > @@ -239,77 +235,3 @@ It outputs an attribute set, and produces a [store derivation] as a side effect passed as an empty string. - -## Builder execution - -The [`builder`](#attr-builder) is executed as follows: - -- A temporary directory is created under the directory specified by - `TMPDIR` (default `/tmp`) where the build will take place. The - current directory is changed to this directory. - -- The environment is cleared and set to the derivation attributes, as - specified above. - -- In addition, the following variables are set: - - - `NIX_BUILD_TOP` contains the path of the temporary directory for - this build. - - - Also, `TMPDIR`, `TEMPDIR`, `TMP`, `TEMP` are set to point to the - temporary directory. This is to prevent the builder from - accidentally writing temporary files anywhere else. Doing so - might cause interference by other processes. - - - `PATH` is set to `/path-not-set` to prevent shells from - initialising it to their built-in default value. - - - `HOME` is set to `/homeless-shelter` to prevent programs from - using `/etc/passwd` or the like to find the user's home - directory, which could cause impurity. Usually, when `HOME` is - set, it is used as the location of the home directory, even if - it points to a non-existent path. - - - `NIX_STORE` is set to the path of the top-level Nix store - directory (typically, `/nix/store`). - - - `NIX_ATTRS_JSON_FILE` & `NIX_ATTRS_SH_FILE` if `__structuredAttrs` - is set to `true` for the derivation. A detailed explanation of this - behavior can be found in the - [section about structured attrs](./advanced-attributes.md#adv-attr-structuredAttrs). - - - For each output declared in `outputs`, the corresponding - environment variable is set to point to the intended path in the - Nix store for that output. Each output path is a concatenation - of the cryptographic hash of all build inputs, the `name` - attribute and the output name. (The output name is omitted if - it’s `out`.) - -- If an output path already exists, it is removed. Also, locks are - acquired to prevent multiple Nix instances from performing the same - build at the same time. - -- A log of the combined standard output and error is written to - `/nix/var/log/nix`. - -- The builder is executed with the arguments specified by the - attribute `args`. If it exits with exit code 0, it is considered to - have succeeded. - -- The temporary directory is removed (unless the `-K` option was - specified). - -- If the build was successful, Nix scans each output path for - references to input paths by looking for the hash parts of the input - paths. Since these are potential runtime dependencies, Nix registers - them as dependencies of the output paths. - -- After the build, Nix sets the last-modified timestamp on all files - in the build result to 1 (00:00:01 1/1/1970 UTC), sets the group to - the default group, and sets the mode of the file to 0444 or 0555 - (i.e., read-only, with execute permission enabled if the file was - originally executable). Note that possible `setuid` and `setgid` - bits are cleared. Setuid and setgid programs are not currently - supported by Nix. This is because the Nix archives used in - deployment have no concept of ownership information, and because it - makes the build result dependent on the user performing the build. diff --git a/doc/manual/source/language/import-from-derivation.md b/doc/manual/source/language/import-from-derivation.md index e901f5bcf5b..f161c6fe391 100644 --- a/doc/manual/source/language/import-from-derivation.md +++ b/doc/manual/source/language/import-from-derivation.md @@ -71,8 +71,9 @@ Boxes are data structures, arrow labels are transformations. | evaluate | | | | | | | | | V | | | -| .------------. | | .------------------. | -| | derivation |----|-instantiate-|->| store derivation | | +| .------------. | | | +| | derivation | | | .------------------. | +| | expression |----|-instantiate-|->| store derivation | | | '------------' | | '------------------' | | | | | | | | | realise | diff --git a/doc/manual/source/language/string-interpolation.md b/doc/manual/source/language/string-interpolation.md index 27780dcbb39..a503d5f04bd 100644 --- a/doc/manual/source/language/string-interpolation.md +++ b/doc/manual/source/language/string-interpolation.md @@ -22,9 +22,9 @@ Rather than writing "--with-freetype2-library=" + freetype + "/lib" ``` -(where `freetype` is a [derivation]), you can instead write +(where `freetype` is a [derivation expression]), you can instead write -[derivation]: @docroot@/glossary.md#gloss-derivation +[derivation expression]: @docroot@/glossary.md#gloss-derivation-expression ```nix "--with-freetype2-library=${freetype}/lib" @@ -148,7 +148,7 @@ An expression that is interpolated must evaluate to one of the following: - `__toString` must be a function that takes the attribute set itself and returns a string - `outPath` must be a string - This includes [derivations](./derivations.md) or [flake inputs](@docroot@/command-ref/new-cli/nix3-flake.md#flake-inputs) (experimental). + This includes [derivation expressions](./derivations.md) or [flake inputs](@docroot@/command-ref/new-cli/nix3-flake.md#flake-inputs) (experimental). A string interpolates to itself. diff --git a/doc/manual/source/protocols/derivation-aterm.md b/doc/manual/source/protocols/derivation-aterm.md index 1ba757ae024..99e3c2be630 100644 --- a/doc/manual/source/protocols/derivation-aterm.md +++ b/doc/manual/source/protocols/derivation-aterm.md @@ -1,6 +1,8 @@ # Derivation "ATerm" file format -For historical reasons, [derivations](@docroot@/glossary.md#gloss-store-derivation) are stored on-disk in [ATerm](https://homepages.cwi.nl/~daybuild/daily-books/technology/aterm-guide/aterm-guide.html) format. +For historical reasons, [store derivations][store derivation] are stored on-disk in [ATerm](https://homepages.cwi.nl/~daybuild/daily-books/technology/aterm-guide/aterm-guide.html) format. + +## The ATerm format used Derivations are serialised in one of the following formats: @@ -17,3 +19,20 @@ Derivations are serialised in one of the following formats: The only `version-string`s that are in use today are for [experimental features](@docroot@/development/experimental-features.md): - `"xp-dyn-drv"` for the [`dynamic-derivations`](@docroot@/development/experimental-features.md#xp-feature-dynamic-derivations) experimental feature. + +## Use for encoding to store object + +When derivation is encoded to a [store object] we make the following choices: + +- The store path name is the derivation name with `.drv` suffixed at the end + + Indeed, the ATerm format above does *not* contain the name of the derivation, on the assumption that a store path will also be provided out-of-band. + +- The derivation is content-addressed using the ["Text" method] of content-addressing derivations + +Currently we always encode derivations to store object using the ATerm format (and the previous two choices), +but we reserve the option to encode new sorts of derivations differently in the future. + +[store derivation]: @docroot@/glossary.md#gloss-store-derivation +[store object]: @docroot@/glossary.md#gloss-store-object +["Text" method]: @docroot@/store/store-object/content-address.md#method-text diff --git a/doc/manual/source/protocols/json/store-object-info.md b/doc/manual/source/protocols/json/store-object-info.md index 6b4f4843711..b7348538c35 100644 --- a/doc/manual/source/protocols/json/store-object-info.md +++ b/doc/manual/source/protocols/json/store-object-info.md @@ -41,10 +41,10 @@ In other words, the same store object residing in different store could have dif * `deriver`: - If known, the path to the [derivation] from which this store object was produced. + If known, the path to the [store derivation] from which this store object was produced. Otherwise `null`. - [derivation]: @docroot@/glossary.md#gloss-store-derivation + [store derivation]: @docroot@/glossary.md#gloss-store-derivation * `registrationTime` (optional): diff --git a/doc/manual/source/release-notes/rl-0.8.md b/doc/manual/source/release-notes/rl-0.8.md index 626c0c92b79..5ba6e0e7217 100644 --- a/doc/manual/source/release-notes/rl-0.8.md +++ b/doc/manual/source/release-notes/rl-0.8.md @@ -39,29 +39,29 @@ Nix 0.8 has the following improvements: notion of “closure store expressions” is gone (and so is the notion of “successors”); the file system references of a store path are now just stored in the database. - + For instance, given any store path, you can query its closure: - + $ nix-store -qR $(which firefox) ... lots of paths ... - + Also, Nix now remembers for each store path the derivation that built it (the “deriver”): - + $ nix-store -qR $(which firefox) /nix/store/4b0jx7vq80l9aqcnkszxhymsf1ffa5jd-firefox-1.0.1.drv - + So to see the build-time dependencies, you can do - + $ nix-store -qR $(nix-store -qd $(which firefox)) - + or, in a nicer format: - + $ nix-store -q --tree $(nix-store -qd $(which firefox)) - + File system references are also stored in reverse. For instance, you can query all paths that directly or indirectly use a certain Glibc: - + $ nix-store -q --referrers-closure \ /nix/store/8lz9yc6zgmc0vlqmn2ipcpkjlmbi51vv-glibc-2.3.4 @@ -92,28 +92,28 @@ Nix 0.8 has the following improvements: - `nix-channel` has new operations `--list` and `--remove`. - New ways of installing components into user environments: - + - Copy from another user environment: - + $ nix-env -i --from-profile .../other-profile firefox - + - Install a store derivation directly (bypassing the Nix expression language entirely): - + $ nix-env -i /nix/store/z58v41v21xd3...-aterm-2.3.1.drv - + (This is used to implement `nix-install-package`, which is therefore immune to evolution in the Nix expression language.) - + - Install an already built store path directly: - + $ nix-env -i /nix/store/hsyj5pbn0d9i...-aterm-2.3.1 - + - Install the result of a Nix expression specified as a command-line argument: - + $ nix-env -f .../i686-linux.nix -i -E 'x: x.firefoxWrapper' - + The difference with the normal installation mode is that `-E` does not use the `name` attributes of derivations. Therefore, this can be used to disambiguate multiple derivations with the @@ -127,7 +127,7 @@ Nix 0.8 has the following improvements: - Implemented a concurrent garbage collector. It is now always safe to run the garbage collector, even if other Nix operations are happening simultaneously. - + However, there can still be GC races if you use `nix-instantiate` and `nix-store --realise` directly to build things. To prevent races, use the @@ -147,13 +147,13 @@ Nix 0.8 has the following improvements: - The behaviour of the garbage collector can be changed globally by setting options in `/nix/etc/nix/nix.conf`. - + - `gc-keep-derivations` specifies whether deriver links should be followed when searching for live paths. - + - `gc-keep-outputs` specifies whether outputs of derivations should be followed when searching for live paths. - + - `env-keep-derivations` specifies whether user environments should store the paths of derivations when they are added (thus keeping the derivations alive). diff --git a/doc/manual/source/release-notes/rl-2.0.md b/doc/manual/source/release-notes/rl-2.0.md index 9f6d4aa8323..aad0de21189 100644 --- a/doc/manual/source/release-notes/rl-2.0.md +++ b/doc/manual/source/release-notes/rl-2.0.md @@ -8,13 +8,13 @@ The following incompatible changes have been made: It has been superseded by the binary cache substituter mechanism since several years. As a result, the following programs have been removed: - + - `nix-pull` - + - `nix-generate-patches` - + - `bsdiff` - + - `bspatch` - The “copy from other stores” substituter mechanism @@ -58,26 +58,26 @@ This release has the following new features: `nix-build`, `nix-shell -p`, `nix-env -qa`, `nix-instantiate --eval`, `nix-push` and `nix-copy-closure`. It has the following major features: - + - Unlike the legacy commands, it has a consistent way to refer to packages and package-like arguments (like store paths). For example, the following commands all copy the GNU Hello package to a remote machine: - + nix copy --to ssh://machine nixpkgs.hello - + nix copy --to ssh://machine /nix/store/0i2jd68mp5g6h2sa5k9c85rb80sn8hi9-hello-2.10 - + nix copy --to ssh://machine '(with import {}; hello)' - + By contrast, `nix-copy-closure` only accepted store paths as arguments. - + - It is self-documenting: `--help` shows all available command-line arguments. If `--help` is given after a subcommand, it shows examples for that subcommand. `nix --help-config` shows all configuration options. - + - It is much less verbose. By default, it displays a single-line progress indicator that shows how many packages are left to be built or downloaded, and (if there are running builds) the most @@ -85,7 +85,7 @@ This release has the following new features: last few lines of builder output. The full build log can be retrieved using `nix log`. - + - It [provides](https://github.com/NixOS/nix/commit/b8283773bd64d7da6859ed520ee19867742a03ba) all `nix.conf` configuration options as command line flags. For @@ -93,122 +93,122 @@ This release has the following new features: http-connections 100` you can write `--http-connections 100`. Boolean options can be written as `--foo` or `--no-foo` (e.g. `--no-auto-optimise-store`). - + - Many subcommands have a `--json` flag to write results to stdout in JSON format. - + > **Warning** - > + > > Please note that the `nix` command is a work in progress and the > interface is subject to change. - + It provides the following high-level (“porcelain”) subcommands: - + - `nix build` is a replacement for `nix-build`. - + - `nix run` executes a command in an environment in which the specified packages are available. It is (roughly) a replacement for `nix-shell -p`. Unlike that command, it does not execute the command in a shell, and has a flag (`-c`) that specifies the unquoted command line to be executed. - + It is particularly useful in conjunction with chroot stores, allowing Linux users who do not have permission to install Nix in `/nix/store` to still use binary substitutes that assume `/nix/store`. For example, - + nix run --store ~/my-nix nixpkgs.hello -c hello --greeting 'Hi everybody!' - + downloads (or if not substitutes are available, builds) the GNU Hello package into `~/my-nix/nix/store`, then runs `hello` in a mount namespace where `~/my-nix/nix/store` is mounted onto `/nix/store`. - + - `nix search` replaces `nix-env -qa`. It searches the available packages for occurrences of a search string in the attribute name, package name or description. Unlike `nix-env -qa`, it has a cache to speed up subsequent searches. - + - `nix copy` copies paths between arbitrary Nix stores, generalising `nix-copy-closure` and `nix-push`. - + - `nix repl` replaces the external program `nix-repl`. It provides an interactive environment for evaluating and building Nix expressions. Note that it uses `linenoise-ng` instead of GNU Readline. - + - `nix upgrade-nix` upgrades Nix to the latest stable version. This requires that Nix is installed in a profile. (Thus it won’t work on NixOS, or if it’s installed outside of the Nix store.) - + - `nix verify` checks whether store paths are unmodified and/or “trusted” (see below). It replaces `nix-store --verify` and `nix-store --verify-path`. - + - `nix log` shows the build log of a package or path. If the build log is not available locally, it will try to obtain it from the configured substituters (such as [cache.nixos.org](https://cache.nixos.org/), which now provides build logs). - + - `nix edit` opens the source code of a package in your editor. - + - `nix eval` replaces `nix-instantiate --eval`. - + - `nix why-depends` shows why one store path has another in its closure. This is primarily useful to finding the causes of closure bloat. For example, - + nix why-depends nixpkgs.vlc nixpkgs.libdrm.dev - + shows a chain of files and fragments of file contents that cause the VLC package to have the “dev” output of `libdrm` in its closure — an undesirable situation. - + - `nix path-info` shows information about store paths, replacing `nix-store -q`. A useful feature is the option `--closure-size` (`-S`). For example, the following command show the closure sizes of every path in the current NixOS system closure, sorted by size: - + nix path-info -rS /run/current-system | sort -nk2 - + - `nix optimise-store` replaces `nix-store --optimise`. The main difference is that it has a progress indicator. - + A number of low-level (“plumbing”) commands are also available: - + - `nix ls-store` and `nix ls-nar` list the contents of a store path or NAR file. The former is primarily useful in conjunction with remote stores, e.g. - + nix ls-store --store https://cache.nixos.org/ -lR /nix/store/0i2jd68mp5g6h2sa5k9c85rb80sn8hi9-hello-2.10 - + lists the contents of path in a binary cache. - + - `nix cat-store` and `nix cat-nar` allow extracting a file from a store path or NAR file. - + - `nix dump-path` writes the contents of a store path to stdout in NAR format. This replaces `nix-store --dump`. - + - `nix show-derivation` displays a store derivation in JSON format. This is an alternative to `pp-aterm`. - + - `nix add-to-store` replaces `nix-store --add`. - + - `nix sign-paths` signs store paths. - + - `nix copy-sigs` copies signatures from one store to another. - + - `nix show-config` shows all configuration options and their current values. @@ -224,11 +224,11 @@ This release has the following new features: `nix-copy-closure`, `nix-push` and substitution are all instances of the general notion of copying paths between different kinds of Nix stores. - + Stores are specified using an URI-like syntax, e.g. or . The following store types are supported: - + - `LocalStore` (stori URI `local` or an absolute path) and the misnamed `RemoteStore` (`daemon`) provide access to a local Nix store, the latter via the Nix daemon. You can use `auto` or the @@ -236,63 +236,63 @@ This release has the following new features: whether you have write permission to the Nix store. It is no longer necessary to set the `NIX_REMOTE` environment variable to use the Nix daemon. - + As noted above, `LocalStore` now supports chroot builds, allowing the “physical” location of the Nix store (e.g. `/home/alice/nix/store`) to differ from its “logical” location (typically `/nix/store`). This allows non-root users to use Nix while still getting the benefits from prebuilt binaries from [cache.nixos.org](https://cache.nixos.org/). - + - `BinaryCacheStore` is the abstract superclass of all binary cache stores. It supports writing build logs and NAR content listings in JSON format. - + - `HttpBinaryCacheStore` (`http://`, `https://`) supports binary caches via HTTP or HTTPS. If the server supports `PUT` requests, it supports uploading store paths via commands such as `nix copy`. - + - `LocalBinaryCacheStore` (`file://`) supports binary caches in the local filesystem. - + - `S3BinaryCacheStore` (`s3://`) supports binary caches stored in Amazon S3, if enabled at compile time. - + - `LegacySSHStore` (`ssh://`) is used to implement remote builds and `nix-copy-closure`. - + - `SSHStore` (`ssh-ng://`) supports arbitrary Nix operations on a remote machine via the same protocol used by `nix-daemon`. - Security has been improved in various ways: - + - Nix now stores signatures for local store paths. When paths are copied between stores (e.g., copied from a binary cache to a local store), signatures are propagated. - + Locally-built paths are signed automatically using the secret keys specified by the `secret-key-files` store option. Secret/public key pairs can be generated using `nix-store --generate-binary-cache-key`. - + In addition, locally-built store paths are marked as “ultimately trusted”, but this bit is not propagated when paths are copied between stores. - + - Content-addressable store paths no longer require signatures — they can be imported into a store by unprivileged users even if they lack signatures. - + - The command `nix verify` checks whether the specified paths are trusted, i.e., have a certain number of trusted signatures, are ultimately trusted, or are content-addressed. - + - Substitutions from binary caches [now](https://github.com/NixOS/nix/commit/ecbc3fedd3d5bdc5a0e1a0a51b29062f2874ac8b) require signatures by default. This was already the case on NixOS. - + - In Linux sandbox builds, we [now](https://github.com/NixOS/nix/commit/eba840c8a13b465ace90172ff76a0db2899ab11b) use `/build` instead of `/tmp` as the temporary build directory. @@ -309,7 +309,7 @@ This release has the following new features: hash or commit hash is specified. For example, calls to `builtins.fetchGit` are only allowed if a `rev` attribute is specified. - + The goal of this feature is to enable true reproducibility and traceability of builds (including NixOS system configurations) at the evaluation level. For example, in the future, `nixos-rebuild` @@ -367,21 +367,21 @@ This release has the following new features: log will be shown if a build fails. - Networking has been improved: - + - HTTP/2 is now supported. This makes binary cache lookups [much more efficient](https://github.com/NixOS/nix/commit/90ad02bf626b885a5dd8967894e2eafc953bdf92). - + - We now retry downloads on many HTTP errors, making binary caches substituters more resilient to temporary failures. - + - HTTP credentials can now be configured via the standard `netrc` mechanism. - + - If S3 support is enabled at compile time, URIs are [supported](https://github.com/NixOS/nix/commit/9ff9c3f2f80ba4108e9c945bbfda2c64735f987b) in all places where Nix allows URIs. - + - Brotli compression is now supported. In particular, [cache.nixos.org](https://cache.nixos.org/) build logs are now compressed using Brotli. @@ -431,9 +431,9 @@ The Nix language has the following new features: - Derivation attributes can now reference the outputs of the derivation using the `placeholder` builtin function. For example, the attribute - + configureFlags = "--prefix=${placeholder "out"} --includedir=${placeholder "dev"}"; - + will cause the `configureFlags` environment variable to contain the actual store paths corresponding to the `out` and `dev` outputs. @@ -444,7 +444,7 @@ The following builtin functions are new or extended: Nixpkgs, which fetches at build time and cannot be used to fetch Nix expressions during evaluation. A typical use case is to import external NixOS modules from your configuration, e.g. - + imports = [ (builtins.fetchGit https://github.com/edolstra/dwarffs + "/module.nix") ]; - Similarly, `builtins.fetchMercurial` allows you to fetch Mercurial @@ -485,7 +485,7 @@ The Nix build environment has the following changes: builder via the file `.attrs.json` in the builder’s temporary directory. This obviates the need for `passAsFile` since JSON files have no size restrictions, unlike process environments. - + [As a convenience to Bash builders](https://github.com/NixOS/nix/commit/2d5b1b24bf70a498e4c0b378704cfdb6471cc699), Nix writes a script named `.attrs.sh` to the builder’s directory diff --git a/doc/manual/source/store/building.md b/doc/manual/source/store/building.md new file mode 100644 index 00000000000..79808273edc --- /dev/null +++ b/doc/manual/source/store/building.md @@ -0,0 +1,97 @@ +# Building + +## Normalizing derivation inputs + +- Each input must be [realised] prior to building the derivation in question. + +[realised]: @docroot@/glossary.md#gloss-realise + +- Once this is done, the derivation is *normalized*, replacing each input deriving path with its store path, which we now know from realising the input. + +## Builder Execution + +The [`builder`](./drv.md#builder) is executed as follows: + +- A temporary directory is created under the directory specified by + `TMPDIR` (default `/tmp`) where the build will take place. The + current directory is changed to this directory. + +- The environment is cleared and set to the derivation attributes, as + specified above. + +- In addition, the following variables are set: + + - `NIX_BUILD_TOP` contains the path of the temporary directory for + this build. + + - Also, `TMPDIR`, `TEMPDIR`, `TMP`, `TEMP` are set to point to the + temporary directory. This is to prevent the builder from + accidentally writing temporary files anywhere else. Doing so + might cause interference by other processes. + + - `PATH` is set to `/path-not-set` to prevent shells from + initialising it to their built-in default value. + + - `HOME` is set to `/homeless-shelter` to prevent programs from + using `/etc/passwd` or the like to find the user's home + directory, which could cause impurity. Usually, when `HOME` is + set, it is used as the location of the home directory, even if + it points to a non-existent path. + + - `NIX_STORE` is set to the path of the top-level Nix store + directory (typically, `/nix/store`). + + - `NIX_ATTRS_JSON_FILE` & `NIX_ATTRS_SH_FILE` if `__structuredAttrs` + is set to `true` for the derivation. A detailed explanation of this + behavior can be found in the + [section about structured attrs](@docroot@/language/advanced-attributes.md#adv-attr-structuredAttrs). + + - For each output declared in `outputs`, the corresponding + environment variable is set to point to the intended path in the + Nix store for that output. Each output path is a concatenation + of the cryptographic hash of all build inputs, the `name` + attribute and the output name. (The output name is omitted if + it’s `out`.) + +- If an output path already exists, it is removed. Also, locks are + acquired to prevent multiple Nix instances from performing the same + build at the same time. + +- A log of the combined standard output and error is written to + `/nix/var/log/nix`. + +- The builder is executed with the arguments specified by the + attribute `args`. If it exits with exit code 0, it is considered to + have succeeded. + +- The temporary directory is removed (unless the `-K` option was + specified). + +## Processing outputs + +If the builder exited successfully, the following steps happen in order to turn the output directories left behind by the builder into proper store objects: + +- **Normalize the file permissions** + + Nix sets the last-modified timestamp on all files + in the build result to 1 (00:00:01 1/1/1970 UTC), sets the group to + the default group, and sets the mode of the file to 0444 or 0555 + (i.e., read-only, with execute permission enabled if the file was + originally executable). Any possible `setuid` and `setgid` + bits are cleared. + + > **Note** + > + > Setuid and setgid programs are not currently supported by Nix. + > This is because the Nix archives used in deployment have no concept of ownership information, + > and because it makes the build result dependent on the user performing the build. + +- **Calculate the references** + + Nix scans each output path for + references to input paths by looking for the hash parts of the input + paths. Since these are potential runtime dependencies, Nix registers + them as dependencies of the output paths. + + Nix also scans for references to other outputs' paths in the same way, because outputs are allowed to refer to each other. + If the outputs' references to each other form a cycle, this is an error, because the references of store objects much be acyclic. diff --git a/doc/manual/source/store/drv.md b/doc/manual/source/store/drv.md new file mode 100644 index 00000000000..b359f85fc8d --- /dev/null +++ b/doc/manual/source/store/drv.md @@ -0,0 +1,310 @@ +# Store Derivation and Deriving Path + +Besides functioning as a [content addressed store] the Nix store layer works as a [build system]. +Other system (like Git or IPFS) also store and transfer immutable data, but they don't concern themselves with *how* that data was created. + +This is where Nix distinguishes itself. +*Derivations* represent individual build steps, and *deriving paths* are needed to refer to the *outputs* of those build steps before they are built. + + +## Store Derivation {#store-derivation} + +A derivation is a specification for running an executable on precisely defined input files to repeatably produce output files at uniquely determined file system paths. + +A derivation consists of: + + - A name + + - A set of [*inputs*][inputs], a set of [deriving paths][deriving path] + + - A map of [*outputs*][outputs], from names to other data + + - The ["system" type][system] (e.g. `x86_64-linux`) where the executable is to run. + + - The [process creation fields]: to spawn the arbitrary process which will perform the build step. + +[store derivation]: #store-derivation +[inputs]: #inputs +[input]: #inputs +[outputs]: #outputs +[output]: #outputs +[process creation fields]: #process-creation-fields +[builder]: #builder +[args]: #args +[env]: #env +[system]: #system + +### Referencing derivations {#derivation-path} + +Derivations are always referred to by the [store path] of the store object they are encoded to. +See the [encoding section](#derivation-encoding) for more details on how this encoding works, and thus what exactly what store path we would end up with for a given derivation. + +The store path of the store object which encodes a derivation is often called a *derivation path* for brevity. + +## Deriving path {#deriving-path} + +Deriving paths are a way to refer to [store objects][store object] that may or may not yet be [realised][realise]. +There are two forms: + +- [*constant*]{#deriving-path-constant}: just a [store path]. + It can be made [valid][validity] by copying it into the store: from the evaluator, command line interface or another store. + +- [*output*]{#deriving-path-output}: a pair of a [store path] to a [store derivation] and an [output] name. + +In pseudo code: + +```typescript +type OutputName = String; + +type ConstantPath = { + path: StorePath; +}; + +type OutputPath = { + drvPath: StorePath; + output: OutputName; +}; + +type DerivingPath = ConstantPath | OutputPath; +``` + +Deriving paths are necessary because, in general and particularly for [content-addressed derivations][content-addressed derivation], the [store path] of an [output] is not known in advance. +We can use an output deriving path to refer to such an out, instead of the store path which we do not yet know. + +[deriving path]: #deriving-path +[validity]: @docroot@/glossary.md#gloss-validity + +## Parts of a derivation + +A derivation is constructed from the parts documented in the following subsections. + +### Inputs {#inputs} + +The inputs are a set of [deriving paths][deriving path], refering to all store objects needed in order to perform this build step. + +The [process creation fields] will presumably include many [store paths][store path]: + + - The path to the executable normally starts with a store path + - The arguments and environment variables likely contain many other store paths. + +But rather than somehow scanning all the other fields for inputs, Nix requires that all inputs be explicitly collected in the inputs field. It is instead the responsibility of the creator of a derivation (e.g. the evaluator) to ensure that every store object referenced in another field (e.g. referenced by store path) is included in this inputs field. + +### Outputs {#outputs} + +The outputs are the derivations are the [store objects][store object] it is obligated to produce. + +Outputs are assigned names, and also consistent of other information based on the type of derivation. + +Output names can be any string which is also a valid [store path] name. +The store path of the output store object (also called an [output path] for short), has a name based on the derivation name and the output name. +In the general case, store paths have name `derivationName + "-" + outputName`. +However, an output named "out" has a store path with name is just the derivation name. +This is to allow derivations with a single output to avoid a superfluous `"-${outputName}"` in their single output's name when no disambiguation is needed. + +> **Example** +> +> A derivation is named `hello`, and has two outputs, `out`, and `dev` +> +> - The derivation's path will be: `/nix/store/-hello.drv`. +> +> - The store path of `out` will be: `/nix/store/-hello`. +> +> - The store path of `dev` will be: `/nix/store/-hello-dev`. + +### System {#system} + +The system type on which the [`builder`](#attr-builder) executable is meant to be run. + +A necessary condition for Nix to schedule a given derivation on some Nix instance is for the "system" of that derivation to match that instance's [`system` configuration option]. + +By putting the `system` in each derivation, Nix allows *heterogenous* build plans, where not all steps can be run on the same machine or same sort of machine. +Nix can schedule builds such that it automatically builds on other platforms by [forwarding build requests](@docroot@/advanced-topics/distributed-builds.md) to other Nix instances. + +[`system` configuration option]: @docroot@/command-ref/conf-file.md#conf-system + +[content-addressed derivation]: @docroot@/glossary.md#gloss-content-addressed-derivation +[realise]: @docroot@/glossary.md#gloss-realise +[store object]: @docroot@/store/store-object.md +[store path]: @docroot@/store/store-path.md + +### Process creation fields {#process-creation-fields} + +These are the three fields which describe how to spawn the process which (along with any of its own child processes) will perform the build. +You may note that this has everything needed for an `execve` system call. + +#### Builder {#builder} + +This is the path to an executable that will perform the build and produce the [outputs]. + +#### Arguments {#args} + +Command-line arguments to be passed to the [`builder`](#builder) executable. + +Note that these are the arguments after the first argument. +The first argument passed to the `builder` will be the value of `builder`, as per the usual convention on Unix. +See [Wikipedia](https://en.wikipedia.org/wiki/Argv) for details. + +#### Environment Variables {#env} + +Environment variables which will be passed to the [builder](#builder) executable. + +### Placeholders + +Placeholders are opaque values used within the [process creation fields] to [store objects] for which we don't yet know [store path]s. +They are strings in the form `/` that are embedded anywhere within the strings of those fields, and we are [considering](https://github.com/NixOS/nix/issues/12361) to add store-path-like placeholders. + +> **Note** +> +> Output Deriving Path exist to solve the same problem as placeholders --- that is, referring to store objects for which we don't yet know a store path. +> They also have a string syntax with `^`, [described in the encoding section](#deriving-path-encoding). +> We could use that syntax instead of `/` for placeholders, but its human-legibility would cause problems. + +There are two types of placeholder, corresponding to the two cases where this problem arises: + +- [Output placeholder]{#output-placeholder}: + + This is a placeholder for a derivation's own output. + +- [Input placeholder]{#input-placeholder}: + + This is a placeholder to a derivation's non-constant [input], + i.e. an input that is an [output derived path]. + +> **Explanation** +> +> In general, we need to realise [realise] a [store object] in order to be sure to have a store object for it. +> But for these two cases this is either impossible or impractical: +> +> - In the output case this is impossible: +> +> We cannot build the output until we have a correct derivation, and we cannot have a correct derivation (without using placeholders) until we have the output path. +> +> - In the input case this is impractical: +> +> If we always build a dependency first, and then refer to its output by store path, we would lose the ability for a derivation graph to describe an entire build plan consisting of multiple build steps. + +## Encoding + +### Derivation {#derivation-encoding} + +There are two formats, documented separately: + +- The legacy ["ATerm" format](@docroot@/protocols/derivation-aterm.md) + +- The experimental, currently under development and changing [JSON format](@docroot@/protocols/json/derivation.md) + +Every derivation has a canonical choice of encoding used to serialize it to a store object. +This ensures that there is a canonical [store path] used to refer to the derivation, as described in [Referencing derivations](#derivation-path). + +> **Note** +> +> Currently, the canonical encoding for every derivation is the "ATerm" format, +> but this is subject to change for types derivations which are not yet stable. + +Regardless of the format used, when serializing a derivation to a store object, that store object will be content-addressed. + +In the common case, the inputs to store objects are either: + + - [constant deriving paths](#deriving-path-constant) for content-addressed source objects, which are "initial inputs" rather than the outputs of some other derivation + + - the outputs of other derivations + +If those other derivations *also* abide by this common case (and likewise for transitive inputs), then the entire closure of the serialized derivation will be content-addressed. + +### Deriving Path {#deriving-path-encoding} + +- *constant* + + Constant deriving paths are encoded simply as the underlying store path is. + Thus, we see that every encoded store path is also a valid encoded (constant) deriving path. + +- *output* + + Output deriving paths are encoded by + + - encoding of a store path referring to a derivation + + - a `^` separator (or `!` in some legacy contexts) + + - the name of an output of the previously referred derivation + + > **Example** + > + > ``` + > /nix/store/lxrn8v5aamkikg6agxwdqd1jz7746wz4-firefox-98.0.2.drv^out + > ``` + > + > This parses like so: + > + > ``` + > /nix/store/lxrn8v5aamkikg6agxwdqd1jz7746wz4-firefox-98.0.2.drv^out + > |------------------------------------------------------------| |-| + > store path (usual encoding) output name + > |--| + > note the ".drv" + > ``` + +## Extending the model to be higher-order + +**Experimental feature**: [`dynamic-derivations`](@docroot@/development/experimental-features.md#xp-feature-dynamic-derivations) + +So far, we have used store paths to refer to derivations. +That works because we've implicitly assumed that all derivations are created *statically* --- created by some mechanism out of band, and then manually inserted into the store. +But what if derivations could also be created dynamically within Nix? +In other words, what if derivations could be the outputs of other derivations? + +:::{.note} +In the parlance of "Build Systems à la carte", we are generalizing the Nix store layer to be a "Monadic" instead of "Applicative" build system. +::: + +How should we refer to such derivations? +A deriving path works, the same as how we refer to other derivation outputs. +But what about a dynamic derivations output? +(i.e. how do we refer to the output of an output of a derivation?) +For that we need to generalize the definition of deriving path, replacing the store path used to refer to the derivation with a nested deriving path: + +```diff + type OutputPath = { +- drvPath: StorePath; ++ drvPath: DerivingPath; + output: OutputName; + }; +``` + +Now, the `drvPath` field of `OutputPath` is itself a `DerivingPath` instead of a `StorePath`. + +With that change, here is updated definition: + +```typescript +type OutputName = String; + +type ConstantPath = { + path: StorePath; +}; + +type OutputPath = { + drvPath: DerivingPath; + output: OutputName; +}; + +type DerivingPath = ConstantPath | OutputPath; +``` + +Under this extended model, `DerivingPath`s are thus inductively built up from a root `ConstantPath`, wrapped with zero or more outer `OutputPath`s. + +### Encoding {#deriving-path-encoding} + +The encoding is adjusted in the natural way, encoding the `drv` field recursively using the same deriving path encoding. +The result of this is that it is possible to have a chain of `^` at the end of the final string, as opposed to just a single one. + +> **Example** +> +> ``` +> /nix/store/lxrn8v5aamkikg6agxwdqd1jz7746wz4-firefox-98.0.2.drv^foo.drv^bar.drv^out +> |----------------------------------------------------------------------------| |-| +> inner deriving path (usual encoding) output name +> |--------------------------------------------------------------------| |-----| +> even more inner deriving path (usual encoding) output name +> |------------------------------------------------------------| |-----| +> innermost constant store path (usual encoding) output name +> ``` diff --git a/src/libcmd/misc-store-flags.cc b/src/libcmd/misc-store-flags.cc index 242bd4483e2..4e29e8981ae 100644 --- a/src/libcmd/misc-store-flags.cc +++ b/src/libcmd/misc-store-flags.cc @@ -120,7 +120,7 @@ Args::Flag contentAddressMethod(ContentAddressMethod * method) - [`text`](@docroot@/store/store-object/content-address.md#method-text): Like `flat`, but used for - [derivations](@docroot@/glossary.md#store-derivation) serialized in store object and + [derivations](@docroot@/glossary.md#gloss-store-derivation) serialized in store object and [`builtins.toFile`](@docroot@/language/builtins.html#builtins-toFile). For advanced use-cases only; for regular usage prefer `nar` and `flat`. diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index e6f6f1dda24..51d2991e799 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -1595,9 +1595,13 @@ static RegisterPrimOp primop_placeholder({ .name = "placeholder", .args = {"output"}, .doc = R"( - Return a placeholder string for the specified *output* that will be - substituted by the corresponding output path at build time. Typical - outputs would be `"out"`, `"bin"` or `"dev"`. + Return at + [output placeholder string](@docroot@/store/drv.md#output-placeholder) + for the specified *output* that will be substituted by the corresponding + [output path](@docroot@/glossary.md#gloss-output-path) + at build time. + + Typical outputs would be `"out"`, `"bin"` or `"dev"`. )", .fun = prim_placeholder, }); @@ -2135,12 +2139,15 @@ static RegisterPrimOp primop_outputOf({ .name = "__outputOf", .args = {"derivation-reference", "output-name"}, .doc = R"( - Return the output path of a derivation, literally or using a placeholder if needed. + Return the output path of a derivation, literally or using an + [input placeholder string](@docroot@/store/drv.md#input-placeholder) + if needed. If the derivation has a statically-known output path (i.e. the derivation output is input-addressed, or fixed content-addresed), the output path will just be returned. - But if the derivation is content-addressed or if the derivation is itself not-statically produced (i.e. is the output of another derivation), a placeholder will be returned instead. + But if the derivation is content-addressed or if the derivation is itself not-statically produced (i.e. is the output of another derivation), an input placeholder will be returned instead. - *`derivation reference`* must be a string that may contain a regular store path to a derivation, or may be a placeholder reference. If the derivation is produced by a derivation, you must explicitly select `drv.outPath`. + *`derivation reference`* must be a string that may contain a regular store path to a derivation, or may be an input placeholder reference. + If the derivation is produced by a derivation, you must explicitly select `drv.outPath`. This primop can be chained arbitrarily deeply. For instance, @@ -2150,9 +2157,9 @@ static RegisterPrimOp primop_outputOf({ "out" ``` - will return a placeholder for the output of the output of `myDrv`. + will return a input placeholder for the output of the output of `myDrv`. - This primop corresponds to the `^` sigil for derivable paths, e.g. as part of installable syntax on the command line. + This primop corresponds to the `^` sigil for [deriving paths](@docroot@/glossary.md#gloss-deriving-paths), e.g. as part of installable syntax on the command line. )", .fun = prim_outputOf, .experimentalFeature = Xp::DynamicDerivations, diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index ff3df46ba9e..e9a18016480 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -189,7 +189,7 @@ public: this, SYSTEM, "system", R"( The system type of the current Nix installation. - Nix will only build a given [derivation](@docroot@/language/derivations.md) locally when its `system` attribute equals any of the values specified here or in [`extra-platforms`](#conf-extra-platforms). + Nix will only build a given [store derivation](@docroot@/glossary.md#gloss-store-derivation) locally when its `system` attribute equals any of the values specified here or in [`extra-platforms`](#conf-extra-platforms). The default value is set when Nix itself is compiled for the system it will run on. The following system types are widely used, as Nix is actively supported on these platforms: @@ -825,7 +825,7 @@ public: R"( System types of executables that can be run on this machine. - Nix will only build a given [derivation](@docroot@/language/derivations.md) locally when its `system` attribute equals any of the values specified here or in the [`system` option](#conf-system). + Nix will only build a given [store derivation](@docroot@/glossary.md#gloss-store-derivation) locally when its `system` attribute equals any of the values specified here or in the [`system` option](#conf-system). Setting this can be useful to build derivations locally on compatible machines: - `i686-linux` executables can be run on `x86_64-linux` machines (set by default) diff --git a/src/nix/derivation-show.cc b/src/nix/derivation-show.cc index bf637246d83..5a07f58e6dc 100644 --- a/src/nix/derivation-show.cc +++ b/src/nix/derivation-show.cc @@ -1,5 +1,5 @@ -// FIXME: integrate this with nix path-info? -// FIXME: rename to 'nix store derivation show' or 'nix debug derivation show'? +// FIXME: integrate this with `nix path-info`? +// FIXME: rename to 'nix store derivation show'? #include "command.hh" #include "common-args.hh" diff --git a/src/nix/search.md b/src/nix/search.md index f65ac9b1748..d355a7764dc 100644 --- a/src/nix/search.md +++ b/src/nix/search.md @@ -62,8 +62,8 @@ R""( # Description -`nix search` searches [*installable*](./nix.md#installables) (which can be evaluated, that is, a -flake or Nix expression, but not a store path or store derivation path) for packages whose name or description matches all of the +`nix search` searches [*installable*](./nix.md#installables) that can be evaluated, that is, a +flake or Nix expression, but not a [store path] or [deriving path]) for packages whose name or description matches all of the regular expressions *regex*. For each matching package, It prints the full attribute name (from the root of the [installable](./nix.md#installables)), the version and the `meta.description` field, highlighting the substrings that @@ -75,6 +75,9 @@ it avoids highlighting the entire name and description of every package. > Note that in this context, `^` is the regex character to match the beginning of a string, *not* the delimiter for > [selecting a derivation output](@docroot@/command-ref/new-cli/nix.md#derivation-output-selection). +[store path]: @docroot@/glossary.md#gloss-store-path +[deriving path]: @docroot@/glossary.md#gloss-deriving-path + # Flake output attributes If no flake output attribute is given, `nix search` searches for From cafefed421c736e27d248d2221426421c10c9539 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Mon, 10 Feb 2025 01:12:56 -0500 Subject: [PATCH 60/60] Rename to "content-address*ing* derivation" "content-address*ed*" derivation is misleading because all derivations are *themselves* content-addressed. What may or may not be content-addressed is not derivation itself, but the *output* of the derivation. The outputs are not *part* of the derivation (for then the derivation wouldn't be complete before we built it) but rather separate entities produced by the derivation. "content-adddress*ed*" is not correctly because it can only describe what the derivation *is*, and that is not what we are trying to do. "content-address*ing*" is correct because it describes what the derivation *does* --- it produces content-addressed data. --- doc/manual/redirects.js | 1 + doc/manual/source/command-ref/nix-store/realise.md | 4 ++-- doc/manual/source/development/testing.md | 2 +- doc/manual/source/glossary.md | 8 ++++---- doc/manual/source/store/drv.md | 4 ++-- src/libexpr-tests/nix_api_expr.cc | 2 +- src/libstore/build/derivation-goal.cc | 2 +- src/libstore/ca-specific-schema.sql | 2 +- src/libstore/daemon.cc | 2 +- src/libstore/derivations.cc | 2 +- src/libstore/derivations.hh | 2 +- src/libstore/remote-store.cc | 2 +- src/libstore/store-api.hh | 2 +- src/libstore/unix/build/local-derivation-goal.cc | 4 ++-- src/libstore/unix/build/local-derivation-goal.hh | 2 +- src/nix-store/nix-store.cc | 2 +- tests/functional/ca/content-addressed.nix | 2 +- tests/functional/ca/derivation-json.sh | 2 +- tests/functional/dyn-drv/old-daemon-error-hack.nix | 2 +- tests/functional/dyn-drv/text-hashed-output.nix | 2 +- 20 files changed, 26 insertions(+), 25 deletions(-) diff --git a/doc/manual/redirects.js b/doc/manual/redirects.js index a1d30d9e81c..17fb66f2870 100644 --- a/doc/manual/redirects.js +++ b/doc/manual/redirects.js @@ -375,6 +375,7 @@ const redirects = { "glossary.html": { "gloss-local-store": "store/types/local-store.html", "gloss-chroot-store": "store/types/local-store.html", + "gloss-content-addressed-derivation": "#gloss-content-addressing-derivation", }, }; diff --git a/doc/manual/source/command-ref/nix-store/realise.md b/doc/manual/source/command-ref/nix-store/realise.md index a899758dfab..240685ce5c7 100644 --- a/doc/manual/source/command-ref/nix-store/realise.md +++ b/doc/manual/source/command-ref/nix-store/realise.md @@ -15,7 +15,7 @@ Each of *paths* is processed as follows: 1. If it is not [valid], substitute the store derivation file itself. 2. Realise its [output paths]: - Try to fetch from [substituters] the [store objects] associated with the output paths in the store derivation's [closure]. - - With [content-addressed derivations] (experimental): + - With [content-addressing derivations] (experimental): Determine the output paths to realise by querying content-addressed realisation entries in the [Nix database]. - For any store paths that cannot be substituted, produce the required store objects: 1. Realise all outputs of the derivation's dependencies @@ -32,7 +32,7 @@ If no substitutes are available and no store derivation is given, realisation fa [store objects]: @docroot@/store/store-object.md [closure]: @docroot@/glossary.md#gloss-closure [substituters]: @docroot@/command-ref/conf-file.md#conf-substituters -[content-addressed derivations]: @docroot@/development/experimental-features.md#xp-feature-ca-derivations +[content-addressing derivations]: @docroot@/development/experimental-features.md#xp-feature-ca-derivations [Nix database]: @docroot@/glossary.md#gloss-nix-database The resulting paths are printed on standard output. diff --git a/doc/manual/source/development/testing.md b/doc/manual/source/development/testing.md index 7d8a9cb18e8..d0c3a1c784e 100644 --- a/doc/manual/source/development/testing.md +++ b/doc/manual/source/development/testing.md @@ -164,7 +164,7 @@ $ checkPhase Sometimes it is useful to group related tests so they can be easily run together without running the entire test suite. Each test group is in a subdirectory of `tests`. -For example, `tests/functional/ca/meson.build` defines a `ca` test group for content-addressed derivation outputs. +For example, `tests/functional/ca/meson.build` defines a `ca` test group for content-addressing derivation outputs. That test group can be run like this: diff --git a/doc/manual/source/glossary.md b/doc/manual/source/glossary.md index 772116e9886..a1964070588 100644 --- a/doc/manual/source/glossary.md +++ b/doc/manual/source/glossary.md @@ -13,7 +13,7 @@ - [Content-Addressing File System Objects](@docroot@/store/file-system-object/content-address.md) - [Content-Addressing Store Objects](@docroot@/store/store-object/content-address.md) - - [content-addressed derivation](#gloss-content-addressed-derivation) + - [content-addressing derivation](#gloss-content-addressing-derivation) Software Heritage's writing on [*Intrinsic and Extrinsic identifiers*](https://www.softwareheritage.org/2020/07/09/intrinsic-vs-extrinsic-identifiers) is also a good introduction to the value of content-addressing over other referencing schemes. @@ -69,7 +69,7 @@ [realise]: #gloss-realise -- [content-addressed derivation]{#gloss-content-addressed-derivation} +- [content-addressing derivation]{#gloss-content-addressing-derivation} A derivation which has the [`__contentAddressed`](./language/advanced-attributes.md#adv-attr-__contentAddressed) @@ -134,7 +134,7 @@ - [input-addressed store object]{#gloss-input-addressed-store-object} A store object produced by building a - non-[content-addressed](#gloss-content-addressed-derivation), + non-[content-addressed](#gloss-content-addressing-derivation), non-[fixed-output](#gloss-fixed-output-derivation) derivation. @@ -142,7 +142,7 @@ A [store object] which is [content-addressed](#gloss-content-address), i.e. whose [store path] is determined by its contents. - This includes derivations, the outputs of [content-addressed derivations](#gloss-content-addressed-derivation), and the outputs of [fixed-output derivations](#gloss-fixed-output-derivation). + This includes derivations, the outputs of [content-addressing derivations](#gloss-content-addressing-derivation), and the outputs of [fixed-output derivations](#gloss-fixed-output-derivation). See [Content-Addressing Store Objects](@docroot@/store/store-object/content-address.md) for details. diff --git a/doc/manual/source/store/drv.md b/doc/manual/source/store/drv.md index b359f85fc8d..83ca80aaabd 100644 --- a/doc/manual/source/store/drv.md +++ b/doc/manual/source/store/drv.md @@ -68,7 +68,7 @@ type OutputPath = { type DerivingPath = ConstantPath | OutputPath; ``` -Deriving paths are necessary because, in general and particularly for [content-addressed derivations][content-addressed derivation], the [store path] of an [output] is not known in advance. +Deriving paths are necessary because, in general and particularly for [content-addressing derivations][content-addressing derivation], the [store path] of an [output] is not known in advance. We can use an output deriving path to refer to such an out, instead of the store path which we do not yet know. [deriving path]: #deriving-path @@ -122,7 +122,7 @@ Nix can schedule builds such that it automatically builds on other platforms by [`system` configuration option]: @docroot@/command-ref/conf-file.md#conf-system -[content-addressed derivation]: @docroot@/glossary.md#gloss-content-addressed-derivation +[content-addressing derivation]: @docroot@/glossary.md#gloss-content-addressing-derivation [realise]: @docroot@/glossary.md#gloss-realise [store object]: @docroot@/store/store-object.md [store path]: @docroot@/store/store-path.md diff --git a/src/libexpr-tests/nix_api_expr.cc b/src/libexpr-tests/nix_api_expr.cc index 5ed78d2fcd9..633224ae6d2 100644 --- a/src/libexpr-tests/nix_api_expr.cc +++ b/src/libexpr-tests/nix_api_expr.cc @@ -172,7 +172,7 @@ TEST_F(nix_api_expr_test, nix_expr_realise_context_bad_build) TEST_F(nix_api_expr_test, nix_expr_realise_context) { - // TODO (ca-derivations): add a content-addressed derivation output, which produces a placeholder + // TODO (ca-derivations): add a content-addressing derivation output, which produces a placeholder auto expr = R"( '' a derivation output: ${ diff --git a/src/libstore/build/derivation-goal.cc b/src/libstore/build/derivation-goal.cc index 0d16f09750b..d09da1f5584 100644 --- a/src/libstore/build/derivation-goal.cc +++ b/src/libstore/build/derivation-goal.cc @@ -1222,7 +1222,7 @@ SingleDrvOutputs DerivationGoal::registerOutputs() to do anything here. We can only early return when the outputs are known a priori. For - floating content-addressed derivations this isn't the case. + floating content-addressing derivations this isn't the case. */ return assertPathValidity(); } diff --git a/src/libstore/ca-specific-schema.sql b/src/libstore/ca-specific-schema.sql index 4ca91f58544..c5e4e389799 100644 --- a/src/libstore/ca-specific-schema.sql +++ b/src/libstore/ca-specific-schema.sql @@ -1,4 +1,4 @@ --- Extension of the sql schema for content-addressed derivations. +-- Extension of the sql schema for content-addressing derivations. -- Won't be loaded unless the experimental feature `ca-derivations` -- is enabled diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc index b921dbe2de8..d6745f51612 100644 --- a/src/libstore/daemon.cc +++ b/src/libstore/daemon.cc @@ -593,7 +593,7 @@ static void performOp(TunnelLogger * logger, ref store, auto drvType = drv.type(); - /* Content-addressed derivations are trustless because their output paths + /* Content-addressing derivations are trustless because their output paths are verified by their content alone, so any derivation is free to try to produce such a path. diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index 1f37b0c384c..5d01c577cbe 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -300,7 +300,7 @@ static DerivationOutput parseDerivationOutput( } else { xpSettings.require(Xp::CaDerivations); if (pathS != "") - throw FormatError("content-addressed derivation output should not specify output path"); + throw FormatError("content-addressing derivation output should not specify output path"); return DerivationOutput::CAFloating { .method = std::move(method), .hashAlgo = std::move(hashAlgo), diff --git a/src/libstore/derivations.hh b/src/libstore/derivations.hh index 765b66ade2a..7856aa9b9fc 100644 --- a/src/libstore/derivations.hh +++ b/src/libstore/derivations.hh @@ -187,7 +187,7 @@ struct DerivationType { }; /** - * Content-addressed derivation types + * Content-addressing derivation types */ struct ContentAddressed { /** diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index b230079eb27..533ea557d25 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -608,7 +608,7 @@ void RemoteStore::queryRealisationUncached(const DrvOutput & id, auto conn(getConnection()); if (GET_PROTOCOL_MINOR(conn->protoVersion) < 27) { - warn("the daemon is too old to support content-addressed derivations, please upgrade it to 2.4"); + warn("the daemon is too old to support content-addressing derivations, please upgrade it to 2.4"); return callback(nullptr); } diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 474dffcb5da..2eba88ea046 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -715,7 +715,7 @@ public: /** * Given a store path, return the realisation actually used in the realisation of this path: - * - If the path is a content-addressed derivation, try to resolve it + * - If the path is a content-addressing derivation, try to resolve it * - Otherwise, find one of its derivers */ std::optional getBuildDerivationPath(const StorePath &); diff --git a/src/libstore/unix/build/local-derivation-goal.cc b/src/libstore/unix/build/local-derivation-goal.cc index 9d26c0b0578..21eb1506d7f 100644 --- a/src/libstore/unix/build/local-derivation-goal.cc +++ b/src/libstore/unix/build/local-derivation-goal.cc @@ -800,7 +800,7 @@ void LocalDerivationGoal::startBuilder() out. */ for (auto & i : drv->outputsAndOptPaths(worker.store)) { /* If the name isn't known a priori (i.e. floating - content-addressed derivation), the temporary location we use + content-addressing derivation), the temporary location we use should be fresh. Freshness means it is impossible that the path is already in the sandbox, so we don't need to worry about removing it. */ @@ -2291,7 +2291,7 @@ SingleDrvOutputs LocalDerivationGoal::registerOutputs() to do anything here. We can only early return when the outputs are known a priori. For - floating content-addressed derivations this isn't the case. + floating content-addressing derivations this isn't the case. */ if (hook) return DerivationGoal::registerOutputs(); diff --git a/src/libstore/unix/build/local-derivation-goal.hh b/src/libstore/unix/build/local-derivation-goal.hh index 1ea2476610a..917028880c5 100644 --- a/src/libstore/unix/build/local-derivation-goal.hh +++ b/src/libstore/unix/build/local-derivation-goal.hh @@ -130,7 +130,7 @@ struct LocalDerivationGoal : public DerivationGoal * rewrite after the build. Otherwise the regular predetermined paths are * put here. * - * - Floating content-addressed derivations do not know their final build + * - Floating content-addressing derivations do not know their final build * output paths until the outputs are hashed, so random locations are * used, and then renamed. The randomness helps guard against hidden * self-references. diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index 99bb2c72601..89eaf35842a 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -252,7 +252,7 @@ static StorePathSet maybeUseOutputs(const StorePath & storePath, bool useOutput, return store->queryDerivationOutputs(storePath); for (auto & i : drv.outputsAndOptPaths(*store)) { if (!i.second.second) - throw UsageError("Cannot use output path of floating content-addressed derivation until we know what it is (e.g. by building it)"); + throw UsageError("Cannot use output path of floating content-addressing derivation until we know what it is (e.g. by building it)"); outputs.insert(*i.second.second); } return outputs; diff --git a/tests/functional/ca/content-addressed.nix b/tests/functional/ca/content-addressed.nix index 6ed9c185b62..e15208491d2 100644 --- a/tests/functional/ca/content-addressed.nix +++ b/tests/functional/ca/content-addressed.nix @@ -16,7 +16,7 @@ in { seed ? 0, }: -# A simple content-addressed derivation. +# A simple content-addressing derivation. # The derivation can be arbitrarily modified by passing a different `seed`, # but the output will always be the same rec { diff --git a/tests/functional/ca/derivation-json.sh b/tests/functional/ca/derivation-json.sh index bd6dd7177c6..0b8bcac0cc8 100644 --- a/tests/functional/ca/derivation-json.sh +++ b/tests/functional/ca/derivation-json.sh @@ -12,7 +12,7 @@ drvPath2=$(nix derivation add < "$TEST_HOME"/simple.json) [[ "$drvPath" = "$drvPath2" ]] -# Content-addressed derivations can be renamed. +# Content-addressing derivations can be renamed. jq '.name = "foo"' < "$TEST_HOME"/simple.json > "$TEST_HOME"/foo.json drvPath3=$(nix derivation add --dry-run < "$TEST_HOME"/foo.json) # With --dry-run nothing is actually written diff --git a/tests/functional/dyn-drv/old-daemon-error-hack.nix b/tests/functional/dyn-drv/old-daemon-error-hack.nix index c9d4a62d4f4..d5da3b3ab80 100644 --- a/tests/functional/dyn-drv/old-daemon-error-hack.nix +++ b/tests/functional/dyn-drv/old-daemon-error-hack.nix @@ -1,6 +1,6 @@ with import ./config.nix; -# A simple content-addressed derivation. +# A simple content-addressing derivation. # The derivation can be arbitrarily modified by passing a different `seed`, # but the output will always be the same rec { diff --git a/tests/functional/dyn-drv/text-hashed-output.nix b/tests/functional/dyn-drv/text-hashed-output.nix index 99203b51849..65d7ab35a6f 100644 --- a/tests/functional/dyn-drv/text-hashed-output.nix +++ b/tests/functional/dyn-drv/text-hashed-output.nix @@ -1,6 +1,6 @@ with import ./config.nix; -# A simple content-addressed derivation. +# A simple content-addressing derivation. # The derivation can be arbitrarily modified by passing a different `seed`, # but the output will always be the same rec {