2018-04-12 05:53:38 +02:00
|
|
|
module Nix.Options where
|
|
|
|
|
|
|
|
import Control.Arrow (second)
|
2018-04-18 02:25:59 +02:00
|
|
|
import Data.Char (isDigit)
|
|
|
|
import Data.Maybe (fromMaybe)
|
2018-04-12 05:53:38 +02:00
|
|
|
import Data.Text (Text)
|
|
|
|
import qualified Data.Text as Text
|
|
|
|
import Options.Applicative hiding (ParserResult(..))
|
|
|
|
import Text.PrettyPrint.ANSI.Leijen hiding ((<$>))
|
|
|
|
|
|
|
|
data Options = Options
|
2018-04-18 02:25:59 +02:00
|
|
|
{ verbose :: Verbosity
|
2018-04-19 08:20:58 +02:00
|
|
|
, tracing :: Bool
|
2018-04-21 07:36:40 +02:00
|
|
|
, reduce :: Maybe FilePath
|
|
|
|
, reduceSets :: Bool
|
|
|
|
, reduceLists :: Bool
|
2018-04-12 06:31:48 +02:00
|
|
|
, parse :: Bool
|
|
|
|
, parseOnly :: Bool
|
|
|
|
, findFile :: Maybe FilePath
|
|
|
|
, strict :: Bool
|
2018-04-18 03:12:19 +02:00
|
|
|
, normalize :: Bool
|
2018-04-12 05:53:38 +02:00
|
|
|
, evaluate :: Bool
|
2018-04-17 23:24:52 +02:00
|
|
|
, json :: Bool
|
|
|
|
, xml :: Bool
|
2018-04-12 06:31:48 +02:00
|
|
|
, attr :: Maybe Text
|
2018-04-12 07:02:31 +02:00
|
|
|
, include :: [FilePath]
|
2018-04-12 05:53:38 +02:00
|
|
|
, check :: Bool
|
|
|
|
, readFrom :: Maybe FilePath
|
|
|
|
, cache :: Bool
|
2018-04-13 01:46:34 +02:00
|
|
|
, repl :: Bool
|
2018-04-12 05:53:38 +02:00
|
|
|
, ignoreErrors :: Bool
|
|
|
|
, expression :: Maybe Text
|
|
|
|
, arg :: [(Text, Text)]
|
|
|
|
, argstr :: [(Text, Text)]
|
|
|
|
, fromFile :: Maybe FilePath
|
|
|
|
, filePaths :: [FilePath]
|
|
|
|
}
|
2018-04-13 09:34:49 +02:00
|
|
|
deriving Show
|
2018-04-12 05:53:38 +02:00
|
|
|
|
2018-04-18 02:25:59 +02:00
|
|
|
defaultOptions :: Options
|
|
|
|
defaultOptions = Options
|
|
|
|
{ verbose = ErrorsOnly
|
2018-04-19 08:20:58 +02:00
|
|
|
, tracing = False
|
2018-04-21 07:36:40 +02:00
|
|
|
, reduce = Nothing
|
|
|
|
, reduceSets = False
|
|
|
|
, reduceLists = False
|
2018-04-18 02:25:59 +02:00
|
|
|
, parse = False
|
|
|
|
, parseOnly = False
|
|
|
|
, findFile = Nothing
|
|
|
|
, strict = False
|
2018-04-18 03:12:19 +02:00
|
|
|
, normalize = False
|
2018-04-18 02:25:59 +02:00
|
|
|
, evaluate = False
|
|
|
|
, json = False
|
|
|
|
, xml = False
|
|
|
|
, attr = Nothing
|
|
|
|
, include = []
|
|
|
|
, check = False
|
|
|
|
, readFrom = Nothing
|
|
|
|
, cache = False
|
|
|
|
, repl = False
|
|
|
|
, ignoreErrors = False
|
|
|
|
, expression = Nothing
|
|
|
|
, arg = []
|
|
|
|
, argstr = []
|
|
|
|
, fromFile = Nothing
|
|
|
|
, filePaths = []
|
|
|
|
}
|
|
|
|
|
|
|
|
data Verbosity
|
|
|
|
= ErrorsOnly
|
|
|
|
| Informational
|
|
|
|
| Talkative
|
|
|
|
| Chatty
|
|
|
|
| Debug
|
|
|
|
| Vomit
|
|
|
|
deriving (Eq, Ord, Enum, Bounded, Show)
|
|
|
|
|
|
|
|
decodeVerbosity :: Int -> Verbosity
|
|
|
|
decodeVerbosity 0 = ErrorsOnly
|
|
|
|
decodeVerbosity 1 = Informational
|
|
|
|
decodeVerbosity 2 = Talkative
|
|
|
|
decodeVerbosity 3 = Chatty
|
|
|
|
decodeVerbosity 4 = Debug
|
|
|
|
decodeVerbosity _ = Vomit
|
|
|
|
|
2018-04-12 05:53:38 +02:00
|
|
|
argPair :: Mod OptionFields (Text, Text) -> Parser (Text, Text)
|
|
|
|
argPair = option $ str >>= \s ->
|
|
|
|
case Text.findIndex (== '=') s of
|
|
|
|
Nothing -> errorWithoutStackTrace
|
|
|
|
"Format of --arg/--argstr in hnix is: name=expr"
|
|
|
|
Just i -> return $ second Text.tail $ Text.splitAt i s
|
|
|
|
|
|
|
|
nixOptions :: Parser Options
|
|
|
|
nixOptions = Options
|
2018-04-18 02:25:59 +02:00
|
|
|
<$> (fromMaybe ErrorsOnly <$>
|
|
|
|
optional
|
|
|
|
(option (do a <- str
|
|
|
|
if all isDigit a
|
|
|
|
then pure $ decodeVerbosity (read a)
|
|
|
|
else fail "Argument to -v/--verbose must be a number")
|
|
|
|
( short 'v'
|
|
|
|
<> long "verbose"
|
|
|
|
<> help "Verbose output")))
|
2018-04-19 08:20:58 +02:00
|
|
|
<*> switch
|
|
|
|
( long "trace"
|
2018-04-21 07:36:40 +02:00
|
|
|
<> help "Enable tracing code (even more can be seen if built with --flags=tracing)")
|
|
|
|
<*> optional (strOption
|
|
|
|
( long "reduce"
|
|
|
|
<> help "When done evaluating, output the evaluated part of the expression to FILE"))
|
|
|
|
<*> switch
|
|
|
|
( long "reduce-sets"
|
|
|
|
<> help "Reduce set members that aren't used; breaks if hasAttr is used")
|
|
|
|
<*> switch
|
|
|
|
( long "reduce-lists"
|
|
|
|
<> help "Reduce list members that aren't used; breaks if elemAt is used")
|
2018-04-12 06:31:48 +02:00
|
|
|
<*> switch
|
|
|
|
( long "parse"
|
|
|
|
<> help "Whether to parse the file (also the default right now)")
|
|
|
|
<*> switch
|
|
|
|
( long "parse-only"
|
|
|
|
<> help "Whether to parse only, no pretty printing or checking")
|
|
|
|
<*> optional (strOption
|
|
|
|
( long "find-file"
|
|
|
|
<> help "Look up the given files in Nix's search path"))
|
|
|
|
<*> switch
|
|
|
|
( long "strict"
|
|
|
|
<> help "When used with --eval, recursively evaluate list elements and attributes")
|
2018-04-18 03:12:19 +02:00
|
|
|
<*> switch
|
|
|
|
( long "force"
|
|
|
|
<> help "Whether to force the results of evaluation to normal form")
|
2018-04-12 05:53:38 +02:00
|
|
|
<*> switch
|
|
|
|
( long "eval"
|
|
|
|
<> help "Whether to evaluate, or just pretty-print")
|
2018-04-17 23:24:52 +02:00
|
|
|
<*> switch
|
|
|
|
( long "json"
|
|
|
|
<> help "Print the resulting value as an JSON representation")
|
|
|
|
<*> switch
|
|
|
|
( long "xml"
|
|
|
|
<> help "Print the resulting value as an XML representation")
|
2018-04-12 06:31:48 +02:00
|
|
|
<*> optional (strOption
|
|
|
|
( short 'A'
|
|
|
|
<> long "attr"
|
|
|
|
<> help "Select an attribute from the top-level Nix expression being evaluated"))
|
2018-04-12 07:02:31 +02:00
|
|
|
<*> many (strOption
|
2018-04-12 06:31:48 +02:00
|
|
|
( short 'I'
|
|
|
|
<> long "include"
|
|
|
|
<> help "Add a path to the Nix expression search path"))
|
2018-04-12 05:53:38 +02:00
|
|
|
<*> switch
|
|
|
|
( long "check"
|
|
|
|
<> help "Whether to check for syntax errors after parsing")
|
|
|
|
<*> optional (strOption
|
|
|
|
( long "read"
|
|
|
|
<> help "Read in an expression tree from a binary cache"))
|
|
|
|
<*> switch
|
|
|
|
( long "cache"
|
|
|
|
<> help "Write out the parsed expression tree to a binary cache")
|
2018-04-13 01:46:34 +02:00
|
|
|
<*> switch
|
|
|
|
( long "repl"
|
|
|
|
<> help "After performing any indicated actions, enter the REPL")
|
2018-04-12 05:53:38 +02:00
|
|
|
<*> switch
|
|
|
|
( long "ignore-errors"
|
|
|
|
<> help "Continue parsing files, even if there are errors")
|
|
|
|
<*> optional (strOption
|
|
|
|
( short 'E'
|
|
|
|
<> long "expr"
|
|
|
|
<> help "Expression to parse or evaluate"))
|
|
|
|
<*> many (argPair
|
|
|
|
( long "arg"
|
|
|
|
<> help "Argument to pass to an evaluated lambda"))
|
|
|
|
<*> many (argPair
|
|
|
|
( long "argstr"
|
|
|
|
<> help "Argument string to pass to an evaluated lambda"))
|
|
|
|
<*> optional (strOption
|
|
|
|
( short 'f'
|
|
|
|
<> long "file"
|
|
|
|
<> help "Parse all of the files given in FILE; - means stdin"))
|
|
|
|
<*> many (strArgument (metavar "FILE" <> help "Path of file to parse"))
|
|
|
|
|
|
|
|
nixOptionsInfo :: ParserInfo Options
|
|
|
|
nixOptionsInfo = info (helper <*> nixOptions)
|
|
|
|
(fullDesc <> progDesc "" <> header "hnix")
|