{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} module Hadolint.Formatter.TTY ( printResults, formatCheck, formatError, ) where import Colourista import qualified Control.Foldl as Foldl import qualified Data.Text as Text import Hadolint.Formatter.Format import Hadolint.Rule (CheckFailure (..), DLSeverity (..), RuleCode (..)) import Language.Docker.Syntax import Text.Megaparsec (TraversableStream) import Text.Megaparsec.Error import Text.Megaparsec.Stream (VisualStream) formatError :: (VisualStream s, TraversableStream s, ShowErrorComponent e) => ParseErrorBundle s e -> String formatError :: forall s e. (VisualStream s, TraversableStream s, ShowErrorComponent e) => ParseErrorBundle s e -> String formatError ParseErrorBundle s e err = String -> String stripNewlines (forall s e. (VisualStream s, TraversableStream s, ShowErrorComponent e) => ParseErrorBundle s e -> String errorMessageLine ParseErrorBundle s e err) formatCheck :: Bool -> Text.Text -> CheckFailure -> Text.Text formatCheck :: Bool -> Text -> CheckFailure -> Text formatCheck Bool nocolor Text source CheckFailure {RuleCode code :: CheckFailure -> RuleCode code :: RuleCode code, DLSeverity severity :: CheckFailure -> DLSeverity severity :: DLSeverity severity, Linenumber line :: CheckFailure -> Linenumber line :: Linenumber line, Text message :: CheckFailure -> Text message :: Text message} = Text -> Linenumber -> Text formatPos Text source Linenumber line forall a. Semigroup a => a -> a -> a <> RuleCode -> Text unRuleCode RuleCode code forall a. Semigroup a => a -> a -> a <> Text " " forall a. Semigroup a => a -> a -> a <> ( if Bool nocolor then DLSeverity -> Text severityText DLSeverity severity else DLSeverity -> Text colorizedSeverity DLSeverity severity ) forall a. Semigroup a => a -> a -> a <> Text ": " forall a. Semigroup a => a -> a -> a <> Text message formatPos :: Filename -> Linenumber -> Text.Text formatPos :: Text -> Linenumber -> Text formatPos Text source Linenumber line = Text source forall a. Semigroup a => a -> a -> a <> Text ":" forall a. Semigroup a => a -> a -> a <> String -> Text Text.pack (forall a. Show a => a -> String show Linenumber line) forall a. Semigroup a => a -> a -> a <> Text " " printResults :: (VisualStream s, TraversableStream s, ShowErrorComponent e, Foldl.Foldable f) => f (Result s e) -> Bool -> IO () printResults :: forall s e (f :: * -> *). (VisualStream s, TraversableStream s, ShowErrorComponent e, Foldable f) => f (Result s e) -> Bool -> IO () printResults f (Result s e) results Bool color = forall (t :: * -> *) (m :: * -> *) a b. (Foldable t, Monad m) => (a -> m b) -> t a -> m () mapM_ forall {s} {e}. (VisualStream s, TraversableStream s, ShowErrorComponent e) => Result s e -> IO () printResult f (Result s e) results where printResult :: Result s e -> IO () printResult Result {Text fileName :: forall s e. Result s e -> Text fileName :: Text fileName, Seq (ParseErrorBundle s e) errors :: forall s e. Result s e -> Seq (ParseErrorBundle s e) errors :: Seq (ParseErrorBundle s e) errors, Failures checks :: forall s e. Result s e -> Failures checks :: Failures checks} = forall {t :: * -> *} {s} {e}. (Foldable t, VisualStream s, TraversableStream s, ShowErrorComponent e) => t (ParseErrorBundle s e) -> IO () printErrors Seq (ParseErrorBundle s e) errors forall (m :: * -> *) a b. Monad m => m a -> m b -> m b >> forall {t :: * -> *}. Foldable t => Text -> t CheckFailure -> IO () printChecks Text fileName Failures checks printErrors :: t (ParseErrorBundle s e) -> IO () printErrors t (ParseErrorBundle s e) errors = forall (t :: * -> *) (m :: * -> *) a b. (Foldable t, Monad m) => (a -> m b) -> t a -> m () mapM_ (String -> IO () putStrLn forall b c a. (b -> c) -> (a -> b) -> a -> c . forall s e. (VisualStream s, TraversableStream s, ShowErrorComponent e) => ParseErrorBundle s e -> String formatError) t (ParseErrorBundle s e) errors printChecks :: Text -> t CheckFailure -> IO () printChecks Text fileName t CheckFailure checks = forall (t :: * -> *) (m :: * -> *) a b. (Foldable t, Monad m) => (a -> m b) -> t a -> m () mapM_ (String -> IO () putStrLn forall b c a. (b -> c) -> (a -> b) -> a -> c . Text -> String Text.unpack forall b c a. (b -> c) -> (a -> b) -> a -> c . Bool -> Text -> CheckFailure -> Text formatCheck Bool color Text fileName) t CheckFailure checks colorizedSeverity :: DLSeverity -> Text.Text colorizedSeverity :: DLSeverity -> Text colorizedSeverity DLSeverity s = case DLSeverity s of DLSeverity DLErrorC -> forall str. (IsString str, Semigroup str) => [str] -> str -> str formatWith [forall str. IsString str => str bold, forall str. IsString str => str red] forall a b. (a -> b) -> a -> b $ DLSeverity -> Text severityText DLSeverity s DLSeverity DLWarningC -> forall str. (IsString str, Semigroup str) => [str] -> str -> str formatWith [forall str. IsString str => str bold, forall str. IsString str => str yellow] forall a b. (a -> b) -> a -> b $ DLSeverity -> Text severityText DLSeverity s DLSeverity DLInfoC -> forall str. (IsString str, Semigroup str) => [str] -> str -> str formatWith [forall str. IsString str => str green] forall a b. (a -> b) -> a -> b $ DLSeverity -> Text severityText DLSeverity s DLSeverity DLStyleC -> forall str. (IsString str, Semigroup str) => [str] -> str -> str formatWith [forall str. IsString str => str cyan] forall a b. (a -> b) -> a -> b $ DLSeverity -> Text severityText DLSeverity s DLSeverity _ -> DLSeverity -> Text severityText DLSeverity s