on iko/ghcjs-patch-master help sign in
Materialization: add scripts for fixing materialized files and shas, expose via passthru and errors (#653)
908a311Michael Peyton Jones
lib/materialize.nix+48−33
@@ -1,4 +1,4 @@
1−{ pkgs, nix, runCommand, checkMaterialization }@defaults:
1+{ pkgs, nix, runCommand, writeShellScript, checkMaterialization }@defaults:
2{ sha256 ? null # Has to make this a fixed output derivation
2{ sha256 ? null # Has to make this a fixed output derivation
3, sha256Arg ? "sha256"
3, sha256Arg ? "sha256"
4 # Name of the sha256 argument for more meaningful
4 # Name of the sha256 argument for more meaningful
@@ -34,37 +34,31 @@ let
34 else x;
34 else x;
35
35
36 unchecked =
36 unchecked =
37+ let
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}";
37− if reasonNotSafe != null
40+ in if reasonNotSafe != null
38 then
41 then
39 # Warn the user if they tried to pin stuff down when it is not safe
42 # Warn the user if they tried to pin stuff down when it is not safe
40 traceIgnoringSha256 reasonNotSafe
43 traceIgnoringSha256 reasonNotSafe
41 (traceIgnoringMaterialized reasonNotSafe calculateNoHash)
44 (traceIgnoringMaterialized reasonNotSafe calculateNoHash)
42− else if sha256 == null && materialized == null
45+ else if materialized != null
46+ then calculateUseMaterialized
47+ else if sha256 != null
43 then
48 then
44− # Let the user know how to calculate a sha256 to use to make this
49+ # Let the user know how to materialize if they want to.
45− # a fixed output derivation.
50+ builtins.trace materializeMessage calculateUseHash
46− builtins.trace ("Get `${sha256Arg}` with `nix-hash --base32 --type sha256 "
51+ else # materialized == null && sha256 == null
47− + toString calculateNoHash + "/`") (traceIgnoringMaterialized
52+ # Let the user know how to calculate a sha256 or materialize if they want to.
48− "${sha256Arg} is not set" calculateNoHash)
53+ builtins.trace sha256message (builtins.trace materializeMessage calculateNoHash);
49− else if materialized == null
50− then
51− # To avoid any IFD dependencies add a `materialized` copy somewhere
52− # and pass it in.
53− builtins.trace ("To materialize, point `materialized` to a copy of " + toString calculateUseHash)
54− calculateUseHash
55− else
56− # Everything is in place we can safely use the sha256 and materialized
57− calculateUseMaterialized;
58
54
59 # Build fully and check the hash and materialized versions
55 # Build fully and check the hash and materialized versions
60− checked = runCommand name {
56+ checked = runCommand name {} (''
61− buildInputs = [ nix ];
62− } (''
63 ERR=$(mktemp -d)/errors.txt
57 ERR=$(mktemp -d)/errors.txt
64 ''
58 ''
65 + (pkgs.lib.optionalString (sha256 != null) ''
59 + (pkgs.lib.optionalString (sha256 != null) ''
66− NEW_HASH=$(nix-hash --base32 --type sha256 ${calculateNoHash})
60+ NEW_HASH=$(${calculateMaterializedSha})
67− if [ "${sha256}" != "$NEW_HASH" ]; then
61+ if [[ ${sha256} != $NEW_HASH ]]; then
68 echo Changes to ${name} not reflected in ${sha256Arg}
62 echo Changes to ${name} not reflected in ${sha256Arg}
69 diff -ru ${calculateUseHash} ${calculateNoHash} || true
63 diff -ru ${calculateUseHash} ${calculateNoHash} || true
70 echo "Calculated hash for ${name} was not ${sha256}. New hash is :" >> $ERR
64 echo "Calculated hash for ${name} was not ${sha256}. New hash is :" >> $ERR
@@ -76,9 +70,7 @@ let
76 + (
70 + (
77 if materialized != null && !__pathExists materialized
71 if materialized != null && !__pathExists materialized
78 then ''
72 then ''
79− echo "Materialized nix used for ${name} is missing. To fix run :" >> $ERR
73+ echo "Materialized nix used for ${name} is missing. To fix run: ${updateMaterialized}" >> $ERR
80− echo " cp -r ${calculateNoHash} ${toString materialized}" >> $ERR
81− echo " chmod -R +w ${toString materialized}" >> $ERR
82 cat $ERR
74 cat $ERR
83 false
75 false
84 ''
76 ''
@@ -89,14 +81,11 @@ let
89 else
81 else
90 echo Changes to plan not reflected in materialized nix for ${name}
82 echo Changes to plan not reflected in materialized nix for ${name}
91 diff -ru ${materialized} ${calculateNoHash} || true
83 diff -ru ${materialized} ${calculateNoHash} || true
92− echo "Materialized nix used for ${name} incorrect. To fix run :" >> $ERR
84+ echo "Materialized nix used for ${name} incorrect. To fix run: ${updateMaterialized}" >> $ERR
93− echo " rm -rf ${toString materialized}" >> $ERR
94− echo " cp -r ${calculateNoHash} ${toString materialized}" >> $ERR
95− echo " chmod -R +w ${toString materialized}" >> $ERR
96 fi
85 fi
97 '')
86 '')
98 + ''
87 + ''
99− if [ -e $ERR ]; then
88+ if [[ -e $ERR ]]; then
100 cat $ERR
89 cat $ERR
101 false
90 false
102 else
91 else
@@ -129,13 +118,39 @@ let
129 # Make sure output files can be removed from the sandbox
118 # Make sure output files can be removed from the sandbox
130 chmod -R +w $out
119 chmod -R +w $out
131 '';
120 '';
121+ calculateMaterializedSha =
122+ writeShellScript "calculateSha" ''${nix}/nix-hash --base32 --type sha256 ${calculateNoHash}'';
123+
124+ # Generate the materialized files in a particular path.
125+ generateMaterialized =
126+ writeShellScript "generateMaterialized" ''
127+ TARGET=$1
128+
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!"
132+ exit 1
133+ fi
134+
135+ # Generate the files
136+ rm -rf $TARGET
137+ cp -r ${calculateNoHash} "$TARGET"
138+ chmod -R +w "$TARGET"
139+ '';
140+ # Update the materialized files at 'materialized', which must already be set.
141+ updateMaterialized =
142+ assert materialized != null;
143+ writeShellScript "updateMaterialized" ''${generateMaterialized} ${toString materialized}'';
132
144
133 # Materialized location was specified, but the files are not there.
145 # Materialized location was specified, but the files are not there.
134 missingMaterialized = materialized != null && !__pathExists materialized;
146 missingMaterialized = materialized != null && !__pathExists materialized;
135
147
136−in
137 # Use the checked version if requested or if the `materialized` version
148 # Use the checked version if requested or if the `materialized` version
138 # is missing (perhaps deleted or not created yet).
149 # is missing (perhaps deleted or not created yet).
139− if checkMaterialization || missingMaterialized
150+ result = if checkMaterialization || missingMaterialized
140 then checked
151 then checked
141− else unchecked
152+ else unchecked;
153+
154+in result
155+ # Also include the scripts for fixing materialization files in passthru.
156+ // { passthru = (result.passthru or {}) // { inherit generateMaterialized updateMaterialized calculateMaterializedSha; }; }
overlays/haskell.nix+1−1
@@ -248,7 +248,7 @@ final: prev: {
248 inherit (final.evalPackages) nix;
248 inherit (final.evalPackages) nix;
249 inherit (final.haskell-nix) checkMaterialization;
249 inherit (final.haskell-nix) checkMaterialization;
250 pkgs = final.evalPackages.pkgs;
250 pkgs = final.evalPackages.pkgs;
251− inherit (final.evalPackages.pkgs) runCommand;
251+ inherit (final.evalPackages.pkgs) runCommand writeShellScript;
252 };
252 };
253
253
254 update-index-state-hashes = import ../scripts/update-index-state-hashes.nix {
254 update-index-state-hashes = import ../scripts/update-index-state-hashes.nix {