diff --git a/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs b/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs index 0acb8df1786..92eeb8799f0 100644 --- a/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs +++ b/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs @@ -41,6 +41,8 @@ import Distribution.Types.VersionRange.Internal import Distribution.Utils.NubList import Distribution.Verbosity import Distribution.Version +import Distribution.Types.DebugInfoLevel (DebugInfoLevel) +import Distribution.Types.OptimisationLevel (OptimisationLevel) import Test.QuickCheck.GenericArbitrary diff --git a/Cabal-syntax/src/Distribution/Parsec.hs b/Cabal-syntax/src/Distribution/Parsec.hs index 9b43b6e41a2..6d384418370 100644 --- a/Cabal-syntax/src/Distribution/Parsec.hs +++ b/Cabal-syntax/src/Distribution/Parsec.hs @@ -252,15 +252,11 @@ instance Parsec Bool where parsec = P.munch1 isAlpha >>= postprocess where postprocess str - | str == "True" = pure True - | str == "False" = pure False - | lstr == "true" = parsecWarning PWTBoolCase caseWarning *> pure True - | lstr == "false" = parsecWarning PWTBoolCase caseWarning *> pure False + | lstr == "true" = pure True + | lstr == "false" = pure False | otherwise = fail $ "Not a boolean: " ++ str where lstr = map toLower str - caseWarning = - "Boolean values are case sensitive, use 'True' or 'False'." instance Parsec a => Parsec (Last a) where parsec = parsecLast diff --git a/Cabal-syntax/src/Distribution/Parsec/Warning.hs b/Cabal-syntax/src/Distribution/Parsec/Warning.hs index 65b1471b054..2472c544b8f 100644 --- a/Cabal-syntax/src/Distribution/Parsec/Warning.hs +++ b/Cabal-syntax/src/Distribution/Parsec/Warning.hs @@ -25,8 +25,6 @@ data PWarnType PWTOther | -- | Invalid UTF encoding PWTUTF - | -- | @true@ or @false@, not @True@ or @False@ - PWTBoolCase | -- | there are version with tags PWTVersionTag | -- | New syntax used, but no @cabal-version: >= 1.2@ specified diff --git a/Cabal-tests/tests/ParserTests.hs b/Cabal-tests/tests/ParserTests.hs index 42ab00ae9f2..88c40fde27f 100644 --- a/Cabal-tests/tests/ParserTests.hs +++ b/Cabal-tests/tests/ParserTests.hs @@ -68,7 +68,6 @@ warningTests = testGroup "warnings triggered" , warningTest PWTLexNBSP "nbsp.cabal" , warningTest PWTLexTab "tab.cabal" , warningTest PWTUTF "utf8.cabal" - , warningTest PWTBoolCase "bool.cabal" , warningTest PWTVersionTag "versiontag.cabal" , warningTest PWTNewSyntax "newsyntax.cabal" , warningTest PWTOldSyntax "oldsyntax.cabal" diff --git a/Cabal-tests/tests/ParserTests/warnings/bool.cabal b/Cabal-tests/tests/ParserTests/warnings/bool.cabal deleted file mode 100644 index 34e6e0f8f22..00000000000 --- a/Cabal-tests/tests/ParserTests/warnings/bool.cabal +++ /dev/null @@ -1,12 +0,0 @@ -name: bool -version: 1 -cabal-version: >= 1.8 - -flag foo - manual: true - -library - build-depends: base >= 4.9 && <4.10 - if flag(foo) - build-depends: containers - hs-source-dirs: . diff --git a/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs b/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs index dd3dfaa028f..1251d237bb6 100644 --- a/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs +++ b/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs @@ -18,20 +18,22 @@ import Distribution.Compiler (CompilerFlavor, CompilerId, import Distribution.InstalledPackageInfo (AbiDependency, ExposedModule, InstalledPackageInfo) import Distribution.ModuleName (ModuleName) import Distribution.PackageDescription -import Distribution.Simple.Compiler (DebugInfoLevel, OptimisationLevel, ProfDetailLevel) +import Distribution.Simple.Compiler (ProfDetailLevel) import Distribution.Simple.InstallDirs -import Distribution.Simple.InstallDirs.Internal +import Distribution.Simple.InstallDirs.Internal (PathComponent) import Distribution.Simple.Setup (HaddockTarget, TestShowDetails) -import Distribution.System +import Distribution.System (OS, Arch) import Distribution.Types.AbiHash (AbiHash) import Distribution.Types.ComponentId (ComponentId) import Distribution.Types.DumpBuildInfo (DumpBuildInfo) -import Distribution.Types.PackageVersionConstraint +import Distribution.Types.PackageVersionConstraint (PackageVersionConstraint) import Distribution.Types.UnitId (DefUnitId, UnitId) import Distribution.Utils.NubList (NubList) import Distribution.Utils.Path (SymbolicPathX) -import Distribution.Verbosity -import Distribution.Verbosity.Internal +import Distribution.Verbosity (VerbosityLevel, VerbosityFlags) +import Distribution.Verbosity.Internal (VerbosityFlag) +import Distribution.Types.DebugInfoLevel (DebugInfoLevel) +import Distribution.Types.OptimisationLevel (OptimisationLevel) import qualified Distribution.Compat.NonEmptySet as NES diff --git a/Cabal/Cabal.cabal b/Cabal/Cabal.cabal index c91d2c11d89..aba6aff5a82 100644 --- a/Cabal/Cabal.cabal +++ b/Cabal/Cabal.cabal @@ -171,11 +171,13 @@ library Distribution.TestSuite Distribution.Types.AnnotatedId Distribution.Types.ComponentInclude + Distribution.Types.DebugInfoLevel Distribution.Types.DumpBuildInfo Distribution.Types.PackageName.Magic Distribution.Types.ComponentLocalBuildInfo Distribution.Types.LocalBuildConfig Distribution.Types.LocalBuildInfo + Distribution.Types.OptimisationLevel Distribution.Types.TargetInfo Distribution.Types.GivenComponent Distribution.Types.ParStrat diff --git a/Cabal/src/Distribution/Simple/Build.hs b/Cabal/src/Distribution/Simple/Build.hs index e79a1924eb9..a8ce8903df9 100644 --- a/Cabal/src/Distribution/Simple/Build.hs +++ b/Cabal/src/Distribution/Simple/Build.hs @@ -309,7 +309,7 @@ dumpBuildInfo verbosity distPref dumpBuildInfoFlag pkg_descr lbi flags = do removeFileForcibly buildInfoFile where buildInfoFile = interpretSymbolicPathLBI lbi $ buildInfoPref distPref - shouldDumpBuildInfo = fromFlagOrDefault NoDumpBuildInfo dumpBuildInfoFlag == DumpBuildInfo + shouldDumpBuildInfo = fromNoFlag dumpBuildInfoFlag == DumpBuildInfo -- \| Given the flavor of the compiler, try to find out -- which program we need. diff --git a/Cabal/src/Distribution/Simple/Command.hs b/Cabal/src/Distribution/Simple/Command.hs index 0fe65f8d751..6f0eced8ad0 100644 --- a/Cabal/src/Distribution/Simple/Command.hs +++ b/Cabal/src/Distribution/Simple/Command.hs @@ -79,7 +79,6 @@ module Distribution.Simple.Command , reqArg' , optArg , optArg' - , optArgDef' , noArg , boolOpt , boolOpt' @@ -280,15 +279,6 @@ optArg' optArg' ad mkflag showflag = optArg ad (succeedReadE (mkflag . Just)) ("", mkflag Nothing) showflag -optArgDef' - :: Monoid b - => ArgPlaceHolder - -> (String, Maybe String -> b) - -> (b -> [Maybe String]) - -> MkOptDescr (a -> b) (b -> a -> a) a -optArgDef' ad (dv, mkflag) showflag = - optArg ad (succeedReadE (mkflag . Just)) (dv, mkflag Nothing) showflag - noArg :: Eq b => b -> MkOptDescr (a -> b) (b -> a -> a) a noArg flag sf lf d = choiceOpt [(flag, (sf, lf), d)] sf lf d diff --git a/Cabal/src/Distribution/Simple/Compiler.hs b/Cabal/src/Distribution/Simple/Compiler.hs index 4f66f90eea8..dd24249f07f 100644 --- a/Cabal/src/Distribution/Simple/Compiler.hs +++ b/Cabal/src/Distribution/Simple/Compiler.hs @@ -52,14 +52,6 @@ module Distribution.Simple.Compiler , coercePackageDBStack , readPackageDb - -- * Support for optimisation levels - , OptimisationLevel (..) - , flagToOptimisationLevel - - -- * Support for debug info levels - , DebugInfoLevel (..) - , flagToDebugInfoLevel - -- * Support for language extensions , CompilerFlag , languageToFlags @@ -95,22 +87,30 @@ module Distribution.Simple.Compiler , showProfDetailLevel ) where -import Distribution.Compat.CharParsing import Distribution.Compat.Prelude -import Distribution.Parsec -import Distribution.Pretty +import Distribution.Parsec (CabalParsing, Parsec (..), parsecToken) +import Distribution.Pretty (prettyShow) import Prelude () import Distribution.Compiler import Distribution.Package (PackageName) -import Distribution.Simple.Utils +import Distribution.Simple.Utils (lowercase, safeLast) import Distribution.Types.UnitId (UnitId) import Distribution.Utils.Path -import Distribution.Version - -import Language.Haskell.Extension + ( CWD + , FileOrDir (..) + , Pkg + , PkgDB + , SymbolicPath + , getSymbolicPath + , interpretSymbolicPath + , makeSymbolicPath + , symbolicPathRelative_maybe + ) +import Distribution.Version (Version, mkVersion) + +import Language.Haskell.Extension (Extension, Language (..)) -import Data.Bool (bool) import qualified Data.Map as Map (lookup) import System.Directory (canonicalizePath) @@ -303,95 +303,6 @@ coercePackageDBStack = map coercePackageDB -- ------------------------------------------------------------ --- * Optimisation levels - --- ------------------------------------------------------------ - --- | Some compilers support optimising. Some have different levels. --- For compilers that do not the level is just capped to the level --- they do support. -data OptimisationLevel - = NoOptimisation - | NormalOptimisation - | MaximumOptimisation - deriving (Bounded, Enum, Eq, Generic, Read, Show) - -instance Binary OptimisationLevel -instance NFData OptimisationLevel -instance Structured OptimisationLevel - -instance Parsec OptimisationLevel where - parsec = parsecOptimisationLevel - -parsecOptimisationLevel :: CabalParsing m => m OptimisationLevel -parsecOptimisationLevel = boolParser <|> intParser - where - boolParser = bool NoOptimisation NormalOptimisation <$> parsec - intParser = intToOptimisationLevel <$> integral - -flagToOptimisationLevel :: Maybe String -> OptimisationLevel -flagToOptimisationLevel Nothing = NormalOptimisation -flagToOptimisationLevel (Just s) = case reads s of - [(i, "")] -> intToOptimisationLevel i - _ -> error $ "Can't parse optimisation level " ++ s - -intToOptimisationLevel :: Int -> OptimisationLevel -intToOptimisationLevel i - | i >= minLevel && i <= maxLevel = toEnum i - | otherwise = - error $ - "Bad optimisation level: " - ++ show i - ++ ". Valid values are " - ++ show minLevel - ++ ".." - ++ show maxLevel - where - minLevel = fromEnum (minBound :: OptimisationLevel) - maxLevel = fromEnum (maxBound :: OptimisationLevel) - --- ------------------------------------------------------------ - --- * Debug info levels - --- ------------------------------------------------------------ - --- | Some compilers support emitting debug info. Some have different --- levels. For compilers that do not the level is just capped to the --- level they do support. -data DebugInfoLevel - = NoDebugInfo - | MinimalDebugInfo - | NormalDebugInfo - | MaximalDebugInfo - deriving (Bounded, Enum, Eq, Generic, Read, Show) - -instance Binary DebugInfoLevel -instance NFData DebugInfoLevel -instance Structured DebugInfoLevel - -instance Parsec DebugInfoLevel where - parsec = parsecDebugInfoLevel - -parsecDebugInfoLevel :: CabalParsing m => m DebugInfoLevel -parsecDebugInfoLevel = flagToDebugInfoLevel . pure <$> parsecToken - -flagToDebugInfoLevel :: Maybe String -> DebugInfoLevel -flagToDebugInfoLevel Nothing = NormalDebugInfo -flagToDebugInfoLevel (Just s) = case reads s of - [(i, "")] - | i >= fromEnum (minBound :: DebugInfoLevel) - && i <= fromEnum (maxBound :: DebugInfoLevel) -> - toEnum i - | otherwise -> - error $ - "Bad debug info level: " - ++ show i - ++ ". Valid values are 0..3" - _ -> error $ "Can't parse debug info level " ++ s - --- ------------------------------------------------------------ - -- * Languages and Extensions -- ------------------------------------------------------------ diff --git a/Cabal/src/Distribution/Simple/Configure.hs b/Cabal/src/Distribution/Simple/Configure.hs index 69b9a80e16f..29b958b8e34 100644 --- a/Cabal/src/Distribution/Simple/Configure.hs +++ b/Cabal/src/Distribution/Simple/Configure.hs @@ -163,6 +163,7 @@ import Distribution.Pretty ) import Distribution.Simple.Errors import Distribution.Types.AnnotatedId +import Distribution.Types.DebugInfoLevel (DebugInfoLevel (..)) import Distribution.Utils.Path import Distribution.Utils.Structured (structuredDecodeOrFailIO, structuredEncode) import System.Directory diff --git a/Cabal/src/Distribution/Simple/Flag.hs b/Cabal/src/Distribution/Simple/Flag.hs index 341fd907e09..b6b92d5600b 100644 --- a/Cabal/src/Distribution/Simple/Flag.hs +++ b/Cabal/src/Distribution/Simple/Flag.hs @@ -31,6 +31,8 @@ module Distribution.Simple.Flag , maybeToFlag , mergeListFlag , BooleanFlag (..) + , NoFlagValue (..) + , fromNoFlag ) where import Data.Monoid (Last (..)) @@ -123,3 +125,15 @@ class BooleanFlag a where instance BooleanFlag Bool where asBool = id + +-- | Flag is a Monoid, with 'NoFlag' as the identity element, and 'Flag' as the binary operation. +-- +-- @since 3.18.0.0 +class NoFlagValue a where + noFlagValue :: a + +-- | Extracts a value from a 'Flag', and returns the 'noFlagValue' on 'NoFlag'. +-- +-- @since 3.18.0.0 +fromNoFlag :: NoFlagValue a => Flag a -> a +fromNoFlag = fromFlagOrDefault noFlagValue diff --git a/Cabal/src/Distribution/Simple/GHC/Internal.hs b/Cabal/src/Distribution/Simple/GHC/Internal.hs index ac2116b4b09..b6668b1fea8 100644 --- a/Cabal/src/Distribution/Simple/GHC/Internal.hs +++ b/Cabal/src/Distribution/Simple/GHC/Internal.hs @@ -76,11 +76,13 @@ import Distribution.Simple.Utils import Distribution.System import Distribution.Types.BuildInfo import Distribution.Types.ComponentLocalBuildInfo +import Distribution.Types.DebugInfoLevel (DebugInfoLevel (..)) import Distribution.Types.GivenComponent import qualified Distribution.Types.InstalledPackageInfo as IPI import Distribution.Types.Library import Distribution.Types.LocalBuildInfo import Distribution.Types.ModuleRenaming +import Distribution.Types.OptimisationLevel (OptimisationLevel (..)) import Distribution.Types.PackageName import Distribution.Types.TargetInfo import Distribution.Types.UnitId diff --git a/Cabal/src/Distribution/Simple/Program/GHC.hs b/Cabal/src/Distribution/Simple/Program/GHC.hs index e049749ee7e..5dc689573d9 100644 --- a/Cabal/src/Distribution/Simple/Program/GHC.hs +++ b/Cabal/src/Distribution/Simple/Program/GHC.hs @@ -48,12 +48,13 @@ import Distribution.Verbosity import Distribution.Version import GHC.IO.Encoding (TextEncoding) -import Language.Haskell.Extension +import Language.Haskell.Extension (Extension, Language) import Data.List (stripPrefix) import qualified Data.Map as Map import Data.Monoid (All (..), Any (..), Endo (..)) import qualified Data.Set as Set +import Distribution.Types.DebugInfoLevel (DebugInfoLevel (..)) import qualified System.Process as Process normaliseGhcArgs :: Maybe Version -> PackageDescription -> [String] -> [String] diff --git a/Cabal/src/Distribution/Simple/Setup/Config.hs b/Cabal/src/Distribution/Simple/Setup/Config.hs index 92fb879df9a..4da3966acf1 100644 --- a/Cabal/src/Distribution/Simple/Setup/Config.hs +++ b/Cabal/src/Distribution/Simple/Setup/Config.hs @@ -63,9 +63,13 @@ import Distribution.Simple.Program import Distribution.Simple.Setup.Common import Distribution.Simple.Utils import Distribution.Types.ComponentId -import Distribution.Types.DumpBuildInfo +import Distribution.Types.DebugInfoLevel (DebugInfoLevel (..)) +import qualified Distribution.Types.DebugInfoLevel as DebugInfoLevel +import Distribution.Types.DumpBuildInfo (DumpBuildInfo (..)) import Distribution.Types.GivenComponent import Distribution.Types.Module +import Distribution.Types.OptimisationLevel (OptimisationLevel (..)) +import qualified Distribution.Types.OptimisationLevel as OptimisationLevel import Distribution.Types.PackageVersionConstraint import Distribution.Types.UnitId import Distribution.Utils.NubList @@ -570,18 +574,20 @@ configureOptions showOrParseArgs = "optimization" configOptimization (\v flags -> flags{configOptimization = v}) - [ optArgDef' + [ reqArg' "n" - (show NoOptimisation, Flag . flagToOptimisationLevel) + (Flag . fromString) ( \case - Flag NoOptimisation -> [] - Flag NormalOptimisation -> [Nothing] - Flag MaximumOptimisation -> [Just "2"] - _ -> [] + NoFlag -> [] + Flag flag -> [OptimisationLevel.toString flag] ) "O" ["enable-optimization", "enable-optimisation"] - "Build with optimization (n is 0--2, default is 1)" + ( let minLevel = OptimisationLevel.toString minBound + maxLevel = OptimisationLevel.toString maxBound + def = OptimisationLevel.toString noFlagValue + in "Build with optimization (n is " ++ minLevel ++ "--" ++ maxLevel ++ ", default is " ++ def ++ ")" + ) , noArg (Flag NoOptimisation) [] @@ -592,19 +598,20 @@ configureOptions showOrParseArgs = "debug-info" configDebugInfo (\v flags -> flags{configDebugInfo = v}) - [ optArg' + [ reqArg' "n" - (Flag . flagToDebugInfoLevel) + (Flag . fromString) ( \case - Flag NoDebugInfo -> [] - Flag MinimalDebugInfo -> [Just "1"] - Flag NormalDebugInfo -> [Nothing] - Flag MaximalDebugInfo -> [Just "3"] - _ -> [] + NoFlag -> [] + Flag flag -> [DebugInfoLevel.toString flag] ) - "" + "g" ["enable-debug-info"] - "Emit debug info (n is 0--3, default is 0)" + ( let minLevel = DebugInfoLevel.toString minBound + maxLevel = DebugInfoLevel.toString maxBound + def = DebugInfoLevel.toString noFlagValue + in "Emit debug info (n is " ++ minLevel ++ "--" ++ maxLevel ++ ", default is " ++ def ++ ")" + ) , noArg (Flag NoDebugInfo) [] diff --git a/Cabal/src/Distribution/Simple/UHC.hs b/Cabal/src/Distribution/Simple/UHC.hs index 2a9261a40b0..dae0af37596 100644 --- a/Cabal/src/Distribution/Simple/UHC.hs +++ b/Cabal/src/Distribution/Simple/UHC.hs @@ -45,6 +45,7 @@ import Distribution.Simple.Program import Distribution.Simple.Utils import Distribution.System import Distribution.Types.MungedPackageId +import Distribution.Types.OptimisationLevel (OptimisationLevel (..)) import Distribution.Utils.Path import Distribution.Verbosity import Distribution.Version diff --git a/Cabal/src/Distribution/Types/DebugInfoLevel.hs b/Cabal/src/Distribution/Types/DebugInfoLevel.hs new file mode 100644 index 00000000000..4087a781e62 --- /dev/null +++ b/Cabal/src/Distribution/Types/DebugInfoLevel.hs @@ -0,0 +1,73 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE InstanceSigs #-} + +module Distribution.Types.DebugInfoLevel + ( DebugInfoLevel (..) + , toString + ) +where + +import Distribution.Compat.CharParsing (integral) +import Distribution.Compat.Prelude +import Distribution.Parsec (CabalParsing, Parsec (..)) +import Prelude () + +import Data.Bool (bool) +import Distribution.Simple.Flag (NoFlagValue (..)) + +-- ------------------------------------------------------------ + +-- * Debug info levels + +-- ------------------------------------------------------------ + +-- | Some compilers support emitting debug info. Some have different +-- levels. For compilers that do not the level is just capped to the +-- level they do support. +data DebugInfoLevel + = NoDebugInfo + | MinimalDebugInfo + | NormalDebugInfo + | MaximalDebugInfo + deriving stock (Bounded, Enum, Eq, Generic, Read, Show) + +instance Binary DebugInfoLevel +instance NFData DebugInfoLevel +instance Structured DebugInfoLevel + +instance NoFlagValue DebugInfoLevel where + noFlagValue :: DebugInfoLevel + noFlagValue = NoDebugInfo + +instance Parsec DebugInfoLevel where + parsec :: CabalParsing m => m DebugInfoLevel + parsec = boolParser <|> intParser + where + boolParser = bool NoDebugInfo NormalDebugInfo <$> parsec + intParser = intToDebugInfoLevel <$> integral + +instance IsString DebugInfoLevel where + fromString :: String -> DebugInfoLevel + fromString s = case reads s of + [(i, "")] -> intToDebugInfoLevel i + _ -> error $ "Can't parse debug info level " ++ s + +toString :: DebugInfoLevel -> String +toString = show . fromEnum + +intToDebugInfoLevel :: Int -> DebugInfoLevel +intToDebugInfoLevel i + | i >= minLevel && i <= maxLevel = toEnum i + | otherwise = + error $ + "Bad debug info level: " + ++ show i + ++ ". Valid values are " + ++ show minLevel + ++ ".." + ++ show maxLevel + where + minLevel = fromEnum (minBound :: DebugInfoLevel) + maxLevel = fromEnum (maxBound :: DebugInfoLevel) diff --git a/Cabal/src/Distribution/Types/DumpBuildInfo.hs b/Cabal/src/Distribution/Types/DumpBuildInfo.hs index b946093b487..fff8fe8ad60 100644 --- a/Cabal/src/Distribution/Types/DumpBuildInfo.hs +++ b/Cabal/src/Distribution/Types/DumpBuildInfo.hs @@ -1,26 +1,38 @@ {-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE InstanceSigs #-} +{-# LANGUAGE LambdaCase #-} module Distribution.Types.DumpBuildInfo ( DumpBuildInfo (..) + , toString ) where -import Distribution.Compat.Prelude -import Distribution.Parsec +import Distribution.Compat.Prelude (Binary, Generic, NFData, Structured) +import Distribution.Parsec (CabalParsing, Parsec (..)) +import Distribution.Simple.Flag (NoFlagValue (..)) data DumpBuildInfo = NoDumpBuildInfo | DumpBuildInfo - deriving (Read, Show, Eq, Ord, Enum, Bounded, Generic) + deriving stock (Read, Show, Eq, Ord, Enum, Bounded, Generic) instance Binary DumpBuildInfo instance NFData DumpBuildInfo instance Structured DumpBuildInfo -instance Parsec DumpBuildInfo where - parsec = parsecDumpBuildInfo +instance NoFlagValue DumpBuildInfo where + noFlagValue :: DumpBuildInfo + noFlagValue = NoDumpBuildInfo -parsecDumpBuildInfo :: CabalParsing m => m DumpBuildInfo -parsecDumpBuildInfo = boolToDumpBuildInfo <$> parsec +instance Parsec DumpBuildInfo where + parsec :: CabalParsing m => m DumpBuildInfo + parsec = boolToDumpBuildInfo <$> parsec boolToDumpBuildInfo :: Bool -> DumpBuildInfo boolToDumpBuildInfo bool = if bool then DumpBuildInfo else NoDumpBuildInfo + +toString :: DumpBuildInfo -> String +toString = \case + NoDumpBuildInfo -> "False" + DumpBuildInfo -> "True" diff --git a/Cabal/src/Distribution/Types/LocalBuildConfig.hs b/Cabal/src/Distribution/Types/LocalBuildConfig.hs index f79d470dcf3..9bd0246b6f6 100644 --- a/Cabal/src/Distribution/Types/LocalBuildConfig.hs +++ b/Cabal/src/Distribution/Types/LocalBuildConfig.hs @@ -20,25 +20,23 @@ module Distribution.Types.LocalBuildConfig import Distribution.Compat.Prelude import Prelude () -import Distribution.Types.ComponentLocalBuildInfo -import Distribution.Types.ComponentRequestedSpec -import Distribution.Types.GivenComponent -import Distribution.Types.PackageDescription -import Distribution.Types.UnitId +import Distribution.Types.ComponentLocalBuildInfo (ComponentLocalBuildInfo) +import Distribution.Types.ComponentRequestedSpec (ComponentRequestedSpec) +import Distribution.Types.GivenComponent (PromisedComponent) +import Distribution.Types.PackageDescription (PackageDescription) +import Distribution.Types.UnitId (UnitId) -import Distribution.PackageDescription -import Distribution.Simple.Compiler -import Distribution.Simple.Flag -import Distribution.Simple.InstallDirs hiding - ( absoluteInstallDirs - , prefixRelativeInstallDirs - , substPathTemplate - ) -import Distribution.Simple.PackageIndex +import Distribution.PackageDescription (ComponentName, FlagAssignment, PackageName) +import Distribution.Simple.Compiler (Compiler, PackageDBStack, ProfDetailLevel) +import Distribution.Simple.Flag (toFlag) +import Distribution.Simple.InstallDirs (InstallDirTemplates) +import Distribution.Simple.PackageIndex (InstalledPackageIndex) import Distribution.Simple.Program.Db (ProgramDb) -import Distribution.Simple.Setup.Config -import Distribution.System -import Distribution.Utils.Path +import Distribution.Simple.Setup.Config (ConfigFlags (..)) +import Distribution.System (Platform) +import Distribution.Types.DebugInfoLevel (DebugInfoLevel) +import Distribution.Types.OptimisationLevel (OptimisationLevel) +import Distribution.Utils.Path (FileOrDir (..), Pkg, SymbolicPath) import Distribution.Compat.Graph (Graph) diff --git a/Cabal/src/Distribution/Types/LocalBuildInfo.hs b/Cabal/src/Distribution/Types/LocalBuildInfo.hs index f525d397aba..15afb3cc076 100644 --- a/Cabal/src/Distribution/Types/LocalBuildInfo.hs +++ b/Cabal/src/Distribution/Types/LocalBuildInfo.hs @@ -131,6 +131,8 @@ import Distribution.System import qualified Data.Map as Map import Distribution.Compat.Graph (Graph) import qualified Distribution.Compat.Graph as Graph +import Distribution.Types.DebugInfoLevel (DebugInfoLevel) +import Distribution.Types.OptimisationLevel (OptimisationLevel) import qualified System.FilePath as FilePath (takeDirectory) diff --git a/Cabal/src/Distribution/Types/OptimisationLevel.hs b/Cabal/src/Distribution/Types/OptimisationLevel.hs new file mode 100644 index 00000000000..cca447a7bb9 --- /dev/null +++ b/Cabal/src/Distribution/Types/OptimisationLevel.hs @@ -0,0 +1,72 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE InstanceSigs #-} + +module Distribution.Types.OptimisationLevel + ( OptimisationLevel (..) + , toString + ) +where + +import Distribution.Compat.CharParsing (integral) +import Distribution.Compat.Prelude +import Distribution.Parsec (CabalParsing, Parsec (..)) +import Prelude () + +import Data.Bool (bool) +import Distribution.Simple.Flag (NoFlagValue (..)) + +-- ------------------------------------------------------------ + +-- * Optimisation levels + +-- ------------------------------------------------------------ + +-- | Some compilers support optimising. Some have different levels. +-- For compilers that do not the level is just capped to the level +-- they do support. +data OptimisationLevel + = NoOptimisation + | NormalOptimisation + | MaximumOptimisation + deriving stock (Bounded, Enum, Eq, Generic, Read, Show) + +instance Binary OptimisationLevel +instance NFData OptimisationLevel +instance Structured OptimisationLevel + +instance NoFlagValue OptimisationLevel where + noFlagValue :: OptimisationLevel + noFlagValue = NormalOptimisation + +instance Parsec OptimisationLevel where + parsec :: CabalParsing m => m OptimisationLevel + parsec = boolParser <|> intParser + where + boolParser = bool NoOptimisation NormalOptimisation <$> parsec + intParser = intToOptimisationLevel <$> integral + +instance IsString OptimisationLevel where + fromString :: String -> OptimisationLevel + fromString s = case reads s of + [(i, "")] -> intToOptimisationLevel i + _ -> error $ "Can't parse optimisation level " ++ s + +toString :: OptimisationLevel -> String +toString = show . fromEnum + +intToOptimisationLevel :: Int -> OptimisationLevel +intToOptimisationLevel i + | i >= minLevel && i <= maxLevel = toEnum i + | otherwise = + error $ + "Bad optimisation level: " + ++ show i + ++ ". Valid values are " + ++ show minLevel + ++ ".." + ++ show maxLevel + where + minLevel = fromEnum (minBound :: OptimisationLevel) + maxLevel = fromEnum (maxBound :: OptimisationLevel) diff --git a/cabal-install/parser-tests/Tests/ParserTests.hs b/cabal-install/parser-tests/Tests/ParserTests.hs index 34b65edcb5e..4bb34b824e1 100644 --- a/cabal-install/parser-tests/Tests/ParserTests.hs +++ b/cabal-install/parser-tests/Tests/ParserTests.hs @@ -31,7 +31,7 @@ import Distribution.Client.Types.WriteGhcEnvironmentFilesPolicy (WriteGhcEnviron import Distribution.Compat.Prelude import Distribution.Compiler (CompilerFlavor (..)) import Distribution.Parsec (simpleParsec) -import Distribution.Simple.Compiler (DebugInfoLevel (..), OptimisationLevel (..), PackageDBX (..), ProfDetailLevel (..)) +import Distribution.Simple.Compiler (PackageDBX (..), ProfDetailLevel (..)) import Distribution.Simple.Flag import Distribution.Simple.InstallDirs (InstallDirs (..), toPathTemplate) import Distribution.Simple.Setup (DumpBuildInfo (..), HaddockTarget (..), TestShowDetails (..)) @@ -50,7 +50,9 @@ import Distribution.Solver.Types.Settings ) import Distribution.System (OS (..), buildOS) import Distribution.Types.CondTree (CondTree (..)) +import Distribution.Types.DebugInfoLevel (DebugInfoLevel (..)) import Distribution.Types.Flag (mkFlagAssignment) +import Distribution.Types.OptimisationLevel (OptimisationLevel (..)) import Distribution.Types.PackageId (PackageIdentifier (..)) import Distribution.Types.PackageName import Distribution.Types.PackageVersionConstraint (PackageVersionConstraint (..)) diff --git a/cabal-install/src/Distribution/Client/Config.hs b/cabal-install/src/Distribution/Client/Config.hs index dd353e422a6..524f4b35c43 100644 --- a/cabal-install/src/Distribution/Client/Config.hs +++ b/cabal-install/src/Distribution/Client/Config.hs @@ -1,5 +1,4 @@ {-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE LambdaCase #-} {-# LANGUAGE PatternSynonyms #-} ----------------------------------------------------------------------------- @@ -138,7 +137,6 @@ import Distribution.Compiler import Distribution.Deprecated.ParseUtils ( FieldDescr (..) , PError (..) - , PWarning (..) , ParseResult (..) , liftField , lineNo @@ -166,10 +164,7 @@ import Distribution.Simple.Command , ShowOrParseArgs (..) , commandDefaultFlags ) -import Distribution.Simple.Compiler - ( DebugInfoLevel (..) - , OptimisationLevel (..) - ) +import Distribution.Simple.Flag (Flag, flagElim, flagToMaybe, fromFlagOrDefault, toFlag, pattern Flag, pattern NoFlag) import Distribution.Simple.InstallDirs ( InstallDirs (..) , PathTemplate @@ -183,7 +178,6 @@ import Distribution.Simple.Setup ( BenchmarkFlags (..) , CommonSetupFlags (..) , ConfigFlags (..) - , Flag , HaddockFlags (..) , TestFlags (..) , configureOptions @@ -191,16 +185,11 @@ import Distribution.Simple.Setup , defaultConfigFlags , defaultHaddockFlags , defaultTestFlags - , flagToMaybe - , fromFlagOrDefault , haddockOptions , installDirsOptions , optionDistPref , programDbOptions , programDbPaths' - , toFlag - , pattern Flag - , pattern NoFlag ) import Distribution.Simple.Utils ( cabalVersion @@ -212,6 +201,8 @@ import Distribution.Simple.Utils , writeFileAtomic ) import Distribution.Solver.Types.ConstraintSource +import qualified Distribution.Types.DebugInfoLevel as DebugInfoLevel +import qualified Distribution.Types.OptimisationLevel as OptimisationLevel import Distribution.Utils.Path (getSymbolicPath, unsafeMakeSymbolicPath) import Distribution.Verbosity ( normal @@ -1190,75 +1181,23 @@ configFieldDescriptions src = (Flag <$> parsec <|> pure NoFlag) configHcFlavor (\v flags -> flags{configHcFlavor = v}) - , -- TODO: The following is a temporary fix. The "optimization" - -- and "debug-info" fields are OptArg, and viewAsFieldDescr - -- fails on that. Instead of a hand-written hackaged parser - -- and printer, we should handle this case properly in the - -- library. - liftField - configOptimization - ( \v flags -> - flags{configOptimization = v} - ) - $ let name = "optimization" - in FieldDescr - name - ( \case - Flag NoOptimisation -> Disp.text "False" - Flag NormalOptimisation -> Disp.text "True" - Flag MaximumOptimisation -> Disp.text "2" - _ -> Disp.empty - ) - ( \line str _ -> case () of - _ - | str == "False" -> ParseOk [] (Flag NoOptimisation) - | str == "True" -> ParseOk [] (Flag NormalOptimisation) - | str == "0" -> ParseOk [] (Flag NoOptimisation) - | str == "1" -> ParseOk [] (Flag NormalOptimisation) - | str == "2" -> ParseOk [] (Flag MaximumOptimisation) - | lstr == "false" -> ParseOk [caseWarning] (Flag NoOptimisation) - | lstr == "true" -> - ParseOk - [caseWarning] - (Flag NormalOptimisation) - | otherwise -> ParseFailed (NoParse name line) - where - lstr = lowercase str - caseWarning = - PWarning $ - "The '" - ++ name - ++ "' field is case sensitive, use 'True' or 'False'." - ) + , liftField configOptimization (\v flags -> flags{configOptimization = v}) $ + let name = "optimization" + in FieldDescr + name + (flagElim Disp.empty (Disp.text . OptimisationLevel.toString)) + ( \line str _ -> case maybe NoFlag Flag (simpleParsec str) of + NoFlag -> ParseFailed (NoParse name line) + flag -> ParseOk [] flag + ) , liftField configDebugInfo (\v flags -> flags{configDebugInfo = v}) $ let name = "debug-info" in FieldDescr name - ( \case - Flag NoDebugInfo -> Disp.text "False" - Flag MinimalDebugInfo -> Disp.text "1" - Flag NormalDebugInfo -> Disp.text "True" - Flag MaximalDebugInfo -> Disp.text "3" - _ -> Disp.empty - ) - ( \line str _ -> case () of - _ - | str == "False" -> ParseOk [] (Flag NoDebugInfo) - | str == "True" -> ParseOk [] (Flag NormalDebugInfo) - | str == "0" -> ParseOk [] (Flag NoDebugInfo) - | str == "1" -> ParseOk [] (Flag MinimalDebugInfo) - | str == "2" -> ParseOk [] (Flag NormalDebugInfo) - | str == "3" -> ParseOk [] (Flag MaximalDebugInfo) - | lstr == "false" -> ParseOk [caseWarning] (Flag NoDebugInfo) - | lstr == "true" -> ParseOk [caseWarning] (Flag NormalDebugInfo) - | otherwise -> ParseFailed (NoParse name line) - where - lstr = lowercase str - caseWarning = - PWarning $ - "The '" - ++ name - ++ "' field is case sensitive, use 'True' or 'False'." + (flagElim Disp.empty (Disp.text . DebugInfoLevel.toString)) + ( \line str _ -> case maybe NoFlag Flag (simpleParsec str) of + NoFlag -> ParseFailed (NoParse name line) + flag -> ParseOk [] flag ) ] ++ toSavedConfig diff --git a/cabal-install/src/Distribution/Client/DistDirLayout.hs b/cabal-install/src/Distribution/Client/DistDirLayout.hs index 0a6e51b09e7..03ab7974b8c 100644 --- a/cabal-install/src/Distribution/Client/DistDirLayout.hs +++ b/cabal-install/src/Distribution/Client/DistDirLayout.hs @@ -43,7 +43,6 @@ import Distribution.Package ) import Distribution.Simple.Compiler ( Compiler (..) - , OptimisationLevel (..) , PackageDBCWD , PackageDBStackCWD , PackageDBX (..) @@ -52,6 +51,7 @@ import Distribution.Simple.Configure (interpretPackageDbFlags) import Distribution.System import Distribution.Types.ComponentName import Distribution.Types.LibraryName +import Distribution.Types.OptimisationLevel (OptimisationLevel (..)) -- | Information which can be used to construct the path to -- the build directory of a build. This is LESS fine-grained diff --git a/cabal-install/src/Distribution/Client/PackageHash.hs b/cabal-install/src/Distribution/Client/PackageHash.hs index 3a94c0e028b..5ad31354ab4 100644 --- a/cabal-install/src/Distribution/Client/PackageHash.hs +++ b/cabal-install/src/Distribution/Client/PackageHash.hs @@ -40,8 +40,6 @@ import Distribution.Package import Distribution.Simple.Compiler ( AbiTag (..) , CompilerId - , DebugInfoLevel (..) - , OptimisationLevel (..) , PackageDBCWD , ProfDetailLevel (..) , showProfDetailLevel @@ -56,10 +54,12 @@ import Distribution.System , Platform , buildOS ) +import Distribution.Types.DebugInfoLevel (DebugInfoLevel (..)) import Distribution.Types.Flag ( FlagAssignment , showFlagAssignment ) +import Distribution.Types.OptimisationLevel (OptimisationLevel (..)) import Distribution.Types.PkgconfigVersion (PkgconfigVersion) import qualified Data.ByteString.Lazy.Char8 as LBS diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs index 0dea2791303..b915449795e 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs @@ -88,8 +88,6 @@ import Distribution.PackageDescription.Configuration (simplifyWithSysParams) import Distribution.Simple.Compiler ( Compiler (..) , CompilerInfo (..) - , DebugInfoLevel (..) - , OptimisationLevel (..) , compilerInfo , interpretPackageDB ) @@ -110,8 +108,6 @@ import Distribution.Simple.Setup ( BenchmarkFlags (..) , CommonSetupFlags (..) , ConfigFlags (..) - , DumpBuildInfo (DumpBuildInfo, NoDumpBuildInfo) - , Flag , HaddockFlags (..) , TestFlags (..) , benchmarkOptions' @@ -119,7 +115,6 @@ import Distribution.Simple.Setup , defaultBenchmarkFlags , defaultHaddockFlags , defaultTestFlags - , fromFlagOrDefault , haddockOptions , installDirsOptions , programDbPaths' @@ -127,13 +122,9 @@ import Distribution.Simple.Setup , showPackageDb , splitArgs , testOptions' - , toFlag - , pattern Flag - , pattern NoFlag ) import Distribution.Simple.Utils ( debug - , lowercase , noticeDoc ) import Distribution.Types.CondTree @@ -144,6 +135,7 @@ import Distribution.Types.CondTree , mapTreeData , traverseCondTreeV ) +import qualified Distribution.Types.DumpBuildInfo as DumpBuildInfo import Distribution.Types.SourceRepo (RepoType) import Distribution.Utils.NubList ( fromNubList @@ -156,7 +148,6 @@ import Distribution.Client.ParseUtils import Distribution.Client.ReplFlags (multiReplOption) import Distribution.Deprecated.ParseUtils ( PError (..) - , PWarning (..) , ParseResult (..) , commaNewLineListFieldParsec , newLineListField @@ -200,6 +191,9 @@ import qualified Data.ByteString.Char8 as BS import Data.Functor ((<&>)) import qualified Data.Map as Map import qualified Data.Set as Set +import Distribution.Simple.Flag (Flag, flagElim, fromFlagOrDefault, toFlag, pattern Flag, pattern NoFlag) +import qualified Distribution.Types.DebugInfoLevel as DebugInfoLevel +import qualified Distribution.Types.OptimisationLevel as OptimisationLevel import Network.URI (URI (..), nullURIAuth) import System.Directory (makeAbsolute) import System.FilePath (splitFileName) @@ -1693,91 +1687,38 @@ legacyPackageConfigFieldDescrs = (\v flags -> flags{configHcFlavor = v}) overrideDumpBuildInfo = - liftField - configDumpBuildInfo - (\v flags -> flags{configDumpBuildInfo = v}) - $ let name = "build-info" - in FieldDescr - name - ( \case - Flag NoDumpBuildInfo -> Disp.text "False" - Flag DumpBuildInfo -> Disp.text "True" - _ -> Disp.empty - ) - ( \line str _ -> case () of - _ - | str == "False" -> ParseOk [] (Flag NoDumpBuildInfo) - | str == "True" -> ParseOk [] (Flag DumpBuildInfo) - | lstr == "false" -> ParseOk [caseWarning name] (Flag NoDumpBuildInfo) - | lstr == "true" -> ParseOk [caseWarning name] (Flag DumpBuildInfo) - | otherwise -> ParseFailed (NoParse name line) - where - lstr = lowercase str - ) - - -- TODO: [code cleanup] The following is a hack. The "optimization" and - -- "debug-info" fields are OptArg, and viewAsFieldDescr fails on that. - -- Instead of a hand-written parser and printer, we should handle this case - -- properly in the library. + liftField configDumpBuildInfo (\v flags -> flags{configDumpBuildInfo = v}) $ + let name = "build-info" + in FieldDescr + name + (flagElim Disp.empty (Disp.text . DumpBuildInfo.toString)) + ( \line str _ -> case maybe NoFlag Flag (simpleParsec str) of + NoFlag -> ParseFailed (NoParse name line) + flag -> ParseOk [] flag + ) overrideFieldOptimization = - liftField - configOptimization - (\v flags -> flags{configOptimization = v}) - $ let name = "optimization" - in FieldDescr - name - ( \case - Flag NoOptimisation -> Disp.text "False" - Flag NormalOptimisation -> Disp.text "True" - Flag MaximumOptimisation -> Disp.text "2" - _ -> Disp.empty - ) - ( \line str _ -> case () of - _ - | str == "False" -> ParseOk [] (Flag NoOptimisation) - | str == "True" -> ParseOk [] (Flag NormalOptimisation) - | str == "0" -> ParseOk [] (Flag NoOptimisation) - | str == "1" -> ParseOk [] (Flag NormalOptimisation) - | str == "2" -> ParseOk [] (Flag MaximumOptimisation) - | lstr == "false" -> ParseOk [caseWarning name] (Flag NoOptimisation) - | lstr == "true" -> ParseOk [caseWarning name] (Flag NormalOptimisation) - | otherwise -> ParseFailed (NoParse name line) - where - lstr = lowercase str - ) + liftField configOptimization (\v flags -> flags{configOptimization = v}) $ + let name = "optimization" + in FieldDescr + name + (flagElim Disp.empty (Disp.text . OptimisationLevel.toString)) + ( \line str _ -> case maybe NoFlag Flag (simpleParsec str) of + NoFlag -> ParseFailed (NoParse name line) + flag -> ParseOk [] flag + ) overrideFieldDebugInfo = liftField configDebugInfo (\v flags -> flags{configDebugInfo = v}) $ let name = "debug-info" in FieldDescr name - ( \case - Flag NoDebugInfo -> Disp.text "False" - Flag MinimalDebugInfo -> Disp.text "1" - Flag NormalDebugInfo -> Disp.text "True" - Flag MaximalDebugInfo -> Disp.text "3" - _ -> Disp.empty - ) - ( \line str _ -> case () of - _ - | str == "False" -> ParseOk [] (Flag NoDebugInfo) - | str == "True" -> ParseOk [] (Flag NormalDebugInfo) - | str == "0" -> ParseOk [] (Flag NoDebugInfo) - | str == "1" -> ParseOk [] (Flag MinimalDebugInfo) - | str == "2" -> ParseOk [] (Flag NormalDebugInfo) - | str == "3" -> ParseOk [] (Flag MaximalDebugInfo) - | lstr == "false" -> ParseOk [caseWarning name] (Flag NoDebugInfo) - | lstr == "true" -> ParseOk [caseWarning name] (Flag NormalDebugInfo) - | otherwise -> ParseFailed (NoParse name line) - where - lstr = lowercase str + (flagElim Disp.empty (Disp.text . DebugInfoLevel.toString)) + ( \line str _ -> case maybe NoFlag Flag (simpleParsec str) of + NoFlag -> ParseFailed (NoParse name line) + flag -> ParseOk [] flag ) - caseWarning name = - PWarning $ - "The '" ++ name ++ "' field is case sensitive, use 'True' or 'False'." - prefixTest name | "test-" `isPrefixOf` name = name | otherwise = "test-" ++ name diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Lens.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Lens.hs index 03164305a62..2151fcb360d 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Lens.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Lens.hs @@ -24,9 +24,7 @@ import Distribution.PackageDescription ( FlagAssignment ) import Distribution.Simple.Compiler - ( DebugInfoLevel (..) - , OptimisationLevel (..) - , PackageDBCWD + ( PackageDBCWD , ProfDetailLevel ) import Distribution.Simple.InstallDirs @@ -51,6 +49,8 @@ import Distribution.Solver.Types.Settings , ReorderGoals (..) , StrongFlags (..) ) +import Distribution.Types.DebugInfoLevel (DebugInfoLevel (..)) +import Distribution.Types.OptimisationLevel (OptimisationLevel (..)) import Distribution.Types.PackageVersionConstraint ( PackageVersionConstraint ) diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs index 751875be403..eb85995e12a 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs @@ -69,8 +69,6 @@ import Distribution.PackageDescription import Distribution.Simple.Compiler ( Compiler , CompilerFlavor - , DebugInfoLevel (..) - , OptimisationLevel (..) , PackageDBCWD , ProfDetailLevel ) @@ -99,6 +97,8 @@ import Distribution.Version import qualified Data.Map as Map import Distribution.Solver.Types.ProjectConfigPath (ProjectConfigPath) +import Distribution.Types.DebugInfoLevel (DebugInfoLevel) +import Distribution.Types.OptimisationLevel (OptimisationLevel) import Distribution.Types.ParStrat import Distribution.Verbosity (VerbosityFlags) diff --git a/cabal-install/src/Distribution/Client/ProjectOrchestration.hs b/cabal-install/src/Distribution/Client/ProjectOrchestration.hs index 606516065a3..b1d0a717f1d 100644 --- a/cabal-install/src/Distribution/Client/ProjectOrchestration.hs +++ b/cabal-install/src/Distribution/Client/ProjectOrchestration.hs @@ -184,17 +184,13 @@ import Distribution.Client.Errors import Distribution.Package import Distribution.Simple.Command (commandShowOptions) import Distribution.Simple.Compiler - ( OptimisationLevel (..) - , compilerCompatVersion + ( compilerCompatVersion , compilerId , compilerInfo , showCompilerId ) import Distribution.Simple.Configure (computeEffectiveProfiling) -import Distribution.Simple.Flag - ( flagToMaybe - , fromFlagOrDefault - ) +import Distribution.Simple.Flag (flagToMaybe, fromFlagOrDefault, fromNoFlag) import Distribution.Simple.LocalBuildInfo ( ComponentName (..) , pkgComponents @@ -218,6 +214,7 @@ import Distribution.Types.Flag , diffFlagAssignment , showFlagAssignment ) +import qualified Distribution.Types.OptimisationLevel as OptimisationLevel import Distribution.Utils.NubList ( fromNubList ) @@ -1258,13 +1255,7 @@ printPlan "Build profile: " ++ unwords [ "-w " ++ (showCompilerId . pkgConfigCompiler) elaboratedShared - , "-O" - ++ ( case globalOptimization <> localOptimization of -- if local is not set, read global - Setup.Flag NoOptimisation -> "0" - Setup.Flag NormalOptimisation -> "1" - Setup.Flag MaximumOptimisation -> "2" - Setup.NoFlag -> "1" - ) + , "-O" ++ (OptimisationLevel.toString . fromNoFlag) (globalOptimization <> localOptimization) ] ++ "\n" diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index f2ace7ff3b5..259b5ae4e37 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -234,6 +234,8 @@ import qualified Data.Map as Map import qualified Data.Set as Set import Distribution.Client.Errors import Distribution.Solver.Types.ProjectConfigPath +import Distribution.Types.DebugInfoLevel (DebugInfoLevel (..)) +import Distribution.Types.OptimisationLevel (OptimisationLevel (..)) import System.Directory (getCurrentDirectory) import System.FilePath import qualified Text.PrettyPrint as Disp diff --git a/cabal-install/src/Distribution/Client/ScriptUtils.hs b/cabal-install/src/Distribution/Client/ScriptUtils.hs index 6f6e03eccf5..8500179ca49 100644 --- a/cabal-install/src/Distribution/Client/ScriptUtils.hs +++ b/cabal-install/src/Distribution/Client/ScriptUtils.hs @@ -119,11 +119,10 @@ import Distribution.Parsec import qualified Distribution.SPDX.License as SPDX import Distribution.Simple.Compiler ( Compiler (..) - , OptimisationLevel (..) ) import Distribution.Simple.Flag ( flagToMaybe - , fromFlagOrDefault + , fromNoFlag ) import Distribution.Simple.PackageDescription ( parseString @@ -434,7 +433,7 @@ scriptDistDirParams scriptPath ctx compiler platform = , distParamComponentName = Just $ CExeName cn , distParamCompilerId = compilerId compiler , distParamPlatform = platform - , distParamOptimization = fromFlagOrDefault NormalOptimisation optimization + , distParamOptimization = fromNoFlag optimization } where cn = scriptComponentName scriptPath diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Configure.hs b/cabal-install/tests/UnitTests/Distribution/Client/Configure.hs index 21a6bcabb46..07694e82214 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Configure.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Configure.hs @@ -9,9 +9,9 @@ import Distribution.Client.NixStyleOptions import Distribution.Client.ProjectConfig.Types import Distribution.Client.ProjectFlags import Distribution.Client.Setup -import Distribution.Simple import Distribution.Simple.Flag import Distribution.Simple.Utils (removeFileForcibly) +import Distribution.Types.OptimisationLevel (OptimisationLevel (..)) import Distribution.Verbosity import System.Directory import System.FilePath diff --git a/changelog.d/11828.md b/changelog.d/11828.md new file mode 100644 index 00000000000..be9ddc26e5f --- /dev/null +++ b/changelog.d/11828.md @@ -0,0 +1,12 @@ +--- +synopsis: "Allow case insensitive bools and move to numeric render" +packages: [Cabal-syntax, Cabal, cabal-install] +prs: 11828 +--- +The `.cabal` file parser now accepts boolean values in a case‑insensitive manner (`true`, `True`, `TRUE`, `false`, etc.) without emitting a warning. +Previously only `True` and `False` were treated as “standard”, and other capitalisations triggered a parse warning. That warning was introduced in 2008 as a backwards‑compatibility shim to prevent Hackage uploads that would break very old Cabal versions. Since all supported Cabal releases can now handle case‑insensitive booleans, the warning has been removed as unnecessary. + +Additionally, the rendering of certain boolean‑like flags has been changed to use numeric levels: +- For the `-O` (optimisation) flag, `True` or an unspecified value now renders as `-O1`, while `False` renders as `-O0`. +- For the `-g` (debug info) flag, `True` or an unspecified value now renders `-g2`, while `False` renders as `-g0`. +This makes the displayed compiler flags more consistent with their internal semantics (e.g. optimisation level 1 is the default).