on iko/ghcjs-patch-master help sign in
Improve cabal.project parsing (#802)

Currently adding comments to a `source-repository-package` breaks the parser.

commit85609feac4c08735045a96e35157286ec05efe98 authorHamish Mackenzie <Hamish.Mackenzie@iohk.io> dateThu 6 Aug 2020, 14:59 (6 years ago) parentaccd7a2
6 files changed+108−2
lib/cabal-project-parser.nix+29−2 test/cabal-source-repo-comments/Main.hs+4 test/cabal-source-repo-comments/cabal.project+13 test/cabal-source-repo-comments/default.nix+35 test/cabal-source-repo-comments/use-cabal-simple.cabal+26 test/default.nix+1
lib/cabal-project-parser.nix+29−2
@@ -14,11 +14,38 @@ let
1414 in
1515 pkgs.lib.lists.head (indexState ++ [ null ]);
1616
17+ # Remove the indentation of the first line from all the lines
18+ unindent = blockLines: (pkgs.lib.foldl' ({matchString, out}: s:
19+ let
20+ m = builtins.match matchString s;
21+ in
22+ if m != null
23+ then {
24+ matchString = "(${builtins.head m})(.*)";
25+ out = out ++ [(builtins.elemAt m 1)];
26+ }
27+ else {
28+ inherit matchString out;
29+ }
30+ ) { matchString = "( *)(.*)"; out = []; } blockLines).out;
31+
32+ # Strip comments except `--sha256`
33+ stripComments = blockLines: pkgs.lib.filter (s: s != "") (
34+ pkgs.lib.foldl' (out: s:
35+ let
36+ m = builtins.match "(.*)--.*" s;
37+ in
38+ if !(pkgs.lib.hasPrefix "--sha256" s) && m != null
39+ then out ++ [(builtins.head m)]
40+ else out ++ [s]
41+ ) [] blockLines
42+ );
43+
1744 # Parse lines of a source-repository-package block
1845 parseBlockLines = blockLines: (pkgs.lib.foldl' ({name, attrs}: s:
1946 let
2047 # Look for a new attribute name
21− pair = builtins.match " *([^:]*): *(.*)" s;
48+ pair = builtins.match "([^ :]*): *(.*)" s;
2249
2350 # Function to build the next parse state when the attribute name is known
2451 nextState = name: value: {
@@ -40,7 +67,7 @@ let
4067 if name != null
4168 then nextState name s # Append another line to the current attirbute
4269 else __trace "Expected attribute but found `${s}`" { inherit name attrs; }
43− ) { name = null; attrs = {}; } blockLines).attrs;
70+ ) { name = null; attrs = {}; } (stripComments (unindent blockLines))).attrs;
4471
4572 hashPath = path:
4673 builtins.readFile (pkgs.runCommand "hash-path" { preferLocalBuild = true; }
test/cabal-source-repo-comments/Main.hsnew file+4
@@ -0,0 +1,4 @@
1+module Main where
2+
3+main :: IO ()
4+main = putStrLn "Hello, Haskell!"
test/cabal-source-repo-comments/cabal.projectnew file+13
@@ -0,0 +1,13 @@
1+packages:
2+ ./
3+
4+source-repository-package
5+ -- Test
6+ type: git
7+ -- Test
8+ location: https://github.com/input-output-hk/haskell.nix.git
9+ -- Test
10+ tag: bc01ebc05a8105035c9449943046b46c8364b932
11+ -- Test
12+ subdir: test/cabal-simple
13+ --sha256: 003lm3pm024vhbfmii7xcdd9v2rczpflxf7gdl2pyxia7p014i8z
test/cabal-source-repo-comments/default.nixnew file+35
@@ -0,0 +1,35 @@
1+{ stdenv, cabalProject', recurseIntoAttrs, haskellLib, testSrc, compiler-nix-name }:
2+
3+with stdenv.lib;
4+
5+let
6+ project = cabalProject' {
7+ inherit compiler-nix-name;
8+ index-state = "2020-05-25T00:00:00Z";
9+ src = testSrc "cabal-source-repo-comments";
10+ };
11+ packages = project.hsPkgs;
12+in recurseIntoAttrs {
13+ ifdInputs = {
14+ inherit (project) plan-nix;
15+ };
16+ run = stdenv.mkDerivation {
17+ name = "call-cabal-project-to-nix-test";
18+
19+ buildCommand = ''
20+ exe="${packages.use-cabal-simple.components.exes.use-cabal-simple}/bin/use-cabal-simple${stdenv.hostPlatform.extensions.executable}"
21+
22+ printf "checking whether executable runs... " >& 2
23+ cat ${haskellLib.check packages.use-cabal-simple.components.exes.use-cabal-simple}
24+
25+ touch $out
26+ '';
27+
28+ meta.platforms = platforms.all;
29+
30+ passthru = {
31+ # Attributes used for debugging with nix repl
32+ inherit packages;
33+ };
34+ };
35+}
test/cabal-source-repo-comments/use-cabal-simple.cabalnew file+26
@@ -0,0 +1,26 @@
1+cabal-version: >=1.10
2+-- Initial package description 'cabal-simple.cabal' generated by 'cabal
3+-- init'. For further documentation, see
4+-- http://haskell.org/cabal/users-guide/
5+
6+name: use-cabal-simple
7+version: 0.1.0.0
8+-- synopsis:
9+-- description:
10+-- bug-reports:
11+license: PublicDomain
12+author: Rodney Lorrimar
13+maintainer: rodney.lorrimar@iohk.io
14+-- category:
15+build-type: Simple
16+
17+executable use-cabal-simple
18+ main-is: Main.hs
19+ -- other-modules:
20+ -- other-extensions:
21+ build-depends: base
22+ , cabal-simple
23+ , extra
24+ , optparse-applicative
25+ -- hs-source-dirs:
26+ default-language: Haskell2010
test/default.nix+1
@@ -167,6 +167,7 @@ let
167167 callStackToNix = callTest ./call-stack-to-nix {};
168168 callCabalProjectToNix = callTest ./call-cabal-project-to-nix { inherit compiler-nix-name; };
169169 cabal-source-repo = callTest ./cabal-source-repo { inherit compiler-nix-name; };
170+ cabal-source-repo-comments = callTest ./cabal-source-repo-comments { inherit compiler-nix-name; };
170171 buildable = callTest ./buildable { inherit compiler-nix-name; };
171172 project-flags-cabal = callTest ./project-flags/cabal.nix { inherit compiler-nix-name; };
172173 project-flags-stack = callTest ./project-flags/stack.nix {};