on edd1d21 help sign in
haskell.nix/lib/stack-cache-generator.nix
79 lines 3.0 kB history raw
1# Generate cache entries for dependencies of package defined in `src`
3{ pkgs, haskellLib, nix-tools }:
4{ src, stackYaml ? "stack.yaml" }:
5let
6 # We only care about the stackYaml file. If src is a local directory
7 # we want to avoid recalculating the cache unless the stack.yaml file
8 # changes.
10 # Using origSrcSubDir bypasses any cleanSourceWith so that it will work when
11 # access to the store is restricted. If origSrc was already in the store
12 # you can pass the project in as a string.
13 rawStackYaml = builtins.readFile ((src.origSrcSubDir or src) + ("/" + stackYaml));
15 # Determine the resolver as it may point to another file we need
16 # to look at.
17 resolver =
18 let
19 rs = pkgs.lib.lists.concatLists (
20 pkgs.lib.lists.filter (l: l != null)
21 (builtins.map (l: builtins.match "^resolver: *(.*)" l)
22 (pkgs.lib.splitString "\n" rawStackYaml)));
23 in
24 pkgs.lib.lists.head (rs ++ [ null ]);
26 # Filter just the stack yaml file and any reolver yaml file it points to.
27 maybeCleanedSource =
28 if haskellLib.canCleanSource src
29 then haskellLib.cleanSourceWith {
30 inherit src;
31 filter = path: type:
32 pkgs.lib.hasSuffix ("/" + stackYaml) path
33 || (resolver != null && pkgs.lib.hasSuffix ("/" + resolver) path);
34 }
35 else src;
37 # All repos served via ssh or git protocols are usually private
38 private = url: pkgs.lib.substring 0 4 url != "http";
40 repos = builtins.fromJSON (builtins.readFile (pkgs.runCommand "stack-repos" {
41 buildInputs = [ nix-tools ];
42 } ''
43 TMP=$(mktemp -d)
44 cd $TMP
45 cp -r "${maybeCleanedSource}/." $TMP
46 chmod -R +w $TMP
47 substituteInPlace ${stackYaml} --replace "# nix-sha256:" "nix-sha256:"
48 stack-repos --stack-yaml ${stackYaml}
49 cp repos.json $out
50 ''));
52 cabalName = path: builtins.readFile (pkgs.runCommand "cabal-name" {
53 buildInputs = [ nix-tools ];
54 } ''
55 cabal-name ${path} > $out
56 '');
58 hashPath = path:
59 builtins.readFile (pkgs.runCommand "hash-path" { preferLocalBuild = true; }
60 "echo -n $(${pkgs.nix}/bin/nix-hash --type sha256 --base32 ${path}) > $out");
61in with pkgs.lib;
62concatMap (dep:
63 let
64 is-private = private dep.url;
65 pkgsrc =
66 if !is-private && dep.sha256 != null
67 then pkgs.fetchgit {
68 inherit (dep) url rev sha256;
69 }
70 else builtins.fetchGit {
71 inherit (dep) url rev;
72 };
73 in map (subdir: {
74 name = cabalName "${pkgsrc}/${subdir}";
75 inherit (dep) url rev;
76 inherit is-private;
77 sha256 = if !is-private then hashPath pkgsrc else null;
78 } // (optionalAttrs (subdir != "") { inherit subdir; }))
79 (dep.subdirs or [ "" ])) repos