packages feed

ormolu 0.1.4.0 → 0.1.4.1

raw patch · 10 files changed

+229/−107 lines, 10 filesdep ~bytestringPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: bytestring

API changes (from Hackage documentation)

+ Ormolu: Always :: ColorMode
+ Ormolu: Auto :: ColorMode
+ Ormolu: Never :: ColorMode
+ Ormolu: [cfgColorMode] :: Config region -> !ColorMode
+ Ormolu: data ColorMode
+ Ormolu.Config: Always :: ColorMode
+ Ormolu.Config: Auto :: ColorMode
+ Ormolu.Config: Never :: ColorMode
+ Ormolu.Config: [cfgColorMode] :: Config region -> !ColorMode
+ Ormolu.Config: data ColorMode
+ Ormolu.Terminal: Always :: ColorMode
+ Ormolu.Terminal: Auto :: ColorMode
+ Ormolu.Terminal: Never :: ColorMode
+ Ormolu.Terminal: bold :: Term a -> Term a
+ Ormolu.Terminal: cyan :: Term a -> Term a
+ Ormolu.Terminal: data ColorMode
+ Ormolu.Terminal: data Term a
+ Ormolu.Terminal: green :: Term a -> Term a
+ Ormolu.Terminal: instance GHC.Base.Applicative Ormolu.Terminal.Term
+ Ormolu.Terminal: instance GHC.Base.Functor Ormolu.Terminal.Term
+ Ormolu.Terminal: instance GHC.Base.Monad Ormolu.Terminal.Term
+ Ormolu.Terminal: instance GHC.Classes.Eq Ormolu.Terminal.ColorMode
+ Ormolu.Terminal: instance GHC.Show.Show Ormolu.Terminal.ColorMode
+ Ormolu.Terminal: newline :: Term ()
+ Ormolu.Terminal: put :: Text -> Term ()
+ Ormolu.Terminal: putS :: String -> Term ()
+ Ormolu.Terminal: putSrcSpan :: SrcSpan -> Term ()
+ Ormolu.Terminal: red :: Term a -> Term a
+ Ormolu.Terminal: runTerm :: Term a -> ColorMode -> Handle -> IO a
- Ormolu: Config :: ![DynOption] -> !Bool -> !Bool -> !Bool -> !region -> Config region
+ Ormolu: Config :: ![DynOption] -> !Bool -> !Bool -> !Bool -> !ColorMode -> !region -> Config region
- Ormolu: withPrettyOrmoluExceptions :: IO ExitCode -> IO ExitCode
+ Ormolu: withPrettyOrmoluExceptions :: ColorMode -> IO ExitCode -> IO ExitCode
- Ormolu.Config: Config :: ![DynOption] -> !Bool -> !Bool -> !Bool -> !region -> Config region
+ Ormolu.Config: Config :: ![DynOption] -> !Bool -> !Bool -> !Bool -> !ColorMode -> !region -> Config region
- Ormolu.Diff.Text: printTextDiff :: Handle -> TextDiff -> IO ()
+ Ormolu.Diff.Text: printTextDiff :: TextDiff -> Term ()
- Ormolu.Exception: withPrettyOrmoluExceptions :: IO ExitCode -> IO ExitCode
+ Ormolu.Exception: withPrettyOrmoluExceptions :: ColorMode -> IO ExitCode -> IO ExitCode

Files

CHANGELOG.md view
@@ -1,11 +1,16 @@+## Ormolu 0.1.4.1++* Added command line option `--color` to control how diffs are printed.+  Standardized the way errors are printed.+ ## Ormolu 0.1.4.0  * Added support for monad comprehensions. [Issue-  665](https://github.com/tweag/ormolu/issues/658).+  665](https://github.com/tweag/ormolu/issues/665).  * Fixed a bug when a space was inserted in front of promoted types even when   it wasn't strictly necessary. [Issue-  668](https://github.com/tweag/ormolu/issues/688).+  668](https://github.com/tweag/ormolu/issues/668).  * Now the checking mode displays diffs per file when unformatted files are   found. The rendering of the diffs is also improved. [Issue
app/Main.hs view
@@ -17,9 +17,11 @@ import Ormolu import Ormolu.Diff.Text (diffText, printTextDiff) import Ormolu.Parser (manualExts)+import Ormolu.Terminal import Ormolu.Utils (showOutputable) import Paths_ormolu (version) import System.Exit (ExitCode (..), exitWith)+import qualified System.FilePath as FP import System.IO (hPutStrLn, stderr)  -- | Entry point of the program.@@ -56,8 +58,8 @@   -- | File to format or stdin as 'Nothing'   Maybe FilePath ->   IO ExitCode-formatOne mode config mpath = withPrettyOrmoluExceptions $-  case mpath of+formatOne mode config mpath = withPrettyOrmoluExceptions (cfgColorMode config) $+  case FP.normalise <$> mpath of     Nothing -> do       r <- ormoluStdin config       case mode of@@ -88,7 +90,7 @@           case diffText originalInput formattedInput inputFile of             Nothing -> return ExitSuccess             Just diff -> do-              printTextDiff stderr diff+              runTerm (printTextDiff diff) (cfgColorMode config) stderr               -- 100 is different to all the other exit code that are emitted               -- either from an 'OrmoluException' or from 'error' and               -- 'notImplemented'.@@ -163,13 +165,13 @@                 short 'm',                 metavar "MODE",                 value Stdout,-                help "Mode of operation: 'stdout' (default), 'inplace', or 'check'"+                help "Mode of operation: 'stdout' (the default), 'inplace', or 'check'"               ]         )     <*> configParser     <*> (many . strArgument . mconcat)       [ metavar "FILE",-        help "Haskell source files to format or stdin (default)"+        help "Haskell source files to format or stdin (the default)"       ]  configParser :: Parser (Config RegionIndices)@@ -196,6 +198,12 @@         short 'c',         help "Fail if formatting is not idempotent"       ]+    <*> (option parseColorMode . mconcat)+      [ long "color",+        metavar "WHEN",+        value Auto,+        help "Colorize the output; WHEN can be 'never', 'always', or 'auto' (the default)"+      ]     <*> ( RegionIndices             <$> (optional . option auto . mconcat)               [ long "start-line",@@ -219,3 +227,10 @@   "inplace" -> Right InPlace   "check" -> Right Check   s -> Left $ "unknown mode: " ++ s++parseColorMode :: ReadM ColorMode+parseColorMode = eitherReader $ \case+  "never" -> Right Never+  "always" -> Right Always+  "auto" -> Right Auto+  s -> Left $ "unknown color mode: " ++ s
ormolu.cabal view
@@ -1,6 +1,6 @@ cabal-version:   1.18 name:            ormolu-version:         0.1.4.0+version:         0.1.4.1 license:         BSD3 license-file:    LICENSE.md maintainer:      Mark Karpov <mark.karpov@tweag.io>@@ -110,6 +110,7 @@         Ormolu.Processing.Cpp         Ormolu.Processing.Postprocess         Ormolu.Processing.Preprocess+        Ormolu.Terminal         Ormolu.Utils      hs-source-dirs:   src@@ -147,6 +148,7 @@     default-language: Haskell2010     build-depends:         base >=4.12 && <5.0,+        filepath >=1.2 && <1.5,         ghc-lib-parser >=8.10 && <8.11,         gitrev >=1.3 && <1.4,         optparse-applicative >=0.14 && <0.17,
src/Ormolu.hs view
@@ -6,6 +6,7 @@     ormoluFile,     ormoluStdin,     Config (..),+    ColorMode (..),     RegionIndices (..),     defaultConfig,     DynOption (..),
src/Ormolu/Config.hs view
@@ -4,6 +4,7 @@ -- | Configuration options used by the tool. module Ormolu.Config   ( Config (..),+    ColorMode (..),     RegionIndices (..),     RegionDeltas (..),     defaultConfig,@@ -13,6 +14,7 @@   ) where +import Ormolu.Terminal (ColorMode (..)) import qualified SrcLoc as GHC  -- | Ormolu configuration.@@ -25,6 +27,8 @@     cfgDebug :: !Bool,     -- | Checks if re-formatting the result is idempotent     cfgCheckIdempotence :: !Bool,+    -- | Whether to use colors and other features of ANSI terminals+    cfgColorMode :: !ColorMode,     -- | Region selection     cfgRegion :: !region   }@@ -57,6 +61,7 @@       cfgUnsafe = False,       cfgDebug = False,       cfgCheckIdempotence = False,+      cfgColorMode = Auto,       cfgRegion =         RegionIndices           { regionStartLine = Nothing,
src/Ormolu/Diff/Text.hs view
@@ -17,9 +17,7 @@ import Data.Maybe (listToMaybe) import Data.Text (Text) import qualified Data.Text as T-import qualified Data.Text.IO as T-import System.Console.ANSI-import System.IO+import Ormolu.Terminal  ---------------------------------------------------------------------------- -- Types@@ -70,53 +68,22 @@       D.First _ -> False       D.Second _ -> False --- | Print the given 'TextDiff' to 'Handle'. This function tries to mimic--- the style of @git diff@.-printTextDiff :: Handle -> TextDiff -> IO ()-printTextDiff h (TextDiff path xs) = do-  supports <- hSupportsANSI h-  let bold m =-        if supports-          then do-            hSetSGR h [SetConsoleIntensity BoldIntensity]-            m-            hSetSGR h [Reset]-          else m-      cyan m =-        if supports-          then do-            hSetSGR h [SetColor Foreground Dull Cyan]-            m-            hSetSGR h [Reset]-          else m-      green m =-        if supports-          then do-            hSetSGR h [SetColor Foreground Dull Green]-            m-            hSetSGR h [Reset]-          else m-      red m =-        if supports-          then do-            hSetSGR h [SetColor Foreground Dull Red]-            m-            hSetSGR h [Reset]-          else m-      put = T.hPutStr h-      newline = hPutStr h "\n"-  (bold . put . T.pack) path+-- | Print the given 'TextDiff' as a 'Term' action. This function tries to+-- mimic the style of @git diff@.+printTextDiff :: TextDiff -> Term ()+printTextDiff (TextDiff path xs) = do+  (bold . putS) path   newline   forM_ (toHunks (assignLines xs)) $ \Hunk {..} -> do     cyan $ do       put "@@ -"-      put (T.pack $ show hunkFirstStartLine)+      putS (show hunkFirstStartLine)       put ","-      put (T.pack $ show hunkFirstLength)+      putS (show hunkFirstLength)       put " +"-      put (T.pack $ show hunkSecondStartLine)+      putS (show hunkSecondStartLine)       put ","-      put (T.pack $ show hunkSecondLength)+      putS (show hunkSecondLength)       put " @@"     newline     forM_ hunkDiff $ \case@@ -140,7 +107,6 @@             put " "           put y           newline-  hFlush h  ---------------------------------------------------------------------------- -- Helpers
src/Ormolu/Exception.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TupleSections #-}  -- | 'OrmoluException' type and surrounding definitions.@@ -9,12 +10,13 @@ where  import Control.Exception+import Control.Monad (forM_) import Data.List.NonEmpty (NonEmpty (..)) import qualified Data.List.NonEmpty as NE+import qualified Data.Text as T import qualified GHC import Ormolu.Diff.Text (TextDiff, printTextDiff)-import Ormolu.Utils (showOutputable)-import qualified Outputable as GHC+import Ormolu.Terminal import System.Exit (ExitCode (..)) import System.IO @@ -34,47 +36,63 @@  instance Exception OrmoluException --- |-printOrmoluException :: Handle -> OrmoluException -> IO ()-printOrmoluException h = \case-  OrmoluParsingFailed s e ->-    hPutStrLn h $-      showParsingErr "The GHC parser (in Haddock mode) failed:" s [e]-  OrmoluOutputParsingFailed s e ->-    hPutStrLn h $-      showParsingErr "Parsing of formatted code failed:" s [e]-        ++ "Please, consider reporting the bug.\n"-  OrmoluASTDiffers path ss ->-    hPutStrLn h . unlines $-      [ "AST of input and AST of formatted code differ."-      ]-        ++ fmap-          withIndent-          ( case fmap (\s -> "at " ++ showOutputable s) ss of-              [] -> ["in " ++ path]-              xs -> xs-          )-        ++ ["Please, consider reporting the bug."]+-- | Print an 'OrmoluException'.+printOrmoluException ::+  OrmoluException ->+  Term ()+printOrmoluException = \case+  OrmoluParsingFailed s e -> do+    bold (putSrcSpan s)+    newline+    put "  The GHC parser (in Haddock mode) failed:"+    newline+    put "  "+    put (T.pack e)+    newline+  OrmoluOutputParsingFailed s e -> do+    bold (putSrcSpan s)+    newline+    put "  Parsing of formatted code failed:"+    put "  "+    put (T.pack e)+    newline+  OrmoluASTDiffers path ss -> do+    putS path+    newline+    put "  AST of input and AST of formatted code differ."+    newline+    forM_ ss $ \s -> do+      put "    at "+      putSrcSpan s+      newline+    put "  Please, consider reporting the bug."+    newline   OrmoluNonIdempotentOutput diff -> do-    hPutStrLn h "Formatting is not idempotent:\n"-    printTextDiff h diff-    hPutStrLn h "\nPlease, consider reporting the bug.\n"-  OrmoluUnrecognizedOpts opts ->-    hPutStrLn h . unlines $-      [ "The following GHC options were not recognized:",-        (withIndent . unwords . NE.toList) opts-      ]+    printTextDiff diff+    newline+    put "  Formatting is not idempotent."+    newline+    put "  Please, consider reporting the bug."+    newline+  OrmoluUnrecognizedOpts opts -> do+    put "The following GHC options were not recognized:"+    newline+    put "  "+    (putS . unwords . NE.toList) opts+    newline  -- | Inside this wrapper 'OrmoluException' will be caught and displayed -- nicely. withPrettyOrmoluExceptions ::+  -- | Color mode+  ColorMode ->   -- | Action that may throw an exception   IO ExitCode ->   IO ExitCode-withPrettyOrmoluExceptions m = m `catch` h+withPrettyOrmoluExceptions colorMode m = m `catch` h   where     h e = do-      printOrmoluException stderr e+      runTerm (printOrmoluException e) colorMode stderr       return . ExitFailure $         case e of           -- Error code 1 is for 'error' or 'notImplemented'@@ -84,19 +102,3 @@           OrmoluASTDiffers {} -> 5           OrmoluNonIdempotentOutput {} -> 6           OrmoluUnrecognizedOpts {} -> 7--------------------------------------------------------------------------------- Helpers---- | Show a parse error.-showParsingErr :: GHC.Outputable a => String -> a -> [String] -> String-showParsingErr msg spn err =-  unlines $-    [ msg,-      withIndent (showOutputable spn)-    ]-      ++ map withIndent err---- | Indent with 2 spaces for readability.-withIndent :: String -> String-withIndent txt = "  " ++ txt
src/Ormolu/Printer/Internal.hs view
@@ -148,7 +148,7 @@     OnNextLine   deriving (Eq, Show) --- | Run an 'R' monad.+-- | Run 'R' monad. runR ::   -- | Monad to run   R () ->
+ src/Ormolu/Terminal.hs view
@@ -0,0 +1,125 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}++-- | An abstraction for colorful output in terminal.+module Ormolu.Terminal+  ( -- * The 'Term' monad+    Term,+    ColorMode (..),+    runTerm,++    -- * Styling+    bold,+    cyan,+    green,+    red,++    -- * Printing+    put,+    putS,+    putSrcSpan,+    newline,+  )+where++import Control.Monad.Reader+import Data.Text (Text)+import qualified Data.Text.IO as T+import qualified GHC+import Ormolu.Utils (showOutputable)+import System.Console.ANSI+import System.IO (Handle, hFlush, hPutStr)++----------------------------------------------------------------------------+-- The 'Term' monad++-- | Terminal monad.+newtype Term a = Term (ReaderT RC IO a)+  deriving (Functor, Applicative, Monad)++-- | Reader context of 'Term'.+data RC = RC+  { -- | Whether to use colors+    rcUseColor :: Bool,+    -- | Handle to print to+    rcHandle :: Handle+  }++-- | Whether to use colors and other features of ANSI terminals.+data ColorMode = Never | Always | Auto+  deriving (Eq, Show)++-- | Run 'Term' monad.+runTerm ::+  -- | Monad to run+  Term a ->+  -- | Color mode+  ColorMode ->+  -- | Handle to print to+  Handle ->+  IO a+runTerm (Term m) colorMode rcHandle = do+  rcUseColor <- case colorMode of+    Never -> return False+    Always -> return True+    Auto -> hSupportsANSI rcHandle+  x <- runReaderT m RC {..}+  hFlush rcHandle+  return x++----------------------------------------------------------------------------+-- Styling++-- | Make the inner computation output bold text.+bold :: Term a -> Term a+bold = withSGR [SetConsoleIntensity BoldIntensity]++-- | Make the inner computation output cyan text.+cyan :: Term a -> Term a+cyan = withSGR [SetColor Foreground Dull Cyan]++-- | Make the inner computation output green text.+green :: Term a -> Term a+green = withSGR [SetColor Foreground Dull Green]++-- | Make the inner computation output red text.+red :: Term a -> Term a+red = withSGR [SetColor Foreground Dull Red]++-- | Alter 'SGR' for inner computation.+withSGR :: [SGR] -> Term a -> Term a+withSGR sgrs (Term m) = Term $ do+  RC {..} <- ask+  if rcUseColor+    then do+      liftIO $ hSetSGR rcHandle sgrs+      x <- m+      liftIO $ hSetSGR rcHandle [Reset]+      return x+    else m++----------------------------------------------------------------------------+-- Printing++-- | Output 'Text'.+put :: Text -> Term ()+put txt = Term $ do+  RC {..} <- ask+  liftIO $ T.hPutStr rcHandle txt++-- | Output 'String'.+putS :: String -> Term ()+putS str = Term $ do+  RC {..} <- ask+  liftIO $ hPutStr rcHandle str++-- | Output a 'GHC.SrcSpan'.+putSrcSpan :: GHC.SrcSpan -> Term ()+putSrcSpan = putS . showOutputable++-- | Output a newline.+newline :: Term ()+newline = Term $ do+  RC {..} <- ask+  liftIO $ T.hPutStr rcHandle "\n"
tests/Ormolu/Diff/TextSpec.hs view
@@ -5,10 +5,11 @@ import Data.Text (Text) import qualified Data.Text.IO as T import Ormolu.Diff.Text+import Ormolu.Terminal import Path import Path.IO import qualified System.FilePath as FP-import System.IO (Handle, hClose)+import System.IO (hClose) import Test.Hspec  spec :: Spec@@ -44,14 +45,14 @@     parseRelFile expectedDiffPath       >>= T.readFile . toFilePath . (diffOutputsDir </>)   let Just actualDiff = diffText inputA inputB "TEST"-  actualDiffText <- printToText (\h -> printTextDiff h actualDiff)+  actualDiffText <- printDiff actualDiff   actualDiffText `shouldBe` expectedDiffText  -- | Print to a 'Text' value.-printToText :: (Handle -> IO ()) -> IO Text-printToText action =+printDiff :: TextDiff -> IO Text+printDiff diff =   withSystemTempFile "ormolu-diff-test" $ \path h -> do-    action h+    runTerm (printTextDiff diff) Never h     hClose h     T.readFile (toFilePath path)