on master help sign in
added assets.nix
commitd37c47c5966f7a80bd602b7dac9876643a44b6eb authorhsloan <ishaqsloan@gmail.com> dateWed 23 Aug 2017, 13:59 (9 years ago) parent877942a
1 file changed+203
assets.nix+203
assets.nixnew file+203
@@ -0,0 +1,203 @@
1+{ nixpkgs }:
2+
3+with nixpkgs.lib;
4+
5+rec {
6+
7+zopfliEncodings = file: nixpkgs.stdenv.mkDerivation {
8+ name = "encodings";
9+
10+ input = file;
11+
12+ builder = builtins.toFile "builder.sh" ''
13+ source "$stdenv/setup"
14+
15+ mkdir -p "$out"
16+
17+ ln -s "$input" "$out/identity"
18+
19+ zopfli -c --i5 --gzip "$input" >"$out/gzip"
20+ zopfli -c --i5 --zlib "$input" >"$out/compress"
21+ zopfli -c --i5 --deflate "$input" >"$out/deflate"
22+ '';
23+
24+ buildInputs = [
25+ nixpkgs.zopfli
26+ ];
27+};
28+
29+gzipEncodings = file: nixpkgs.stdenv.mkDerivation {
30+ name = "encodings";
31+
32+ input = file;
33+
34+ builder = builtins.toFile "builder.sh" ''
35+ source "$stdenv/setup"
36+
37+ mkdir -p "$out"
38+
39+ ln -s "$input" "$out/identity"
40+
41+ gzip -c7 "$input" > "$out/gzip"
42+ '';
43+
44+ buildInputs = [
45+ nixpkgs.gzip
46+ ];
47+};
48+
49+noEncodings = file: nixpkgs.stdenv.mkDerivation {
50+ name = "encodings";
51+
52+ input = file;
53+
54+ builder = builtins.toFile "builder.sh" ''
55+ source "$stdenv/setup"
56+
57+ mkdir -p "$out"
58+
59+ ln -s "$input" "$out/identity"
60+ '';
61+
62+ buildInputs = [
63+ ];
64+};
65+
66+mapFiles = f: mapFilesWithName ({name, value}: {
67+ inherit name;
68+ value = {
69+ inherit (value) type;
70+ path = f value.path;
71+ };
72+});
73+
74+mapFilesWithName = f: unionMapFilesWithName (x: { ${x.name} = f x; });
75+
76+setToList = s: map (name: { inherit name; value = s.${name}; }) (builtins.attrNames s);
77+
78+unionMapFilesWithName = f: d:
79+ let go = {name, value}:
80+ if value.type == "directory" then [{
81+ inherit name;
82+ value = {
83+ inherit (value) type;
84+ contents = unionMapFilesWithName f value.contents;
85+ };
86+ }] else setToList (f {
87+ inherit name value;
88+ });
89+ in builtins.listToAttrs (builtins.concatLists (map go (setToList d)));
90+
91+readDirRecursive = dir:
92+ let d = filterAttrs (n: d: !(hasPrefix "." n)) (builtins.readDir dir);
93+ go = name:
94+ let path = dir + "/${name}";
95+ type = d.${name};
96+ in if type == "directory" then {
97+ inherit name;
98+ value = {
99+ inherit type;
100+ contents = readDirRecursive path;
101+ };
102+ } else {
103+ inherit name;
104+ value = {
105+ inherit type path;
106+ };
107+ };
108+ in builtins.listToAttrs (map go (builtins.attrNames d));
109+
110+doubleQuoteString = s: "\"" + builtins.replaceStrings ["\\" "\""] ["\\\\" "\\\""] s + "\"";
111+
112+dirToPath = contents: toPath {
113+ type = "directory";
114+ inherit contents;
115+};
116+
117+mapSnds = f: l: zipLists (map (x: x.fst) l) (f (map (x: x.snd) l));
118+
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:
123+ let a = take n l;
124+ b = drop 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);
127+
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";
133+ inherit chunk next;
134+ preferLocalBuild = true;
135+ builder = builtins.toFile "chunkDerivations.sh" ''
136+ source "$stdenv/setup"
137+
138+ echo $chunk
139+
140+ echo "[ $chunk ] ++ (import $next)" >"$out"
141+ '';
142+});
143+
144+toPath = x:
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 {
149+ name = "toPath";
150+ inherit files;
151+ passAsFile = optional filesIsLarge "files";
152+ preferLocalBuild = true;
153+ builder = builtins.toFile "builder.sh" ''
154+ set -e
155+ source "$stdenv/setup"
156+
157+ eval "declare -A files=(${if filesIsLarge then ''$(cat "$filesPath")'' else ''$files''})"
158+
159+ mkdir "$out"
160+
161+ for filename in "''${!files[@]}" ; do
162+ ln -s "''${files[$filename]}" "$out/$filename"
163+ done
164+ '';
165+ }) else x.path;
166+
167+hashFile = path: builtins.readFile (nixpkgs.runCommand "hashFile" {
168+ buildInputs = [
169+ nixpkgs.nix
170+ ];
171+ preferLocalBuild = true;
172+ inherit path;
173+} ''
174+ nix-hash --flat --base32 --type sha256 "$path" | tr -d '\n' >"$out"
175+'');
176+
177+dir = contents: {
178+ type = "directory";
179+ inherit contents;
180+};
181+
182+symlink = path: {
183+ type = "symlink";
184+ inherit path;
185+};
186+
187+mkAsset = encodings: {name, value}:
188+ let nameWithHash = "${hashFile value.path}-${name}";
189+ in {
190+ ${nameWithHash} = dir {
191+ type = symlink (builtins.toFile "type" "immutable");
192+ encodings = symlink (encodings value.path);
193+ };
194+ ${name} = dir {
195+ type = symlink (builtins.toFile "type" "redirect");
196+ target = symlink (builtins.toFile "target" "${nameWithHash}");
197+ };
198+};
199+
200+mkAssetsWith = encodings: d: dirToPath (unionMapFilesWithName (mkAsset encodings) (readDirRecursive d));
201+
202+mkAssets = mkAssetsWith zopfliEncodings;
203+}