1 -----------------------------------------------------------------------------
4 -- Module : Distribution.Simple.PackageDescription
5 -- Copyright : Isaac Jones 2003-2005
8 -- Maintainer : cabal-devel@haskell.org
9 -- Portability : portable
11 -- This defines parsers for the @.cabal@ format
12 module Distribution
.Simple
.PackageDescription
13 ( -- * Read and Parse files
14 readGenericPackageDescription
17 -- * Utility Parsing function
21 import Distribution
.Compat
.Prelude
24 import qualified Data
.ByteString
as BS
25 import Data
.List
(groupBy)
26 import Distribution
.Fields
.ParseResult
27 import Distribution
.PackageDescription
28 import Distribution
.PackageDescription
.Parsec
29 ( parseGenericPackageDescription
30 , parseHookedBuildInfo
32 import Distribution
.Parsec
.Error
(showPError
)
33 import Distribution
.Parsec
.Warning
34 ( PWarnType
(PWTExperimental
)
38 import Distribution
.Simple
.Errors
39 import Distribution
.Simple
.Utils
(dieWithException
, equating
, warn
)
40 import Distribution
.Verbosity
(Verbosity
, normal
)
41 import System
.Directory
(doesFileExist)
42 import Text
.Printf
(printf
)
44 readGenericPackageDescription
:: Verbosity
-> FilePath -> IO GenericPackageDescription
45 readGenericPackageDescription
= readAndParseFile parseGenericPackageDescription
47 readHookedBuildInfo
:: Verbosity
-> FilePath -> IO HookedBuildInfo
48 readHookedBuildInfo
= readAndParseFile parseHookedBuildInfo
50 -- | Helper combinator to do parsing plumbing for files.
52 -- Given a parser and a filename, return the parse of the file,
53 -- after checking if the file exists.
55 -- Argument order is chosen to encourage partial application.
57 :: (BS
.ByteString
-> ParseResult a
)
58 -- ^ File contents to final value parser
64 readAndParseFile parser verbosity fpath
= do
65 exists
<- doesFileExist fpath
67 dieWithException verbosity
$
68 ErrorParsingFileDoesntExist fpath
69 bs
<- BS
.readFile fpath
70 parseString parser verbosity fpath bs
73 :: (BS
.ByteString
-> ParseResult a
)
74 -- ^ File contents to final value parser
81 parseString parser verbosity name bs
= do
82 let (warnings
, result
) = runParseResult
(parser bs
)
83 traverse_
(warn verbosity
. showPWarning name
) (flattenDups verbosity warnings
)
86 Left
(_
, errors
) -> do
87 traverse_
(warn verbosity
. showPError name
) errors
88 dieWithException verbosity
$ FailedParsing name
90 -- | Collapse duplicate experimental feature warnings into single warning, with
91 -- a count of further sites
92 flattenDups
:: Verbosity
-> [PWarning
] -> [PWarning
]
93 flattenDups verbosity ws
94 | verbosity
<= normal
= rest
++ experimentals
95 |
otherwise = ws
-- show all instances
97 (exps
, rest
) = partition (\(PWarning w _ _
) -> w
== PWTExperimental
) ws
100 . groupBy (equating warningStr
)
101 . sortBy (comparing warningStr
)
104 warningStr
(PWarning _ _ w
) = w
106 -- flatten if we have 3 or more examples
107 flatCount
:: [PWarning
] -> [PWarning
]
110 flatCount w
@[_
, _
] = w
111 flatCount
(PWarning t pos w
: xs
) =
115 (w
<> printf
" (and %d more occurrences)" (length xs
))