on master help sign in
Added support for modes (#101)
ff54497iko
app/Main.hs+10−2
@@ -5,6 +5,7 @@ import Control.Monad.Except
5import Data.Aeson
5import Data.Aeson
6import qualified Data.ByteString.Lazy as BSL
6import qualified Data.ByteString.Lazy as BSL
7import Data.Default
7import Data.Default
8+import Data.Maybe
8import qualified Data.Text.IO as T
9import qualified Data.Text.IO as T
9import qualified Data.Yaml as Yaml
10import qualified Data.Yaml as Yaml
10import FormatHeuristic
11import FormatHeuristic
@@ -39,8 +40,15 @@ main = do
39 FileMode f -> case formatFromFilePath f of
40 FileMode f -> case formatFromFilePath f of
40 Nothing -> \_ -> throwError UnknownOutputFormat
41 Nothing -> \_ -> throwError UnknownOutputFormat
41 Just (writer, f') -> lift . BSL.writeFile f' <=< runPandocIO . writer
42 Just (writer, f') -> lift . BSL.writeFile f' <=< runPandocIO . writer
43+ reportConfig =
44+ ReportConfig
45+ { treeStyle = reportTreeStyle opts
46+ , reportMode = fromMaybe All $ mode opts
47+ }
42− (report, status) = runReport (reportConfig opts) (a, b)
48+ (report, status) = runReport reportConfig (a, b)
49+ case mode opts of
43− either handler pure <=< runExceptT $ write report
50+ Just _ -> either handler pure <=< runExceptT $ write report
51+ Nothing -> pure ()
44 case status of
52 case status of
45 NoBreakingChanges -> exitSuccess
53 NoBreakingChanges -> exitSuccess
46 BreakingChanges -> exitWith $ ExitFailure 1
54 BreakingChanges -> exitWith $ ExitFailure 1
app/OpenAPI/Checker/Options.hs+23−26
@@ -1,6 +1,5 @@
1module OpenAPI.Checker.Options
1module OpenAPI.Checker.Options
2 ( Options (..)
2 ( Options (..)
3− , Mode (..)
4 , OutputMode (..)
3 , OutputMode (..)
5 , optionsParserInfo
4 , optionsParserInfo
6 , execParser
5 , execParser
@@ -14,14 +13,13 @@ import Options.Applicative
14data Options = Options
13data Options = Options
15 { clientFile :: FilePath
14 { clientFile :: FilePath
16 , serverFile :: FilePath
15 , serverFile :: FilePath
17− , mode :: Mode
16+ , -- | 'Nothing' means "don't produce any output"
17+ mode :: Maybe ReportMode
18 , outputMode :: OutputMode
18 , outputMode :: OutputMode
19− , reportConfig :: ReportConfig
19+ , reportTreeStyle :: ReportTreeStyle
20 }
20 }
21 deriving stock (Generic)
21 deriving stock (Generic)
22
22
23−data Mode = Silent | OnlyErrors | All
24−
25data OutputMode = StdoutMode | FileMode FilePath
23data OutputMode = StdoutMode | FileMode FilePath
26
24
27optionsParserInfo :: ParserInfo Options
25optionsParserInfo :: ParserInfo Options
@@ -44,20 +42,20 @@ optionsParser =
44 <> long "server"
42 <> long "server"
45 <> help "The specification that will be used for the server of the API.")
43 <> help "The specification that will be used for the server of the API.")
46 <*> (flag'
44 <*> (flag'
47− Silent
45+ Nothing
48 (long "silent"
46 (long "silent"
49 <> help "Silence all output.")
47 <> help "Silence all output.")
50 <|> flag'
48 <|> flag'
51− OnlyErrors
49+ (Just OnlyErrors)
52 (long "only-errors"
50 (long "only-errors"
53 <> help "Only report incompatibility errors in the output.")
51 <> help "Only report incompatibility errors in the output.")
54 <|> flag'
52 <|> flag'
55− All
53+ (Just All)
56 (long "all"
54 (long "all"
57 <> help
55 <> help
58 "Report both incompatible and compatible changes. \
56 "Report both incompatible and compatible changes. \
59 \Compatible changes will not trigger a failure exit code.")
57 \Compatible changes will not trigger a failure exit code.")
60− <|> pure All)
58+ <|> pure (Just All))
61 <*> ((FileMode
59 <*> ((FileMode
62 <$> strOption
60 <$> strOption
63 (short 'o' <> long "output"
61 (short 'o' <> long "output"
@@ -65,20 +63,19 @@ optionsParser =
65 "The file path where the output should be writtrn. \
63 "The file path where the output should be writtrn. \
66 \Leave blank to output result to stdout."))
64 \Leave blank to output result to stdout."))
67 <|> pure StdoutMode)
65 <|> pure StdoutMode)
68− <*> (ReportConfig
69− <$> (flag'
66+ <*> (flag'
70− FoldingBlockquotesTreeStyle
67+ FoldingBlockquotesTreeStyle
71− (long "folding-block-quotes-style"
68+ (long "folding-block-quotes-style"
72− <> help
69+ <> help
73− "The report tree is structured using \
70+ "The report tree is structured using \
74− \summary/detail HTML elements and indented using \
71+ \summary/detail HTML elements and indented using \
75− \block quotes. This style renders well on GitHub.\
72+ \block quotes. This style renders well on GitHub.\
76− \Intended for HTML output format. Markdown has rendering \
73+ \Intended for HTML output format. Markdown has rendering \
77− \bugs on GitHub.")
74+ \bugs on GitHub.")
78− <|> flag'
75+ <|> flag'
79− HeadersTreeStyle
76+ HeadersTreeStyle
80− (long "header-style"
77+ (long "header-style"
81− <> help
78+ <> help
82− "The report tree is structured using \
79+ "The report tree is structured using \
83− \increasing levels of headers.")
80+ \increasing levels of headers.")
84− <|> pure HeadersTreeStyle))
81+ <|> pure HeadersTreeStyle)
src/OpenAPI/Checker/Report.hs+28−8
@@ -5,6 +5,7 @@ module OpenAPI.Checker.Report
5 , Pandoc
5 , Pandoc
6 , ReportConfig (..)
6 , ReportConfig (..)
7 , ReportTreeStyle (..)
7 , ReportTreeStyle (..)
8+ , ReportMode (..)
8 )
9 )
9where
10where
10
11
@@ -56,18 +57,26 @@ data ReportStatus
56 -- there actually are any breaking changes.
57 -- there actually are any breaking changes.
57 OnlyUnsupportedChanges
58 OnlyUnsupportedChanges
58
59
60+data ReportMode = OnlyErrors | All
61+ deriving stock (Eq)
62+
59data ReportConfig = ReportConfig
63data ReportConfig = ReportConfig
60 { treeStyle :: ReportTreeStyle
64 { treeStyle :: ReportTreeStyle
65+ , reportMode :: ReportMode
61 }
66 }
62
67
63instance Default ReportConfig where
68instance Default ReportConfig where
64 def =
69 def =
65 ReportConfig
70 ReportConfig
66 { treeStyle = HeadersTreeStyle
71 { treeStyle = HeadersTreeStyle
72+ , reportMode = All
67 }
73 }
68
74
69data ReportTreeStyle = HeadersTreeStyle | FoldingBlockquotesTreeStyle
75data ReportTreeStyle = HeadersTreeStyle | FoldingBlockquotesTreeStyle
70
76
77+twoRowTable :: [(Inlines, Inlines)] -> Blocks
78+twoRowTable x = simpleTable (para . fst <$> x) [para . snd <$> x]
79+
71generateReport :: ReportConfig -> ReportInput -> (Pandoc, ReportStatus)
80generateReport :: ReportConfig -> ReportInput -> (Pandoc, ReportStatus)
72generateReport cfg inp =
81generateReport cfg inp =
73 let partitionUnsupported = P.partition (\(AnIssue _ i) -> issueIsUnsupported i)
82 let partitionUnsupported = P.partition (\(AnIssue _ i) -> issueIsUnsupported i)
@@ -77,23 +86,34 @@ generateReport cfg inp =
77 breakingChangesPresent = not $ P.null breaking
86 breakingChangesPresent = not $ P.null breaking
78 nonBreakingChangesPresent = not $ P.null nonBreaking
87 nonBreakingChangesPresent = not $ P.null nonBreaking
79 unsupportedChangesPresent = not $ P.null unsupported
88 unsupportedChangesPresent = not $ P.null unsupported
89+ nonBreakingChangesShown = case reportMode cfg of
90+ All -> True
91+ OnlyErrors -> False
80 builder = buildReport cfg
92 builder = buildReport cfg
81 report =
93 report =
82 doc $
94 doc $
83 header 1 "Summary"
95 header 1 "Summary"
84− <> simpleTable
96+ <> twoRowTable
85− (para
86− <$> [ refOpt breakingChangesPresent breakingChangesId "⚠️ Breaking changes"
97+ ([ ( refOpt breakingChangesPresent breakingChangesId "⚠️ Breaking changes"
98+ , show' $ P.size breaking
99+ )
100+ ]
101+ ++ when'
102+ nonBreakingChangesShown
87− , refOpt nonBreakingChangesPresent nonBreakingChangesId "🙆 Non-breaking changes"
103+ [ ( refOpt nonBreakingChangesPresent nonBreakingChangesId "🙆 Non-breaking changes"
104+ , show' $ P.size nonBreaking
105+ )
106+ ]
88− , refOpt unsupportedChangesPresent unsupportedChangesId "🤷 Unsupported feature changes"
107+ ++ [ ( refOpt unsupportedChangesPresent unsupportedChangesId "🤷 Unsupported feature changes"
89− ])
90− [para . show' <$> [P.size breaking, P.size nonBreaking, P.size unsupported]]
108+ , show' $ P.size unsupported
109+ )
110+ ])
91 <> when'
111 <> when'
92 breakingChangesPresent
112 breakingChangesPresent
93 (header 1 (anchor breakingChangesId <> "⚠️ Breaking changes")
113 (header 1 (anchor breakingChangesId <> "⚠️ Breaking changes")
94 <> builder (showErrs breaking))
114 <> builder (showErrs breaking))
95 <> when'
115 <> when'
96− nonBreakingChangesPresent
116+ (nonBreakingChangesPresent && nonBreakingChangesShown)
97 (header 1 (anchor nonBreakingChangesId <> "🙆 Non-breaking changes")
117 (header 1 (anchor nonBreakingChangesId <> "🙆 Non-breaking changes")
98 <> builder (showErrs nonBreaking))
118 <> builder (showErrs nonBreaking))
99 <> when'
119 <> when'