1{ pkgs, nix, runCommand, writeShellScript, checkMaterialization }@defaults:
2{ sha256 ? null # Has to make this a fixed output derivation
4 # Name of the sha256 argument for more meaningful
5 # error messages when checking the materialization.
6, materialized # null or path where to find materialized version of
7 # the output. If this is set but does not exist
8 # the derivation will fail but with a message
9 # advising how to populate it.
11 # Some times there a reasont the derivation will
12 # not produce output that can be safely materialized.
13 # Set this to a string explaining why and materialization
14 # will not be used (if sha256 was set an error will be
15 # displayed including the reasonNotSafe string).
16, checkMaterialization ? defaults.checkMaterialization
17 # When checkMaterialization is set the derivation
18 # will be calculated the slow way (without using `sha256`
19 # and `materialized`) the result will be used to check
20 # `sha256` and `materialized` (if set).
24 inherit (derivation) name;
26 traceIgnoringSha256 = reason: x:
28 then builtins.trace ("Warning: ignoring sha256 for " + name + " " + reason) x
31 traceIgnoringMaterialized = reason: x:
32 if materialized != null
33 then builtins.trace ("Warning: ignoring materialized for " + name + " " + reason) x
38 sha256message = "To make this a fixed-output derivation but not materialized, set `${sha256Arg}` to the output of ${calculateMaterializedSha}";
39 materializeMessage = "To materialize the output entirely, pass a writable path as the `materialized` argument and pass that path to ${generateMaterialized}";
40 in if reasonNotSafe != null
42 # Warn the user if they tried to pin stuff down when it is not safe
43 traceIgnoringSha256 reasonNotSafe
44 (traceIgnoringMaterialized reasonNotSafe calculateNoHash)
45 else if materialized != null
46 then calculateUseMaterialized
47 else if sha256 != null
49 # Let the user know how to materialize if they want to.
50 builtins.trace materializeMessage calculateUseHash
51 else # materialized == null && sha256 == null
52 # Let the user know how to calculate a sha256 or materialize if they want to.
53 builtins.trace sha256message (builtins.trace materializeMessage calculateNoHash);
55 # Build fully and check the hash and materialized versions
56 checked = runCommand name {} (''
57 ERR=$(mktemp -d)/errors.txt
59 + (pkgs.lib.optionalString (sha256 != null) ''
60 NEW_HASH=$(${calculateMaterializedSha})
61 if [[ ${sha256} != $NEW_HASH ]]; then
62 echo Changes to ${name} not reflected in ${sha256Arg}
63 diff -ru ${calculateUseHash} ${calculateNoHash} || true
64 echo "Calculated hash for ${name} was not ${sha256}. New hash is :" >> $ERR
65 echo " ${sha256Arg} = \"$NEW_HASH\";" >> $ERR
67 echo ${sha256Arg} used for ${name} is correct
71 if materialized != null && !__pathExists materialized
73 echo "Materialized nix used for ${name} is missing. To fix run: ${updateMaterialized}" >> $ERR
78 (pkgs.lib.optionalString (materialized != null && __pathExists materialized) ''
79 if diff -qr ${materialized} ${calculateNoHash} &>/dev/null; then
80 echo materialized nix used for ${name} is correct
82 echo Changes to plan not reflected in materialized nix for ${name}
83 diff -ru ${materialized} ${calculateNoHash} || true
84 echo "Materialized nix used for ${name} incorrect. To fix run: ${updateMaterialized}" >> $ERR
88 if [[ -e $ERR ]]; then
92 cp -Lr ${unchecked} $out
93 # Make sure output files can be removed from the sandbox
100 outputHashMode = "recursive";
101 outputHashAlgo = "sha256";
104 calculateNoHash = derivation;
106 # Use `cp -Lr` here to get rid of symlinks so we know the result
107 # can be safely materialized (no symlinks to the store).
108 runCommand name hashArgs ''
109 cp -Lr ${derivation} $out
110 # Make sure output files can be removed from the sandbox
113 calculateUseMaterialized =
114 assert materialized != null;
115 assert __pathExists materialized;
116 runCommand name (pkgs.lib.optionalAttrs (sha256 == null) hashArgs) ''
117 cp -Lr ${materialized} $out
118 # Make sure output files can be removed from the sandbox
121 calculateMaterializedSha =
122 writeShellScript "calculateSha" ''${nix}/bin/nix-hash --base32 --type sha256 ${calculateNoHash}'';
124 # Generate the materialized files in a particular path.
125 generateMaterialized =
126 writeShellScript "generateMaterialized" ''
129 # Crudely try and guard people from writing to the Nix store accidentally
130 if [[ ''${TARGET##/nix/store/} != $TARGET ]]; then
131 echo "Attempted to write to $TARGET in the Nix store! Put your materialized files somewhere else!"
137 cp -r ${calculateNoHash} "$TARGET"
138 chmod -R +w "$TARGET"
140 # Update the materialized files at 'materialized', which must already be set.
142 assert materialized != null;
143 writeShellScript "updateMaterialized" ''${generateMaterialized} ${toString materialized}'';
145 # Materialized location was specified, but the files are not there.
146 missingMaterialized = materialized != null && !__pathExists materialized;
148 # Use the checked version if requested or if the `materialized` version
149 # is missing (perhaps deleted or not created yet).
150 result = if checkMaterialization || missingMaterialized
155 # Also include the scripts for fixing materialization files in passthru.
156 // { passthru = (result.passthru or {}) // { inherit generateMaterialized updateMaterialized calculateMaterializedSha; }; }
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list