Safe Haskell | None |
---|
The options
package lets library and application developers easily work
with command-line options.
The following example is a full program that can accept two options,
--message
and --quiet
:
{-# LANGUAGE TemplateHaskell #-} import OptionsdefineOptions
"MainOptions" $ dostringOption
"optMessage" "message" "Hello world!" "A message to show the user."boolOption
"optQuiet" "quiet" False "Whether to be quiet." main :: IO () main =runCommand
$ \opts args -> do if optQuiet opts then return () else putStrLn (optMessage opts)
$ ./hello Hello world! $ ./hello --message='ciao mondo' ciao mondo $ ./hello --quiet $
In addition, this library will automatically create documentation options
such as --help
and --help-all
:
$ ./hello --help Help Options: -h, --help Show option summary. --help-all Show all help options. Application Options: --message A message to show the user. --quiet Whether to be quiet.
- class Options a
- defaultOptions :: Options a => a
- runCommand :: (MonadIO m, Options opts) => (opts -> [String] -> m a) -> m a
- data Subcommand cmdOpts action
- subcommand :: (Options cmdOpts, Options subcmdOpts) => String -> (cmdOpts -> subcmdOpts -> [String] -> action) -> Subcommand cmdOpts action
- runSubcommand :: (Options opts, MonadIO m) => [Subcommand opts (m a)] -> m a
- defineOptions :: String -> OptionsM () -> Q [Dec]
- boolOption :: String -> String -> Bool -> String -> OptionsM ()
- stringOption :: String -> String -> String -> String -> OptionsM ()
- stringsOption :: String -> String -> [String] -> String -> OptionsM ()
- textOption :: String -> String -> Text -> String -> OptionsM ()
- textsOption :: String -> String -> [Text] -> String -> OptionsM ()
- pathOption :: String -> String -> FilePath -> String -> OptionsM ()
- intOption :: String -> String -> Int -> String -> OptionsM ()
- integerOption :: String -> String -> Integer -> String -> OptionsM ()
- floatOption :: String -> String -> Float -> String -> OptionsM ()
- doubleOption :: String -> String -> Double -> String -> OptionsM ()
- data ImportedOptions a
- importedOptions :: Options a => ImportedOptions a
- options :: String -> ImportedOptions a -> OptionsM ()
- data Option a
- option :: String -> (Option String -> Option a) -> OptionsM ()
- optionShortFlags :: Option a -> [Char]
- optionLongFlags :: Option a -> [String]
- optionDefault :: Option a -> String
- optionType :: Option a -> OptionType a
- optionDescription :: Option a -> String
- optionGroup :: Option a -> Group
- data OptionType a
- optionTypeBool :: OptionType Bool
- optionTypeString :: OptionType String
- optionTypeText :: OptionType Text
- optionTypeFilePath :: OptionType FilePath
- optionTypeInt :: OptionType Int
- optionTypeInt8 :: OptionType Int8
- optionTypeInt16 :: OptionType Int16
- optionTypeInt32 :: OptionType Int32
- optionTypeInt64 :: OptionType Int64
- optionTypeWord :: OptionType Word
- optionTypeWord8 :: OptionType Word8
- optionTypeWord16 :: OptionType Word16
- optionTypeWord32 :: OptionType Word32
- optionTypeWord64 :: OptionType Word64
- optionTypeInteger :: OptionType Integer
- optionTypeFloat :: OptionType Float
- optionTypeDouble :: OptionType Double
- optionTypeMaybe :: OptionType a -> OptionType (Maybe a)
- optionTypeList :: Char -> OptionType a -> OptionType [a]
- optionTypeSet :: Ord a => Char -> OptionType a -> OptionType (Set a)
- optionTypeMap :: Ord k => Char -> Char -> OptionType k -> OptionType v -> OptionType (Map k v)
- optionTypeEnum :: Enum a => Name -> [(String, a)] -> OptionType a
- data Group
- group :: String -> (Group -> Group) -> Group
- groupTitle :: Group -> String
- groupDescription :: Group -> String
- class Parsed a
- parsedError :: Parsed a => a -> Maybe String
- parsedHelp :: Parsed a => a -> String
- data ParsedOptions opts
- parsedOptions :: ParsedOptions opts -> Maybe opts
- parsedArguments :: ParsedOptions opts -> [String]
- parseOptions :: Options opts => [String] -> ParsedOptions opts
- data ParsedSubcommand action
- parsedSubcommand :: ParsedSubcommand action -> Maybe action
- parseSubcommand :: Options cmdOpts => [Subcommand cmdOpts action] -> [String] -> ParsedSubcommand action
Options
Options are defined together in a single data type, which will be an
instance of Options
.
See defineOptions
for details on defining instances of Options
.
See options
for details on including imported Options
types in locally
defined options.
defaultOptions :: Options a => aSource
An options value containing only the default values for each option. This is equivalent to the options value when parsing an empty argument list.
Commands
runCommand :: (MonadIO m, Options opts) => (opts -> [String] -> m a) -> m aSource
Retrieve getArgs
, and attempt to parse it into a
valid value of an Options
type plus a list of left-over arguments. The
options and arguments are then passed to the provided computation.
If parsing fails, this computation will print an error and call
exitFailure
.
If parsing succeeds, and the user has passed a --help
flag, and the
developer is using the default help flag definitions, then this computation
will print documentation and call exitSuccess
.
See runSubcommand
for details on subcommand support.
Subcommands
data Subcommand cmdOpts action Source
:: (Options cmdOpts, Options subcmdOpts) | |
=> String | The subcommand name. |
-> (cmdOpts -> subcmdOpts -> [String] -> action) | The action to run. |
-> Subcommand cmdOpts action |
runSubcommand :: (Options opts, MonadIO m) => [Subcommand opts (m a)] -> m aSource
Used to run applications that are split into subcommands.
Use subcommand
to define available commands and their actions, then pass
them to this computation to select one and run it. If the user specifies
an invalid subcommand, this computation will print an error and call
exitFailure
. In handling of invalid flags or --help
, runSubcommand
acts like runCommand
.
{-# LANGUAGE TemplateHaskell #-} import Control.Monad (unless) import OptionsdefineOptions
"MainOptions" $ doboolOption
"optQuiet" "quiet" False "Whether to be quiet."defineOptions
"HelloOpts" $ dostringOption
"optHello" "hello" "Hello!" "How to say hello."defineOptions
"ByeOpts" $ dostringOption
"optName" "name" "" "The user's name." hello :: MainOptions -> HelloOpts -> [String] -> IO () hello mainOpts opts args = unless (optQuiet mainOpts) $ do putStrLn (optHello opts) bye :: MainOptions -> ByeOpts -> [String] -> IO () bye mainOpts opts args = unless (optQuiet mainOpts) $ do putStrLn ("Good bye " ++ optName opts) main :: IO () main =runSubcommand
[subcommand
"hello" hello ,subcommand
"bye" bye ]
$ ./app hello Hello! $ ./app hello --hello='Allo!' Allo! $ ./app bye Good bye $ ./app bye --name='John' Good bye John
Defining options
defineOptions :: String -> OptionsM () -> Q [Dec]Source
Defines a new data type, containing fields for application or library
options. The new type will be an instance of Options
.
Example: this use of defineOptions
:
defineOptions
"MainOptions" $ dostringOption
"optMessage" "message" "Hello world!" ""boolOption
"optQuiet" "quiet" False ""
expands to the following definition:
data MainOptions = MainOptions { optMessage :: String , optQuiet :: Bool } instance Options MainOptions
Simple option definitions
Using imported options
data ImportedOptions a Source
importedOptions :: Options a => ImportedOptions aSource
options :: String -> ImportedOptions a -> OptionsM ()Source
Include options defined elsewhere into the current options definition.
This is typically used by application developers to include options defined
in third-party libraries. For example, the author of the "foo" library
would define and export FooOptions
:
module Foo (FooOptions, foo) where import OptionsdefineOptions
"FooOptions" $ doboolOption
"optFrob" "frob" True "Enable frobnication." foo :: FooOptions -> IO ()
and the author of an application would use options
to let users specify
--frob
:
module Main where import Options import FoodefineOptions
"MainOptions" $ doboolOption
"optVerbose" "verbose" False "Be really loud."options
"optFoo" (importedOptions
::ImportedOptions
FooOptions) main :: IO () main = runCommand $ \opts args -> do foo (optFoo opts)
Use of options
may be arbitrarily nested. Library authors are encouraged
to aggregate their options into a single top-level type, so application
authors can include it easily in their own option definitions.
Advanted option definitions
Defines a new option in the current options type.
All options must have a field name and one or more flags. Options may also have a default value, a description, or a group.
The field name is how the option will be accessed in Haskell, and is
typically prefixed with "opt". This is used to define a record field,
and must be a valid Haskell field name (see defineOptions
for details).
The flags are how the user specifies an option on the command line. Flags
may be short or long. See optionShortFlags
and optionLongFlags
for
details.
option
"optPort" (\o -> o {optionLongFlags
= ["port"] ,optionDefault
= "80" ,optionType
=optionTypeWord16
}
optionShortFlags :: Option a -> [Char]Source
Short flags are a single character. When entered by a user, they are preceded by a dash and possibly other short flags.
Short flags must be a letter or a number.
Example: An option with optionShortFlags = ['p']
may be set using:
$ ./app -p 443 $ ./app -p443
optionLongFlags :: Option a -> [String]Source
Long flags are multiple characters. When entered by a user, they are preceded by two dashes.
Long flags may contain letters, numbers, '-'
, and '_'
.
Example: An option with optionLongFlags = ["port"]
may be set using:
$ ./app --port 443 $ ./app --port=443
optionDefault :: Option a -> StringSource
Options may have a default value. This will be parsed as if the user had entered it on the command line.
optionType :: Option a -> OptionType aSource
There are many types which an application or library might want
to use when designing their options. By default, options are
strings, but optionType
may be set to any supported type. See
the "Option types" section for a list of supported types.
optionDescription :: Option a -> StringSource
An option's description is used with the default implementation
of --help
. It should be a short string describing what the option
does.
optionGroup :: Option a -> GroupSource
Which group the option is in. See the "Option groups" section for details.
Option types
data OptionType a Source
An option's type determines how the option will be parsed, and which Haskell type the parsed value will be stored as. There are many types available, covering most basic types and a few more advanced types.
optionTypeBool :: OptionType BoolSource
Store an option as a
. The option's value must be either
Bool
"true"
or "false"
.
Boolean options are unary, which means that their value is optional when specified on the command line. If a flag is present, the option is set to True.
$ ./app -q $ ./app --quiet
Boolean options may still be specified explicitly by using long flags with
the --flag=value
format. This is the only way to set a unary flag to
"false"
.
$ ./app --quiet=true $ ./app --quiet=false
optionTypeString :: OptionType StringSource
Store an option value as a
. The value is decoded to Unicode
first, if needed. The value may contain non-Unicode bytes, in which case
they will be stored using GHC 7.4's encoding for mixed-use strings.
String
optionTypeText :: OptionType TextSource
Store an option value as a
. The value is decoded to Unicode
first, if needed. If the value cannot be decoded, the stored value may have
the Unicode substitution character Text
'\65533'
in place of some of the
original input.
optionTypeFilePath :: OptionType FilePathSource
Store an option value as a
.
FilePath
optionTypeInteger :: OptionType IntegerSource
Store an option as an
. The option value must be an integer.
There is no minimum or maximum value.
Integer
optionTypeMaybe :: OptionType a -> OptionType (Maybe a)Source
Store an option as a
of another type. The value will be
Maybe
Nothing
if the option was not provided or is an empty string.
option
"optTimeout" (\o -> o {optionLongFlags
= ["timeout"] ,optionType
=optionTypeMaybe
optionTypeInt
})
:: Char | Element separator |
-> OptionType a | Element type |
-> OptionType [a] |
Store an option as a list, using another option type for the elements. The separator should be a character that will not occur within the values, such as a comma or semicolon.
option
"optNames" (\o -> o {optionLongFlags
= ["names"] ,optionDefault
= "Alice;Bob;Charles" ,optionType
=optionTypeList
';'optionTypeString
})
:: Ord a | |
=> Char | Element separator |
-> OptionType a | Element type |
-> OptionType (Set a) |
Store an option as a
, using another option type for the
elements. The separator should be a character that will not occur within
the values, such as a comma or semicolon.
Set
Duplicate elements in the input are permitted.
option
"optNames" (\o -> o {optionLongFlags
= ["names"] ,optionDefault
= "Alice;Bob;Charles" ,optionType
=optionTypeSet
';'optionTypeString
})
:: Ord k | |
=> Char | Item separator |
-> Char | Key/Value separator |
-> OptionType k | Key type |
-> OptionType v | Value type |
-> OptionType (Map k v) |
Store an option as a Map
, using other option types for the keys and
values.
The item separator is used to separate key/value pairs from eachother. It should be a character that will not occur within either the keys or values.
The value separator is used to separate the key from the value. It should be a character that will not occur within the keys. It may occur within the values.
Duplicate keys in the input are permitted. The final value for each key is stored.
option
"optNames" (\o -> o {optionLongFlags
= ["names"] ,optionDefault
= "name=Alice;hometown=Bucharest" ,optionType
=optionTypeMap
';' '='optionTypeString
optionTypeString
})
optionTypeEnum :: Enum a => Name -> [(String, a)] -> OptionType aSource
Store an option as one of a set of enumerated values. The option type must be defined in a separate file.
-- MyApp/Types.hs data Mode = ModeFoo | ModeBar deriving (Enum)
-- Main.hs import MyApp.TypesdefineOptions
"MainOptions" $ dooption
"optMode" (\o -> o {optionLongFlags
= ["mode"] ,optionDefault
= "foo" ,optionType
=optionTypeEnum
''Mode [ ("foo", ModeFoo) , ("bar", ModeBar) ] })
$ ./app Running in mode ModeFoo $ ./app --mode=bar Running in mode ModeBar
Option groups
Define an option group.
Option groups are used to make long --help
output more readable, by
hiding obscure or rarely-used options from the main summary.
If an option is in a group named "examples"
, it will only be shown
in the help output if the user provides the flag --help-examples
or
--help-all
. The flag --help-all
will show all options, in all groups.
groupTitle :: Group -> StringSource
A short title for the group, which is used when printing
--help
output.
groupDescription :: Group -> StringSource
A description of the group, which is used when printing
--help
output.
Parsing argument lists
See
and parseOptions
.
parseSubcommand
Parsed (ParsedSubcommand a) | |
Parsed (ParsedOptions a) |
parsedError :: Parsed a => a -> Maybe StringSource
Get the error that prevented options from being parsed from argv,
or Nothing
if no error was detected.
parsedHelp :: Parsed a => a -> StringSource
Get a help message to show the user. If the arguments included
a help flag, this will be a message appropriate to that flag.
Otherwise, it is a summary (equivalent to --help
).
This is always a non-empty string, regardless of whether the parse succeeded or failed. If you need to perform additional validation on the options value, this message can be displayed if validation fails.
Parsing options
parsedOptions :: ParsedOptions opts -> Maybe optsSource
Get the options value that was parsed from argv, or Nothing
if the
arguments could not be converted into options.
Note: This function return Nothing
if the user provided a help flag. To
check whether an error occured during parsing, check the value of
.
parsedError
parsedArguments :: ParsedOptions opts -> [String]Source
Get command-line arguments remaining after parsing options. The arguments are unchanged from the original argument list, and have not been decoded or otherwise transformed.
parseOptions :: Options opts => [String] -> ParsedOptions optsSource
Attempt to convert a list of command-line arguments into an options value. This can be used by application developers who want finer control over error handling, or who want to perform additional validation on the options value.
The argument list must be in the same encoding as the result of
getArgs
.
Use
, parsedOptions
, parsedArguments
, and
parsedError
to inspect the result of parsedHelp
.
parseOptions
Example:
getOptionsOrDie :: Options a => IO a getOptionsOrDie = do argv <- System.Environment.getArgs let parsed =parseOptions
argv caseparsedOptions
parsed of Just opts -> return opts Nothing -> caseparsedError
parsed of Just err -> do hPutStrLn stderr (parsedHelp
parsed) hPutStrLn stderr err exitFailure Nothing -> do hPutStr stdout (parsedHelp
parsed) exitSuccess
Parsing subcommands
parsedSubcommand :: ParsedSubcommand action -> Maybe actionSource
Get the subcommand action that was parsed from argv, or Nothing
if the
arguments could not be converted into a valid action.
Note: This function return Nothing
if the user provided a help flag. To
check whether an error occured during parsing, check the value of
.
parsedError
parseSubcommand :: Options cmdOpts => [Subcommand cmdOpts action] -> [String] -> ParsedSubcommand actionSource
Attempt to convert a list of command-line arguments into a subcommand action. This can be used by application developers who want finer control over error handling, or who want subcommands that run in an unusual monad.
The argument list must be in the same encoding as the result of
getArgs
.
Use
, parsedSubcommand
, and parsedError
to inspect the
result of parsedHelp
.
parseSubcommand
Example:
runSubcommand :: Options cmdOpts => [Subcommand cmdOpts (IO a)] -> IO a runSubcommand subcommands = do argv <- System.Environment.getArgs let parsed =parseSubcommand
subcommands argv caseparsedSubcommand
parsed of Just cmd -> cmd Nothing -> caseparsedError
parsed of Just err -> do hPutStrLn stderr (parsedHelp
parsed) hPutStrLn stderr err exitFailure Nothing -> do hPutStr stdout (parsedHelp
parsed) exitSuccess