diff --git a/Cabal/src/Distribution/Simple/PackageDescription.hs b/Cabal/src/Distribution/Simple/PackageDescription.hs index 4c64aedf767..bb7e54550c3 100644 --- a/Cabal/src/Distribution/Simple/PackageDescription.hs +++ b/Cabal/src/Distribution/Simple/PackageDescription.hs @@ -24,12 +24,16 @@ import Distribution.Compat.Prelude import Distribution.Fields.ParseResult import Distribution.PackageDescription import Distribution.PackageDescription.Parsec -import Distribution.Parsec.Error (showPError) -import Distribution.Parsec.Warning (showPWarning) -import Distribution.Simple.Utils -import Distribution.Verbosity + ( parseGenericPackageDescription, parseHookedBuildInfo ) +import Distribution.Parsec.Error ( showPError ) +import Distribution.Parsec.Warning + ( PWarning(..), PWarnType(PWTExperimental), showPWarning ) +import Distribution.Simple.Utils ( equating, die', warn ) +import Distribution.Verbosity ( normal, Verbosity ) -import qualified Data.ByteString as BS +import Data.List ( groupBy ) +import Text.Printf ( printf ) +import qualified Data.ByteString as BS import System.Directory (doesFileExist) readGenericPackageDescription :: Verbosity -> FilePath -> IO GenericPackageDescription @@ -65,10 +69,35 @@ parseString -> IO a parseString parser verbosity name bs = do let (warnings, result) = runParseResult (parser bs) - traverse_ (warn verbosity . showPWarning name) warnings + traverse_ (warn verbosity . showPWarning name) (flattenDups verbosity warnings) case result of Right x -> return x Left (_, errors) -> do traverse_ (warn verbosity . showPError name) errors die' verbosity $ "Failed parsing \"" ++ 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)) + ] \ No newline at end of file