Skip to content

Commit e5a868c

Browse files
committed
WIP2
1 parent 4a380f7 commit e5a868c

File tree

3 files changed

+47
-1
lines changed

3 files changed

+47
-1
lines changed

cabal-install-parsers/Changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.6.4
2+
3+
- Add support for reading project files with conditionals.
4+
15
## 0.6.3
26

37
- Drop support for GHC prior 8.8.4

cabal-install-parsers/cabal-install-parsers.cabal

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: 2.2
22
name: cabal-install-parsers
3-
version: 0.6.3
3+
version: 0.6.4
44
synopsis: Utilities to work with cabal-install files
55
description:
66
@cabal-install-parsers@ provides parsers for @cabal-install@ files:

cabal-install-parsers/src/Cabal/Project.hs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ module Cabal.Project (
1515
-- * Parse project
1616
readProject,
1717
parseProject,
18+
readProjectWithConditionals,
19+
parseProjectWithConditionals,
1820
-- * Resolve project
1921
resolveProject,
2022
ResolveError (..),
@@ -179,6 +181,13 @@ readProject fp = do
179181
prj1 <- resolveProject fp prj0 >>= either throwIO return
180182
readPackagesOfProject prj1 >>= either throwIO return
181183

184+
readProjectWithConditionals :: FilePath -> IO (C.CondTree C.ConfVar () (Project URI Void (FilePath, C.GenericPackageDescription)))
185+
readProjectWithConditionals fp = do
186+
contents <- BS.readFile fp
187+
prj0 <- either throwIO return (parseProjectWithConditionals fp contents)
188+
prj1 <- traverse (\p -> resolveProject fp p >>= either throwIO return) prj0
189+
traverse (\p -> readPackagesOfProject p >>= either throwIO return) prj1
190+
182191
-- | Parse project file. Extracts only few fields.
183192
--
184193
-- >>> fmap prjPackages $ parseProject "cabal.project" "packages: foo bar/*.cabal"
@@ -207,6 +216,39 @@ parseProject = parseWith $ \fields0 -> do
207216

208217
parseSec _ = return id
209218

219+
-- | Parse project files with conditionals.
220+
--
221+
-- >>> fmap (fmap prjPackages) $ parseProjectWithConditionals "cabal.project" "packages: foo bar/*.cabal"
222+
-- Right (CondNode {condTreeData = ["foo","bar/*.cabal"], condTreeConstraints = (), condTreeComponents = []})
223+
--
224+
-- TODO:
225+
--
226+
-- >>> fmap (fmap prjPackages) $ parseProjectWithConditionals "cabal.project" "packages: foo bar/*.cabal\nif impl(ghc >=9)\n packages: quu"
227+
-- Right (CondNode {condTreeData = ["foo","bar/*.cabal"], condTreeConstraints = (), condTreeComponents = []})
228+
--
229+
parseProjectWithConditionals :: FilePath -> ByteString -> Either (ParseError NonEmpty) (C.CondTree C.ConfVar () (Project Void String String))
230+
parseProjectWithConditionals = parseWith $ \fields0 -> do
231+
let (fields1, sections) = C.partitionFields fields0
232+
let fields2 = M.filterWithKey (\k _ -> k `elem` knownFields) fields1
233+
(\n -> C.CondNode n () []) <$> parse fields0 fields2 sections
234+
where
235+
knownFields = C.fieldGrammarKnownFieldList $ grammar []
236+
237+
parse otherFields fields sections = do
238+
let prettyOtherFields = map void $ C.fromParsecFields $ filter otherFieldName otherFields
239+
prj <- C.parseFieldGrammar C.cabalSpecLatest fields $ grammar prettyOtherFields
240+
foldl' (&) prj <$> traverse parseSec (concat sections)
241+
242+
-- Special case for source-repository-package. If you add another such
243+
-- special case, make sure to update otherFieldName appropriately.
244+
parseSec :: C.Section C.Position -> C.ParseResult (Project Void String String -> Project Void String String)
245+
parseSec (C.MkSection (C.Name _pos name) [] fields) | name == sourceRepoSectionName = do
246+
let fields' = fst $ C.partitionFields fields
247+
repos <- C.parseFieldGrammar C.cabalSpecLatest fields' sourceRepositoryPackageGrammar
248+
return $ over prjSourceReposL (++ toList (srpFanOut repos))
249+
250+
parseSec _ = return id
251+
210252
-- | Returns 'True' if a field should be a part of 'prjOtherFields'. This
211253
-- excludes any field that is a part of 'grammar' as well as
212254
-- @source-repository-package@ (see 'parseProject', which has a special case

0 commit comments

Comments
 (0)