Allow to customize the TODO marker string

This commit is contained in:
Alexander Kobjolke 2022-03-07 12:48:33 +01:00
parent 461f34a100
commit 4514d0f120
5 changed files with 61 additions and 28 deletions

View file

@ -30,7 +30,7 @@ import Annotator.Rule
import Annotator.Annotation
version :: Vsn.Version
version = Vsn.makeVersion [0,0,3,0]
version = Vsn.makeVersion [0,0,4,0]
type App a = ReaderT Options IO a
@ -54,6 +54,7 @@ data Options = Options
, onlyNewest :: Bool
, annotationFiles :: [FilePath]
, autoAnnotations :: [Annotation]
, todoMarker :: String
}
deriving (Show, Eq)
@ -67,6 +68,7 @@ defaultOptions = Options
, onlyNewest = True
, annotationFiles = []
, autoAnnotations = []
, todoMarker = "TODO"
}
options :: [OptDescr (Options -> Options)]
@ -90,11 +92,22 @@ options =
(NoArg (\opts -> opts { onlyNewest = False}))
"handle all defects not just Newest"
, Option ['C'] ["context"]
(OptArg ((\f opts -> opts { contextLines = fromMaybe 0 $ readMaybe f }) . fromMaybe "0") "NUM")
(OptArg (\f opts -> opts { contextLines = fromMaybe 0 (f >>= readMaybe) }) "NUM")
"specify how much context should be shown around a violation"
, Option ['t'] ["todo-marker"]
(OptArg (\f opts -> opts { todoMarker = fromMaybe "TODO" f }) "STRING")
"override the default TODO marker with a custom string"
, Option ['A'] ["annotations"]
(ReqArg (\f opts -> opts { annotationFiles = (nub $ annotationFiles opts ++ [f]) }) "FILE")
"load automatic annotation rules"
(unlines [ "load automatic annotation rules"
, " some examples:"
, " " <> show (Intentional (Rule "rule_1") "some reason")
, " " <> show (FalsePositive (Rule "rule_1") "some reason")
, " " <> show (ToDo (Rule "rule_1"))
, " # a comment"
, " -- another comment"
]
)
]
readMaybe :: (Read a) => String -> Maybe a
@ -230,6 +243,7 @@ handleViolations violations = do
opts <- ask
let fname = filename $ NE.head violations
fname' = fname <> ".fix"
todo = todoMarker opts
header' = "Processing " <> (show $ NE.length violations) <> " violation(s) in file " <> fname
header = unlines
[ header'
@ -252,7 +266,7 @@ handleViolations violations = do
annotations <- (catMaybes . NE.toList) <$> mapM (handleViolation content) violations
let annotatedLines = sortBy (comparing fst) $ fmap annotationToLine annotations
let annotatedLines = sortBy (comparing fst) $ fmap (annotationToLine todo) annotations
newContent = unlines . map snd $ mergeLines annotatedLines numberedContent
liftIO $ writeFile fname' newContent
@ -261,10 +275,14 @@ handleViolations violations = do
else do
verbose Low $ "skipping non-existent file " <> fname
where
annotationToLine :: AnnotatedViolation -> (Int, String)
annotationToLine (AnnotatedViolation Violation{..} a indent) =
(line, indent ++ showAnnotation a description)
annotationToLine :: String -> AnnotatedViolation -> (Int, String)
annotationToLine todo (AnnotatedViolation Violation{..} a indent) =
(line, indent ++ showAnnotation todo a description)
showAnnotation :: String -> Annotation -> String -> String
showAnnotation _ (Intentional (Rule rule) reason) _ = mconcat ["// ", "coverity[", rule, "_violation", "] ", reason]
showAnnotation _ (FalsePositive (Rule rule) reason) _ = mconcat ["// ", "coverity[", rule, "_violation", " : FALSE", "] ", reason]
showAnnotation todo (ToDo (Rule rule)) description = "// " <> todo <> " " <> rule <> ": " <> description
data UserChoice = Abort
| Annotate Annotation

View file

@ -1,24 +1,23 @@
{-# LANGUAGE LambdaCase #-}
module Annotator.Annotation (Annotation(..), showAnnotation, fromFile) where
module Annotator.Annotation (Annotation(..), fromFile) where
import Data.Char (isSpace)
import Annotator.Rule
import Data.Monoid
data Annotation = Intentional !Rule !String
| FalsePositive !Rule !String
| ToDo !Rule
deriving (Show, Read, Eq)
showAnnotation :: Annotation -> String -> String
showAnnotation (Intentional (Rule rule) reason) _ = mconcat ["// ", "coverity[", rule, "_violation", "] ", reason]
showAnnotation (FalsePositive (Rule rule) reason) _ = mconcat ["// ", "coverity[", rule, "_violation", " : FALSE", "] ", reason]
showAnnotation (ToDo (Rule rule)) description = "// FIXME violation " <> rule <> ": " <> description
fromFile :: FilePath -> IO [Either String Annotation]
fromFile fn = fmap safeRead . removeBoring . lines <$> readFile fn
where
removeBoring :: [String] -> [String]
removeBoring = filter (const True)
removeBoring = filter (not . isBoring)
isBoring x = isComment x || isEmpty x
isComment x = take 1 x == "#" || take 2 x == "--"
isEmpty = null . dropWhile isSpace
safeRead :: String -> Either String Annotation
safeRead s = case reads s of

View file

@ -3,8 +3,4 @@
module Annotator.Rule where
newtype Rule = Rule String
deriving (Eq, Read)
instance Show Rule where
show :: Rule -> String
show (Rule r) = r
deriving (Eq, Read, Show)