@@ -4,20 +4,14 @@ import Prelude
44
55import Data.Array as Array
66import Data.Either (Either(..))
7−import Data.Enum (fromEnum)
87import Data.Foldable (for_)
98import Data.Maybe (Maybe(..))
109import Data.Newtype (unwrap)
1110import Data.String.CodeUnits as String
12−import Data.Tuple.Nested ((/\))
1311import Effect (Effect)
1412import Effect.Console (log)
1513import Node.FS.Simple as FS
1614import Node.CLI as Process
17−import Options.Applicative (Parser, argument, execParserPure, fullDesc, header, help, helper, info, long, many, metavar, progDesc, str, switch, (<**>))
18−import Options.Applicative.Builder (defaultPrefs)
19−import Options.Applicative.Types (CompletionResult(..), ParserFailure(ParserFailure), ParserResult(..))
20−import Options.Applicative.Help.Types (ParserHelp(ParserHelp), renderHelp)
2115import Purslint.Config (defaultConfig, filterRules, parseConfig)
2216import Purslint.Fix (applyAllFixes)
2317import Purslint.Rule (Rule)
@@ -105,13 +99,6 @@ import Purslint.Rules.RedundantParens (redundantParensRule)
10599import Purslint.Runner (runRules)
106100import Purslint.Types (LintResult(..), LintWarning(..), Severity(..), SourceCode(..), Suggestion(..))
107101
108−type CliOptions =
109− { fix :: Boolean
110− , listRules :: Boolean
111− , initConfig :: Boolean
112− , paths :: Array String
113− }
114−
115102-- | All available rules (81 total)
116103allRules :: Array Rule
117104allRules =
@@ -350,70 +337,38 @@ initConfig = do
350337 FS.writeTextFile ".purslintrc" sampleConfig
351338 log "Created .purslintrc"
352339
353−parseFlags :: Array String -> Effect (Maybe CliOptions)
354−parseFlags args = case parseFlags' (Array.drop 2 args) of
355− Success cli -> pure (Just cli)
356− Failure (ParserFailure pf) -> case pf programName of
357− ph@(ParserHelp _) /\ exitCode /\ i /\ _unit -> do
358− log $ renderHelp i ph
359− Process.exit (fromEnum exitCode)
360− pure Nothing
361− CompletionInvoked (CompletionResult { execCompletion }) -> do
362− executedCompletion <- execCompletion programName
363− log executedCompletion
364− Process.exit 0
365− pure Nothing
366− where
367− programName = "purslint"
368−
369−parseFlags' :: Array String -> ParserResult CliOptions
370−parseFlags' = execParserPure defaultPrefs opts
371− where
372− opts =
373− info (flagsParser <**> helper) $
374− fullDesc
375− <> progDesc "Lint PureScript source files"
376− <> header "purslint - a linter for PureScript"
377−
378−flagsParser :: Parser CliOptions
379−flagsParser = ado
380− fix <- switch $ long "fix" <> help "Auto-fix issues (where possible)"
381− listRules <- switch $ long "list" <> help "List all available rules"
382− initConfig <- switch $ long "init" <> help "Create a sample .purslintrc"
383− pathsList <- many $ argument str $ metavar "PATH..."
384− let paths = Array.fromFoldable pathsList
385− in { fix, listRules, initConfig, paths }
386−
387340main :: Effect Unit
388341main = do
389342 args <- Process.argv
390− maybeCli <- parseFlags args
391− case maybeCli of
392− Nothing -> pure unit
393− Just cli ->
394− if cli.listRules then
395− listRules
396− else if cli.initConfig then
397− initConfig
398− else if Array.null cli.paths then
399− showUsage
343+ -- args[0] is node, args[1] is the script, args[2..] are the actual arguments
344+ let userArgs = Array.drop 1 args
345+ case userArgs of
346+ [] -> showUsage
347+ ["--help"] -> showUsage
348+ ["-h"] -> showUsage
349+ ["--list"] -> listRules
350+ ["--init"] -> initConfig
351+ _ -> do
352+ -- Check for --fix flag
353+ let hasFix = Array.elem "--fix" userArgs
354+ let paths = Array.filter (\a -> a /= "--fix") userArgs
355+
356+ -- Load config and filter rules
357+ config <- loadConfig
358+ let enabledRules = filterRules allRules config
359+
360+ if hasFix then do
361+ -- Fix mode
362+ _ <- Array.foldM (\acc path -> do
363+ count <- fixPath enabledRules path
364+ pure (acc + count)) 0 paths
365+ pure unit
400366 else do
401− -- Load config and filter rules
402− config <- loadConfig
403− let enabledRules = filterRules allRules config
404−
405− if cli.fix then do
406− -- Fix mode
407− _ <- Array.foldM (\acc path -> do
408− count <- fixPath enabledRules path
409− pure (acc + count)) 0 cli.paths
410− pure unit
411− else do
412− -- Lint mode
413− totalWarnings <- Array.foldM (\acc path -> do
414− count <- lintPathWithConfig enabledRules path
415− pure (acc + count)) 0 cli.paths
416− when (totalWarnings > 0) do
417− log ""
418− log $ "Total: " <> show totalWarnings <> " warning" <> if totalWarnings == 1 then "" else "s"
419− Process.exit 1
367+ -- Lint mode
368+ totalWarnings <- Array.foldM (\acc path -> do
369+ count <- lintPathWithConfig enabledRules path
370+ pure (acc + count)) 0 paths
371+ when (totalWarnings > 0) do
372+ log ""
373+ log $ "Total: " <> show totalWarnings <> " warning" <> if totalWarnings == 1 then "" else "s"
374+ Process.exit 1