-
Notifications
You must be signed in to change notification settings - Fork 704
/
Copy pathPackageDescription.hs
136 lines (124 loc) · 3.87 KB
/
PackageDescription.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
{-# LANGUAGE DataKinds #-}
-----------------------------------------------------------------------------
-- |
-- Module : Distribution.Simple.PackageDescription
-- Copyright : Isaac Jones 2003-2005
-- License : BSD3
--
-- Maintainer : [email protected]
-- Portability : portable
--
-- This defines parsers for the @.cabal@ format
module Distribution.Simple.PackageDescription
( -- * Read and Parse files
readGenericPackageDescription
, readHookedBuildInfo
-- * Utility Parsing function
, parseString
) where
import Distribution.Compat.Prelude
import Prelude ()
import qualified Data.ByteString as BS
import Data.List (groupBy)
import Distribution.Fields.ParseResult
import Distribution.PackageDescription
import Distribution.PackageDescription.Parsec
( parseGenericPackageDescription
, parseHookedBuildInfo
)
import Distribution.Parsec.Error (showPError)
import Distribution.Parsec.Warning
( PWarnType (PWTExperimental)
, PWarning (..)
, showPWarning
)
import Distribution.Simple.Errors
import Distribution.Simple.Utils (dieWithException, equating, warn)
import Distribution.Utils.Path
import Distribution.Verbosity (Verbosity, normal)
import GHC.Stack
import System.Directory (doesFileExist)
import Text.Printf (printf)
readGenericPackageDescription
:: HasCallStack
=> Verbosity
-> Maybe (SymbolicPath CWD (Dir Pkg))
-> SymbolicPath Pkg File
-> IO GenericPackageDescription
readGenericPackageDescription =
readAndParseFile parseGenericPackageDescription
readHookedBuildInfo
:: Verbosity
-> Maybe (SymbolicPath CWD (Dir Pkg))
-- ^ working directory
-> SymbolicPath Pkg File
-> IO HookedBuildInfo
readHookedBuildInfo =
readAndParseFile parseHookedBuildInfo
-- | Helper combinator to do parsing plumbing for files.
--
-- Given a parser and a filename, return the parse of the file,
-- after checking if the file exists.
--
-- Argument order is chosen to encourage partial application.
readAndParseFile
:: (BS.ByteString -> ParseResult a)
-- ^ File contents to final value parser
-> Verbosity
-- ^ Verbosity level
-> Maybe (SymbolicPath CWD (Dir Pkg))
-- ^ Working directory
-> SymbolicPath Pkg File
-- ^ File to read
-> IO a
readAndParseFile parser verbosity mbWorkDir fpath = do
let ipath = interpretSymbolicPath mbWorkDir fpath
upath = getSymbolicPath fpath
exists <- doesFileExist ipath
unless exists $
dieWithException verbosity $
ErrorParsingFileDoesntExist upath
bs <- BS.readFile ipath
parseString parser verbosity upath bs
parseString
:: (BS.ByteString -> ParseResult a)
-- ^ File contents to final value parser
-> Verbosity
-- ^ Verbosity level
-> String
-- ^ File name
-> BS.ByteString
-> IO a
parseString parser verbosity name bs = do
let (warnings, result) = runParseResult (parser bs)
traverse_ (warn verbosity . showPWarning name) (flattenDups verbosity warnings)
case result of
Right x -> return x
Left (_, errors) -> do
traverse_ (warn verbosity . showPError name) errors
dieWithException verbosity $ FailedParsing name
-- | Collapse duplicate experimental feature warnings into single warning, with
-- a count of further sites
flattenDups :: Verbosity -> [PWarning] -> [PWarning]
flattenDups verbosity ws
| verbosity <= normal = rest ++ experimentals
| otherwise = ws -- show all instances
where
(exps, rest) = partition (\(PWarning w _ _) -> w == PWTExperimental) ws
experimentals =
concatMap flatCount
. groupBy (equating warningStr)
. sortBy (comparing warningStr)
$ exps
warningStr (PWarning _ _ w) = w
-- flatten if we have 3 or more examples
flatCount :: [PWarning] -> [PWarning]
flatCount w@[] = w
flatCount w@[_] = w
flatCount w@[_, _] = w
flatCount (PWarning t pos w : xs) =
[ PWarning
t
pos
(w <> printf " (and %d more occurrences)" (length xs))
]