on a2bc3db help sign in
haskell.nix/lib/stack-cache-generator.nix
91 lines 3.3 kB history raw
1# Generate cache entries for dependencies of package defined in `src`
3{ pkgs, haskellLib, nix-tools }:
4{ src
5, stackYaml ? "stack.yaml"
6, sha256map ? null
7 # An alternative to adding `# nix-sha256:` comments into the
8 # stack.yaml file:
9 # sha256map =
10 # { "https://github.com/jgm/pandoc-citeproc"."0.17"
11 # = "0dxx8cp2xndpw3jwiawch2dkrkp15mil7pyx7dvd810pwc22pm2q"; };
12, lookupSha256 ?
13 if sha256map != null
14 then { location, tag, ...}: sha256map."${location}"."${tag}"
15 else _: null
16, resolverSha256 ? null
17, ...
18}:
19let
20 # We only care about the stackYaml file. If src is a local directory
21 # we want to avoid recalculating the cache unless the stack.yaml file
22 # changes.
24 inherit (haskellLib.fetchResolver {
25 inherit src stackYaml resolverSha256;
26 }) resolver fetchedResolver;
28 # Filter just the stack yaml file and any reolver yaml file it points to.
29 maybeCleanedSource =
30 if haskellLib.canCleanSource src
31 then haskellLib.cleanSourceWith {
32 inherit src;
33 filter = path: type:
34 pkgs.lib.hasSuffix ("/" + stackYaml) path
35 || (resolver != null && pkgs.lib.hasSuffix ("/" + resolver) path);
36 }
37 else src;
39 # All repos served via ssh or git protocols are usually private
40 private = url: pkgs.lib.substring 0 4 url != "http";
42 repos = builtins.fromJSON (builtins.readFile (pkgs.runCommand "stack-repos" {
43 buildInputs = [ nix-tools ];
44 } ''
45 TMP=$(mktemp -d)
46 cd $TMP
47 cp -r "${maybeCleanedSource}/." $TMP
48 chmod -R +w $TMP
49 substituteInPlace ${stackYaml} --replace "# nix-sha256:" "nix-sha256:"
50 ${pkgs.lib.optionalString (fetchedResolver != null) ''
51 substituteInPlace ${stackYaml} --replace "${resolver}" "${fetchedResolver}"
52 ''}
53 stack-repos --stack-yaml ${stackYaml}
54 cp repos.json $out
55 ''));
57 cabalName = path: builtins.readFile (pkgs.runCommand "cabal-name" {
58 buildInputs = [ nix-tools ];
59 } ''
60 cabal-name ${path} > $out
61 '');
63 hashPath = path:
64 builtins.readFile (pkgs.runCommand "hash-path" { preferLocalBuild = true; }
65 "echo -n $(${pkgs.nix}/bin/nix-hash --type sha256 --base32 ${path}) > $out");
66in with pkgs.lib;
67concatMap (dep:
68 let
69 is-private = private dep.url;
70 sha256 = if dep.sha256 != null
71 then dep.sha256
72 else lookupSha256 {
73 location = dep.url;
74 tag = dep.rev;
75 };
76 pkgsrc =
77 if !is-private && sha256 != null
78 then pkgs.fetchgit {
79 inherit (dep) url rev;
80 inherit sha256;
81 }
82 else builtins.fetchGit {
83 inherit (dep) url rev;
84 };
85 in map (subdir: {
86 name = cabalName "${pkgsrc}/${subdir}";
87 inherit (dep) url rev;
88 inherit is-private;
89 sha256 = if !is-private then hashPath pkgsrc else null;
90 } // (optionalAttrs (subdir != "") { inherit subdir; }))
91 (dep.subdirs or [ "" ])) repos