@@ -0,0 +1,203 @@
7+zopfliEncodings = file: nixpkgs.stdenv.mkDerivation {
12+ builder = builtins.toFile "builder.sh" ''
13+ source "$stdenv/setup"
17+ ln -s "$input" "$out/identity"
19+ zopfli -c --i5 --gzip "$input" >"$out/gzip"
20+ zopfli -c --i5 --zlib "$input" >"$out/compress"
21+ zopfli -c --i5 --deflate "$input" >"$out/deflate"
29+gzipEncodings = file: nixpkgs.stdenv.mkDerivation {
34+ builder = builtins.toFile "builder.sh" ''
35+ source "$stdenv/setup"
39+ ln -s "$input" "$out/identity"
41+ gzip -c7 "$input" > "$out/gzip"
49+noEncodings = file: nixpkgs.stdenv.mkDerivation {
54+ builder = builtins.toFile "builder.sh" ''
55+ source "$stdenv/setup"
59+ ln -s "$input" "$out/identity"
66+mapFiles = f: mapFilesWithName ({name, value}: {
69+ inherit (value) type;
74+mapFilesWithName = f: unionMapFilesWithName (x: { ${x.name} = f x; });
76+setToList = s: map (name: { inherit name; value = s.${name}; }) (builtins.attrNames s);
78+unionMapFilesWithName = f: d:
79+ let go = {name, value}:
80+ if value.type == "directory" then [{
83+ inherit (value) type;
84+ contents = unionMapFilesWithName f value.contents;
86+ }] else setToList (f {
89+ in builtins.listToAttrs (builtins.concatLists (map go (setToList d)));
91+readDirRecursive = dir:
92+ let d = filterAttrs (n: d: !(hasPrefix "." n)) (builtins.readDir dir);
94+ let path = dir + "/${name}";
96+ in if type == "directory" then {
100+ contents = readDirRecursive path;
108+ in builtins.listToAttrs (map go (builtins.attrNames d));
110+doubleQuoteString = s: "\"" + builtins.replaceStrings ["\\" "\""] ["\\\\" "\\\""] s + "\"";
112+dirToPath = contents: toPath {
117+mapSnds = f: l: zipLists (map (x: x.fst) l) (f (map (x: x.snd) l));
119+# This crazy function is here to avoid https://github.com/NixOS/nix/issues/875
120+# It works by creating a dependent chain of derivations that must be built to finish evaluation of the overall nix expression, without evaluating too many. Based on the current operation of nix, n should not be greater than 1012, and should probably be substantially less.
121+# chunkDerivations :: Int -> [a] -> [a]
122+chunkDerivations = n: l:
125+ go = x: if x == [] then builtins.toFile "emptyList.nix" "[]" else chunkDerivations2 n (take n x) (go (drop n x));
126+ in a ++ import (go b);
128+# chunkDerivations2 :: Int -> [a] -> ExprFile [a] -> ExprFile [a]
129+chunkDerivations2 = n: chunk': next:
130+ let chunk = map (path: "(import ${builtins.unsafeDiscardOutputDependency path.drvPath}).${path.outputName}") chunk';
131+ in builtins.seq (builtins.toPath next) (nixpkgs.stdenv.mkDerivation {
132+ name = "chunkDerivations";
134+ preferLocalBuild = true;
135+ builder = builtins.toFile "chunkDerivations.sh" ''
136+ source "$stdenv/setup"
140+ echo "[ $chunk ] ++ (import $next)" >"$out"
145+ if x.type == "directory" then (
146+ let files = builtins.concatStringsSep " " (map (np: let n = np.fst; p = np.snd; in "[" + doubleQuoteString n + "]=" + doubleQuoteString (toString p)) (mapSnds (chunkDerivations 128) (map (n: { fst = n; snd = toPath x.contents.${n}; }) (builtins.attrNames x.contents))));
147+ filesIsLarge = builtins.stringLength files > 65536;
148+ in nixpkgs.stdenv.mkDerivation {
151+ passAsFile = optional filesIsLarge "files";
152+ preferLocalBuild = true;
153+ builder = builtins.toFile "builder.sh" ''
155+ source "$stdenv/setup"
157+ eval "declare -A files=(${if filesIsLarge then ''$(cat "$filesPath")'' else ''$files''})"
161+ for filename in "''${!files[@]}" ; do
162+ ln -s "''${files[$filename]}" "$out/$filename"
167+hashFile = path: builtins.readFile (nixpkgs.runCommand "hashFile" {
171+ preferLocalBuild = true;
174+ nix-hash --flat --base32 --type sha256 "$path" | tr -d '\n' >"$out"
187+mkAsset = encodings: {name, value}:
188+ let nameWithHash = "${hashFile value.path}-${name}";
190+ ${nameWithHash} = dir {
191+ type = symlink (builtins.toFile "type" "immutable");
192+ encodings = symlink (encodings value.path);
195+ type = symlink (builtins.toFile "type" "redirect");
196+ target = symlink (builtins.toFile "target" "${nameWithHash}");
200+mkAssetsWith = encodings: d: dirToPath (unionMapFilesWithName (mkAsset encodings) (readDirRecursive d));
202+mkAssets = mkAssetsWith zopfliEncodings;