Portability | portable |
---|---|
Stability | stable |
Maintainer | Jose Raymundo Cruz (jose.r.cruz01@gmail.com) |
Safe Haskell | None |
Core HsOptions library source.
- flagError :: String -> String -> String
- usingFileKw :: (String, [String])
- helpKw :: (String, [String])
- inheritKw :: String
- inheritRegex :: String
- reservedWords :: [String]
- isOptional :: FlagConf (Maybe a)
- emptyValueIs :: a -> FlagConf a
- defaultIs :: a -> FlagConf a
- defaultIf :: (FlagResults -> Maybe a) -> FlagConf a
- aliasIs :: [String] -> FlagConf a
- requiredIf :: (FlagResults -> Bool) -> FlagConf (Maybe a)
- parser :: (FlagArgument -> Maybe a) -> FlagConf a
- maybeParser :: (FlagArgument -> Maybe a) -> FlagConf (Maybe a)
- operation :: OperationToken -> FlagConf a
- append :: OperationToken
- append' :: OperationToken
- prepend :: OperationToken
- prepend' :: OperationToken
- assign :: OperationToken
- toMaybeParser :: (FlagArgument -> Maybe a) -> FlagArgument -> Maybe (Maybe a)
- get :: FlagResults -> Flag a -> a
- flagDefault :: FlagResults -> [FlagConf a] -> Maybe a
- flagAlias :: [FlagConf a] -> [String]
- flagDAlias :: [FlagDataConf] -> [String]
- flagDDefaultOperation :: [FlagDataConf] -> OperationToken
- flagEmptyValue :: [FlagConf a] -> Maybe a
- runRealParser :: [FlagConf a] -> FlagArgument -> Maybe a
- runParser :: FlagResults -> [FlagConf a] -> FlagArgument -> Maybe a
- combine :: [FlagData] -> FlagData
- validate :: GlobalRule -> FlagData
- flagToData :: Flag a -> FlagData
- fConfToFDataConf :: FlagConf a -> FlagDataConf
- invalidFlag :: (String, [FlagConf a]) -> Maybe String
- invalidFlagName :: String -> Bool
- mapAlias :: FlagAliasMap -> String -> String
- replaceStr :: String -> (String, String) -> String
- executeOp :: ParseResults -> (String, OperationToken, FlagValueToken) -> FlagArgument
- execAssign :: ParseResults -> (String, FlagValueToken) -> FlagArgument
- execAppend :: ParseResults -> (String, FlagValueToken) -> FlagArgument
- execAppend' :: ParseResults -> (String, FlagValueToken) -> FlagArgument
- execPrepend :: ParseResults -> (String, FlagValueToken) -> FlagArgument
- execPrepend' :: ParseResults -> (String, FlagValueToken) -> FlagArgument
- previousOrEmpty :: FlagResults -> String -> FlagArgument
- applyInherit :: ParseResults -> FlagArgument -> FlagArgument
- parseToken :: (ParseResults, Token) -> ParseResults
- parseArgs :: [Token] -> ParseResults -> ParseResults
- concatToks :: TokenizeResult -> TokenizeResult -> TokenizeResult
- readFile' :: String -> IO (Either SomeException String)
- parseConfFile :: ([String], FlagData) -> String -> IO TokenizeResult
- removeComments :: String -> String
- isUsingConfFlag :: Token -> IO (Maybe String)
- includeConfig :: ([String], FlagData) -> [Token] -> IO TokenizeResult
- reportCircularDependency :: [String] -> IO TokenizeResult
- tokenize :: ([String], FlagData) -> String -> IO TokenizeResult
- mkDefaultOp :: [(String, (String, [FlagDataConf]))] -> DefaultOp
- process :: FlagData -> [String] -> IO (Either [FlagError] ProcessResults)
- process' :: FlagData -> [Token] -> Either [FlagError] ProcessResults
- updateFlagAlias :: FlagData -> [Token] -> [Token]
- getFlagName :: Token -> Maybe String
- updateName :: Token -> String -> Token
- anyArgIsHelp :: [String] -> Bool
- processMain :: String -> FlagData -> (ProcessResults -> IO ()) -> ([FlagError] -> IO ()) -> (String -> [(String, [String], String)] -> IO ()) -> IO ()
- getQuotedArgs :: IO [String]
- hasFatalError :: [FlagError] -> Bool
- pipelines :: [[PipelineFunction]] -> PipelineFunction
- pipeline :: [PipelineFunction] -> PipelineFunction
- validateReservedWords :: PipelineFunction
- ifIsJust :: Maybe a -> (a -> Bool) -> Bool
- addMissingFlags :: PipelineFunction
- validateUnknownFlags :: PipelineFunction
- validateFlagParsers :: PipelineFunction
- validateRequiredIf :: PipelineFunction
- validateDependentDefault :: PipelineFunction
- validateGlobalRules :: PipelineFunction
- requiredIfValidator :: [FlagDataConf] -> FlagResults -> FlagArgument -> ValidationResult
- defaultIfValidator :: [FlagDataConf] -> FlagResults -> FlagArgument -> ValidationResult
- make :: (String, String, [FlagConf a]) -> Flag a
- defaultDisplayHelp :: String -> [(String, [String], String)] -> IO ()
- mapOptOption :: [String] -> String -> OptDescr String
- splitShortName :: [String] -> (String, [String])
- defaultDisplayErrors :: [FlagError] -> IO ()
- getFlagHelp :: FlagData -> [(String, [String], String)]
- flagDIsOptional :: [FlagDataConf] -> Bool
- flagDIsRequiredIf :: [FlagDataConf] -> FlagResults -> Bool
- flagDHasDefaultForResults :: [FlagDataConf] -> FlagResults -> Bool
- flagDHasDefault :: [FlagDataConf] -> Bool
- flagDHasEmptyValue :: [FlagDataConf] -> Bool
- runDValidator :: [FlagDataConf] -> FlagArgument -> Bool
- validationError :: String -> String -> ValidationResult
- checkValidator :: [FlagDataConf] -> FlagArgument -> ValidationResult
- valueParser :: Read a => FlagArgument -> Maybe a
- intParser :: FlagArgument -> Maybe Int
- doubleParser :: FlagArgument -> Maybe Double
- floatParser :: FlagArgument -> Maybe Float
- arrayParser :: Read a => FlagArgument -> Maybe [a]
- charParser :: FlagArgument -> Maybe Char
- stringParser :: FlagArgument -> Maybe String
- boolParser :: FlagArgument -> Maybe Bool
- boolFlag :: [FlagConf Bool]
Documentation
flagError :: String -> String -> StringSource
Takes a flag's name and an error message and builds a proper error for the flag.
Arguments:
-
flag_name
: the name of the flag -
error
: the error message
Returns:
- A pretty error message for the flag name.
usingFileKw :: (String, [String])Source
The keyword for the usingFile
flag and its aliases.
This flag is used to include a configuration text file for flag parsing.
helpKw :: (String, [String])Source
The keyword for the help
flag and its aliases.
When the user pass in this flag the display error
function is called.
The keyword for the inherit
feature.
This keyword allows the user to set a flag's value based on it's previous value.
Regex used to match the inheritKw
.
reservedWords :: [String]Source
Holds all words that are reserved on by the library and cannot be used as flag names.
isOptional :: FlagConf (Maybe a)Source
Creates a flag configuration that makes the flag as optional.
Since the flag is optional then it's type must
bet
, so that it can be Flag
(Maybe
a)Nothing
if the flag was not
provided by the user or
if it was provided.
Just
value
Returns:
- A flag configuration that marks the flag as optional.
This method is a specification of the
requiredIf
method. Is is equivalent to:
>>>
requiredIf (const False)
emptyValueIs :: a -> FlagConf aSource
Creates a flag configuration that defines the default value when the flag is empty.
Sets the value a flag should take if it is the case that this flag was
provided by the user but not it's value (i.e. runhaskell Program.hs
--user_id
).
Arguments:
-
empty_value
: the value to use if the flag value is empty.
Returns:
- A flag configuration that sets the flag's empty value.
defaultIs :: a -> FlagConf aSource
Creates a flag configuration that sets sets the default value for a flag if the flag is not provided by the user.
Arguments:
-
default value
: the default value of the flag.
Returns:
- A flag configuration that sets the flag's default value.
This method is a specification of the
defaultIs
method. Is is equivalent to:
>>>
defaultIf a (const True)
defaultIf :: (FlagResults -> Maybe a) -> FlagConf aSource
Creates a flag configuration that sets a dependent default value for a flag.
This configuration requires a function that takes in a FlagResults
as
argument and returns a `Maybe a` value, Nothing
says that there is no
default value and `Just something` says that there is a default value.
Arguments:
default_getter
: function that given aFlagResults
returns the default value (Just
) orNothing
if no default value exist;
Returns:
- A flag configuration that sets the dependent default value for the flag.
aliasIs :: [String] -> FlagConf aSource
Creates a flag configuration for the aliases of the flag.
Sets multiple alias for a single flag. (i.e. --user_id alias:
["u", "uid","user_identifier"])
. These aliases can be used to set
the flag value, so --user_id = 8
is equivalent to -u = 8
.
Arguments:
aliases
: the alias list for the flag.
Returns:
- A flag configuration that sets the aliases for a given flag.
requiredIf :: (FlagResults -> Bool) -> FlagConf (Maybe a)Source
Creates a flag configuration that marks a flag as conditionally required.
The flag will be required from the user if the condition
returns True
and the user does not provides the flag in the input stream, a "flag is
required" error is displayed in this scenario.
The flag type must be
, if the Maybe
acondition
returns False
and
the flag is not provided then it's value is Nothing
. On the other hand
if the flag is provided it's value will be
.
Just
value
Arguments:
condition
: the condition to determine if the flag is required.
Returns:
- A flag configuration that sets the conditional flag required constraint.
parser :: (FlagArgument -> Maybe a) -> FlagConf aSource
Sets the flag's parser configuration.
It takes the function that will parse the string input to the corresponding
flag type value. A set of this functions, such as intParser
, was created
to provide a basic set of parsers.
Arguments:
parser_function
: a function that takes a flag argument and returnsNothing
if the argument can not be parsed or the parsed value (Just
) if the argument can be parsed correctly.
Returns:
- A flag configuration that defines how to parse the string input.
maybeParser :: (FlagArgument -> Maybe a) -> FlagConf (Maybe a)Source
Combination of the parser
and toMaybeParser
for syntactic sugar since
this is a very common scenario.
Basically is defined as:
maybeParser = parser . toMaybeParser
So instead of always doing:
>>>
user_id = make ("user_id", "help", [parser $ toMaybeParser intParser])
You can do:
>>>
user_id = make ("user_id", "help", [maybePaser intParser])
Arguments:
parser_function
: parser function that defines how to parse the string input to the flag's value.
Returns:
- A flag configuration that sets how to parse the string input.
operation :: OperationToken -> FlagConf aSource
Creates a flag configuration for the default operation of the flag.
Defines the default operation for the flag if no operation is made
explicit by the user. If this method is not called then the default
operation is always assign
.
>>>
runhaskell Program.hs --user_name += batman
Operation was explicit: Operation = "Append operation"
>>>
runhaskell Program.hs --user_name batman
Operation not specified: Operation = @default_operation@
Arguments:
default_operation
: operation to use if no operation is provided for the flag in the input stream.
Returns:
- A flag configuration that sets the default operation of the flag.
append :: OperationTokenSource
Append operation (+=). One of the available flag operations.
The flag value is appended with it's previous value using a space in
between values. It is used as the argument of operation
function:
>>>
operation append
Sets the default operation for the flag to append
Returns:
- Append flag operation.
prepend :: OperationTokenSource
Prepend operation (=+). One of the available flag operations.
The flag value is prepended with it's previous value using a space in
between values. It is used as the argument of operation
function:
>>>
operation prepend
Sets the default operation for the flag to prepend
Returns:
- Prepend flag operation.
assign :: OperationTokenSource
Assign operation (=). Default flag operation if no operation is set.
Sets the flag value to the current value, overwriting any previous value the flag may have.
>>>
operation assign
Sets the default operation for the flag to assign
Returns:
- Assign flag operation.
toMaybeParser :: (FlagArgument -> Maybe a) -> FlagArgument -> Maybe (Maybe a)Source
Wraps a parser function that takes a FlagArgument
and returns a
"
" and converts it to a function that returns a
"Maybe
a
".
Maybe
(Maybe
a)
This new function does will never fail if the argument is missing or
if the argument value is missing (FlagMissing
or FlagValueMissing
),
instead this function maps any of these two to a Nothing
value.
If the flag argument is of type FlagValue
then the original parser
is used.
It is a convenient way to reuse current parsers, like intParser
, without
having to redefine them. For instance "intParser
" is of type
, but "FlagArgument
-> (Maybe
Int
)toMaybeParser intParser
" is of
type
.
FlagArgument
-> (Maybe
(Maybe
Int
))
Usage example:
user_id :: Flag (Maybe Int) user_id = make ("user_id", "help", [parser (toMaybeParser intParser)])
As you can observe intParser
was reused.
Arguments:
original_parser
: the original parser to be wrapped.
Returns:
- A new parser that changes the result type to an optional type.
get :: FlagResults -> Flag a -> aSource
Method to get a flag value out of a FlagResults
.
This is the method used to get the proper value for each flag after the
input stream has been processed. The processMain
method will create the
FlagResults
data structure for a set of defined flags.
This is an example on how to use this method:
user_id :: Flag Int user_id = make ("user_id", "help", [parser intParser] main_success :: (FlagResults, ArgsResults) -> IO () main_success (flags, _) = putStrLn ("Next user id: " ++ show ((get flags user_id) + 1)))
Arguments:
flag_results
: theFlagResults
created from the input stream.
Returns:
- The value of the given flag.
Throws:
- An exception is raised if flag does not exist in the
FlagResults
. At this point, theget
method should always succeed parsing a flag value. If the flag is not found then that means that the flag was not processed by the parser, possibly because the flag was not added to theFlagData
sent to the processor.
flagDefault :: FlagResults -> [FlagConf a] -> Maybe aSource
Finds the default value from a flag's list of configurations if the default value was configured for the flag.
If a dependent default value was configured for the flag then it is matched
agains the flag_results
, if the match returns True
then the default
value is returned, otherwise Nothing
is returned.
Arguments:
flag_results
: the currentFlagResults
.configurations
: the list of configurations for the flag.
Returns:
flagAlias :: [FlagConf a] -> [String]Source
Returns the list of flag alias configured for the flag.
Arguments:
configurations
: the list of configurations for the flag.
Returns:
- A list of all the flag alias configured for the flag.
flagDAlias :: [FlagDataConf] -> [String]Source
Returns the list of flag alias configured for the flag.
Similar to flagAlias
but for FlagDataConf
instead.
Arguments:
configurations
: the list of configurations for the flag.
Returns:
- A list of all the flag alias configured for the flag.
flagDDefaultOperation :: [FlagDataConf] -> OperationTokenSource
Finds the default operation for the flag.
If the default operation is not found the the assign
operation is used
as the default.
Arguments:
configurations
: the list of configurations for the flag.
Returns:
- The default operation for the flag.
flagEmptyValue :: [FlagConf a] -> Maybe aSource
Finds the value to use if the flag value is empty.
Arguments:
configurations
: the list of configurations for the flag.
Returns:
- Nothing: if there is no empty value configured for the flag * Just value: if the empty value is found.
runRealParser :: [FlagConf a] -> FlagArgument -> Maybe aSource
Finds the parser for the flags and runs it against the flag argument.
Arguments:
configurations
: the list of configurations for the flag.flag_argument
: the argument of the flag.
Returns:
- The parsed value of the
flag_argument
by using the original flag parser
Throws:
- An exception if no parser is found. This method depend on previous validation that the parser was configured for the flag.
runParser :: FlagResults -> [FlagConf a] -> FlagArgument -> Maybe aSource
Runs the parser for the flag depending on the type of FlagArgument
.
Takes into considerations scenarios where the flag argument is missing but the user defined a default value for the flag or if the flag argument is empty and the user defined an empty value for the flag.
Arguments:
flag_results
: the currentFlagResults
.configurations
: the list of configurations for the flag.flag_argument
: the argument of the flag.
Returns:
- The default value for the flag: if a default value was configured and
the flag argument is
FlagMissing
. - The empty value for the flag: if an empty value was configured and
the flag argument is
FlagValueMissing
- Otherwise: The result of the real parser configured for the flag.
combine :: [FlagData] -> FlagDataSource
Takes a list of FlagData
and combines them together into a single
FlagData
.
Validates that a flag name is not repeated in the incoming list of flag data.
Usage example:
flagData = combine [ flagToData user_id , flagToData user_name, , flagToData database ]
Arguments:
-
flag_data_list
: list of flag data to combine.
Returns:
- A combined
FlagData
result
Throws:
- An exception if any two flag names are duplicated in the input
flag_data_list
.
validate :: GlobalRule -> FlagDataSource
Constructs a FlagData
out of a GlobalRule
.
This global rule will be used in the last validation stage of the
process
method.
Usage example:
flagData = combine [ flagToData user_id , validate (\fr -> if get fr user_id < 0 then Just "user id negative error" else Nothing) ]
Multiple validation rules can exist.
Arguments:
global_rule
: global validation rule
Returns:
- A
FlagData
representation of theglobal_rule
.
flagToData :: Flag a -> FlagDataSource
fConfToFDataConf :: FlagConf a -> FlagDataConfSource
Maps a
to a FlagConf
aFlagDataConf
data type.
Arguments:
flag_conf
: the flag configuration to be mapped to aFlagDataConf
.
Returns:
- A corresponding
FlagDataConf
mapped from the input.
invalidFlag :: (String, [FlagConf a]) -> Maybe StringSource
Checks if a flag is invalid.
Among the validation rules checks that the file name follows the correct convention, as well as all the flag's aliases.
Arguments:
(flag_name, flag_configuration)
: the data of the flag required to validate it.
Returns:
invalidFlagName :: String -> BoolSource
mapAlias :: FlagAliasMap -> String -> StringSource
Maps a flag alias to the real flag name.
For example if the flag --user_id
has the -uid
alias configured in the
flag_alias_map
then:
>>>
mapAlias flag_alias_map "uid"
will return "user_id"
If the alias is not found in the flag_alias_map
then the flag_alias
argument is returned unmodified.
Arguments:
flag_alias_map
: the map of flag alias to flag name.flag_alias
: the alias to be mapped to the real flag name.
Returns:
- The real flag name for the
flag_alias
if found or the same argument unmodified if not found.
replaceStr :: String -> (String, String) -> StringSource
Replaces the sub_string
with the replacement_string
in the input
input_string
.
>>>
replaceStr "One two three@" ("two", "four")
"One four three"
Arguments:
input_string
: the string to be searched.sub_string
: the string to be replaced in theinput_string
.replacement_string
: the string to be used as a replacement ofsub_string
.
Returns:
- The
input_string
with anysub_string
replaced forreplacement_string
.
executeOp :: ParseResults -> (String, OperationToken, FlagValueToken) -> FlagArgumentSource
Creates the flag argument from the parser results for a given flag based on the operation performed on the flag.
Maps the flag opereration to the respective method that will produce the
flag value, such as execAppend
(that produces the flag value by
appending the current value with the previous value).
Arguments:
parse_results
: the current state of the parse process.(flag_name, operation, flag_value)
: flag and flag value information, as well as the operation being performed to the flag.
Returns:
- A flag argument containing the final value for the flag after the operation was performed.
execAssign :: ParseResults -> (String, FlagValueToken) -> FlagArgumentSource
Performs the assign flag operation.
Assigns the current value to the flag disregarding any previous state of the flag.
Arguments:
parse_results
: the current state of the parse process.(flag_name, flag_value)
: name and value of the current operation.
Returns:
-
FlagValue
if the flag is being assigned to a not empty value,FlagValueMissing
otherwise.
execAppend :: ParseResults -> (String, FlagValueToken) -> FlagArgumentSource
Performs the append flag operation.
Appends the current value of the flag to the previous value of the flag. A space is used as a separator between the two values.
If the current value for the flag is empty then the previous value is taken as the new flag value.
Arguments:
parse_results
: the current state of the parse process.(flag_name, flag_value)
: name and value of the current operation.
Returns:
- The current value of the flag appended to the previous value of the flag using a space as separator.
execAppend' :: ParseResults -> (String, FlagValueToken) -> FlagArgumentSource
Performs the append' flag operation.
Similar to append
but does not use a space as separator.
If the current value for the flag is empty then the previous value is taken as the new flag value.
Arguments:
parse_results
: the current state of the parse process.(flag_name, flag_value)
: name and value of the current operation.
Returns:
- The current value of the flag appended to the previous value of the flag without using any in between separator.
execPrepend :: ParseResults -> (String, FlagValueToken) -> FlagArgumentSource
Performs the prepend flag operation.
Prepends the current value of the flag to the previous value of the flag. A space is used as a separator between the two values.
If the current value for the flag is empty then the previous value is taken as the new flag value.
Arguments:
parse_results
: the current state of the parse process.(flag_name, flag_value)
: name and value of the current operation.
Returns:
- The current value of the flag prepended to the previous value of the flag using a space as separator.
execPrepend' :: ParseResults -> (String, FlagValueToken) -> FlagArgumentSource
Performs the prepend' flag operation.
Similar to prepend
but does not use a space as separator.
If the current value for the flag is empty then the previous value is taken as the new flag value.
Arguments:
parse_results
: the current state of the parse process.(flag_name, flag_value)
: name and value of the current operation.
Returns:
- The current value of the flag prepend to the previous value of the flag without using any in between separator.
previousOrEmpty :: FlagResults -> String -> FlagArgumentSource
Tries to find the previous result of a flag in the FlagResults
.
Arguments:
parse_results
: the current parsed flags.flag_name
: flag name used to find the flag's value.
Returns:
- The value of the flag inside the
parse_results
if it exists orFlagValueMissing
otherwise.
applyInherit :: ParseResults -> FlagArgument -> FlagArgumentSource
Checks if the value for the flag includes the $(inherit) keyword and replaces this keyword by the previous value of the flag.
It is a generalization of the append or prepend features, you can insert the previous value of the flag in any position of the new value.
For example, if the previous flag value was "batman"
and the new value
was "a-$(inherit)-z"
then the new value will be expanded to
"a-batman-z"
.
Arguments:
parse_results
: the current parsed flags.argument
: the value of the flag.
Returns:
- A new flag value by expanding any $(inherit) keyword with the previous value of the flag.
parseToken :: (ParseResults, Token) -> ParseResultsSource
Takes a Token
and produces a ParseResults
.
ParseResults
contains the final result of the flag after being analysed.
If the token is an ArgToken
then it is mapped unmodified to a
ParseResults
. If the token is a FlagToken
then the flag operation is
performed and the inherit keyword is expanded, then a ParseResults
is
created with this final flag value.
Arguments:
(parse_results, token)
: the parse results so far and the current token to parse.
Returns:
- A parse results after evaluating the current token.
parseArgs :: [Token] -> ParseResults -> ParseResultsSource
Takes a list of tokens, an initial ParseResults
and returns a
complete merge ParsedResults
after parsing each token in order.
Every token is parsed using the parseToken
and it's result is
continuously merged until all tokens are consumed.
Arguments:
tokens
: the list of tokens to parse.initial_parse_result
: the initial state of the parse process.
Returns:
- A complete
ParseResults
after parsing all of the input tokens in order.
concatToks :: TokenizeResult -> TokenizeResult -> TokenizeResultSource
Concatenates two TokenizeResult
together.
If both are errors (Left
) then the errors are concatenated.
If only one of them is errors (Left
) then that result is returned.
If non are errors, but tokens (Right
), then the tokens are concatenated
and returned.
Arguments:
tokenize_result1
: first result.tokenize_result2
: second result.
Returns:
-
tokenize_result1
concatenated withtokenize_result2
parseConfFile :: ([String], FlagData) -> String -> IO TokenizeResultSource
Parses the content of a configuration file.
If there is an error reading the file then that error is returned, otherwise the file content is processed and tokenized.
A preprocessor stage is performed on the content to remove the comments in the text file (comments starts with a hash (#) ).
Arguments:
(parents, flag_data)
: the parents is the tree of configuraiton file parents of this current configuration file. The flag_data is the information about the flags defined in the code.configuration_filename
: the path of the configuration file to include.
Returns:
- The tokenized version of the content of the configuration file or
an error (
Left
) if any errors found during the process.
removeComments :: String -> StringSource
Removes all the comments of the input_text
.
A comment is a string that begins with hash symbol (#) and ends with a line change ('\n').
Arguments:
input_text
: the input text.
Returns:
- The same input text but with all comments removed.
includeConfig :: ([String], FlagData) -> [Token] -> IO TokenizeResultSource
Recursively expands all the configuration file includes from the input token stream.
It takes the input tokens and searches for any instance of the
--usingFile
flag. If this flag is found then that flag is consumed,
the configuration file defined by that flag is tokenized and these new
tokens are inserted in the current spot of the input token stream.
This is a recurvise process that will stop once all the --usingFile
have been consumed and we got a stream of pure flag tokens.
If a circular dependency is detected then an error is reported to user.
parents
has the current tree of parents so we can check if we are
including one parent configuration file, which will cause an infinite loop.
Arguments:
(parents, flag_data)
: the parents is the tree of configuraiton file parents of this current configuration file. The flag_data is the information about the flags defined in the code.input_tokens
: the input token stream.
Returns:
- A new token stream with all the configuration file includes expanded, or an error if any error is found (either with circular dependency or invalid flag values).
reportCircularDependency :: [String] -> IO TokenizeResultSource
Creates an error message when a circular dependency is found.
Creates a pretty error highlighting the circular dependency.
Arguments:
tree
: the tree of configuration files that caused the problem.
Returns:
- An error showing the problem.
tokenize :: ([String], FlagData) -> String -> IO TokenizeResultSource
Takes an input string and creates a stream of tokens after parsing
the input with the parseInput
.
After the initial token stream is created all the configuration files includes are expanded to create a clean token stream.
Arguments:
(parents, flag_data)
: the parents is the tree of configuraiton file parents of this current configuration file. The flag_data is the information about the flags defined in the code.input_string
: the input string to tokenize.
Returns:
- A tokenized stream processed from the input string.
mkDefaultOp :: [(String, (String, [FlagDataConf]))] -> DefaultOpSource
Creates a map of flag name to flag default operation.
This map is used in the parser to correctly retrieve which is the default operation for each flag when the user does not explicitly specifies the flag operation.
Arguments:
flag_list
: all the flags in the code (including the flag configuration).
Returns:
- A map from flag to default operation.
process :: FlagData -> [String] -> IO (Either [FlagError] ProcessResults)Source
Does the actual flag parsing.
It begins by parsing the entire input stream and creating a tokenized input stream. A recursive search is done in these tokens to find any configuration files includes. Each conf file include is expanded until the tokenized stream is just composed of flags and positional arguments.
This tokenized stream is validated then by the rules of each flag, such as type validation, required flags, constraints, etc.
This method is an IO action because it needs to expand the configuration file includes (open the file and get it's content). When the stream is tokenized and no more IO is needed the 'process\'' method is called.
The validation is divided in two, local validation and global validation.
Local validation handled things like reserved words, unknown flags and correct flag types.
Global validation happens at the end and does all the validation that needs a context, such as global validation constraints, conditionally required flags and dependent default. Global validation only happens if the local validation succeeds.
Arguments:
flag_data
: a set of all the flags to process.input_stream
: the command line input stream.
Returns:
process' :: FlagData -> [Token] -> Either [FlagError] ProcessResultsSource
Does the actual flag parsing after the input stream have been tokenized and the configuration files have been expanded.
Updates the tokenized input stream and changes any flag alias set by the
user to the actual name of the flag, meaning if the user sent --uid = 8
then the token is changed to --user_id = 8
(considering uid
is an alias
for user_id
). This means from this point forward the flag name is used
as the flag identifier (any alias was mapped to the flag name).
Performs local validation:
- Verifies that no reserved words was used for the flag's name.
- Validates that no unknown flag was sent by the user.
- Validates that for every value set to a flag this value can be parsed
to the type the flag is expecting. (i.e. checks the string value of an
Int
flag can be parsed from string toInt
correctly).
Performs global validation:
- Validates the
requiredIf
constraints. - Validates the
defaultIf
constraints. - Validates all global validation rules are passing (rules created by
using the
validate
function)
Arguments:
flag_data
: a set of all the flags to process.tokenized_input_stream
: the complete input stream after tokenized.
Returns:
* Either a list of errors
(Left
) or a successful result
(Right
).
updateFlagAlias :: FlagData -> [Token] -> [Token]Source
Maps the flag alias to the real flag name for each of the input tokens.
The alias is mapped using the mapAlias
method.
Arguments:
flag_data
: contains information for the configured aliases.tokens
: the list of tokens.
Returns:
- An update list of tokens with each flag alias replaced with the real name of the flag.
getFlagName :: Token -> Maybe StringSource
updateName :: Token -> String -> TokenSource
Replaces the name of a flag with a new name.
Arguments:
token
: the token.name
: the new name for the flag.
Returns:
- An updated token with the name replaced with the new name if the token
is a
FlagToken
. The unmodified token otherwise.
anyArgIsHelp :: [String] -> BoolSource
Checks if the help flag was sent by the user.
Arguments:
arguments
: the arguments from the user.
Returns:
-
True
if the user sent the--help
or the-h
flags.
processMain :: String -> FlagData -> (ProcessResults -> IO ()) -> ([FlagError] -> IO ()) -> (String -> [(String, [String], String)] -> IO ()) -> IO ()Source
Processes the input arguments and parses all the flags.
Starts the process flags pipeline. First checks if the user wants to
display the help text of the program. This is done by looking for the
flag "--help
" or "-h
" flag in the input stream. If this flag is
found then the display_help
function is called with all the compiled
helptext and the program description.
If the user does not wants to display the help then the process
function
is called to do the actual flag parsing. This function can return errors
or a success result (FlagResults
, ArgsResults
). If any error is found
then the failure
function is called with the list of errors, otherwise the
success
function is called with the results.
See the process
documentation to see the rules and conditions of flag
parsing.
Arguments:
description
: the description of the program. Sent to thedisplay_help
function.flag_data
: a collection of all the flags defined in the code.success
: a success callback function. Called if no errors were found while parsing the flags from the input.failure
: a failure callback function. Called if some errors were found while parsing the input.display_help
: a display help callback function. Called when the "--help
" or "-h
" flag was sent by the user.
Returns:
- An IO action.
getQuotedArgs :: IO [String]Source
Returns the arguments sent by the user.
Double quote any argument that contains whitespace.
Returns:
- The list of the command line arguments quoting any argument with whitespace.
hasFatalError :: [FlagError] -> BoolSource
Checks if a fatal error occurred.
Arguments:
errors
: all flag errors.
Returns:
-
True
if aFlagFatalError
is found.False
otherwise.
pipelines :: [[PipelineFunction]] -> PipelineFunctionSource
Merges a list of pipelines.
If any pipeline returns an error then the error is returned without processing the remaining pipelines.
Arguments:
pipelines
: a list of pipelines.
Returns:
- A pipeline function that merges a list of pipelines.
pipeline :: [PipelineFunction] -> PipelineFunctionSource
Executes the pipeline functions in order.
The result of the current pipeline function is sent to the next function in the list.
The functions are evaluated until the list is consumed or any function returns a fatal error.
Arguments:
pipelines
: the list of pipeline functions
Returns:
- A pipeline function that executes the list of pipelines in order.
validateReservedWords :: PipelineFunctionSource
Pipeline function that validates no flag is using a reserved word as it's name.
Arguments:
(flag_data, flag_results)
: the flag data and the current flag results.
Returns:
- An error if any flag is using a reserved word as it's name. The
flag_results
is not modified for the next pipeline function.
addMissingFlags :: PipelineFunctionSource
Pipeline function that modifies the results by inserting all missing flags into it.
At this point the flags have been processed by the parser, so the
FlagResults
will have only the flags sent by the user. The remaining
flags are inserted into the FlagResults
with a FlagMissing
value.
This is useful so that future pipeline functions don't need to worry
about any flag not present in the flag results, as all defined flags
will be there, and missing flags will be there with the FlagMissing
value.
Arguments:
(flag_data, flag_results)
: the flag data and the current flag results.
Returns:
- The modified
flag_results
.
validateUnknownFlags :: PipelineFunctionSource
Pipeline function that checks if any unknown flag was sent by the user.
If a flag exists in the flag_results
that does not exist in the
flag_data
then an error is returned.
Arguments:
(flag_data, flag_results)
: the flag data and the current flag results.
Returns:
- An error if an unknown flag is found.
validateFlagParsers :: PipelineFunctionSource
Pipeline function that runs the checkValidator
on all the
define flags on flag_data
.
Arguments:
(flag_data, flag_results)
: the flag data and the current flag results.
Returns:
- An error if the flag validator fails.
validateRequiredIf :: PipelineFunctionSource
Pipeline function that runs the requiredIfValidator
on all the
define flags on flag_data
.
Arguments:
(flag_data, flag_results)
: the flag data and the current flag results.
Returns: * An error if the flag is required.
validateDependentDefault :: PipelineFunctionSource
Pipeline function that runs the defaultIfValidator
on all the
define flags on flag_data
.
Arguments:
(flag_data, flag_results)
: the flag data and the current flag results.
Returns: * An error if the flag is required.
validateGlobalRules :: PipelineFunctionSource
Pipeline function that runs all the global rules defined in the
flag_data
.
Arguments:
(flag_data, flag_results)
: the flag data and the current flag results.
Returns: * An error if any validation rules fails.
requiredIfValidator :: [FlagDataConf] -> FlagResults -> FlagArgument -> ValidationResultSource
Validates if the flag should be conditionally required.
If the flag is missing, was marked as conditionally required (using
requiredIf
) and the required predicate returns true then
a "flag required" error is reported.
In any other condition a success validation result is returned.
Arguments:
flag_configurations
: the configurations for a flag.flag_results
: current state of the flags.flag_argument
: the flag argument.
Returns:
-
ValidationSuccess
if the flag is not required. An error (ValidationError
) if it is not.
defaultIfValidator :: [FlagDataConf] -> FlagResults -> FlagArgument -> ValidationResultSource
Validates if the flag has a default value or the flag is optional when the flag is missing.
If the flag is missing and it is not optional or it does not have a default value configured then a "flag required" error is reported.
In any other condition a success validation result is returned.
Arguments:
flag_configurations
: the configurations for a flag.flag_results
: current state of the flags.
Returns:
-
ValidationSuccess
if the flag is valid with respect to the default value. An error (ValidationError
) if it is not.
make :: (String, String, [FlagConf a]) -> Flag aSource
Defines a flag.
A defined flag consist of a name, a helptext and a list of flag configurations. The name is the flag identifier, it must be unique among all other defined flags.
The name must follow the pattern " 'Letter'
followed by many
'Letters || Numbers || Dashes (-) || Underscores (_)'
".
If the name of the flag is invalid an
exception is thrown.
A parser for the flag must be set in the configuration
by using parser
or maybeParser
. If a parser is not found an exception is thrown.
Arguments:
(name, helptext, configurations)
: A triple containing the flag name, the helptext and the flag configurations.
Returns:
- A flag.
Throws:
- An exception if the name is invalid (does not follows the pattern).
- An exception if the parser was not set in the
configurations
.
defaultDisplayHelp :: String -> [(String, [String], String)] -> IO ()Source
Prints the help text to the screen using an standard format.
Arguments:
description
: the description of the program.flag_helptexts
: A list of triples (name, aliases, helptext) that contains an entry for each flag, with the flag's name, aliases and helptext.
mapOptOption :: [String] -> String -> OptDescr StringSource
Creates an option description from the names and helptext.
Arguments:
names
: the names for the flag.helptext
: the helptext for the flag.
Returns:
- An
OptDescr
that describes the flag.
splitShortName :: [String] -> (String, [String])Source
Takes the single character strings from the input_list
and
separates them from the list.
>>>
splitShortName ["one", "a", "two","b"]
("ab", ["one", "two"])
Arguments:
input_list
: a list of strings.
Returns:
- A tuple where the first element is a list of the single character
strings from the
input_list
and the second if the remaining strings from theinput_list
.
defaultDisplayErrors :: [FlagError] -> IO ()Source
Displaye the list of errors to the screen.
Arguments:
errors
: list of errors to display.
getFlagHelp :: FlagData -> [(String, [String], String)]Source
Creates a data structure with all the flag helptext information.
Arguments:
flag_data
: all configured flags in the system.
Returns:
- A list of triples. Each triple contains (flag_name, [flag_alias],
flag_helptext). After all flags in
flag_data
are processed the two system flags (help
andusingFile
) are appended to the end of the list.
flagDIsOptional :: [FlagDataConf] -> BoolSource
flagDIsRequiredIf :: [FlagDataConf] -> FlagResults -> BoolSource
Returns whether the flag should be required to the user based on the current results.
First checks if the flag was configured as conditionally required (with the
use of the requiredIf
function).
If it was, this required condition is checked against the current state.
Arguments:
flag_configurations
: the configurations for a flag.flag_results
: current state of the flags.
Returns:
-
True
if the flag should be required to the user.
flagDHasDefaultForResults :: [FlagDataConf] -> FlagResults -> BoolSource
Returns True
if any of the FlagDataConf_HasDefault
returns
True
.
For all the configured default values of the flag (like when
using defaultIs
or defaultIf
checks if any of the predicates
returns true for the given FlagResults
.
Arguments:
flag_configurations
: the configurations for a flag.flag_results
: current state of the flags.
Returns:
flagDHasDefault :: [FlagDataConf] -> BoolSource
flagDHasEmptyValue :: [FlagDataConf] -> BoolSource
Checks if an empty value was configured for the flag, like
when the emptyValueIs
function is used.
Arguments:
flag_configurations
: the configurations for a flag.
Returns:
runDValidator :: [FlagDataConf] -> FlagArgument -> BoolSource
Finds the flag validator (FlagDataConf_Validator
) in the list of
flag configurations and runs it against the flag argument.
Arguments:
flag_configurations
: the configurations for a flag.flag_argument
: the argument for the flag.
Returns:
- The result of the validator when run against the flag argument.
validationError :: String -> String -> ValidationResultSource
Creates a failed validation result for a flag.
Constructor method to easily created a failed validation result
(ValidationError
).
Arguments:
flag_name
: flag name that caused the error.error_message
: error message.
Returns:
- A validation result for a flag error.
checkValidator :: [FlagDataConf] -> FlagArgument -> ValidationResultSource
Checks if the flag value provided in FlagArgument
is valid by using
the validation found in the flag_configurations
.
The configured flag validator will only be used if required.
Under these conditions the flag is considered valid, and a
ValidationSuccess
is returned, without the need to use the flag
validator:
- The flag is missing but was marked as optional.
- The flag is missing but has a default value.
- The flag is empty but has an empty value configured.
If none of the above applies, then this is the expected results:
- The flag is missing: A "flag is required" error is reported.
- The flag is empty: A "flag value is empty" error is reported.
- The flag has a value: The configured flag validator is run with this value. If it fails a "flag value invalid" error is reported.
Arguments:
flag_configurations
: the configurations for a flag.flag_argument
: the argument for the flag.
Returns:
-
ValidationSuccess
if the flag is valid or an error (ValidationError
) if it is not.
valueParser :: Read a => FlagArgument -> Maybe aSource
intParser :: FlagArgument -> Maybe IntSource
arrayParser :: Read a => FlagArgument -> Maybe [a]Source
boolFlag :: [FlagConf Bool]Source
A predefined set of flag configurations for a boolean flag.
Defines a set of configurations that specifies:
- The parser to be
boolParser
. - The default value to be
False
. - The empty value to be
True
This defines a default boolean flag behavior such that if the flag is
missing then it is treated as False
, if the flag is present (i.e
--help
) then it is True
.