on cc35ee6 help sign in
haskell.nix/lib/stack-cache-generator.nix
107 lines 4.1 kB history raw
1# Generate cache entries for dependencies of package defined in `src`
3{ src
4, stackYaml ? "stack.yaml"
5, sha256map ? null
6 # An alternative to adding `# nix-sha256:` comments into the
7 # stack.yaml file:
8 # sha256map =
9 # { "https://github.com/jgm/pandoc-citeproc"."0.17"
10 # = "0dxx8cp2xndpw3jwiawch2dkrkp15mil7pyx7dvd810pwc22pm2q"; };
11, branchMap ? null
12 # A way to specify in which branch a git commit can
13 # be found
14, lookupBranch ?
15 if branchMap != null
16 then { location, tag, ...}: branchMap."${location}"."${tag}" or null
17 else _: null
18, resolverSha256 ? null
19, nix-tools
20, evalPackages
21, ...
22}@args:
23let
24 inherit (evalPackages) runCommand;
25 inherit (evalPackages.haskell-nix) haskellLib;
27 # We only care about the stackYaml file. If src is a local directory
28 # we want to avoid recalculating the cache unless the stack.yaml file
29 # changes.
31 inherit (haskellLib.fetchResolver {
32 inherit src stackYaml resolverSha256;
33 }) resolver fetchedResolver;
35 # Filter just the stack yaml file and any resolver yaml file it points to.
36 maybeCleanedSource = haskellLib.cleanSourceWith {
37 inherit src;
38 filter = path: type:
39 let
40 origSrc = if src ? _isLibCleanSourceWith then src.origSrc else src;
41 origSubDir = if src ? _isLibCleanSourceWithEx then src.origSubDir else "";
42 relPath = evalPackages.lib.removePrefix (toString origSrc + origSubDir + "/") path;
44 # checks if path1 is a parent directory for path2
45 isParent = path1: path2: evalPackages.lib.hasPrefix "${path1}/" path2;
47 in
48 (relPath == stackYaml)
49 || (resolver != null && (relPath == resolver || isParent relPath resolver))
50 ;
51 };
53 # All repos served via ssh or git protocols are usually private
54 private = url: evalPackages.lib.substring 0 4 url != "http";
56 repos = builtins.fromJSON (builtins.readFile (evalPackages.runCommand "stack-repos" {
57 buildInputs = [ nix-tools ];
58 } ''
59 TMP=$(mktemp -d)
60 cd $TMP
61 cp -r "${maybeCleanedSource}/." $TMP
62 chmod -R +w $TMP
63 substituteInPlace ${stackYaml} --replace "# nix-sha256:" "nix-sha256:"
64 ${evalPackages.lib.optionalString (fetchedResolver != null) ''
65 substituteInPlace ${stackYaml} --replace "${resolver}" "${fetchedResolver}"
66 ''}
67 stack-repos --stack-yaml ${stackYaml}
68 cp repos.json $out
69 ''));
71 cabalName = path: builtins.readFile (evalPackages.runCommand "cabal-name" {
72 buildInputs = [ nix-tools ];
73 } ''
74 cabal-name ${path} > $out
75 '');
77 hashPath = path:
78 builtins.readFile (evalPackages.runCommand "hash-path" { preferLocalBuild = true; }
79 "echo -n $(${evalPackages.nix}/bin/nix-hash --type sha256 --base32 ${path}) > $out");
80in with evalPackages.lib;
81concatMap (dep:
82 let
83 is-private = private dep.url;
84 sha256 =
85 if dep.sha256 != null then dep.sha256
86 else if sha256map != null then sha256map."${dep.url}"."${dep.rev}"
87 else null;
88 branch = lookupBranch {
89 location = dep.url;
90 tag = dep.rev;
91 };
92 pkgsrc =
93 if !is-private && sha256 != null
94 then evalPackages.fetchgit {
95 inherit (dep) url rev;
96 inherit sha256;
97 }
98 else builtins.fetchGit ({
99 inherit (dep) url rev;
100 } // evalPackages.lib.optionalAttrs (branch != null) { ref = branch; });
101 in map (subdir: {
102 name = cabalName "${pkgsrc}/${subdir}";
103 inherit (dep) url rev;
104 inherit is-private;
105 sha256 = if !is-private then hashPath pkgsrc else null;
106 } // (optionalAttrs (subdir != "") { inherit subdir; }))
107 (dep.subdirs or [ "" ])) repos