on iko/ghcjs-patch-master help sign in
download stack resolver if a sha256 is provided (#748)
c773606Hamish Mackenzie
lib/call-stack-to-nix.nix+30−8
@@ -5,21 +5,26 @@
5 *
5 *
6 * see also `call-cabal-project-to-nix`!
6 * see also `call-cabal-project-to-nix`!
7 */
7 */
8−{ runCommand, nix-tools, pkgs, mkCacheFile, materialize }:
8+{ runCommand, nix-tools, pkgs, mkCacheFile, materialize, haskellLib }:
9{ name ? src.name or null # optional name for better error messages
9{ name ? src.name or null # optional name for better error messages
10, src
10, src
11−, stackYaml ? null
11+, stackYaml ? "stack.yaml"
12, ignorePackageYaml ? false
12, ignorePackageYaml ? false
13, cache ? null
13, cache ? null
14, stack-sha256 ? null
14, stack-sha256 ? null
15+, resolverSha256 ? null
15, materialized ? null # Location of a materialized copy of the nix files
16, materialized ? null # Location of a materialized copy of the nix files
16, checkMaterialization ? null # If true the nix files will be generated used to check plan-sha256 and material
17, checkMaterialization ? null # If true the nix files will be generated used to check plan-sha256 and material
17, ... }:
18, ... }:
18let
19let
20+ inherit (haskellLib.fetchResolver {
21+ inherit src stackYaml resolverSha256;
22+ }) resolver fetchedResolver;
23+
19 subDir' = src.origSubDir or "";
24 subDir' = src.origSubDir or "";
20 stackToNixArgs = builtins.concatStringsSep " " [
25 stackToNixArgs = builtins.concatStringsSep " " [
21 "--full"
26 "--full"
22− "--stack-yaml=${src}/${if stackYaml == null then "stack.yaml" else stackYaml}"
27+ "--stack-yaml=$SRC/${stackYaml}"
23 (if ignorePackageYaml then "--ignore-package-yaml" else "")
28 (if ignorePackageYaml then "--ignore-package-yaml" else "")
24 "-o ."
29 "-o ."
25 ];
30 ];
@@ -31,7 +36,7 @@ let
31 } // pkgs.lib.optionalAttrs (checkMaterialization != null) {
36 } // pkgs.lib.optionalAttrs (checkMaterialization != null) {
32 inherit checkMaterialization;
37 inherit checkMaterialization;
33 }) (runCommand (if name == null then "stack-to-nix-pkgs" else name + "-stack-to-nix-pkgs") {
38 }) (runCommand (if name == null then "stack-to-nix-pkgs" else name + "-stack-to-nix-pkgs") {
34− nativeBuildInputs = [ nix-tools pkgs.nix-prefetch-git pkgs.cacert ];
39+ nativeBuildInputs = [ nix-tools pkgs.nix-prefetch-git pkgs.cacert pkgs.xorg.lndir ];
35 # Needed or stack-to-nix will die on unicode inputs
40 # Needed or stack-to-nix will die on unicode inputs
36 LOCALE_ARCHIVE = pkgs.lib.optionalString (pkgs.stdenv.hostPlatform.libc == "glibc") "${pkgs.glibcLocales}/lib/locale/locale-archive";
41 LOCALE_ARCHIVE = pkgs.lib.optionalString (pkgs.stdenv.hostPlatform.libc == "glibc") "${pkgs.glibcLocales}/lib/locale/locale-archive";
37 LANG = "en_US.UTF-8";
42 LANG = "en_US.UTF-8";
@@ -39,15 +44,32 @@ let
39 preferLocalBuild = false;
44 preferLocalBuild = false;
40 } (''
45 } (''
41 mkdir -p $out${subDir'}
46 mkdir -p $out${subDir'}
47+ ${
48+ # If no resolver was fetched use the original stack.yaml
49+ if fetchedResolver == null
50+ then ''
51+ SRC=${src}
52+ ''
53+ else
54+ # Replace the resolver path in the stack.yaml with the fetched version
55+ ''
56+ SRC=$(mktemp -d)
57+ cd $SRC
58+ lndir -silent "${src}/." $SRC
59+ rm ${stackYaml}
60+ cp ${src}/${stackYaml} .
61+ chmod +w ${stackYaml}
62+ substituteInPlace ${stackYaml} --replace "${resolver}" "${fetchedResolver}"
63+ ''}
42− '' + pkgs.lib.optionalString (cache != null) ''
64+ ${pkgs.lib.optionalString (cache != null) ''
43− cp ${mkCacheFile cache}/.stack-to-nix.cache* $out${subDir'}
65+ cp ${mkCacheFile cache}/.stack-to-nix.cache* $out${subDir'}
44− '' + ''
66+ ''}
45 (cd $out${subDir'} && stack-to-nix ${stackToNixArgs})
67 (cd $out${subDir'} && stack-to-nix ${stackToNixArgs})
46
68
47 # We need to strip out any references to $src, as those won't
69 # We need to strip out any references to $src, as those won't
48 # be accessable in restricted mode.
70 # be accessable in restricted mode.
49 for nixf in $(find $out -name "*.nix" -type f); do
71 for nixf in $(find $out -name "*.nix" -type f); do
50− substituteInPlace $nixf --replace "${src}" "."
72+ substituteInPlace $nixf --replace "$SRC" "."
51 done
73 done
52
74
53 # move pkgs.nix to default.nix ensure we can just nix `import` the result.
75 # move pkgs.nix to default.nix ensure we can just nix `import` the result.
lib/default.nix+5
@@ -261,4 +261,9 @@ in {
261 if lib.isAttrs versionOrArgs
261 if lib.isAttrs versionOrArgs
262 then versionOrArgs
262 then versionOrArgs
263 else { version = versionOrArgs; };
263 else { version = versionOrArgs; };
264+
265+ # Find the resolver in the stack.yaml file and fetch it if a sha256 value is provided
266+ fetchResolver = import ./fetch-resolver.nix {
267+ inherit (pkgs.evalPackages) pkgs;
268+ };
264}
269}
lib/fetch-resolver.nixnew file+33
@@ -0,0 +1,33 @@
1+# Find the resolver in the stack.yaml file and fetch it if a sha256 value is provided
2+{ pkgs }:
3+{ src
4+, stackYaml ? "stack.yaml"
5+, resolverSha256 ? null
6+}:
7+let
8+ # Using origSrcSubDir bypasses any cleanSourceWith so that it will work when
9+ # access to the store is restricted. If origSrc was already in the store
10+ # you can pass the project in as a string.
11+ rawStackYaml = builtins.readFile ((src.origSrcSubDir or src) + ("/" + stackYaml));
12+
13+ # Determine the resolver as it may point to another file we need
14+ # to look at.
15+ resolver =
16+ let
17+ rs = pkgs.lib.lists.concatLists (
18+ pkgs.lib.lists.filter (l: l != null)
19+ (builtins.map (l: builtins.match "^resolver: *(.*)" l)
20+ (pkgs.lib.splitString "\n" rawStackYaml)));
21+ in
22+ pkgs.lib.lists.head (rs ++ [ null ]);
23+
24+ # If we found a resolver andwe have a resolverSha256 then we should download it.
25+ fetchedResolver =
26+ if resolver != null && resolverSha256 != null
27+ then pkgs.fetchurl {
28+ url = resolver;
29+ sha256 = resolverSha256;
30+ }
31+ else null;
32+
33+in { inherit resolver fetchedResolver; }
lib/stack-cache-generator.nix+7−15
@@ -13,6 +13,7 @@
13 if sha256map != null
13 if sha256map != null
14 then { location, tag, ...}: sha256map."${location}"."${tag}"
14 then { location, tag, ...}: sha256map."${location}"."${tag}"
15 else _: null
15 else _: null
16+, resolverSha256 ? null
16, ...
17, ...
17}:
18}:
18let
19let
@@ -20,21 +21,9 @@ let
20 # we want to avoid recalculating the cache unless the stack.yaml file
21 # we want to avoid recalculating the cache unless the stack.yaml file
21 # changes.
22 # changes.
22
23
23− # Using origSrcSubDir bypasses any cleanSourceWith so that it will work when
24+ inherit (haskellLib.fetchResolver {
24− # access to the store is restricted. If origSrc was already in the store
25+ inherit src stackYaml resolverSha256;
25− # you can pass the project in as a string.
26+ }) resolver fetchedResolver;
26− rawStackYaml = builtins.readFile ((src.origSrcSubDir or src) + ("/" + stackYaml));
27−
28− # Determine the resolver as it may point to another file we need
29− # to look at.
30− resolver =
31− let
32− rs = pkgs.lib.lists.concatLists (
33− pkgs.lib.lists.filter (l: l != null)
34− (builtins.map (l: builtins.match "^resolver: *(.*)" l)
35− (pkgs.lib.splitString "\n" rawStackYaml)));
36− in
37− pkgs.lib.lists.head (rs ++ [ null ]);
38
27
39 # Filter just the stack yaml file and any reolver yaml file it points to.
28 # Filter just the stack yaml file and any reolver yaml file it points to.
40 maybeCleanedSource =
29 maybeCleanedSource =
@@ -58,6 +47,9 @@ let
58 cp -r "${maybeCleanedSource}/." $TMP
47 cp -r "${maybeCleanedSource}/." $TMP
59 chmod -R +w $TMP
48 chmod -R +w $TMP
60 substituteInPlace ${stackYaml} --replace "# nix-sha256:" "nix-sha256:"
49 substituteInPlace ${stackYaml} --replace "# nix-sha256:" "nix-sha256:"
50+ ${pkgs.lib.optionalString (fetchedResolver != null) ''
51+ substituteInPlace ${stackYaml} --replace "${resolver}" "${fetchedResolver}"
52+ ''}
61 stack-repos --stack-yaml ${stackYaml}
53 stack-repos --stack-yaml ${stackYaml}
62 cp repos.json $out
54 cp repos.json $out
63 ''));
55 ''));
overlays/haskell.nix+1−1
@@ -260,7 +260,7 @@ final: prev: {
260 callStackToNix = import ../lib/call-stack-to-nix.nix {
260 callStackToNix = import ../lib/call-stack-to-nix.nix {
261 pkgs = final.evalPackages.pkgs;
261 pkgs = final.evalPackages.pkgs;
262 inherit (final.evalPackages.pkgs) runCommand;
262 inherit (final.evalPackages.pkgs) runCommand;
263− inherit (final.evalPackages.haskell-nix) nix-tools mkCacheFile materialize;
263+ inherit (final.evalPackages.haskell-nix) nix-tools mkCacheFile materialize haskellLib;
264 };
264 };
265
265
266 # given a source location call `cabal-to-nix` (from nix-tools) on it
266 # given a source location call `cabal-to-nix` (from nix-tools) on it
test/default.nix+1
@@ -159,6 +159,7 @@ let
159 builder-haddock = callTest ./builder-haddock {};
159 builder-haddock = callTest ./builder-haddock {};
160 stack-simple = callTest ./stack-simple {};
160 stack-simple = callTest ./stack-simple {};
161 stack-local-resolver = callTest ./stack-local-resolver {};
161 stack-local-resolver = callTest ./stack-local-resolver {};
162+ stack-remote-resolver = callTest ./stack-remote-resolver {};
162 snapshots = callTest ./snapshots {};
163 snapshots = callTest ./snapshots {};
163 shell-for = callTest ./shell-for {};
164 shell-for = callTest ./shell-for {};
164 shell-for-setup-deps = callTest ./shell-for-setup-deps {};
165 shell-for-setup-deps = callTest ./shell-for-setup-deps {};
test/stack-remote-resolver/.gitignorenew file+2
@@ -0,0 +1,2 @@
1+/.stack-work/
2+/*.cabal
test/stack-remote-resolver/default.nixnew file+15
@@ -0,0 +1,15 @@
1+{ project', recurseIntoAttrs, testSrc }:
2+
3+let
4+ project = project' {
5+ src = testSrc "stack-remote-resolver";
6+ resolverSha256 = "1rldkqqsxd8zxybrkqhc25bcxinhz212kz45jcz8jinfihc91jl7";
7+ };
8+ packages = project.hsPkgs;
9+
10+in recurseIntoAttrs {
11+ ifdInputs = {
12+ inherit (project) stack-nix;
13+ };
14+ inherit (packages.stack-remote-resolver.components) library;
15+}
test/stack-remote-resolver/package.yamlnew file+7
@@ -0,0 +1,7 @@
1+name: stack-remote-resolver
2+
3+dependencies:
4+- base
5+
6+library:
7+ source-dirs: src
test/stack-remote-resolver/src/Lib.hsnew file+6
@@ -0,0 +1,6 @@
1+module Lib
2+ ( someFunc
3+ ) where
4+
5+someFunc :: IO ()
6+someFunc = putStrLn "someFunc"
test/stack-remote-resolver/stack.yamlnew file+4
@@ -0,0 +1,4 @@
1+resolver: https://raw.githubusercontent.com/input-output-hk/haskell.nix/master/test/stack-local-resolver/snapshot.yaml
2+
3+packages:
4+- .