Merge pull request #178717 from ShamrockLee/write-multiple-references

trivial-builders: replace writeReferencesToFile with writeClosure

authored by Someone and committed by GitHub 63709965 84102223

+85 -60
+7 -3
doc/build-helpers/trivial-build-helpers.chapter.md
··· 658 659 ## `writeReferencesToFile` {#trivial-builder-writeReferencesToFile} 660 661 - Writes the closure of transitive dependencies to a file. 662 663 - This produces the equivalent of `nix-store -q --requisites`. 664 665 For example, 666 667 ```nix 668 - writeReferencesToFile (writeScriptBin "hi" ''${hello}/bin/hello'') 669 ``` 670 671 produces an output path `/nix/store/<hash>-runtime-deps` containing
··· 658 659 ## `writeReferencesToFile` {#trivial-builder-writeReferencesToFile} 660 661 + Deprecated. Use [`writeClosure`](#trivial-builder-writeClosure) instead. 662 663 + ## `writeClosure` {#trivial-builder-writeClosure} 664 + 665 + Given a list of [store paths](https://nixos.org/manual/nix/stable/glossary#gloss-store-path) (or string-like expressions coercible to store paths), write their collective [closure](https://nixos.org/manual/nix/stable/glossary#gloss-closure) to a text file. 666 + 667 + The result is equivalent to the output of `nix-store -q --requisites`. 668 669 For example, 670 671 ```nix 672 + writeClosure [ (writeScriptBin "hi" ''${hello}/bin/hello'') ] 673 ``` 674 675 produces an output path `/nix/store/<hash>-runtime-deps` containing
+2
nixos/doc/manual/release-notes/rl-2405.section.md
··· 171 172 - Invidious has changed its default database username from `kemal` to `invidious`. Setups involving an externally provisioned database (i.e. `services.invidious.database.createLocally == false`) should adjust their configuration accordingly. The old `kemal` user will not be removed automatically even when the database is provisioned automatically.(https://github.com/NixOS/nixpkgs/pull/265857) 173 174 - `inetutils` now has a lower priority to avoid shadowing the commonly used `util-linux`. If one wishes to restore the default priority, simply use `lib.setPrio 5 inetutils` or override with `meta.priority = 5`. 175 176 - `paperless`' `services.paperless.extraConfig` setting has been removed and converted to the freeform type and option named `services.paperless.settings`.
··· 171 172 - Invidious has changed its default database username from `kemal` to `invidious`. Setups involving an externally provisioned database (i.e. `services.invidious.database.createLocally == false`) should adjust their configuration accordingly. The old `kemal` user will not be removed automatically even when the database is provisioned automatically.(https://github.com/NixOS/nixpkgs/pull/265857) 173 174 + - `writeReferencesToFile` is deprecated in favour of the new trivial build helper `writeClosure`. The latter accepts a list of paths and has an unambiguous name and cleaner implementation. 175 + 176 - `inetutils` now has a lower priority to avoid shadowing the commonly used `util-linux`. If one wishes to restore the default priority, simply use `lib.setPrio 5 inetutils` or override with `meta.priority = 5`. 177 178 - `paperless`' `services.paperless.extraConfig` setting has been removed and converted to the freeform type and option named `services.paperless.settings`.
-18
nixos/tests/nixops/default.nix
··· 93 94 inherit (import ../ssh-keys.nix pkgs) snakeOilPrivateKey snakeOilPublicKey; 95 96 - /* 97 - Return a store path with a closure containing everything including 98 - derivations and all build dependency outputs, all the way down. 99 - */ 100 - allDrvOutputs = pkg: 101 - let name = "allDrvOutputs-${pkg.pname or pkg.name or "unknown"}"; 102 - in 103 - pkgs.runCommand name { refs = pkgs.writeReferencesToFile pkg.drvPath; } '' 104 - touch $out 105 - while read ref; do 106 - case $ref in 107 - *.drv) 108 - cat $ref >>$out 109 - ;; 110 - esac 111 - done <$refs 112 - ''; 113 - 114 in 115 tests
··· 93 94 inherit (import ../ssh-keys.nix pkgs) snakeOilPrivateKey snakeOilPublicKey; 95 96 in 97 tests
+2 -2
pkgs/build-support/docker/default.nix
··· 29 , tarsum 30 , util-linux 31 , vmTools 32 - , writeReferencesToFile 33 , writeScript 34 , writeShellScriptBin 35 , writeText ··· 630 imageName = lib.toLower name; 631 imageTag = lib.optionalString (tag != null) tag; 632 inherit fromImage baseJson; 633 - layerClosure = writeReferencesToFile layer; 634 passthru.buildArgs = args; 635 passthru.layer = layer; 636 passthru.imageTag =
··· 29 , tarsum 30 , util-linux 31 , vmTools 32 + , writeClosure 33 , writeScript 34 , writeShellScriptBin 35 , writeText ··· 630 imageName = lib.toLower name; 631 imageTag = lib.optionalString (tag != null) tag; 632 inherit fromImage baseJson; 633 + layerClosure = writeClosure [ layer ]; 634 passthru.buildArgs = args; 635 passthru.layer = layer; 636 passthru.imageTag =
+2 -2
pkgs/build-support/oci-tools/default.nix
··· 1 - { lib, writeText, runCommand, writeReferencesToFile }: 2 3 { 4 buildContainer = ··· 72 set -o pipefail 73 mkdir -p $out/rootfs/{dev,proc,sys} 74 cp ${config} $out/config.json 75 - xargs tar c < ${writeReferencesToFile args} | tar -xC $out/rootfs/ 76 ''; 77 } 78
··· 1 + { lib, writeText, runCommand, writeClosure }: 2 3 { 4 buildContainer = ··· 72 set -o pipefail 73 mkdir -p $out/rootfs/{dev,proc,sys} 74 cp ${config} $out/config.json 75 + xargs tar c < ${writeClosure args} | tar -xC $out/rootfs/ 76 ''; 77 } 78
+2 -2
pkgs/build-support/references-by-popularity/closure-graph.py
··· 8 # and how deep in the tree they live. Equally-"popular" paths are then 9 # sorted by name. 10 # 11 - # The existing writeReferencesToFile prints the paths in a simple 12 - # ascii-based sorting of the paths. 13 # 14 # Sorting the paths by graph improves the chances that the difference 15 # between two builds appear near the end of the list, instead of near
··· 8 # and how deep in the tree they live. Equally-"popular" paths are then 9 # sorted by name. 10 # 11 + # The existing writeClosure prints the paths in a simple ascii-based 12 + # sorting of the paths. 13 # 14 # Sorting the paths by graph improves the chances that the difference 15 # between two builds appear near the end of the list, instead of near
+2 -7
pkgs/build-support/singularity-tools/default.nix
··· 4 , storeDir ? builtins.storeDir 5 , writeScript 6 , singularity 7 - , writeReferencesToFile 8 , bash 9 , vmTools 10 , gawk ··· 50 }: 51 let 52 projectName = singularity.projectName or "singularity"; 53 - layer = mkLayer { 54 - inherit name; 55 - contents = contents ++ [ bash runScriptFile ]; 56 - inherit projectName; 57 - }; 58 runAsRootFile = shellScript "run-as-root.sh" runAsRoot; 59 runScriptFile = shellScript "run-script.sh" runScript; 60 result = vmTools.runInLinuxVM ( 61 runCommand "${projectName}-image-${name}.img" 62 { 63 buildInputs = [ singularity e2fsprogs util-linux gawk ]; 64 - layerClosure = writeReferencesToFile layer; 65 preVM = vmTools.createEmptyImage { 66 size = diskSize; 67 fullName = "${projectName}-run-disk";
··· 4 , storeDir ? builtins.storeDir 5 , writeScript 6 , singularity 7 + , writeClosure 8 , bash 9 , vmTools 10 , gawk ··· 50 }: 51 let 52 projectName = singularity.projectName or "singularity"; 53 runAsRootFile = shellScript "run-as-root.sh" runAsRoot; 54 runScriptFile = shellScript "run-script.sh" runScript; 55 result = vmTools.runInLinuxVM ( 56 runCommand "${projectName}-image-${name}.img" 57 { 58 buildInputs = [ singularity e2fsprogs util-linux gawk ]; 59 + layerClosure = writeClosure contents; 60 preVM = vmTools.createEmptyImage { 61 size = diskSize; 62 fullName = "${projectName}-run-disk";
+14 -10
pkgs/build-support/trivial-builders/default.nix
··· 1 - { lib, stdenv, stdenvNoCC, lndir, runtimeShell, shellcheck-minimal }: 2 3 let 4 inherit (lib) ··· 625 626 # Docs in doc/build-helpers/trivial-build-helpers.chapter.md 627 # See https://nixos.org/manual/nixpkgs/unstable/#trivial-builder-writeReferencesToFile 628 - writeReferencesToFile = path: runCommand "runtime-deps" 629 { 630 - exportReferencesGraph = [ "graph" path ]; 631 } 632 '' 633 - touch $out 634 - while read path; do 635 - echo $path >> $out 636 - read dummy 637 - read nrRefs 638 - for ((i = 0; i < nrRefs; i++)); do read ref; done 639 - done < graph 640 ''; 641 642 # Docs in doc/build-helpers/trivial-build-helpers.chapter.md
··· 1 + { lib, config, stdenv, stdenvNoCC, jq, lndir, runtimeShell, shellcheck-minimal }: 2 3 let 4 inherit (lib) ··· 625 626 # Docs in doc/build-helpers/trivial-build-helpers.chapter.md 627 # See https://nixos.org/manual/nixpkgs/unstable/#trivial-builder-writeReferencesToFile 628 + # TODO: Convert to throw after Nixpkgs 24.05 branch-off. 629 + writeReferencesToFile = (if config.allowAliases then lib.warn else throw) 630 + "writeReferencesToFile is deprecated in favour of writeClosure" 631 + (path: writeClosure [ path ]); 632 + 633 + # Docs in doc/build-helpers/trivial-build-helpers.chapter.md 634 + # See https://nixos.org/manual/nixpkgs/unstable/#trivial-builder-writeClosure 635 + writeClosure = paths: runCommand "runtime-deps" 636 { 637 + # Get the cleaner exportReferencesGraph interface 638 + __structuredAttrs = true; 639 + exportReferencesGraph.graph = paths; 640 + nativeBuildInputs = [ jq ]; 641 } 642 '' 643 + jq -r ".graph | map(.path) | sort | .[]" "$NIX_ATTRS_JSON_FILE" > "$out" 644 ''; 645 646 # Docs in doc/build-helpers/trivial-build-helpers.chapter.md
+3
pkgs/build-support/trivial-builders/test/default.nix
··· 26 then references 27 else {}; 28 writeCBin = callPackage ./writeCBin.nix {}; 29 writeShellApplication = callPackage ./writeShellApplication.nix {}; 30 writeScriptBin = callPackage ./writeScriptBin.nix {}; 31 writeShellScript = callPackage ./write-shell-script.nix {};
··· 26 then references 27 else {}; 28 writeCBin = callPackage ./writeCBin.nix {}; 29 + writeClosure-union = callPackage ./writeClosure-union.nix { 30 + inherit (references) samples; 31 + }; 32 writeShellApplication = callPackage ./writeShellApplication.nix {}; 33 writeScriptBin = callPackage ./writeScriptBin.nix {}; 34 writeShellScript = callPackage ./write-shell-script.nix {};
+10 -6
pkgs/build-support/trivial-builders/test/references/default.nix
··· 12 , cleanSamples ? lib.filterAttrs (n: lib.isStringLike) 13 # Test targets 14 , writeDirectReferencesToFile 15 - , writeReferencesToFile 16 }: 17 18 # -------------------------------------------------------------------------- # ··· 46 samplesToString = attrs: 47 lib.concatMapStringsSep " " (name: "[${name}]=${lib.escapeShellArg "${attrs.${name}}"}") (builtins.attrNames attrs); 48 49 - references = lib.mapAttrs (n: v: writeReferencesToFile v) samples; 50 directReferences = lib.mapAttrs (n: v: writeDirectReferencesToFile v) samples; 51 52 testScriptBin = stdenvNoCC.mkDerivation (finalAttrs: { 53 name = "references-test"; ··· 61 mkdir -p "$out/bin" 62 substitute "$src" "$out/bin/${finalAttrs.meta.mainProgram}" \ 63 --replace "@SAMPLES@" ${lib.escapeShellArg (samplesToString samples)} \ 64 - --replace "@REFERENCES@" ${lib.escapeShellArg (samplesToString references)} \ 65 - --replace "@DIRECT_REFS@" ${lib.escapeShellArg (samplesToString directReferences)} 66 runHook postInstall 67 chmod +x "$out/bin/${finalAttrs.meta.mainProgram}" 68 ''; ··· 79 80 passthru = { 81 inherit 82 directReferences 83 - references 84 samples 85 ; 86 }; ··· 109 ''; 110 passthru = { 111 inherit 112 directReferences 113 - references 114 samples 115 testScriptBin 116 ;
··· 12 , cleanSamples ? lib.filterAttrs (n: lib.isStringLike) 13 # Test targets 14 , writeDirectReferencesToFile 15 + , writeClosure 16 }: 17 18 # -------------------------------------------------------------------------- # ··· 46 samplesToString = attrs: 47 lib.concatMapStringsSep " " (name: "[${name}]=${lib.escapeShellArg "${attrs.${name}}"}") (builtins.attrNames attrs); 48 49 + closures = lib.mapAttrs (n: v: writeClosure [ v ]) samples; 50 directReferences = lib.mapAttrs (n: v: writeDirectReferencesToFile v) samples; 51 + collectiveClosure = writeClosure (lib.attrValues samples); 52 53 testScriptBin = stdenvNoCC.mkDerivation (finalAttrs: { 54 name = "references-test"; ··· 62 mkdir -p "$out/bin" 63 substitute "$src" "$out/bin/${finalAttrs.meta.mainProgram}" \ 64 --replace "@SAMPLES@" ${lib.escapeShellArg (samplesToString samples)} \ 65 + --replace "@CLOSURES@" ${lib.escapeShellArg (samplesToString closures)} \ 66 + --replace "@DIRECT_REFS@" ${lib.escapeShellArg (samplesToString directReferences)} \ 67 + --replace "@COLLECTIVE_CLOSURE@" ${lib.escapeShellArg collectiveClosure} 68 runHook postInstall 69 chmod +x "$out/bin/${finalAttrs.meta.mainProgram}" 70 ''; ··· 81 82 passthru = { 83 inherit 84 + collectiveClosure 85 directReferences 86 + closures 87 samples 88 ; 89 }; ··· 112 ''; 113 passthru = { 114 inherit 115 + collectiveClosure 116 directReferences 117 + closures 118 samples 119 testScriptBin 120 ;
+16 -9
pkgs/build-support/trivial-builders/test/references/references-test.sh
··· 33 34 cd "$(dirname "${BASH_SOURCE[0]}")" # nixpkgs root 35 36 - # Injected by Nix (to avoid evaluating in a derivation) 37 - # turn them into arrays 38 - # shellcheck disable=SC2206 # deliberately unquoted 39 declare -A samples=( @SAMPLES@ ) 40 - # shellcheck disable=SC2206 # deliberately unquoted 41 declare -A directRefs=( @DIRECT_REFS@ ) 42 - # shellcheck disable=SC2206 # deliberately unquoted 43 - declare -A references=( @REFERENCES@ ) 44 45 - echo >&2 Testing direct references... 46 for i in "${!samples[@]}"; do 47 echo >&2 Checking "$i" "${samples[$i]}" "${directRefs[$i]}" 48 diff -U3 \ ··· 52 53 echo >&2 Testing closure... 54 for i in "${!samples[@]}"; do 55 - echo >&2 Checking "$i" "${samples[$i]}" "${references[$i]}" 56 diff -U3 \ 57 - <(sort <"${references[$i]}") \ 58 <(nix-store -q --requisites "${samples[$i]}" | sort) 59 done 60 61 echo 'OK!'
··· 33 34 cd "$(dirname "${BASH_SOURCE[0]}")" # nixpkgs root 35 36 + # Inject the path to compare from the Nix expression 37 + 38 + # Associative Arrays 39 declare -A samples=( @SAMPLES@ ) 40 declare -A directRefs=( @DIRECT_REFS@ ) 41 + declare -A closures=( @CLOSURES@ ) 42 + 43 + # Path string 44 + collectiveClosure=@COLLECTIVE_CLOSURE@ 45 46 + echo >&2 Testing direct closures... 47 for i in "${!samples[@]}"; do 48 echo >&2 Checking "$i" "${samples[$i]}" "${directRefs[$i]}" 49 diff -U3 \ ··· 53 54 echo >&2 Testing closure... 55 for i in "${!samples[@]}"; do 56 + echo >&2 Checking "$i" "${samples[$i]}" "${closures[$i]}" 57 diff -U3 \ 58 + <(sort <"${closures[$i]}") \ 59 <(nix-store -q --requisites "${samples[$i]}" | sort) 60 done 61 + 62 + echo >&2 Testing mixed closures... 63 + echo >&2 Checking all samples "(${samples[*]})" "$collectiveClosure" 64 + diff -U3 \ 65 + <(sort <"$collectiveClosure") \ 66 + <(nix-store -q --requisites "${samples[@]}" | sort) 67 68 echo 'OK!'
+23
pkgs/build-support/trivial-builders/test/writeClosure-union.nix
···
··· 1 + { lib 2 + , runCommandLocal 3 + # Test targets 4 + , writeClosure 5 + , samples 6 + }: 7 + runCommandLocal "test-trivial-builders-writeClosure-union" { 8 + __structuredAttrs = true; 9 + closures = lib.mapAttrs (n: v: writeClosure [ v ]) samples; 10 + collectiveClosure = writeClosure (lib.attrValues samples); 11 + inherit samples; 12 + meta.maintainers = with lib.maintainers; [ 13 + ShamrockLee 14 + ]; 15 + } '' 16 + set -eu -o pipefail 17 + echo >&2 Testing mixed closures... 18 + echo >&2 Checking all samples "(''${samples[*]})" "$collectiveClosure" 19 + diff -U3 \ 20 + <(sort <"$collectiveClosure") \ 21 + <(cat "''${closures[@]}" | sort | uniq) 22 + touch "$out" 23 + ''
+2 -1
pkgs/top-level/stage.nix
··· 110 trivialBuilders = self: super: 111 import ../build-support/trivial-builders { 112 inherit lib; 113 inherit (self) runtimeShell stdenv stdenvNoCC; 114 - inherit (self.pkgsBuildHost) shellcheck-minimal; 115 inherit (self.pkgsBuildHost.xorg) lndir; 116 }; 117
··· 110 trivialBuilders = self: super: 111 import ../build-support/trivial-builders { 112 inherit lib; 113 + inherit (self) config; 114 inherit (self) runtimeShell stdenv stdenvNoCC; 115 + inherit (self.pkgsBuildHost) jq shellcheck-minimal; 116 inherit (self.pkgsBuildHost.xorg) lndir; 117 }; 118