Skip to content

Commit

Permalink
Flatten duplicate warnings about experimental features
Browse files Browse the repository at this point in the history
For some projects (e.g. glean) that make wide use of colon specifiers or
visibility, we get hundreds (thousands) of duplicating warnings about
these language features, spamming our builds.

Flatten this warning into a single instance per parse, and a count of
others.

Example:
```
Warning: glean.cabal:1674:15: colon specifier is experimental feature (issue
Warning: glean.cabal:1625:24: visibility is experimental feature (issue haskell#5660)
(and 32 more occurrences)
```

Test plan:
- try on glean.cabal from https://github.com/facebookincubator/Glean and
  see it working as above
- cabal test all
  • Loading branch information
donsbot committed Mar 1, 2022
1 parent 632571c commit 0886572
Showing 1 changed file with 32 additions and 6 deletions.
38 changes: 32 additions & 6 deletions Cabal/src/Distribution/Simple/PackageDescription.hs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,15 @@ 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
import Distribution.Parsec.Error ( showPError )
import Distribution.Parsec.Warning
( PWarning(..), PWarnType(PWTExperimental), showPWarning )
import Distribution.Simple.Utils ( equating, die', warn )
import Distribution.Verbosity ( 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
Expand Down Expand Up @@ -65,10 +68,33 @@ 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 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 :: [PWarning] -> [PWarning]
flattenDups ws = rest ++ experimentals
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))
]

0 comments on commit 0886572

Please sign in to comment.