unused/app/Main.hs
2018-03-18 22:34:45 -04:00

116 lines
3.8 KiB
Haskell

module Main where
import App (runProgram)
import Common
import qualified Data.Maybe as M
import Options.Applicative
import Types (Options(Options))
import Unused.CLI (SearchRunner(..))
import Unused.Grouping (CurrentGrouping(..))
import Unused.TermSearch (SearchBackend(..))
import Unused.Types (RemovalLikelihood(..))
import Unused.Util (stringToInt)
main :: IO ()
main = runProgram =<< parseCLI
parseCLI :: IO Options
parseCLI = execParser (withInfo parseOptions pHeader pDescription pFooter)
where
pHeader = "Unused: Analyze potentially unused code"
pDescription =
"Unused allows a developer to leverage an existing tags file \
\(located at .git/tags, tags, or tmp/tags) to identify tokens \
\in a codebase that are unused."
pFooter = "CLI USAGE: $ unused"
withInfo :: Parser a -> String -> String -> String -> ParserInfo a
withInfo opts h d f = info (helper <*> opts) $ header h <> progDesc d <> footer f
parseOptions :: Parser Options
parseOptions =
Options <$> parseSearchRunner <*> parseDisplaySingleOccurrenceMatches <*> parseLikelihoods <*>
parseAllLikelihoods <*>
parseIgnorePaths <*>
parseGroupings <*>
parseWithoutCache <*>
parseFromStdIn <*>
parseCommitCount <*>
parseSearchBackend
parseSearchRunner :: Parser SearchRunner
parseSearchRunner =
flag SearchWithProgress SearchWithoutProgress $
short 'P' <> long "no-progress" <> help "Don't display progress during analysis"
parseDisplaySingleOccurrenceMatches :: Parser Bool
parseDisplaySingleOccurrenceMatches =
switch $ short 's' <> long "single-occurrence" <> help "Display only single occurrences"
parseLikelihoods :: Parser [RemovalLikelihood]
parseLikelihoods = many (parseLikelihood <$> parseLikelihoodOption)
parseLikelihood :: String -> RemovalLikelihood
parseLikelihood "high" = High
parseLikelihood "medium" = Medium
parseLikelihood "low" = Low
parseLikelihood _ = Unknown
parseLikelihoodOption :: Parser String
parseLikelihoodOption =
strOption $
short 'l' <> long "likelihood" <>
help "[Allows multiple] [Allowed: high, medium, low] Display results based on likelihood"
parseAllLikelihoods :: Parser Bool
parseAllLikelihoods = switch $ short 'a' <> long "all-likelihoods" <> help "Display all likelihoods"
parseIgnorePaths :: Parser [String]
parseIgnorePaths =
many $
strOption $
long "ignore" <> metavar "PATH" <> help "[Allows multiple] Ignore paths that contain PATH"
parseGroupings :: Parser CurrentGrouping
parseGroupings = M.fromMaybe GroupByDirectory <$> maybeGroup
where
maybeGroup = optional $ parseGrouping <$> parseGroupingOption
parseGrouping :: String -> CurrentGrouping
parseGrouping "directory" = GroupByDirectory
parseGrouping "term" = GroupByTerm
parseGrouping "file" = GroupByFile
parseGrouping "none" = NoGroup
parseGrouping _ = NoGroup
parseGroupingOption :: Parser String
parseGroupingOption =
strOption $
short 'g' <> long "group-by" <> help "[Allowed: directory, term, file, none] Group results"
parseWithoutCache :: Parser Bool
parseWithoutCache =
switch $ short 'C' <> long "no-cache" <> help "Ignore cache when performing calculations"
parseFromStdIn :: Parser Bool
parseFromStdIn = switch $ long "stdin" <> help "Read tags from STDIN"
parseCommitCount :: Parser (Maybe Int)
parseCommitCount = (stringToInt =<<) <$> commitParser
where
commitParser =
optional $
strOption $ long "commits" <> help "Number of recent commit SHAs to display per token"
parseSearchBackend :: Parser SearchBackend
parseSearchBackend = M.fromMaybe Ag <$> maybeBackend
where
maybeBackend = optional $ parseBackend <$> parseBackendOption
parseBackendOption =
strOption $ long "search" <> help "[Allowed: ag, rg] Select searching backend"
parseBackend :: String -> SearchBackend
parseBackend "ag" = Ag
parseBackend "rg" = Rg
parseBackend _ = Ag