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 # A name to use when referring to the thing currently being
12 # materialized. Clients can pass in an attribute name or similar.
14 # Some times there a reasont the derivation will
15 # not produce output that can be safely materialized.
16 # Set this to a string explaining why and materialization
17 # will not be used (if sha256 was set an error will be
18 # displayed including the reasonNotSafe string).
19, checkMaterialization ? defaults.checkMaterialization
20 # When checkMaterialization is set the derivation
21 # will be calculated the slow way (without using `sha256`
22 # and `materialized`) the result will be used to check
23 # `sha256` and `materialized` (if set).
27 inherit (derivation) name;
29 traceIgnoringSha256 = reason: x:
31 then builtins.trace ("Warning: ignoring sha256 for " + name + " " + reason) x
34 traceIgnoringMaterialized = reason: x:
35 if materialized != null
36 then builtins.trace ("Warning: ignoring materialized for " + name + " " + reason) x
41 sha256message = "To make ${this} a fixed-output derivation but not materialized, set `${sha256Arg}` to the output of the 'calculateMaterializedSha' script in 'passthru'.";
42 materializeMessage = "To materialize ${this} entirely, pass a writable path as the `materialized` argument and run the 'updateMaterialized' script in 'passthru'.";
43 in if reasonNotSafe != null
45 # Warn the user if they tried to pin stuff down when it is not safe
46 traceIgnoringSha256 reasonNotSafe
47 (traceIgnoringMaterialized reasonNotSafe calculateNoHash)
48 else if materialized != null
49 then calculateUseMaterialized
50 else if sha256 != null
52 # Let the user know how to materialize if they want to.
53 builtins.trace materializeMessage calculateUseHash
54 else # materialized == null && sha256 == null
55 # Let the user know how to calculate a sha256 or materialize if they want to.
56 builtins.trace sha256message (builtins.trace materializeMessage calculateNoHash);
58 # Build fully and check the hash and materialized versions
60 # Let the user know what we are checking. This is useful for debugging issues
61 # where materialization fails to prevent infinite recurstion when:
62 # checkMaterialization = true;
63 (if materialized != null
64 then __trace "Checking materialization in ${toString materialized}"
66 runCommand name {} (''
67 ERR=$(mktemp -d)/errors.txt
69 + (pkgs.lib.optionalString (sha256 != null) ''
70 NEW_HASH=$(${calculateMaterializedSha})
71 if [[ ${sha256} != $NEW_HASH ]]; then
72 echo Changes to ${name} not reflected in ${sha256Arg}
73 diff -ru ${calculateUseHash} ${calculateNoHash} || true
74 echo "Calculated hash for ${name} was not ${sha256}. New hash is :" >> $ERR
75 echo " ${sha256Arg} = \"$NEW_HASH\";" >> $ERR
77 echo ${sha256Arg} used for ${name} is correct
81 if materialized != null && !__pathExists materialized
83 echo "Materialized nix used for ${name} is missing. To fix run: ${updateMaterialized}" >> $ERR
88 (pkgs.lib.optionalString (materialized != null && __pathExists materialized) ''
89 if diff -qr ${materialized} ${calculateNoHash} &>/dev/null; then
90 echo materialized nix used for ${name} is correct
92 echo Changes to plan not reflected in materialized nix for ${name}
93 diff -ru ${materialized} ${calculateNoHash} || true
94 echo "Materialized nix used for ${name} incorrect. To fix run: ${updateMaterialized}" >> $ERR
98 if [[ -e $ERR ]]; then
102 cp -Lr ${unchecked} $out
103 # Make sure output files can be removed from the sandbox
110 outputHashMode = "recursive";
111 outputHashAlgo = "sha256";
114 calculateNoHash = derivation;
116 # Use `cp -Lr` here to get rid of symlinks so we know the result
117 # can be safely materialized (no symlinks to the store).
118 runCommand name hashArgs ''
119 cp -Lr ${derivation} $out
120 # Make sure output files can be removed from the sandbox
123 calculateUseMaterialized =
124 assert materialized != null;
125 assert __pathExists materialized;
126 runCommand name (pkgs.lib.optionalAttrs (sha256 == null) hashArgs) ''
127 cp -Lr ${materialized} $out
128 # Make sure output files can be removed from the sandbox
131 calculateMaterializedSha =
132 writeShellScript "calculateSha" ''${nix}/bin/nix-hash --base32 --type sha256 ${calculateNoHash}'';
134 # Generate the materialized files in a particular path.
135 generateMaterialized =
136 writeShellScript "generateMaterialized" ''
139 # Crudely try and guard people from writing to the Nix store accidentally
140 if [[ ''${TARGET##/nix/store/} != $TARGET ]]; then
141 echo "Attempted to write to $TARGET in the Nix store! Put your materialized files somewhere else!"
147 cp -r ${calculateNoHash} "$TARGET"
148 chmod -R +w "$TARGET"
150 # Update the materialized files at 'materialized', which must already be set.
152 assert materialized != null;
153 writeShellScript "updateMaterialized" ''${generateMaterialized} ${toString materialized}'';
155 # Materialized location was specified, but the files are not there.
156 missingMaterialized = materialized != null && !__pathExists materialized;
158 # Use the checked version if requested or if the `materialized` version
159 # is missing (perhaps deleted or not created yet).
160 result = if checkMaterialization || missingMaterialized
165 # Also include the scripts for fixing materialization files in passthru.
166 // { 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