on iko/ghcjs-patch-master help sign in
Do not use evalPackages to create sourceRepo for builds (#918)
bdd6969Joachim Breitner
lib/cabal-project-parser.nix+13−25
@@ -69,36 +69,24 @@ let
69 else __trace "Expected attribute but found `${s}`" { inherit name attrs; }
69 else __trace "Expected attribute but found `${s}`" { inherit name attrs; }
70 ) { name = null; attrs = {}; } (stripComments (unindent blockLines))).attrs;
70 ) { name = null; attrs = {}; } (stripComments (unindent blockLines))).attrs;
71
71
72− hashPath = path:
72+ # Gets data for all the repositories to fetch
73− builtins.readFile (pkgs.runCommand "hash-path" { preferLocalBuild = true; }
73+ # A comment like
74− "echo -n $(${pkgs.nix}/bin/nix-hash --type sha256 --base32 ${path}) > $out");
75−
76− # Use pkgs.fetchgit if we have a sha256. Add comment like this
77 # --shar256: 003lm3pm0000hbfmii7xcdd9v20000flxf7gdl2pyxia7p014i8z
74 # --shar256: 003lm3pm0000hbfmii7xcdd9v20000flxf7gdl2pyxia7p014i8z
78− # otherwise use __fetchGit.
75+ # will be trated like a field and returned here
76+ # (used in call-cabal-project-to-nix.nix to create a fixed-output derivation)
79− fetchRepo = cabalProjectFileName: lookupSha256: repo:
77+ extractRepoData = cabalProjectFileName: lookupSha256: repo:
80 builtins.map (subdir:
78 builtins.map (subdir:
81− let sha256 = repo."--sha256" or (lookupSha256 repo);
79+ {
82− in (if sha256 != null
83− then pkgs.evalPackages.fetchgit {
84− url = repo.location;
80+ url = repo.location;
85− rev = repo.tag;
86− inherit sha256;
87− }
88− else
89− let drv = builtins.fetchGit {
90− url = repo.location;
91− ref = repo.tag;
81+ ref = repo.tag;
92− };
82+ sha256 = repo."--sha256" or (lookupSha256 repo);
93− in __trace "WARNING: No sha256 found for source-repository-package ${repo.location} ${repo.tag} download may fail in restricted mode (hydra)"
83+ inherit subdir;
94− (__trace "Consider adding `--sha256: ${hashPath drv}` to the ${cabalProjectFileName} file or passing in a lookupSha256 argument"
84+ })
95− drv)
96− ) + (if subdir == "." then "" else "/" + subdir))
97 (if repo ? subdir
85 (if repo ? subdir
98 then pkgs.lib.filter (x: x != "") (pkgs.lib.splitString " " repo.subdir)
86 then pkgs.lib.filter (x: x != "") (pkgs.lib.splitString " " repo.subdir)
99 else ["."]);
87 else ["."]);
100
88
101− # Parse a source-repository-package and fetch it if has `type: git`
89+ # Parse a source-repository-package and return data of `type: git` repositories
102 parseBlock = cabalProjectFileName: lookupSha256: block:
90 parseBlock = cabalProjectFileName: lookupSha256: block:
103 let
91 let
104 x = span (pkgs.lib.strings.hasPrefix " ") (pkgs.lib.splitString "\n" block);
92 x = span (pkgs.lib.strings.hasPrefix " ") (pkgs.lib.splitString "\n" block);
@@ -110,7 +98,7 @@ let
110 otherText = "\nsource-repository-package\n" + block;
98 otherText = "\nsource-repository-package\n" + block;
111 }
99 }
112 else {
100 else {
113− sourceRepo = fetchRepo cabalProjectFileName lookupSha256 attrs;
101+ sourceRepo = extractRepoData cabalProjectFileName lookupSha256 attrs;
114 otherText = pkgs.lib.strings.concatStringsSep "\n" x.snd;
102 otherText = pkgs.lib.strings.concatStringsSep "\n" x.snd;
115 };
103 };
116
104
lib/call-cabal-project-to-nix.nix+34−8
@@ -157,17 +157,46 @@ let
157 # restricted-eval mode (as long as a sha256 is included).
157 # restricted-eval mode (as long as a sha256 is included).
158 # Replace source-repository-package blocks that have a sha256 with
158 # Replace source-repository-package blocks that have a sha256 with
159 # packages: block containing nix store paths of the fetched repos.
159 # packages: block containing nix store paths of the fetched repos.
160+
161+ hashPath = path:
162+ builtins.readFile (pkgs.runCommand "hash-path" { preferLocalBuild = true; }
163+ "echo -n $(${pkgs.nix}/bin/nix-hash --type sha256 --base32 ${path}) > $out");
164+
160 replaceSoureRepos = projectFile:
165 replaceSoureRepos = projectFile:
161 let
166 let
167+ fetchRepo = fetchgit: repoData:
168+ let
169+ fetched =
170+ if repoData.sha256 != null
171+ then fetchgit { inherit (repoData) url sha256; rev = repoData.ref; }
172+ else
173+ let drv = builtins.fetchGit { inherit (repoData) url ref; };
174+ in __trace "WARNING: No sha256 found for source-repository-package ${repoData.url} ${repoData.ref} download may fail in restricted mode (hydra)"
175+ (__trace "Consider adding `--sha256: ${hashPath drv}` to the ${cabalProjectFileName} file or passing in a lookupSha256 argument"
176+ drv);
177+ in fetched + (if repoData.subdir == "." then "" else "/" + repoData.subdir);
178+
162 blocks = pkgs.lib.splitString "\nsource-repository-package\n" ("\n" + projectFile);
179 blocks = pkgs.lib.splitString "\nsource-repository-package\n" ("\n" + projectFile);
163 initialText = pkgs.lib.lists.take 1 blocks;
180 initialText = pkgs.lib.lists.take 1 blocks;
164 repoBlocks = builtins.map (pkgs.haskell-nix.haskellLib.parseBlock cabalProjectFileName lookupSha256) (pkgs.lib.lists.drop 1 blocks);
181 repoBlocks = builtins.map (pkgs.haskell-nix.haskellLib.parseBlock cabalProjectFileName lookupSha256) (pkgs.lib.lists.drop 1 blocks);
165− sourceRepos = pkgs.lib.lists.concatMap (x: x.sourceRepo) repoBlocks;
182+ sourceRepoData = pkgs.lib.lists.concatMap (x: x.sourceRepo) repoBlocks;
166 otherText = pkgs.evalPackages.writeText "cabal.project" (pkgs.lib.strings.concatStringsSep "\n" (
183 otherText = pkgs.evalPackages.writeText "cabal.project" (pkgs.lib.strings.concatStringsSep "\n" (
167 initialText
184 initialText
168 ++ (builtins.map (x: x.otherText) repoBlocks)));
185 ++ (builtins.map (x: x.otherText) repoBlocks)));
186+
187+ # we need the repository content twice:
188+ # * at eval time (below to build the fixed project file)
189+ # Here we want to use pkgs.evalPackages.fetchgit, so one can calculate
190+ # the build plan for any target without a remote builder
191+ # * at built time (passed out)
192+ # Here we want to use plain pkgs.fetchgit, which is what a builder
193+ # on the target system would use, so that the derivation is unaffected
194+ # and, say, a linux release build job can identify the derivation
195+ # as built by a darwin builder, and fetch it from a cache
196+ sourceReposBuild = builtins.map (fetchRepo pkgs.evalPackages.fetchgit) sourceRepoData ;
197+ sourceReposEval = builtins.map (fetchRepo pkgs.fetchgit) sourceRepoData;
169 in {
198 in {
170− inherit sourceRepos;
199+ sourceRepos = sourceReposBuild;
171 makeFixedProjectFile = ''
200 makeFixedProjectFile = ''
172 cp -f ${otherText} ./cabal.project
201 cp -f ${otherText} ./cabal.project
173 chmod +w -R ./cabal.project
202 chmod +w -R ./cabal.project
@@ -184,18 +213,15 @@ let
184 "${f}/" "./.source-repository-packages/${builtins.toString n}/"
213 "${f}/" "./.source-repository-packages/${builtins.toString n}/"
185 echo " ./.source-repository-packages/${builtins.toString n}" >> ./cabal.project
214 echo " ./.source-repository-packages/${builtins.toString n}" >> ./cabal.project
186 '')
215 '')
187− (pkgs.lib.lists.range 0 ((builtins.length fixedProject.sourceRepos) - 1))
216+ (pkgs.lib.lists.range 0 ((builtins.length sourceReposEval) - 1))
188− sourceRepos
217+ sourceReposEval
189 )
218 )
190 );
219 );
191 };
220 };
192
221
193 fixedProject =
222 fixedProject =
194 if rawCabalProject == null
223 if rawCabalProject == null
195− then {
196− sourceRepos = [];
197− makeFixedProjectFile = "";
224+ then { sourceRepos = []; makeFixedProjectFile = ""; }
198− }
199 else replaceSoureRepos rawCabalProject;
225 else replaceSoureRepos rawCabalProject;
200
226
201 # The use of the actual GHC can cause significant problems:
227 # The use of the actual GHC can cause significant problems:
test/unit.nix+6−6
@@ -25,9 +25,9 @@ let
25 package.identifier.name = "nnn";
25 package.identifier.name = "nnn";
26 };
26 };
27
27
28− testRepo = pkgs.fetchgit {
28+ testRepoData = {
29 url = "https://github.com/input-output-hk/haskell.nix.git";
29 url = "https://github.com/input-output-hk/haskell.nix.git";
30− rev = "487eea1c249537d34c27f6143dff2b9d5586c657";
30+ ref = "487eea1c249537d34c27f6143dff2b9d5586c657";
31 sha256 = "077j5j3j86qy1wnabjlrg4dmqy1fv037dyq3xb8ch4ickpxxs123";
31 sha256 = "077j5j3j86qy1wnabjlrg4dmqy1fv037dyq3xb8ch4ickpxxs123";
32 };
32 };
33in
33in
@@ -65,7 +65,7 @@ lib.runTests {
65 '');
65 '');
66 expected = __toJSON {
66 expected = __toJSON {
67 otherText = "-- end of block\n";
67 otherText = "-- end of block\n";
68− sourceRepo = [testRepo];
68+ sourceRepo = [(testRepoData // { subdir = "."; })];
69 };
69 };
70 };
70 };
71
71
@@ -80,7 +80,7 @@ lib.runTests {
80 '');
80 '');
81 expected = __toJSON {
81 expected = __toJSON {
82 otherText = "-- end of block\n";
82 otherText = "-- end of block\n";
83− sourceRepo = [(testRepo + "/dir")];
83+ sourceRepo = [(testRepoData // { subdir = "dir"; })];
84 };
84 };
85 };
85 };
86
86
@@ -95,7 +95,7 @@ lib.runTests {
95 '');
95 '');
96 expected = __toJSON {
96 expected = __toJSON {
97 otherText = "-- end of block\n";
97 otherText = "-- end of block\n";
98− sourceRepo = [(testRepo + "/dir1") (testRepo + "/dir2")];
98+ sourceRepo = [(testRepoData // { subdir = "dir1"; }) (testRepoData // { subdir = "dir2"; })];
99 };
99 };
100 };
100 };
101
101
@@ -112,7 +112,7 @@ lib.runTests {
112 '');
112 '');
113 expected = __toJSON {
113 expected = __toJSON {
114 otherText = "-- end of block\n";
114 otherText = "-- end of block\n";
115− sourceRepo = [(testRepo + "/dir1") (testRepo + "/dir2")];
115+ sourceRepo = [(testRepoData // { subdir = "dir1"; }) (testRepoData // { subdir = "dir2"; })];
116 };
116 };
117 };
117 };
118}
118}