-- | Hadolint GNU Format Output
--
-- See https://www.gnu.org/prep/standards/html_node/Errors.html for reference.

module Hadolint.Formatter.Gnu
  ( printResults,
  )
where


import Data.Text (Text, pack)
import Hadolint.Formatter.Format
import Hadolint.Rule (CheckFailure (..), RuleCode (..))
import Text.Megaparsec (TraversableStream)
import Text.Megaparsec.Error
import Text.Megaparsec.Stream (VisualStream)
import qualified Data.List.NonEmpty as NonEmpty
import qualified Data.Text.IO as TextIO


printResults ::
  (VisualStream s, TraversableStream s, ShowErrorComponent e, Foldable f) =>
  f (Result s e) ->
  IO ()
printResults :: f (Result s e) -> IO ()
printResults = (Result s e -> IO ()) -> f (Result s e) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Result s e -> IO ()
forall s e.
(VisualStream s, TraversableStream s, ShowErrorComponent e) =>
Result s e -> IO ()
printResult


printResult ::
  (VisualStream s, TraversableStream s, ShowErrorComponent e) =>
  Result s e ->
  IO ()
printResult :: Result s e -> IO ()
printResult (Result Text
filename Seq (ParseErrorBundle s e)
errors Failures
checks) =
  Seq (ParseErrorBundle s e) -> IO ()
forall s e (f :: * -> *).
(VisualStream s, TraversableStream s, ShowErrorComponent e,
 Foldable f) =>
f (ParseErrorBundle s e) -> IO ()
printErrors Seq (ParseErrorBundle s e)
errors IO () -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Text -> Failures -> IO ()
forall (f :: * -> *). Foldable f => Text -> f CheckFailure -> IO ()
printChecks Text
filename Failures
checks


printErrors ::
  (VisualStream s, TraversableStream s, ShowErrorComponent e, Foldable f) =>
  f (ParseErrorBundle s e) ->
  IO ()
printErrors :: f (ParseErrorBundle s e) -> IO ()
printErrors = (ParseErrorBundle s e -> IO ())
-> f (ParseErrorBundle s e) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (Text -> IO ()
TextIO.putStrLn (Text -> IO ())
-> (ParseErrorBundle s e -> Text) -> ParseErrorBundle s e -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParseErrorBundle s e -> Text
forall s e.
(VisualStream s, TraversableStream s, ShowErrorComponent e) =>
ParseErrorBundle s e -> Text
formatError)


printChecks :: (Foldable f) => Text -> f CheckFailure -> IO ()
printChecks :: Text -> f CheckFailure -> IO ()
printChecks Text
filename = (CheckFailure -> IO ()) -> f CheckFailure -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (Text -> IO ()
TextIO.putStrLn (Text -> IO ()) -> (CheckFailure -> Text) -> CheckFailure -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> CheckFailure -> Text
formatCheck Text
filename)


formatError ::
  (VisualStream s, TraversableStream s, ShowErrorComponent e) =>
  ParseErrorBundle s e ->
  Text
formatError :: ParseErrorBundle s e -> Text
formatError err :: ParseErrorBundle s e
err@(ParseErrorBundle NonEmpty (ParseError s e)
e PosState s
_) =
  String -> Text
pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$
    String
"hadolint:"
      String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String -> String
stripNewlines
          ( ParseErrorBundle s e -> String
forall s e. TraversableStream s => ParseErrorBundle s e -> String
errorPositionPretty ParseErrorBundle s e
err
              String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
": "
              String -> String -> String
forall a. Semigroup a => a -> a -> a
<> ParseError s e -> String
forall s e.
(VisualStream s, ShowErrorComponent e) =>
ParseError s e -> String
parseErrorTextPretty (NonEmpty (ParseError s e) -> ParseError s e
forall a. NonEmpty a -> a
NonEmpty.head NonEmpty (ParseError s e)
e)
          )


formatCheck :: Text -> CheckFailure -> Text
formatCheck :: Text -> CheckFailure -> Text
formatCheck Text
source (CheckFailure RuleCode
code DLSeverity
severity Text
message Linenumber
line) =
  Text
"hadolint:"
    Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
source
    Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
":"
    Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
pack (Linenumber -> String
forall a. Show a => a -> String
show Linenumber
line)
    Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
": "
    Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> RuleCode -> Text
unRuleCode RuleCode
code
    Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" "
    Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> DLSeverity -> Text
severityText DLSeverity
severity
    Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
": "
    Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
message