Add wiki links to output, and a -W controlling it. (Fixes #920)

This commit is contained in:
Vidar Holen 2018-10-10 21:27:52 -07:00
parent 79319558a5
commit e0e46e979a
5 changed files with 89 additions and 14 deletions

View File

@ -1,6 +1,7 @@
## ??? ## ???
### Added ### Added
- Command line option --severity/-S for filtering by minimum severity - Command line option --severity/-S for filtering by minimum severity
- Command line option --wiki-link-count/-W for showing wiki links
- SC2236/SC2237: Suggest -n/-z instead of ! -z/-n - SC2236/SC2237: Suggest -n/-z instead of ! -z/-n
- SC2238: Warn when redirecting to a known command name, e.g. ls > rm - SC2238: Warn when redirecting to a known command name, e.g. ls > rm
### Changed ### Changed

View File

@ -71,6 +71,11 @@ not warn at all, as `ksh` supports decimals in arithmetic contexts.
: Print version information and exit. : Print version information and exit.
**-W** *NUM*,\ **--wiki-link-count=NUM**
: For TTY output, show *NUM* wiki links to more information about mentioned
warnings. Set to 0 to disable them entirely.
**-x**,\ **--external-sources** **-x**,\ **--external-sources**
: Follow 'source' statements even when the file is not specified as input. : Follow 'source' statements even when the file is not specified as input.

View File

@ -100,6 +100,9 @@ options = [
"Minimum severity of errors to consider (error, warning, info, style)", "Minimum severity of errors to consider (error, warning, info, style)",
Option "V" ["version"] Option "V" ["version"]
(NoArg $ Flag "version" "true") "Print version information", (NoArg $ Flag "version" "true") "Print version information",
Option "W" ["wiki-link-count"]
(ReqArg (Flag "wiki-link-count") "NUM")
"The number of wiki links to show, when applicable.",
Option "x" ["external-sources"] Option "x" ["external-sources"]
(NoArg $ Flag "externals" "true") "Allow 'source' outside of FILES" (NoArg $ Flag "externals" "true") "Allow 'source' outside of FILES"
] ]
@ -296,6 +299,14 @@ parseOption flag options =
} }
} }
Flag "wiki-link-count" countString -> do
count <- parseNum countString
return options {
formatterOptions = (formatterOptions options) {
foWikiLinkCount = count
}
}
_ -> return options _ -> return options
where where
die s = do die s = do
@ -304,7 +315,7 @@ parseOption flag options =
parseNum ('S':'C':str) = parseNum str parseNum ('S':'C':str) = parseNum str
parseNum num = do parseNum num = do
unless (all isDigit num) $ do unless (all isDigit num) $ do
printErr $ "Bad exclusion: " ++ num printErr $ "Invalid number: " ++ num
throwError SyntaxFailure throwError SyntaxFailure
return (Prelude.read num :: Integer) return (Prelude.read num :: Integer)

View File

@ -22,17 +22,26 @@ module ShellCheck.Formatter.TTY (format) where
import ShellCheck.Interface import ShellCheck.Interface
import ShellCheck.Formatter.Format import ShellCheck.Formatter.Format
import Control.Monad
import Data.IORef
import Data.List import Data.List
import GHC.Exts import GHC.Exts
import System.Info
import System.IO import System.IO
import System.Info
wikiLink = "https://www.shellcheck.net/wiki/"
-- An arbitrary Ord thing to order warnings
type Ranking = (Char, Severity, Integer)
format :: FormatterOptions -> IO Formatter format :: FormatterOptions -> IO Formatter
format options = return Formatter { format options = do
topErrorRef <- newIORef []
return Formatter {
header = return (), header = return (),
footer = return (), footer = outputWiki topErrorRef,
onFailure = outputError options, onFailure = outputError options,
onResult = outputResult options onResult = outputResult options topErrorRef
} }
colorForLevel level = colorForLevel level =
@ -45,13 +54,60 @@ colorForLevel level =
"source" -> 0 -- none "source" -> 0 -- none
_ -> 0 -- none _ -> 0 -- none
rankError :: PositionedComment -> Ranking
rankError err = (ranking, cSeverity $ pcComment err, cCode $ pcComment err)
where
ranking =
if cCode (pcComment err) `elem` uninteresting
then 'Z'
else 'A'
-- A list of the most generic, least directly helpful
-- error codes to downrank.
uninteresting = [
1009, -- Mentioned parser error was..
1019, -- Expected this to be an argument
1036, -- ( is invalid here
1047, -- Expected 'fi'
1062, -- Expected 'done'
1070, -- Parsing stopped here (generic)
1072, -- Missing/unexpected ..
1073, -- Couldn't parse this ..
1088, -- Parsing stopped here (paren)
1089 -- Parsing stopped here (keyword)
]
appendComments errRef comments max = do
previous <- readIORef errRef
let current = map (\x -> (rankError x, cCode $ pcComment x, cMessage $ pcComment x)) comments
writeIORef errRef . take max . nubBy equal . sort $ previous ++ current
where
fst3 (x,_,_) = x
equal x y = fst3 x == fst3 y
outputWiki :: IORef [(Ranking, Integer, String)] -> IO ()
outputWiki errRef = do
issues <- readIORef errRef
unless (null issues) $ do
putStrLn "For more information:"
mapM_ showErr issues
where
showErr (_, code, msg) =
putStrLn $ " " ++ wikiLink ++ "SC" ++ show code ++ " -- " ++ shorten msg
limit = 40
shorten msg =
if length msg < limit
then msg
else (take (limit-3) msg) ++ "..."
outputError options file error = do outputError options file error = do
color <- getColorFunc $ foColorOption options color <- getColorFunc $ foColorOption options
hPutStrLn stderr $ color "error" $ file ++ ": " ++ error hPutStrLn stderr $ color "error" $ file ++ ": " ++ error
outputResult options result sys = do outputResult options ref result sys = do
color <- getColorFunc $ foColorOption options color <- getColorFunc $ foColorOption options
let comments = crComments result let comments = crComments result
appendComments ref comments (fromIntegral $ foWikiLinkCount options)
let fileGroups = groupWith sourceFile comments let fileGroups = groupWith sourceFile comments
mapM_ (outputForFile color sys) fileGroups mapM_ (outputForFile color sys) fileGroups
@ -87,7 +143,7 @@ cuteIndent comment =
in in
if sameLine && delta > 2 && delta < 32 then arrow delta else "^--" if sameLine && delta > 2 && delta < 32 then arrow delta else "^--"
code code = "SC" ++ show code code num = "SC" ++ show num
getColorFunc colorOption = do getColorFunc colorOption = do
term <- hIsTerminalDevice stdout term <- hIsTerminalDevice stdout

View File

@ -26,7 +26,7 @@ module ShellCheck.Interface
, ParseResult(prComments, prTokenPositions, prRoot) , ParseResult(prComments, prTokenPositions, prRoot)
, AnalysisSpec(asScript, asShellType, asExecutionMode, asCheckSourced) , AnalysisSpec(asScript, asShellType, asExecutionMode, asCheckSourced)
, AnalysisResult(arComments) , AnalysisResult(arComments)
, FormatterOptions(foColorOption) , FormatterOptions(foColorOption, foWikiLinkCount)
, Shell(Ksh, Sh, Bash, Dash) , Shell(Ksh, Sh, Bash, Dash)
, ExecutionMode(Executed, Sourced) , ExecutionMode(Executed, Sourced)
, ErrorMessage , ErrorMessage
@ -145,12 +145,14 @@ newAnalysisResult = AnalysisResult {
} }
-- Formatter options -- Formatter options
newtype FormatterOptions = FormatterOptions { data FormatterOptions = FormatterOptions {
foColorOption :: ColorOption foColorOption :: ColorOption,
foWikiLinkCount :: Integer
} }
newFormatterOptions = FormatterOptions { newFormatterOptions = FormatterOptions {
foColorOption = ColorAuto foColorOption = ColorAuto,
foWikiLinkCount = 3
} }