@@ -58,8 +58,10 @@ import Distribution.Text
58
58
import Distribution.Utils.Generic (isAscii )
59
59
import Language.Haskell.Extension
60
60
61
+ import Control.Applicative (Const (.. ))
61
62
import Control.Monad (mapM )
62
63
import Data.List (group )
64
+ import Data.Monoid (Endo (.. ))
63
65
import qualified System.Directory as System
64
66
( doesFileExist , doesDirectoryExist )
65
67
import qualified Data.Map as Map
@@ -74,6 +76,7 @@ import System.FilePath
74
76
import System.FilePath.Windows as FilePath.Windows
75
77
( isValid )
76
78
79
+ import qualified Data.Set as Set
77
80
78
81
-- | Results of some kind of failed package check.
79
82
--
@@ -147,6 +150,7 @@ checkPackage gpkg mpkg =
147
150
++ checkPackageVersions gpkg
148
151
++ checkDevelopmentOnlyFlags gpkg
149
152
++ checkFlagNames gpkg
153
+ ++ checkUnusedFlags gpkg
150
154
where
151
155
pkg = fromMaybe (flattenPackageDescription gpkg) mpkg
152
156
@@ -1585,7 +1589,7 @@ checkConditionals pkg =
1585
1589
COr c1 c2 -> condfv c1 ++ condfv c2
1586
1590
CAnd c1 c2 -> condfv c1 ++ condfv c2
1587
1591
1588
- checkFlagNames :: GenericPackageDescription -> [PackageCheck ]
1592
+ checkFlagNames :: GenericPackageDescription -> [PackageCheck ]
1589
1593
checkFlagNames gpd
1590
1594
| null invalidFlagNames = []
1591
1595
| otherwise = [ PackageDistInexcusable
@@ -1606,6 +1610,36 @@ checkFlagNames gpd
1606
1610
-- mon ascii letter
1607
1611
invalidFlagName cs = any (not . isAscii) cs
1608
1612
1613
+ checkUnusedFlags :: GenericPackageDescription -> [PackageCheck ]
1614
+ checkUnusedFlags gpd
1615
+ | declared == used = []
1616
+ | otherwise = [ PackageDistSuspicious
1617
+ $ " Declared and used flag sets differ: "
1618
+ ++ s declared ++ " /= " ++ s used ++ " . "
1619
+ ]
1620
+ where
1621
+ s :: Set. Set FlagName -> String
1622
+ s = commaSep . map unFlagName . Set. toList
1623
+
1624
+ declared :: Set. Set FlagName
1625
+ declared = Set. fromList $ map flagName $ genPackageFlags gpd
1626
+
1627
+ used :: Set. Set FlagName
1628
+ used = Set. fromList $ ($ [] ) $ appEndo $ getConst $
1629
+ (traverse . traverseCondTreeV) tellFlag (condLibrary gpd) *>
1630
+ (traverse . _2 . traverseCondTreeV) tellFlag (condSubLibraries gpd) *>
1631
+ (traverse . _2 . traverseCondTreeV) tellFlag (condForeignLibs gpd) *>
1632
+ (traverse . _2 . traverseCondTreeV) tellFlag (condExecutables gpd) *>
1633
+ (traverse . _2 . traverseCondTreeV) tellFlag (condTestSuites gpd) *>
1634
+ (traverse . _2 . traverseCondTreeV) tellFlag (condBenchmarks gpd)
1635
+
1636
+ _2 :: Functor f => (a -> f b ) -> (c , a ) -> f (c , b )
1637
+ _2 f (c, a) = (,) c <$> f a
1638
+
1639
+ tellFlag :: ConfVar -> Const (Endo [FlagName ]) ConfVar
1640
+ tellFlag (Flag fn) = Const (Endo (fn : ))
1641
+ tellFlag _ = Const mempty
1642
+
1609
1643
checkDevelopmentOnlyFlagsBuildInfo :: BuildInfo -> [PackageCheck ]
1610
1644
checkDevelopmentOnlyFlagsBuildInfo bi =
1611
1645
catMaybes [
0 commit comments