packages feed

cabal-gild 1.8.2.1 → 1.8.3.0

raw patch · 9 files changed

+303/−109 lines, 9 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- CabalGild.Unstable.Exception.UnexpectedArgument: UnexpectedArgument :: String -> UnexpectedArgument
- CabalGild.Unstable.Exception.UnexpectedArgument: fromString :: String -> UnexpectedArgument
- CabalGild.Unstable.Exception.UnexpectedArgument: instance GHC.Classes.Eq CabalGild.Unstable.Exception.UnexpectedArgument.UnexpectedArgument
- CabalGild.Unstable.Exception.UnexpectedArgument: instance GHC.Internal.Exception.Type.Exception CabalGild.Unstable.Exception.UnexpectedArgument.UnexpectedArgument
- CabalGild.Unstable.Exception.UnexpectedArgument: instance GHC.Internal.Show.Show CabalGild.Unstable.Exception.UnexpectedArgument.UnexpectedArgument
- CabalGild.Unstable.Exception.UnexpectedArgument: newtype UnexpectedArgument
+ CabalGild.Unstable.Exception.MixedArgumentStyles: MixedArgumentStyles :: String -> MixedArgumentStyles
+ CabalGild.Unstable.Exception.MixedArgumentStyles: instance GHC.Classes.Eq CabalGild.Unstable.Exception.MixedArgumentStyles.MixedArgumentStyles
+ CabalGild.Unstable.Exception.MixedArgumentStyles: instance GHC.Internal.Exception.Type.Exception CabalGild.Unstable.Exception.MixedArgumentStyles.MixedArgumentStyles
+ CabalGild.Unstable.Exception.MixedArgumentStyles: instance GHC.Internal.Show.Show CabalGild.Unstable.Exception.MixedArgumentStyles.MixedArgumentStyles
+ CabalGild.Unstable.Exception.MixedArgumentStyles: newtype MixedArgumentStyles
+ CabalGild.Unstable.Main: processFile :: (MonadRead m, MonadThrow m, MonadWalk m, MonadWarn m, MonadWrite m) => Context -> FilePath -> m ()
+ CabalGild.Unstable.Main: processFiles :: (MonadRead m, MonadCatch m, MonadWalk m, MonadWarn m, MonadWrite m) => Context -> [FilePath] -> m ()
+ CabalGild.Unstable.Main: processOne :: (MonadRead m, MonadThrow m, MonadWalk m, MonadWarn m, MonadWrite m) => Context -> m ()
+ CabalGild.Unstable.Type.Config: [files] :: Config -> [FilePath]
- CabalGild: mainWith :: (MonadHandle m, MonadLog m, MonadRead m, MonadThrow m, MonadWalk m, MonadWarn m, MonadWrite m) => [String] -> m ()
+ CabalGild: mainWith :: (MonadHandle m, MonadLog m, MonadRead m, MonadCatch m, MonadWalk m, MonadWarn m, MonadWrite m) => [String] -> m ()
- CabalGild.Unstable.Main: mainWith :: (MonadHandle m, MonadLog m, MonadRead m, MonadThrow m, MonadWalk m, MonadWarn m, MonadWrite m) => [String] -> m ()
+ CabalGild.Unstable.Main: mainWith :: (MonadHandle m, MonadLog m, MonadRead m, MonadCatch m, MonadWalk m, MonadWarn m, MonadWrite m) => [String] -> m ()
- CabalGild.Unstable.Type.Config: Config :: Optional Leniency -> Optional Bool -> Optional Input -> Optional Mode -> Optional Output -> Optional FilePath -> Optional Bool -> Config
+ CabalGild.Unstable.Type.Config: Config :: Optional Leniency -> [FilePath] -> Optional Bool -> Optional Input -> Optional Mode -> Optional Output -> Optional FilePath -> Optional Bool -> Config
- CabalGild.Unstable.Type.Config: fromFlags :: MonadThrow m => [Flag] -> m Config
+ CabalGild.Unstable.Type.Config: fromFlags :: MonadThrow m => [Flag] -> [String] -> m Config
- CabalGild.Unstable.Type.Context: fromConfig :: (MonadHandle m, MonadLog m, MonadThrow m, MonadWalk m) => Config -> m Context
+ CabalGild.Unstable.Type.Context: fromConfig :: (MonadHandle m, MonadLog m, MonadWarn m, MonadThrow m, MonadWalk m) => Config -> m Context
- CabalGild.Unstable.Type.Flag: fromArguments :: MonadThrow m => [String] -> m [Flag]
+ CabalGild.Unstable.Type.Flag: fromArguments :: MonadThrow m => [String] -> m ([Flag], [String])

Files

README.md view
@@ -117,10 +117,24 @@  ## Usage -Gild is a command line utility named `cabal-gild`. By default it reads from-standard input (STDIN) and writes to standard output (STDOUT). Its behavior can-be modified with command line options, which are described below.+Gild is a command line utility named `cabal-gild`. Pass one or more files as+arguments to format them in-place: +``` sh+$ cabal-gild p.cabal+$ cabal-gild a.cabal b.cabal+```++When no files are given, Gild reads from standard input (STDIN) and writes to+standard output (STDOUT):++``` sh+$ cabal-gild < p.cabal > q.cabal+```++When run interactively with no arguments, Gild will look for a `*.cabal` file+in the current directory and format it in-place.+ ### Options  Run `cabal-gild --help` to see the options that Gild supports. They are:@@ -136,30 +150,12 @@   to the expected output. (Note that Gild will never produce CRLF line endings   when formatting.) -- `--input=FILE`: Uses `FILE` as the input. If this is `-` (which is the-  default), then the input will be read from STDIN.--- `--io=FILE`: Shortcut for setting both `--input=FILE` and `--output=FILE` at-  the same time. This is useful for formatting a file in-place.- - `--mode=MODE`: Sets the mode to `MODE`, which must be either `format` (the   default) or `check`. When the mode is `format`, Gild will output the   formatted package description. When the mode is `check`, Gild will exit   successfully if the input is already formatted, otherwise it will exit-  unsuccessfully.--- `--output=FILE`: Uses `FILE` as the output. If this is `-` (which is the-  default), then the output will be written to STDOUT. To modify a file in-  place, use the same file as both input and output. For example:--  ``` sh-  $ cabal-gild --input p.cabal --output p.cabal-  ```--  If the output is the same file as the input and the input is already-  formatted, then nothing will happen. The output will not be modified.--  It is an error to provide a value for this option when the mode is `check`.+  unsuccessfully. When checking multiple files, all files are checked before+  exiting.  - `--stdin=FILE`: When reading input from STDIN, use `FILE` as the effective   input file. This is useful when a file's contents are already available, like@@ -169,7 +165,22 @@   $ cabal-gild --stdin p.cabal < p.cabal   ``` -  It is an error to provide a value for this option unless the input is `-`.+  It is an error to provide a value for this option when a file argument is+  given.++### Deprecated Options++The following options are deprecated and will be removed in a future version.+Use positional file arguments instead.++- `--input=FILE`: Uses `FILE` as the input. Use a positional argument instead.++- `--output=FILE`: Uses `FILE` as the output. Use piping instead.++- `--io=FILE`: Shortcut for setting both `--input` and `--output`. Use a+  positional argument instead.++It is an error to combine these options with positional file arguments.  ### Pragmas 
cabal-gild.cabal view
@@ -11,7 +11,7 @@ maintainer: Taylor Fausak name: cabal-gild synopsis: Formats package descriptions.-version: 1.8.2.1+version: 1.8.3.0  source-repository head   type: git@@ -90,12 +90,12 @@     CabalGild.Unstable.Exception.InvalidLeniency     CabalGild.Unstable.Exception.InvalidMode     CabalGild.Unstable.Exception.InvalidOption+    CabalGild.Unstable.Exception.MixedArgumentStyles     CabalGild.Unstable.Exception.MoreThanOneCabalFileFound     CabalGild.Unstable.Exception.NoCabalFileFound     CabalGild.Unstable.Exception.ParseError     CabalGild.Unstable.Exception.SpecifiedOutputWithCheckMode     CabalGild.Unstable.Exception.SpecifiedStdinWithFileInput-    CabalGild.Unstable.Exception.UnexpectedArgument     CabalGild.Unstable.Exception.UnknownOption     CabalGild.Unstable.Exception.UnsatisfiedRequire     CabalGild.Unstable.Extra.ByteString
+ source/library/CabalGild/Unstable/Exception/MixedArgumentStyles.hs view
@@ -0,0 +1,13 @@+module CabalGild.Unstable.Exception.MixedArgumentStyles where++import qualified Control.Monad.Catch as Exception++-- | This exception is thrown when positional file arguments are used together+-- with the deprecated @--input@, @--output@, or @--io@ flags.+newtype MixedArgumentStyles+  = MixedArgumentStyles String+  deriving (Eq, Show)++instance Exception.Exception MixedArgumentStyles where+  displayException (MixedArgumentStyles opt) =+    "cannot use --" <> opt <> " with positional file arguments"
− source/library/CabalGild/Unstable/Exception/UnexpectedArgument.hs
@@ -1,16 +0,0 @@-module CabalGild.Unstable.Exception.UnexpectedArgument where--import qualified Control.Monad.Catch as Exception---- | This exception is thrown when an unexpected command line argument is--- encountered.-newtype UnexpectedArgument-  = UnexpectedArgument String-  deriving (Eq, Show)--instance Exception.Exception UnexpectedArgument where-  displayException (UnexpectedArgument s) = "unexpected argument: " <> s---- | Constructs an 'UnexpectedArgument' from the given 'String'.-fromString :: String -> UnexpectedArgument-fromString = UnexpectedArgument
source/library/CabalGild/Unstable/Main.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE ScopedTypeVariables #-}+ -- | This module defines the main entry point for the application. module CabalGild.Unstable.Main where @@ -59,7 +61,7 @@   ( MonadHandle.MonadHandle m,     MonadLog.MonadLog m,     MonadRead.MonadRead m,-    Exception.MonadThrow m,+    Exception.MonadCatch m,     MonadWalk.MonadWalk m,     MonadWarn.MonadWarn m,     MonadWrite.MonadWrite m@@ -67,10 +69,66 @@   [String] ->   m () mainWith arguments = do-  flags <- Flag.fromArguments arguments-  config <- Config.fromFlags flags+  (flags, positionalArgs) <- Flag.fromArguments arguments+  config <- Config.fromFlags flags positionalArgs   context <- Context.fromConfig config +  case Config.files config of+    [] -> processOne context+    fps -> processFiles context fps++processFiles ::+  forall m.+  ( MonadRead.MonadRead m,+    Exception.MonadCatch m,+    MonadWalk.MonadWalk m,+    MonadWarn.MonadWarn m,+    MonadWrite.MonadWrite m+  ) =>+  Context.Context ->+  [FilePath] ->+  m ()+processFiles context = go False+  where+    go :: Bool -> [FilePath] -> m ()+    go anyFail [] =+      Monad.when anyFail $ Exception.throwM CheckFailure.CheckFailure+    go anyFail (fp : fps) = do+      result <- Exception.try (processFile context fp)+      let anyFail' = case (result :: Either CheckFailure.CheckFailure ()) of+            Left _ -> True+            Right _ -> anyFail+      go anyFail' fps++processFile ::+  ( MonadRead.MonadRead m,+    Exception.MonadThrow m,+    MonadWalk.MonadWalk m,+    MonadWarn.MonadWarn m,+    MonadWrite.MonadWrite m+  ) =>+  Context.Context ->+  FilePath ->+  m ()+processFile context fp =+  let ctx =+        context+          { Context.input = Input.File fp,+            Context.output = Output.File fp,+            Context.stdin = fp+          }+   in processOne ctx++processOne ::+  ( MonadRead.MonadRead m,+    Exception.MonadThrow m,+    MonadWalk.MonadWalk m,+    MonadWarn.MonadWarn m,+    MonadWrite.MonadWrite m+  ) =>+  Context.Context ->+  m ()+processOne context = do   input <- MonadRead.read $ Context.input context   output <- format (Context.stdin context) input 
source/library/CabalGild/Unstable/Type/Config.hs view
@@ -14,6 +14,7 @@ -- Each field typically corresponds to a flag. data Config = Config   { crlf :: Optional.Optional Leniency.Leniency,+    files :: [FilePath],     help :: Optional.Optional Bool,     input :: Optional.Optional Input.Input,     mode :: Optional.Optional Mode.Mode,@@ -28,6 +29,7 @@ initial =   Config     { crlf = Optional.Default,+      files = [],       help = Optional.Default,       input = Optional.Default,       mode = Optional.Default,@@ -59,5 +61,7 @@  -- | Converts a list of flags into a config by starting with 'initial' and -- repeatedly calling 'applyFlag'.-fromFlags :: (Exception.MonadThrow m) => [Flag.Flag] -> m Config-fromFlags = Monad.foldM applyFlag initial+fromFlags :: (Exception.MonadThrow m) => [Flag.Flag] -> [String] -> m Config+fromFlags flags args = do+  config <- Monad.foldM applyFlag initial flags+  pure config {files = args}
source/library/CabalGild/Unstable/Type/Context.hs view
@@ -3,6 +3,8 @@ import qualified CabalGild.Unstable.Class.MonadHandle as MonadHandle import qualified CabalGild.Unstable.Class.MonadLog as MonadLog import qualified CabalGild.Unstable.Class.MonadWalk as MonadWalk+import qualified CabalGild.Unstable.Class.MonadWarn as MonadWarn+import qualified CabalGild.Unstable.Exception.MixedArgumentStyles as MixedArgumentStyles import qualified CabalGild.Unstable.Exception.MoreThanOneCabalFileFound as MoreThanOneCabalFileFound import qualified CabalGild.Unstable.Exception.NoCabalFileFound as NoCabalFileFound import qualified CabalGild.Unstable.Exception.SpecifiedOutputWithCheckMode as SpecifiedOutputWithCheckMode@@ -42,6 +44,7 @@ fromConfig ::   ( MonadHandle.MonadHandle m,     MonadLog.MonadLog m,+    MonadWarn.MonadWarn m,     Exception.MonadThrow m,     MonadWalk.MonadWalk m   ) =>@@ -55,7 +58,9 @@           unlines             [ "cabal-gild version " <> version,               "",-              "<https://github.com/tfausak/cabal-gild>"+              "<https://github.com/tfausak/cabal-gild>",+              "",+              "Usage: cabal-gild [OPTIONS] [FILE ...]"             ]     MonadLog.logLn       . List.dropWhileEnd Char.isSpace@@ -66,6 +71,25 @@     MonadLog.logLn version     Exception.throwM Exit.ExitSuccess +  case (Config.files config, Config.input config, Config.output config) of+    (_ : _, Optional.Specific _, _) ->+      Exception.throwM $ MixedArgumentStyles.MixedArgumentStyles Flag.inputOption+    (_ : _, _, Optional.Specific _) ->+      Exception.throwM $ MixedArgumentStyles.MixedArgumentStyles Flag.outputOption+    ([], Optional.Specific _, Optional.Specific _) -> do+      MonadWarn.warnLn "warning: --input is deprecated, use a positional argument instead"+      MonadWarn.warnLn "warning: --output is deprecated, use piping instead"+    ([], Optional.Specific _, _) ->+      MonadWarn.warnLn "warning: --input is deprecated, use a positional argument instead"+    ([], _, Optional.Specific _) ->+      MonadWarn.warnLn "warning: --output is deprecated, use piping instead"+    _ -> pure ()++  case (Config.files config, Config.stdin config) of+    (_ : _, Optional.Specific _) ->+      Exception.throwM $ MixedArgumentStyles.MixedArgumentStyles Flag.stdinOption+    _ -> pure ()+   case (Config.input config, Config.stdin config) of     (Optional.Specific (Input.File _), Optional.Specific _) ->       Exception.throwM SpecifiedStdinWithFileInput.SpecifiedStdinWithFileInput@@ -83,7 +107,7 @@       preOutput = Maybe.fromMaybe Output.Stdout . Optional.toMaybe $ Config.output config   (theInput, theOutput) <- do     isTerm <- MonadHandle.isTerminalDevice IO.stdin-    if preInput == Input.Stdin && preOutput == Output.Stdout && isTerm+    if null (Config.files config) && preInput == Input.Stdin && preOutput == Output.Stdout && isTerm       then do         cabalFiles <- MonadWalk.walk "." ["*.cabal"] []         case cabalFiles of
source/library/CabalGild/Unstable/Type/Flag.hs view
@@ -2,7 +2,6 @@  import qualified CabalGild.Unstable.Exception.DuplicateOption as DuplicateOption import qualified CabalGild.Unstable.Exception.InvalidOption as InvalidOption-import qualified CabalGild.Unstable.Exception.UnexpectedArgument as UnexpectedArgument import qualified CabalGild.Unstable.Exception.UnknownOption as UnknownOption import qualified Control.Monad.Catch as Exception import qualified Data.Foldable as Foldable@@ -56,12 +55,12 @@       ['i']       [inputOption]       (GetOpt.ReqArg Input "FILE")-      "Sets the input file. Use '-' for standard input (STDIN).\nDefault: '-'",+      "Deprecated. Sets the input file. Use a positional argument instead.",     GetOpt.Option       []       [ioOption]       (GetOpt.ReqArg IO "FILE")-      "Shortcut for setting both the input and output files.",+      "Deprecated. Shortcut for setting both the input and output files.\nUse a positional argument instead.",     GetOpt.Option       ['m']       [modeOption]@@ -71,7 +70,7 @@       ['o']       [outputOption]       (GetOpt.ReqArg Output "FILE")-      "Sets the output file. Use '-' for standard output (STDOUT).\nDefault: '-'",+      "Deprecated. Sets the output file. Use piping instead.",     GetOpt.Option       ['s']       [stdinOption]@@ -97,17 +96,16 @@ stdinOption :: String stdinOption = "stdin" --- | Converts a list of command line arguments into a list of flags. If there--- are any unexpected arguments, invalid options, or unknown options, an+-- | Converts a list of command line arguments into a list of flags and+-- positional arguments. If there are any invalid options or unknown options, an -- exception will be thrown.-fromArguments :: (Exception.MonadThrow m) => [String] -> m [Flag]+fromArguments :: (Exception.MonadThrow m) => [String] -> m ([Flag], [String]) fromArguments arguments = do   let (flgs, args, opts, errs) = GetOpt.getOpt' GetOpt.Permute options arguments-  Foldable.traverse_ (Exception.throwM . UnexpectedArgument.fromString) args   Foldable.traverse_ (Exception.throwM . InvalidOption.fromString) errs   Foldable.traverse_ (Exception.throwM . UnknownOption.fromString) opts   detectDuplicateOptions flgs-  pure flgs+  pure (flgs, args)  detectDuplicateOptions :: (Exception.MonadThrow m) => [Flag] -> m () detectDuplicateOptions =
source/test-suite/Main.hs view
@@ -10,11 +10,11 @@ import qualified CabalGild.Unstable.Exception.CheckFailure as CheckFailure import qualified CabalGild.Unstable.Exception.DuplicateOption as DuplicateOption import qualified CabalGild.Unstable.Exception.InvalidOption as InvalidOption+import qualified CabalGild.Unstable.Exception.MixedArgumentStyles as MixedArgumentStyles import qualified CabalGild.Unstable.Exception.MoreThanOneCabalFileFound as MoreThanOneCabalFileFound import qualified CabalGild.Unstable.Exception.NoCabalFileFound as NoCabalFileFound import qualified CabalGild.Unstable.Exception.SpecifiedOutputWithCheckMode as SpecifiedOutputWithCheckMode import qualified CabalGild.Unstable.Exception.SpecifiedStdinWithFileInput as SpecifiedStdinWithFileInput-import qualified CabalGild.Unstable.Exception.UnexpectedArgument as UnexpectedArgument import qualified CabalGild.Unstable.Exception.UnknownOption as UnknownOption import qualified CabalGild.Unstable.Extra.String as String import qualified CabalGild.Unstable.Main as Gild@@ -59,9 +59,15 @@     expectException ["--help=invalid"] $       InvalidOption.fromString "option `--help' doesn't allow an argument" -  Hspec.it "fails with an unexpected argument" $ do-    expectException ["unexpected"] $-      UnexpectedArgument.fromString "unexpected"+  Hspec.it "accepts a positional argument" $ do+    let (a, s, _w) =+          runGild+            ["p.cabal"]+            [(Input.File "p.cabal", String.toUtf8 "")]+            (".", [])+            False+    a `Hspec.shouldSatisfy` Either.isRight+    s `Hspec.shouldBe` Map.empty    Hspec.it "fails when --crlf is given twice" $ do     expectException ["--crlf=strict", "--crlf=lenient"] $@@ -102,16 +108,16 @@       ["--stdin=f", "--stdin=g"]       $ DuplicateOption.DuplicateOption "stdin" "f" "g" -  Hspec.it "reads from an input file" $ do+  Hspec.it "formats a positional file in-place" $ do     let (a, s, w) =           runGild-            ["--input", "input.cabal"]+            ["input.cabal"]             [(Input.File "input.cabal", String.toUtf8 "")]             (".", [])             False     a `Hspec.shouldSatisfy` Either.isRight     w `Hspec.shouldBe` []-    s `Hspec.shouldBe` Map.singleton Output.Stdout (String.toUtf8 "")+    s `Hspec.shouldBe` Map.empty    Hspec.it "writes to an output file" $ do     let (a, s, w) =@@ -121,7 +127,7 @@             (".", [])             False     a `Hspec.shouldSatisfy` Either.isRight-    w `Hspec.shouldBe` []+    w `Hspec.shouldBe` ["warning: --output is deprecated, use piping instead"]     s `Hspec.shouldBe` Map.singleton (Output.File "output.cabal") (String.toUtf8 "")    Hspec.it "succeeds when checking formatted input" $ do@@ -176,7 +182,7 @@             (".", [])             False     a `shouldBeFailure` SpecifiedStdinWithFileInput.SpecifiedStdinWithFileInput-    w `Hspec.shouldBe` []+    w `Hspec.shouldBe` ["warning: --input is deprecated, use a positional argument instead"]     s `Hspec.shouldBe` Map.empty    Hspec.it "fails when --output is given with check mode" $ do@@ -187,13 +193,13 @@             (".", [])             False     a `shouldBeFailure` SpecifiedOutputWithCheckMode.SpecifiedOutputWithCheckMode-    w `Hspec.shouldBe` []+    w `Hspec.shouldBe` ["warning: --output is deprecated, use piping instead"]     s `Hspec.shouldBe` Map.empty    Hspec.it "does not overwrite output when input is formatted" $ do     let (a, s, w) =           runGild-            ["--io", "io.cabal"]+            ["io.cabal"]             [(Input.File "io.cabal", String.toUtf8 "")]             (".", [])             False@@ -201,82 +207,82 @@     w `Hspec.shouldBe` []     s `Hspec.shouldBe` Map.empty -  Hspec.it "writes to stdout when input is formatted" $ do+  Hspec.it "formats a positional file to output" $ do     let (a, s, w) =           runGild-            ["--input", "p.cabal"]-            [(Input.File "p.cabal", String.toUtf8 "")]+            ["io.cabal"]+            [(Input.File "io.cabal", String.toUtf8 "f:a")]             (".", [])             False     a `Hspec.shouldSatisfy` Either.isRight     w `Hspec.shouldBe` []-    s `Hspec.shouldBe` Map.singleton Output.Stdout (String.toUtf8 "")+    s `Hspec.shouldBe` Map.singleton (Output.File "io.cabal") (String.toUtf8 "f: a\n") -  Hspec.it "writes to output when input is formatted" $ do+  Hspec.it "does not overwrite CRLF file when lenient" $ do     let (a, s, w) =           runGild-            ["--input", "p.cabal", "--output", "q.cabal"]-            [(Input.File "p.cabal", String.toUtf8 "")]+            ["p.cabal"]+            [(Input.File "p.cabal", String.toUtf8 "s\r\n")]             (".", [])             False     a `Hspec.shouldSatisfy` Either.isRight     w `Hspec.shouldBe` []-    s `Hspec.shouldBe` Map.singleton (Output.File "q.cabal") (String.toUtf8 "")+    s `Hspec.shouldBe` Map.empty -  Hspec.it "writes to output when stdin is formatted" $ do+  Hspec.it "overwrites CRLF file when strict" $ do     let (a, s, w) =           runGild-            ["--output", "q.cabal"]-            [(Input.Stdin, String.toUtf8 "")]+            ["--crlf", "strict", "p.cabal"]+            [(Input.File "p.cabal", String.toUtf8 "s\r\n")]             (".", [])             False     a `Hspec.shouldSatisfy` Either.isRight     w `Hspec.shouldBe` []-    s `Hspec.shouldBe` Map.singleton (Output.File "q.cabal") (String.toUtf8 "")+    s `Hspec.shouldBe` Map.singleton (Output.File "p.cabal") (String.toUtf8 "s\n") -  Hspec.it "sets input and output simultaneously" $ do+  Hspec.it "uses --stdin for discovery" $ do     let (a, s, w) =           runGild-            ["--io", "io.cabal"]-            [(Input.File "io.cabal", String.toUtf8 "f:a")]-            (".", [])+            ["--stdin", "d/p.cabal"]+            [(Input.Stdin, String.toUtf8 "library\n -- cabal-gild: discover\n exposed-modules:")]+            ("d", [["M.hs"]])             False     a `Hspec.shouldSatisfy` Either.isRight     w `Hspec.shouldBe` []-    s `Hspec.shouldBe` Map.singleton (Output.File "io.cabal") (String.toUtf8 "f: a\n")+    s `Hspec.shouldBe` Map.singleton Output.Stdout (String.toUtf8 "library\n  -- cabal-gild: discover\n  exposed-modules: M\n") -  Hspec.it "does not overwrite CRLF file when lenient" $ do-    let (a, s, w) =+  Hspec.it "warns when --input is used" $ do+    let (a, _s, w) =           runGild-            ["--io", "p.cabal"]-            [(Input.File "p.cabal", String.toUtf8 "s\r\n")]+            ["--input", "p.cabal"]+            [(Input.File "p.cabal", String.toUtf8 "")]             (".", [])             False     a `Hspec.shouldSatisfy` Either.isRight-    w `Hspec.shouldBe` []-    s `Hspec.shouldBe` Map.empty+    w `Hspec.shouldBe` ["warning: --input is deprecated, use a positional argument instead"] -  Hspec.it "overwrites CRLF file when strict" $ do-    let (a, s, w) =+  Hspec.it "warns when --output is used" $ do+    let (a, _s, w) =           runGild-            ["--crlf", "strict", "--io", "p.cabal"]-            [(Input.File "p.cabal", String.toUtf8 "s\r\n")]+            ["--output", "q.cabal"]+            [(Input.Stdin, String.toUtf8 "")]             (".", [])             False     a `Hspec.shouldSatisfy` Either.isRight-    w `Hspec.shouldBe` []-    s `Hspec.shouldBe` Map.singleton (Output.File "p.cabal") (String.toUtf8 "s\n")+    w `Hspec.shouldBe` ["warning: --output is deprecated, use piping instead"] -  Hspec.it "uses --stdin for discovery" $ do-    let (a, s, w) =+  Hspec.it "warns when --io is used" $ do+    let (a, _s, w) =           runGild-            ["--stdin", "d/p.cabal"]-            [(Input.Stdin, String.toUtf8 "library\n -- cabal-gild: discover\n exposed-modules:")]-            ("d", [["M.hs"]])+            ["--io", "io.cabal"]+            [(Input.File "io.cabal", String.toUtf8 "")]+            (".", [])             False     a `Hspec.shouldSatisfy` Either.isRight-    w `Hspec.shouldBe` []-    s `Hspec.shouldBe` Map.singleton Output.Stdout (String.toUtf8 "library\n  -- cabal-gild: discover\n  exposed-modules: M\n")+    w+      `Hspec.shouldBe` [ "warning: --input is deprecated, use a positional argument instead",+                         "warning: --output is deprecated, use piping instead"+                       ]    Hspec.it "succeeds with empty input" $ do     expectGilded@@ -1511,13 +1517,13 @@     let d = "input"         (a, s, w) =           runGild-            ["--input", FilePath.combine d "io.cabal"]+            [FilePath.combine d "io.cabal"]             [(Input.File $ FilePath.combine d "io.cabal", String.toUtf8 "library\n -- cabal-gild: discover src --exclude src/N.hs\n exposed-modules:")]             (d, [["src", "M.hs"], ["src", "N.hs"]])             False     a `Hspec.shouldSatisfy` Either.isRight     w `Hspec.shouldBe` []-    s `Hspec.shouldBe` Map.singleton Output.Stdout (String.toUtf8 "library\n  -- cabal-gild: discover src --exclude src/N.hs\n  exposed-modules: M\n")+    s `Hspec.shouldBe` Map.singleton (Output.File $ FilePath.combine d "io.cabal") (String.toUtf8 "library\n  -- cabal-gild: discover src --exclude src/N.hs\n  exposed-modules: M\n")    Hspec.it "allows excluding simple wildcards" $ do     expectDiscover@@ -1868,13 +1874,13 @@     let d = "input"         (a, s, w) =           runGild-            ["--input", FilePath.combine d "io.cabal"]+            [FilePath.combine d "io.cabal"]             [(Input.File $ FilePath.combine d "io.cabal", String.toUtf8 "library\n -- cabal-gild: discover src --include src/M.hs\n exposed-modules:")]             (d, [["src", "M.hs"], ["src", "N.hs"]])             False     a `Hspec.shouldSatisfy` Either.isRight     w `Hspec.shouldBe` []-    s `Hspec.shouldBe` Map.singleton Output.Stdout (String.toUtf8 "library\n  -- cabal-gild: discover src --include src/M.hs\n  exposed-modules: M\n")+    s `Hspec.shouldBe` Map.singleton (Output.File $ FilePath.combine d "io.cabal") (String.toUtf8 "library\n  -- cabal-gild: discover src --include src/M.hs\n  exposed-modules: M\n")    Hspec.it "discovers asm-sources" $ do     expectDiscover@@ -2105,6 +2111,93 @@     w `Hspec.shouldBe` []     s `Hspec.shouldBe` Map.empty +  Hspec.it "formats multiple positional files in-place" $ do+    let (a, s, w) =+          runGild+            ["a.cabal", "b.cabal"]+            [ (Input.File "a.cabal", String.toUtf8 "f:a"),+              (Input.File "b.cabal", String.toUtf8 "g:b")+            ]+            (".", [])+            False+    a `Hspec.shouldSatisfy` Either.isRight+    w `Hspec.shouldBe` []+    s+      `Hspec.shouldBe` Map.fromList+        [ (Output.File "a.cabal", String.toUtf8 "f: a\n"),+          (Output.File "b.cabal", String.toUtf8 "g: b\n")+        ]++  Hspec.it "checks multiple positional files" $ do+    let (a, s, w) =+          runGild+            ["--mode", "check", "a.cabal", "b.cabal"]+            [ (Input.File "a.cabal", String.toUtf8 "f: a\n"),+              (Input.File "b.cabal", String.toUtf8 "g: b\n")+            ]+            (".", [])+            False+    a `Hspec.shouldSatisfy` Either.isRight+    w `Hspec.shouldBe` []+    s `Hspec.shouldBe` Map.empty++  Hspec.it "fails check when any positional file is unformatted" $ do+    let (a, s, w) =+          runGild+            ["--mode", "check", "a.cabal", "b.cabal"]+            [ (Input.File "a.cabal", String.toUtf8 "f: a\n"),+              (Input.File "b.cabal", String.toUtf8 "g:b")+            ]+            (".", [])+            False+    a `shouldBeFailure` CheckFailure.CheckFailure+    w `Hspec.shouldBe` []+    s `Hspec.shouldBe` Map.empty++  Hspec.it "fails when positional args are mixed with --input" $ do+    let (a, s, w) =+          runGild+            ["--input", "a.cabal", "b.cabal"]+            []+            (".", [])+            False+    a `shouldBeFailure` MixedArgumentStyles.MixedArgumentStyles "input"+    w `Hspec.shouldBe` []+    s `Hspec.shouldBe` Map.empty++  Hspec.it "fails when positional args are mixed with --output" $ do+    let (a, s, w) =+          runGild+            ["--output", "a.cabal", "b.cabal"]+            []+            (".", [])+            False+    a `shouldBeFailure` MixedArgumentStyles.MixedArgumentStyles "output"+    w `Hspec.shouldBe` []+    s `Hspec.shouldBe` Map.empty++  Hspec.it "fails when positional args are mixed with --io" $ do+    let (a, s, w) =+          runGild+            ["--io", "a.cabal", "b.cabal"]+            []+            (".", [])+            False+    a `shouldBeFailure` MixedArgumentStyles.MixedArgumentStyles "input"+    w `Hspec.shouldBe` []+    s `Hspec.shouldBe` Map.empty++  Hspec.it "fails when positional args are mixed with --stdin" $ do+    let (a, s, w) =+          runGild+            ["--stdin", "a.cabal", "b.cabal"]+            []+            (".", [])+            False+    a `shouldBeFailure` MixedArgumentStyles.MixedArgumentStyles "stdin"+    w `Hspec.shouldBe` []+    s `Hspec.shouldBe` Map.empty+ withTemporaryDirectory :: IO () -> IO () withTemporaryDirectory =   Temp.withSystemTempDirectory "cabal-gild"@@ -2222,6 +2315,15 @@  instance (Monad m) => Exception.MonadThrow (TestT m) where   throwM = TestT . ExceptT.throwE . Exception.toException++instance (Monad m) => Exception.MonadCatch (TestT m) where+  catch (TestT m) h = TestT . ExceptT.ExceptT $ do+    result <- ExceptT.runExceptT m+    case result of+      Left e -> case Exception.fromException e of+        Just e' -> ExceptT.runExceptT . runTestT $ h e'+        Nothing -> pure (Left e)+      Right a -> pure (Right a)  instance (Monad m) => MonadWalk.MonadWalk (TestT m) where   walk d i x = do