Download src/Assertica/Verify/CLI.hs from Snapkitty/assertica: direct link, hf CLI and curl.
- Browser
- Download file 6.42 kB
-
https://huggingface.co/Snapkitty/assertica/resolve/main/src/Assertica/Verify/CLI.hs
- Command line
-
hf download hf://Snapkitty/assertica/src/Assertica/Verify/CLI.hs
-
curl -L -o CLI.hs https://huggingface.co/Snapkitty/assertica/resolve/main/src/Assertica/Verify/CLI.hs
6.42 kB
| {-| | |
| Module : Assertica.Verify.CLI | |
| Description : Command-line interface for verification | |
| Copyright : (c) 2026 Ahmad Ali Parr | |
| License : BSL-1.0 | |
| Provides a command-line interface for running verification from the shell. | |
| Usage: | |
| assertica-verify --file FILE [--output FORMAT] [--generate-haskell] [--strict] | |
| assertica-verify --dir DIR [--output FORMAT] [--generate-haskell] [--strict] | |
| Options: | |
| --file FILE Verify single file (required if --dir not given) | |
| --dir DIR Verify all .as files in directory (required if --file not given) | |
| --output FORMAT Output format: json, text, csv (default: text) | |
| --generate-haskell Generate Haskell code for verified modules | |
| --strict Treat warnings as errors | |
| --help Show this help message | |
| Exit codes: | |
| 0 All verifications passed | |
| N N verifications failed | |
| -} | |
| module Assertica.Verify.CLI | |
| ( -- * Main CLI entry point | |
| main | |
| -- * CLI argument parsing | |
| , CLIArgs (..) | |
| , OutputFormat (..) | |
| , parseCLIArgs | |
| , defaultCLIArgs | |
| -- * CLI execution | |
| , runCLI | |
| ) where | |
| import System.Environment (getArgs, getProgName) | |
| import System.Exit (exitFailure, exitSuccess, exitWith, ExitCode(..)) | |
| import System.IO (hPutStrLn, stderr) | |
| import Assertica.Verify.Pipeline (verifyFile, verifyDirectory) | |
| import Assertica.Verify.CI (ciVerify, generateBatchJSON, generateBatchCSV, getExitCode, generateBatchHumanReadable) | |
| import Assertica.Verify.Report (toJSON, toHumanReadable, toCSV, Verdict(..)) | |
| -- ============================================================================ | |
| -- CLI TYPES | |
| -- ============================================================================ | |
| {-| Output format specification. | |
| -} | |
| data OutputFormat | |
| = JSON | |
| | Text | |
| | CSV | |
| deriving (Eq, Show) | |
| {-| Parsed command-line arguments. | |
| -} | |
| data CLIArgs = CLIArgs | |
| { argFile :: Maybe FilePath -- ^ File to verify | |
| , argDir :: Maybe FilePath -- ^ Directory to verify | |
| , argOutputFormat :: OutputFormat -- ^ Output format | |
| , argGenerateHS :: Bool -- ^ Generate Haskell code | |
| , argStrict :: Bool -- ^ Strict mode (warnings as errors) | |
| , argHelp :: Bool -- ^ Show help | |
| } | |
| deriving (Show) | |
| {-| Default CLI arguments. | |
| -} | |
| defaultCLIArgs :: CLIArgs | |
| defaultCLIArgs = CLIArgs | |
| { argFile = Nothing | |
| , argDir = Nothing | |
| , argOutputFormat = Text | |
| , argGenerateHS = False | |
| , argStrict = False | |
| , argHelp = False | |
| } | |
| -- ============================================================================ | |
| -- ARGUMENT PARSING | |
| -- ============================================================================ | |
| {-| Parse command-line arguments. | |
| Deterministic: Same arguments always produce same CLIArgs. | |
| -} | |
| parseCLIArgs :: [String] -> Either String CLIArgs | |
| parseCLIArgs args = go args defaultCLIArgs | |
| where | |
| go :: [String] -> CLIArgs -> Either String CLIArgs | |
| go [] acc = Right acc | |
| go ("--file":path:rest) acc = go rest (acc { argFile = Just path }) | |
| go ("--dir":path:rest) acc = go rest (acc { argDir = Just path }) | |
| go ("--output":"json":rest) acc = go rest (acc { argOutputFormat = JSON }) | |
| go ("--output":"text":rest) acc = go rest (acc { argOutputFormat = Text }) | |
| go ("--output":"csv":rest) acc = go rest (acc { argOutputFormat = CSV }) | |
| go ("--generate-haskell":rest) acc = go rest (acc { argGenerateHS = True }) | |
| go ("--strict":rest) acc = go rest (acc { argStrict = True }) | |
| go ("--help":rest) acc = go rest (acc { argHelp = True }) | |
| go ("-h":rest) acc = go rest (acc { argHelp = True }) | |
| go (unknown:_) _ = Left $ "Unknown argument: " ++ unknown | |
| -- ============================================================================ | |
| -- MAIN CLI ENTRY POINT | |
| -- ============================================================================ | |
| {-| Main CLI entry point. | |
| Parse arguments and dispatch to appropriate action. | |
| -} | |
| main :: IO () | |
| main = do | |
| args <- getArgs | |
| case parseCLIArgs args of | |
| Left err -> do | |
| hPutStrLn stderr $ "Error: " ++ err | |
| exitFailure | |
| Right opts | |
| | argHelp opts -> showHelp | |
| | otherwise -> runCLI opts | |
| {-| Run CLI with parsed arguments. | |
| -} | |
| runCLI :: CLIArgs -> IO () | |
| runCLI opts | |
| | argHelp opts = showHelp | |
| | maybe False (not . null) (argFile opts) = do | |
| let file = case argFile opts of | |
| Just f -> f | |
| Nothing -> error "File not provided" | |
| report <- verifyFile file | |
| case argOutputFormat opts of | |
| JSON -> putStrLn (toJSON report) | |
| Text -> putStrLn (toHumanReadable report) | |
| CSV -> putStrLn (toCSV report) | |
| let exitCode = if vrVerdict report == Reject then ExitFailure 1 else ExitSuccess | |
| exitWith exitCode | |
| | maybe False (not . null) (argDir opts) = do | |
| let dir = case argDir opts of | |
| Just d -> d | |
| Nothing -> error "Directory not provided" | |
| batchReport <- ciVerify dir | |
| case argOutputFormat opts of | |
| JSON -> putStrLn (generateBatchJSON batchReport) | |
| Text -> putStrLn (generateBatchHumanReadable batchReport) | |
| CSV -> putStrLn (generateBatchCSV batchReport) | |
| exitWith (getExitCode batchReport) | |
| | otherwise = do | |
| hPutStrLn stderr "Error: Must provide either --file or --dir" | |
| exitFailure | |
| where | |
| vrVerdict r = Assertica.Verify.Report.vrVerdict r | |
| {-| Show help message. | |
| -} | |
| showHelp :: IO () | |
| showHelp = do | |
| progName <- getProgName | |
| putStrLn $ unlines | |
| [ "Usage: " ++ progName ++ " [options]" | |
| , "" | |
| , "Options:" | |
| , " --file FILE Verify single file" | |
| , " --dir DIR Verify all .as files in directory" | |
| , " --output FORMAT Output format: json, text, csv (default: text)" | |
| , " --generate-haskell Generate Haskell code for verified modules" | |
| , " --strict Treat warnings as errors" | |
| , " --help, -h Show this help message" | |
| , "" | |
| , "Examples:" | |
| , " " ++ progName ++ " --file example.as" | |
| , " " ++ progName ++ " --dir ./proofs --output json" | |
| , " " ++ progName ++ " --dir ./proofs --generate-haskell --output text" | |
| , "" | |
| , "Exit codes:" | |
| , " 0 All verifications passed" | |
| , " N > 0 N verifications failed" | |
| ] | |
| exitSuccess | |