cabal-gild 1.3.1.2 → 1.3.1.3
raw patch · 11 files changed
+364/−42 lines, 11 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ CabalGild.Unstable.Action.FormatFields: isConditional :: CabalSpecVersion -> Name p -> Bool
+ CabalGild.Unstable.Extra.CharParsing: parens :: CabalParsing m => m a -> m a
+ CabalGild.Unstable.Extra.CharParsing: token :: CabalParsing m => String -> m ()
+ CabalGild.Unstable.Extra.SectionArg: value :: SectionArg a -> ByteString
+ CabalGild.Unstable.Type.Condition: And :: Condition a -> Condition a -> Condition a
+ CabalGild.Unstable.Type.Condition: Lit :: Bool -> Condition a
+ CabalGild.Unstable.Type.Condition: Not :: Condition a -> Condition a
+ CabalGild.Unstable.Type.Condition: Or :: Condition a -> Condition a -> Condition a
+ CabalGild.Unstable.Type.Condition: Par :: Condition a -> Condition a
+ CabalGild.Unstable.Type.Condition: Var :: a -> Condition a
+ CabalGild.Unstable.Type.Condition: data Condition a
+ CabalGild.Unstable.Type.Condition: instance GHC.Classes.Eq a => GHC.Classes.Eq (CabalGild.Unstable.Type.Condition.Condition a)
+ CabalGild.Unstable.Type.Condition: instance GHC.Show.Show a => GHC.Show.Show (CabalGild.Unstable.Type.Condition.Condition a)
+ CabalGild.Unstable.Type.Condition: parseCondition :: ParsecParser a -> ParsecParser (Condition a)
+ CabalGild.Unstable.Type.Condition: parseLit :: CabalParsing m => m Bool
+ CabalGild.Unstable.Type.Condition: prettyCondition :: (a -> Doc) -> Condition a -> Doc
+ CabalGild.Unstable.Type.Variable: Arch :: Arch -> Variable
+ CabalGild.Unstable.Type.Variable: Flag :: FlagName -> Variable
+ CabalGild.Unstable.Type.Variable: Impl :: CompilerFlavor -> VersionRange -> Variable
+ CabalGild.Unstable.Type.Variable: Os :: OS -> Variable
+ CabalGild.Unstable.Type.Variable: data Variable
+ CabalGild.Unstable.Type.Variable: instance GHC.Classes.Eq CabalGild.Unstable.Type.Variable.Variable
+ CabalGild.Unstable.Type.Variable: instance GHC.Show.Show CabalGild.Unstable.Type.Variable.Variable
+ CabalGild.Unstable.Type.Variable: parseArch :: CabalParsing m => m Arch
+ CabalGild.Unstable.Type.Variable: parseFlag :: CabalParsing m => m FlagName
+ CabalGild.Unstable.Type.Variable: parseIdent :: CabalParsing m => m String
+ CabalGild.Unstable.Type.Variable: parseImpl :: CabalParsing m => m (CompilerFlavor, VersionRange)
+ CabalGild.Unstable.Type.Variable: parseOs :: CabalParsing m => m OS
+ CabalGild.Unstable.Type.Variable: parseVariable :: CabalParsing m => m Variable
+ CabalGild.Unstable.Type.Variable: prettyVariable :: Variable -> Doc
- CabalGild.Unstable.Action.Render: field :: Int -> Field (Position, [Comment p]) -> Block
+ CabalGild.Unstable.Action.Render: field :: CabalSpecVersion -> Int -> Field (Position, [Comment p]) -> Block
- CabalGild.Unstable.Action.Render: fields :: Int -> [Field (Position, [Comment p])] -> Block
+ CabalGild.Unstable.Action.Render: fields :: CabalSpecVersion -> Int -> [Field (Position, [Comment p])] -> Block
- CabalGild.Unstable.Action.Render: run :: Applicative m => ([Field (Position, [Comment p])], [Comment p]) -> m ByteString
+ CabalGild.Unstable.Action.Render: run :: Applicative m => CabalSpecVersion -> ([Field (Position, [Comment p])], [Comment p]) -> m ByteString
- CabalGild.Unstable.Action.Render: toByteString :: [Field (Position, [Comment p])] -> [Comment p] -> ByteString
+ CabalGild.Unstable.Action.Render: toByteString :: CabalSpecVersion -> [Field (Position, [Comment p])] -> [Comment p] -> ByteString
- CabalGild.Unstable.Extra.Name: isElif :: Name a -> Bool
+ CabalGild.Unstable.Extra.Name: isElif :: CabalSpecVersion -> Name a -> Bool
Files
- README.md +2/−2
- cabal-gild.cabal +5/−2
- source/library/CabalGild/Unstable/Action/FormatFields.hs +32/−1
- source/library/CabalGild/Unstable/Action/Render.hs +20/−29
- source/library/CabalGild/Unstable/Extra/CharParsing.hs +10/−0
- source/library/CabalGild/Unstable/Extra/Name.hs +5/−2
- source/library/CabalGild/Unstable/Extra/SectionArg.hs +8/−0
- source/library/CabalGild/Unstable/Main.hs +1/−1
- source/library/CabalGild/Unstable/Type/Condition.hs +68/−0
- source/library/CabalGild/Unstable/Type/Variable.hs +72/−0
- source/test-suite/Main.hs +141/−5
README.md view
@@ -1,6 +1,6 @@ # Gild -[](https://github.com/tfausak/cabal-gild/actions/workflows/ci.yaml)+[](https://github.com/tfausak/cabal-gild/actions/workflows/ci.yml) [](https://hackage.haskell.org/package/cabal-gild) Gild is an opinionated command line utility that formats Haskell package@@ -100,7 +100,7 @@ In general you should prefer downloading the appropriate binary for you platform. However it is possible to build Gild from source. It supports Linux,-macOS, and Windows along with the four most recent versions of GHC. Any other+macOS, and Windows along with the three most recent versions of GHC. Any other configurations are unsupported. With Cabal:
cabal-gild.cabal view
@@ -11,7 +11,7 @@ maintainer: Taylor Fausak name: cabal-gild synopsis: Formats package descriptions.-version: 1.3.1.2+version: 1.3.1.3 source-repository head type: git@@ -38,7 +38,7 @@ -Wno-safe -Wno-unsafe - if impl(ghc >= 9.8)+ if impl(ghc >=9.8) ghc-options: -Wno-missing-role-annotations if flag(pedantic)@@ -91,6 +91,7 @@ CabalGild.Unstable.Exception.UnexpectedArgument CabalGild.Unstable.Exception.UnknownOption CabalGild.Unstable.Extra.ByteString+ CabalGild.Unstable.Extra.CharParsing CabalGild.Unstable.Extra.Either CabalGild.Unstable.Extra.Field CabalGild.Unstable.Extra.FieldLine@@ -103,6 +104,7 @@ CabalGild.Unstable.Type.Block CabalGild.Unstable.Type.Chunk CabalGild.Unstable.Type.Comment+ CabalGild.Unstable.Type.Condition CabalGild.Unstable.Type.Config CabalGild.Unstable.Type.Context CabalGild.Unstable.Type.Dependency@@ -127,6 +129,7 @@ CabalGild.Unstable.Type.Set CabalGild.Unstable.Type.SomeParsecParser CabalGild.Unstable.Type.TestedWith+ CabalGild.Unstable.Type.Variable CabalGild.Unstable.Type.VersionRange hs-source-dirs: source/library
source/library/CabalGild/Unstable/Action/FormatFields.hs view
@@ -4,7 +4,9 @@ import qualified CabalGild.Unstable.Extra.FieldLine as FieldLine import qualified CabalGild.Unstable.Extra.Name as Name+import qualified CabalGild.Unstable.Extra.SectionArg as SectionArg import qualified CabalGild.Unstable.Extra.String as String+import qualified CabalGild.Unstable.Type.Condition as Condition import qualified CabalGild.Unstable.Type.Dependency as Dependency import qualified CabalGild.Unstable.Type.ExeDependency as ExeDependency import qualified CabalGild.Unstable.Type.Extension as Extension@@ -16,6 +18,8 @@ import qualified CabalGild.Unstable.Type.PkgconfigDependency as PkgconfigDependency import qualified CabalGild.Unstable.Type.SomeParsecParser as SPP import qualified CabalGild.Unstable.Type.TestedWith as TestedWith+import qualified CabalGild.Unstable.Type.Variable as Variable+import qualified Data.ByteString as ByteString import qualified Data.Functor.Identity as Identity import qualified Data.Map as Map import qualified Data.Maybe as Maybe@@ -24,6 +28,7 @@ import qualified Distribution.Fields as Fields import qualified Distribution.ModuleName as ModuleName import qualified Distribution.Parsec as Parsec+import qualified Distribution.Parsec.FieldLineStream as FieldLineStream import qualified Text.PrettyPrint as PrettyPrint -- | A wrapper around 'field' to allow this to be composed with other actions.@@ -49,7 +54,33 @@ maybe (fst $ Name.annotation n) (fst . FieldLine.annotation) $ Maybe.listToMaybe fls in Fields.Field n $ fieldLines csv position fls spp- Fields.Section n sas fs -> Fields.Section n sas $ fmap (field csv) fs+ Fields.Section n sas fs ->+ let result =+ Parsec.runParsecParser' csv (Condition.parseCondition Variable.parseVariable) "<conditional>"+ . FieldLineStream.fieldLineStreamFromBS+ . ByteString.intercalate (ByteString.singleton 0x20)+ $ fmap SectionArg.value sas+ position =+ fst+ . maybe (Name.annotation n) SectionArg.annotation+ $ Maybe.listToMaybe sas+ newSas =+ if isConditional csv n+ then case result of+ Left _ -> sas+ Right c ->+ pure+ . Fields.SecArgName (position, [])+ . String.toUtf8+ . PrettyPrint.renderStyle style+ $ Condition.prettyCondition Variable.prettyVariable c+ else sas+ in Fields.Section n newSas $ fmap (field csv) fs++isConditional :: CabalSpecVersion.CabalSpecVersion -> Fields.Name p -> Bool+isConditional csv n =+ Name.isIf n+ || Name.isElif csv n -- | Attempts to parse the given field lines using the given parser. If parsing -- fails, the field lines will be returned as is. Comments within the field
source/library/CabalGild/Unstable/Action/Render.hs view
@@ -9,6 +9,7 @@ import qualified CabalGild.Unstable.Type.Line as Line import qualified Data.ByteString as ByteString import qualified Data.Function as Function+import qualified Distribution.CabalSpecVersion as CabalSpecVersion import qualified Distribution.Compat.Lens as Lens import qualified Distribution.Fields as Fields import qualified Distribution.Parsec.Position as Position@@ -17,32 +18,34 @@ -- actions. run :: (Applicative m) =>+ CabalSpecVersion.CabalSpecVersion -> ([Fields.Field (Position.Position, [Comment.Comment p])], [Comment.Comment p]) -> m ByteString.ByteString-run = pure . uncurry toByteString+run csv = pure . uncurry (toByteString csv) -- | Renders the given fields and comments to a byte string. toByteString ::+ CabalSpecVersion.CabalSpecVersion -> [Fields.Field (Position.Position, [Comment.Comment p])] -> [Comment.Comment p] -> ByteString.ByteString-toByteString fs cs =+toByteString csv fs cs = let i = 0 :: Int in Block.toByteString . Lens.set Block.lineBeforeLens False . Lens.set Block.lineAfterLens True- $ fields i fs <> comments i cs+ $ fields csv i fs <> comments i cs -- | Renders the given fields to a block at the given indentation level.-fields :: Int -> [Fields.Field (Position.Position, [Comment.Comment p])] -> Block.Block-fields = foldMap . field+fields :: CabalSpecVersion.CabalSpecVersion -> Int -> [Fields.Field (Position.Position, [Comment.Comment p])] -> Block.Block+fields csv = foldMap . field csv -- | Renders the given field to a block at the given indentation level. -- -- If a field only has one line and no comments, then it can be rendered all on -- one line.-field :: Int -> Fields.Field (Position.Position, [Comment.Comment p]) -> Block.Block-field i f = case f of+field :: CabalSpecVersion.CabalSpecVersion -> Int -> Fields.Field (Position.Position, [Comment.Comment p]) -> Block.Block+field csv i f = case f of Fields.Field n fls -> case fls of [fl] | null . snd $ FieldLine.annotation fl,@@ -62,8 +65,8 @@ } <> fieldLines (i + 1) fls Fields.Section n sas fs ->- Lens.set Block.lineBeforeLens (not $ Name.isElif n || Name.isElse n)- . Lens.set Block.lineAfterLens (not $ Name.isIf n || Name.isElif n)+ Lens.set Block.lineBeforeLens (not $ Name.isElif csv n || Name.isElse n)+ . Lens.set Block.lineAfterLens (not $ Name.isIf n || Name.isElif csv n) $ comments i (snd $ Name.annotation n) <> comments i (concatMap (snd . SectionArg.annotation) sas) <> Block.fromLine@@ -71,7 +74,7 @@ { Line.indent = i, Line.chunk = Lens.set Chunk.spaceAfterLens True (name n) <> sectionArgs sas }- <> Lens.set Block.lineBeforeLens False (fields (i + 1) fs)+ <> Lens.set Block.lineBeforeLens False (fields csv (i + 1) fs) -- | Returns true if the two positions are on the same row. sameRow :: (Position.Position, cs) -> (Position.Position, cs) -> Bool@@ -108,25 +111,13 @@ -- | Renders the given section argument to a chunk. sectionArg :: Fields.SectionArg a -> Chunk.Chunk-sectionArg sa = case sa of- Fields.SecArgName _ bs ->- Lens.set Chunk.spaceBeforeLens True- . Lens.set Chunk.spaceAfterLens True- $ Chunk.fromByteString bs- Fields.SecArgStr _ bs ->- Lens.set Chunk.spaceBeforeLens True- . Lens.set Chunk.spaceAfterLens True- . Chunk.fromByteString- . flip ByteString.snoc 0x22- $ ByteString.cons 0x22 bs- Fields.SecArgOther _ bs ->- let b =- bs /= ByteString.singleton 0x21 -- !- && bs /= ByteString.singleton 0x28 -- (- && bs /= ByteString.singleton 0x29 -- )- in Lens.set Chunk.spaceBeforeLens b- . Lens.set Chunk.spaceAfterLens b- $ Chunk.fromByteString bs+sectionArg sa = Lens.set Chunk.spaceBeforeLens True+ . Lens.set Chunk.spaceAfterLens True+ . Chunk.fromByteString+ $ case sa of+ Fields.SecArgName _ bs -> bs+ Fields.SecArgStr _ bs -> flip ByteString.snoc 0x22 $ ByteString.cons 0x22 bs+ Fields.SecArgOther _ bs -> bs -- | Renders the given comments to a block at the given indentation level. comments :: Int -> [Comment.Comment a] -> Block.Block
+ source/library/CabalGild/Unstable/Extra/CharParsing.hs view
@@ -0,0 +1,10 @@+module CabalGild.Unstable.Extra.CharParsing where++import qualified Distribution.Compat.CharParsing as Parse+import qualified Distribution.Parsec as Parsec++parens :: (Parsec.CabalParsing m) => m a -> m a+parens = Parse.between (token "(") (token ")")++token :: (Parsec.CabalParsing m) => String -> m ()+token s = Parse.string s *> Parse.spaces
source/library/CabalGild/Unstable/Extra/Name.hs view
@@ -1,6 +1,7 @@ module CabalGild.Unstable.Extra.Name where import qualified CabalGild.Unstable.Extra.String as String+import qualified Distribution.CabalSpecVersion as CabalSpecVersion import qualified Distribution.Compat.Lens as Lens import qualified Distribution.Fields as Fields @@ -21,8 +22,10 @@ isIf = (== String.toUtf8 "if") . value -- | Returns true when the name is @"elif"@, false otherwise.-isElif :: Fields.Name a -> Bool-isElif = (== String.toUtf8 "elif") . value+isElif :: CabalSpecVersion.CabalSpecVersion -> Fields.Name a -> Bool+isElif csv n =+ csv >= CabalSpecVersion.CabalSpecV2_2+ && value n == String.toUtf8 "elif" -- | Returns true when the name is @"else"@, false otherwise. isElse :: Fields.Name a -> Bool
source/library/CabalGild/Unstable/Extra/SectionArg.hs view
@@ -1,5 +1,6 @@ module CabalGild.Unstable.Extra.SectionArg where +import qualified Data.ByteString as ByteString import qualified Distribution.Fields as Fields -- | Extracts the annotation from the given 'Fields.SectionArg'.@@ -8,3 +9,10 @@ Fields.SecArgName x _ -> x Fields.SecArgStr x _ -> x Fields.SecArgOther x _ -> x++-- | Extracts the value from the given 'Fields.SectionArg'.+value :: Fields.SectionArg a -> ByteString.ByteString+value sa = case sa of+ Fields.SecArgName _ x -> x+ Fields.SecArgStr _ x -> x+ Fields.SecArgOther _ x -> x
source/library/CabalGild/Unstable/Main.hs view
@@ -97,7 +97,7 @@ Monad.>=> ReflowText.run csv Monad.>=> EvaluatePragmas.run filePath Monad.>=> FormatFields.run csv- Monad.>=> Render.run+ Monad.>=> Render.run csv ) (fields, comments)
+ source/library/CabalGild/Unstable/Type/Condition.hs view
@@ -0,0 +1,68 @@+{-# LANGUAGE FlexibleContexts #-}++module CabalGild.Unstable.Type.Condition where++import qualified CabalGild.Unstable.Extra.CharParsing as Parse+import qualified Distribution.Compat.CharParsing as Parse+import qualified Distribution.Parsec as Parsec+import qualified Text.Parsec as P+import qualified Text.Parsec.Expr as PE+import qualified Text.PrettyPrint as PrettyPrint++data Condition a+ = Par (Condition a)+ | Not (Condition a)+ | And (Condition a) (Condition a)+ | Or (Condition a) (Condition a)+ | Lit Bool+ | Var a+ deriving (Eq, Show)++parseCondition :: Parsec.ParsecParser a -> Parsec.ParsecParser (Condition a)+parseCondition parseVariable = Parsec.PP $ \csv -> do+ let operators :: (P.Stream s m Char) => PE.OperatorTable s u m (Condition b)+ operators =+ [ [PE.Prefix (Not <$ Parse.char '!' <* Parse.spaces)],+ [PE.Infix (And <$ Parse.string "&&" <* Parse.spaces) PE.AssocRight],+ [PE.Infix (Or <$ Parse.string "||" <* Parse.spaces) PE.AssocRight]+ ]+ Parse.spaces+ PE.buildExpressionParser operators $+ Parsec.unPP+ ( Parse.choice+ [ Par <$> Parse.parens (parseCondition parseVariable),+ Not <$> (Parse.token "!" *> parseCondition parseVariable),+ Lit <$> Parse.try parseLit,+ Var <$> parseVariable+ ]+ )+ csv++parseLit :: (Parsec.CabalParsing m) => m Bool+parseLit =+ Parse.choice+ [ True <$ Parse.token "True",+ True <$ Parse.token "true",+ False <$ Parse.token "False",+ False <$ Parse.token "false"+ ]++prettyCondition :: (a -> PrettyPrint.Doc) -> Condition a -> PrettyPrint.Doc+prettyCondition f x =+ case x of+ Par y -> PrettyPrint.parens (prettyCondition f y)+ Not y -> PrettyPrint.char '!' <> prettyCondition f y+ And y z ->+ PrettyPrint.hsep+ [ prettyCondition f y,+ PrettyPrint.text "&&",+ prettyCondition f z+ ]+ Or y z ->+ PrettyPrint.hsep+ [ prettyCondition f y,+ PrettyPrint.text "||",+ prettyCondition f z+ ]+ Lit y -> PrettyPrint.text $ if y then "true" else "false"+ Var y -> f y
+ source/library/CabalGild/Unstable/Type/Variable.hs view
@@ -0,0 +1,72 @@+module CabalGild.Unstable.Type.Variable where++import qualified CabalGild.Unstable.Extra.CharParsing as Parse+import qualified Data.Char as Char+import qualified Distribution.Compat.CharParsing as Parse+import qualified Distribution.Compiler as Compiler+import qualified Distribution.Parsec as Parsec+import qualified Distribution.Pretty as Pretty+import qualified Distribution.System as System+import qualified Distribution.Types.Flag as Flag+import qualified Distribution.Types.VersionRange as VersionRange+import qualified Text.PrettyPrint as PrettyPrint++data Variable+ = Arch System.Arch+ | Flag Flag.FlagName+ | Impl Compiler.CompilerFlavor VersionRange.VersionRange+ | Os System.OS+ deriving (Eq, Show)++parseVariable :: (Parsec.CabalParsing m) => m Variable+parseVariable =+ Parse.choice+ [ Arch <$> parseArch,+ Flag <$> parseFlag,+ uncurry Impl <$> parseImpl,+ Os <$> parseOs+ ]++parseArch :: (Parsec.CabalParsing m) => m System.Arch+parseArch =+ fmap (System.classifyArch System.Permissive) $+ Parse.token "arch" *> Parse.parens parseIdent++parseFlag :: (Parsec.CabalParsing m) => m Flag.FlagName+parseFlag = Parse.token "flag" *> Parse.parens (Parsec.parsec <* Parse.spaces)++parseImpl :: (Parsec.CabalParsing m) => m (Compiler.CompilerFlavor, VersionRange.VersionRange)+parseImpl = do+ Parse.token "impl"+ Parse.parens $+ (,)+ <$> Parsec.parsec+ <* Parse.spaces+ <*> Parse.option VersionRange.anyVersion Parsec.parsec+ <* Parse.spaces++parseOs :: (Parsec.CabalParsing m) => m System.OS+parseOs =+ fmap (System.classifyOS System.Permissive) $+ Parse.token "os" *> Parse.parens parseIdent++parseIdent :: (Parsec.CabalParsing m) => m String+parseIdent =+ let isIdent c = Char.isAlphaNum c || c == '_' || c == '-'+ in Parse.munch1 isIdent <* Parse.spaces++prettyVariable :: Variable -> PrettyPrint.Doc+prettyVariable x =+ case x of+ Arch y ->+ PrettyPrint.text "arch"+ <> PrettyPrint.parens (Pretty.pretty y)+ Flag y ->+ PrettyPrint.text "flag"+ <> PrettyPrint.parens (Pretty.pretty y)+ Impl y z ->+ PrettyPrint.text "impl"+ <> PrettyPrint.parens (Pretty.pretty y PrettyPrint.<+> Pretty.pretty z)+ Os y ->+ PrettyPrint.text "os"+ <> PrettyPrint.parens (Pretty.pretty y)
source/test-suite/Main.hs view
@@ -521,8 +521,139 @@ Hspec.it "properly formats conditionals" $ do expectGilded "if ! impl ( ghc >= 9.8 )"- "if !impl(ghc >= 9.8)\n"+ "if !impl(ghc >=9.8)\n" + Hspec.describe "conditionals" $ do+ Hspec.it "formats variable" $ do+ expectGilded+ "if flag ( x )"+ "if flag(x)\n"++ Hspec.it "formats false" $ do+ expectGilded+ "if false"+ "if false\n"++ Hspec.it "formats upper false" $ do+ expectGilded+ "if False"+ "if false\n"++ Hspec.it "formats true" $ do+ expectGilded+ "if true"+ "if true\n"++ Hspec.it "formats upper true" $ do+ expectGilded+ "if True"+ "if true\n"++ Hspec.it "formats not" $ do+ expectGilded+ "if ! flag ( x )"+ "if !flag(x)\n"++ Hspec.it "formats or" $ do+ expectGilded+ "if flag ( x )||flag ( y )"+ "if flag(x) || flag(y)\n"++ Hspec.it "formats and" $ do+ expectGilded+ "if flag ( x )&&flag ( y )"+ "if flag(x) && flag(y)\n"++ Hspec.it "formats arch" $ do+ expectGilded+ "if arch ( aarch64 )"+ "if arch(aarch64)\n"++ Hspec.it "formats upper arch" $ do+ expectGilded+ "if arch ( AARCH64 )"+ "if arch(aarch64)\n"++ Hspec.it "formats arch alias" $ do+ expectGilded+ "if arch ( arm64 )"+ "if arch(aarch64)\n"++ Hspec.it "formats flag" $ do+ expectGilded+ "if flag ( x )"+ "if flag(x)\n"++ Hspec.it "formats upper flag" $ do+ expectGilded+ "if flag ( X )"+ "if flag(x)\n"++ Hspec.it "formats impl" $ do+ expectGilded+ "if impl ( ghc > 0 )"+ "if impl(ghc >0)\n"++ Hspec.it "formats upper impl" $ do+ expectGilded+ "if impl ( GHC > 0 )"+ "if impl(ghc >0)\n"++ Hspec.it "formats impl without version range" $ do+ expectGilded+ "if impl ( ghc )"+ "if impl(ghc >=0)\n"++ Hspec.it "formats os" $ do+ expectGilded+ "if os ( osx )"+ "if os(osx)\n"++ Hspec.it "formats upper os" $ do+ expectGilded+ "if os ( OSX )"+ "if os(osx)\n"++ Hspec.it "formats os alias" $ do+ expectGilded+ "if os ( darwin )"+ "if os(osx)\n"++ Hspec.it "does not format old elif" $ do+ expectGilded+ "elif flag ( x )"+ "elif flag ( x )\n"++ Hspec.it "formats new elif" $ do+ expectGilded+ "cabal-version: 2.2\nelif flag ( x )"+ "cabal-version: 2.2\nelif flag(x)\n"++ Hspec.it "keeps explicit parentheses" $ do+ expectGilded+ "if ( true )"+ "if (true)\n"++ Hspec.it "formats multiple nots" $ do+ expectGilded+ "if ! ! flag ( a )"+ "if !!flag(a)\n"++ Hspec.it "formats multiple ands" $ do+ expectGilded+ "if flag ( a ) && flag ( b ) && flag ( c )"+ "if flag(a) && flag(b) && flag(c)\n"++ Hspec.it "formats multiple ors" $ do+ expectGilded+ "if flag ( a ) || flag ( b ) || flag ( c )"+ "if flag(a) || flag(b) || flag(c)\n"++ Hspec.it "formats mixed operators" $ do+ expectGilded+ "if ! flag ( a ) && flag ( b ) || flag ( c )"+ "if !flag(a) && flag(b) || flag(c)\n"+ Hspec.describe "license-files" $ do -- These tests apply to other "list" fields as well. The license-files -- field is just a representative example.@@ -1203,15 +1334,20 @@ "if p\n a\nelse\n b" "if p\n a\nelse\n b\n" - Hspec.it "groups 'elif' with 'if'" $ do+ Hspec.it "does not group old 'elif' with 'if'" $ do expectGilded "if p\n a\nelif q\n b"- "if p\n a\nelif q\n b\n"+ "if p\n a\n\nelif q\n b\n" + Hspec.it "groups new 'elif' with 'if'" $ do+ expectGilded+ "cabal-version: 2.2\nif p\n a\nelif q\n b"+ "cabal-version: 2.2\n\nif p\n a\nelif q\n b\n"+ Hspec.it "groups 'else' with 'elif'" $ do expectGilded- "if p\n a\nelif q\n b\nelse\n c"- "if p\n a\nelif q\n b\nelse\n c\n"+ "cabal-version: 2.2\nif p\n a\nelif q\n b\nelse\n c"+ "cabal-version: 2.2\n\nif p\n a\nelif q\n b\nelse\n c\n" Hspec.it "does not group 'else' with anything else" $ do expectGilded