cmdargs-0.10.18: Command line argument processing

Safe Haskell | None
Language | Haskell2010

System.Console.CmdArgs.Explicit

Contents

- Running command lines
- Constructing command lines
- Displaying help
- Utilities for working with command lines

Description

This module constructs command lines. You may either use the helper functions (`flagNone`, `flagOpt`, `mode` etc.) or construct the type directly. These types are intended to give all the necessary power to the person constructing a command line parser.

For people constructing simpler command line parsers, the module System.Console.CmdArgs.Implicit may be more appropriate.

As an example of a parser:

       arguments :: Mode [(String,String)]
       arguments = mode "explicit" [] "Explicit sample program" (flagArg (upd "file") "FILE")
           [flagOpt "world" ["hello","h"] (upd "world") "WHO" "World argument"
           ,flagReq ["greeting","g"] (upd "greeting") "MSG" "Greeting to give"
           ,flagHelpSimple (("help",""):)]
           where upd msg x v = Right $ (msg,x):v

And this can be invoked by:

       main = do
           xs <- processArgs arguments
           if ("help","") `elem` xs then
               print $ helpText [] HelpFormatDefault arguments
            else
               print xs

Groups: The `Group` structure allows flags/modes to be grouped for the purpose of displaying help. When processing command lines, the group structure is ignored.

Modes: The Explicit module allows multiple mode programs by placing additional modes in `modeGroupModes`. Every mode is allowed sub-modes, and thus multiple levels of mode may be created. Given a mode `x` with sub-modes `xs`, if the first argument corresponds to the name of a sub-mode, then that sub-mode will be applied. If not, then the arguments will be processed by mode `x`. Consequently, if you wish to force the user to explicitly enter a mode, simply give sub-modes, and leave `modeArgs` as `Nothing`. Alternatively, if you want one sub-mode to be selected by default, place all it's flags both in the sub-mode and the outer mode.

Parsing rules: Command lines are parsed as per most GNU programs. Short arguments single letter flags start with `-`, longer flags start with `--`, and everything else is considered an argument. Anything after `--` alone is considered to be an argument. For example:

    -f --flag argument1 -- --argument2

This command line passes one single letter flag (`f`), one longer flag (`flag`) and two arguments (`argument1` and `--argument2`).

Synopsis

- process :: Mode a -> [String] -> Either String a
- processArgs :: Mode a -> IO a
- processValue :: Mode a -> [String] -> a
- processValueIO :: Mode a -> [String] -> IO a
- type Name = String
- type Help = String
- type FlagHelp = String
- parseBool :: String -> Maybe Bool
- data Group a = Group {
  - groupUnnamed :: [a]
  - groupHidden :: [a]
  - groupNamed :: [(Help, [a])]
  }
- fromGroup :: Group a -> [a]
- toGroup :: [a] -> Group a
- data Mode a = Mode {
  - modeGroupModes :: Group (Mode a)
  - modeNames :: [Name]
  - modeValue :: a
  - modeCheck :: a -> Either String a
  - modeReform :: a -> Maybe [String]
  - modeExpandAt :: Bool
  - modeHelp :: Help
  - modeHelpSuffix :: [String]
  - modeArgs :: ([Arg a], Maybe (Arg a))
  - modeGroupFlags :: Group (Flag a)
  }
- modeModes :: Mode a -> [Mode a]
- modeFlags :: Mode a -> [Flag a]
- data FlagInfo
  - = FlagReq
  - | FlagOpt String
  - | FlagOptRare String
  - | FlagNone
- fromFlagOpt :: FlagInfo -> String
- type Update a = String -> a -> Either String a
- data Flag a = Flag {
  - flagNames :: [Name]
  - flagInfo :: FlagInfo
  - flagValue :: Update a
  - flagType :: FlagHelp
  - flagHelp :: Help
  }
- data Arg a = Arg {
  - argValue :: Update a
  - argType :: FlagHelp
  - argRequire :: Bool
  }
- checkMode :: Mode a -> Maybe String
- class Remap m where
- remap2 :: Remap m => (a -> b) -> (b -> a) -> m a -> m b
- remapUpdate :: (a -> b) -> (b -> (a, a -> b)) -> Update a -> Update b
- modeEmpty :: a -> Mode a
- mode :: Name -> a -> Help -> Arg a -> [Flag a] -> Mode a
- modes :: String -> a -> Help -> [Mode a] -> Mode a
- flagNone :: [Name] -> (a -> a) -> Help -> Flag a
- flagOpt :: String -> [Name] -> Update a -> FlagHelp -> Help -> Flag a
- flagReq :: [Name] -> Update a -> FlagHelp -> Help -> Flag a
- flagArg :: Update a -> FlagHelp -> Arg a
- flagBool :: [Name] -> (Bool -> a -> a) -> Help -> Flag a
- flagHelpSimple :: (a -> a) -> Flag a
- flagHelpFormat :: (HelpFormat -> TextFormat -> a -> a) -> Flag a
- flagVersion :: (a -> a) -> Flag a
- flagNumericVersion :: (a -> a) -> Flag a
- flagsVerbosity :: (Verbosity -> a -> a) -> [Flag a]
- data HelpFormat
  - = HelpFormatDefault
  - | HelpFormatOne
  - | HelpFormatAll
  - | HelpFormatBash
  - | HelpFormatZsh
- helpText :: [String] -> HelpFormat -> Mode a -> [Text]
- expandArgsAt :: [String] -> IO [String]
- splitArgs :: String -> [String]
- joinArgs :: [String] -> String
- data Complete
  - = CompleteValue String
  - | CompleteFile String FilePath
  - | CompleteDir String FilePath
- complete :: Mode a -> [String] -> (Int, Int) -> [Complete]

# Running command lines

process :: Mode a -> [String] -> Either String a Source #

Process a list of flags (usually obtained from `getArgs`/`expandArgsAt`) with a mode. Returns `Left` and an error message if the command line fails to parse, or `Right` and the associated value.

processArgs :: Mode a -> IO a Source #

Process the flags obtained by ``getArgs`` and ``expandArgsAt`` with a mode. Displays an error and exits with failure if the command line fails to parse, or returns the associated value. Implemented in terms of `process`. This function makes use of the following environment variables:

- `$CMDARGS_COMPLETE` - causes the program to produce completions using `complete`, then exit. Completions are based on the result of `getArgs`, the index of the current argument is taken from `$CMDARGS_COMPLETE` (set it to `-` to complete the last argument), and the index within that argument is taken from `$CMDARGS_COMPLETE_POS` (if set).
- `$CMDARGS_HELPER`/`$CMDARGS_HELPER_PROG` - uses the helper mechanism for entering command line programs as described in System.Console.CmdArgs.Helper.

processValue :: Mode a -> [String] -> a Source #

Process a list of flags (usually obtained from ``getArgs`` and ``expandArgsAt``) with a mode. Throws an error if the command line fails to parse, or returns the associated value. Implemeneted in terms of `process`. This function does not take account of any environment variables that may be set (see `processArgs`).

If you are in `IO` you will probably get a better user experience by calling `processValueIO`.

processValueIO :: Mode a -> [String] -> IO a Source #

Like `processValue` but on failure prints to stderr and exits the program.

# Constructing command lines

type Name = String Source #

A name, either the name of a flag (`--foo`) or the name of a mode.

type Help = String Source #

A help message that goes with either a flag or a mode.

type FlagHelp = String Source #

The type of a flag, i.e. `--foo=TYPE`.

parseBool :: String -> Maybe Bool Source #

Parse a boolean, accepts as True: true yes on enabled 1.

data Group a Source #

A group of items (modes or flags). The items are treated as a list, but the group structure is used when displaying the help message.

Constructors

Group |

Fields

- groupUnnamed :: [a]

  Normal items.

- groupHidden :: [a]

  Items that are hidden (not displayed in the help message).

- groupNamed :: [(Help, [a])]

  Items that have been grouped, along with a description of each group.

Instances

Functor Group Source # |
Methods fmap :: (a -> b) -> Group a -> Group b # (<$) :: a -> Group b -> Group a #
Show a => Show (Group a) Source # |
Methods showsPrec :: Int -> Group a -> ShowS # show :: Group a -> String # showList :: [Group a] -> ShowS #
Monoid (Group a) Source # |
Methods mempty :: Group a # mappend :: Group a -> Group a -> Group a # mconcat :: [Group a] -> Group a #

fromGroup :: Group a -> [a] Source #

Convert a group into a list.

toGroup :: [a] -> Group a Source #

Convert a list into a group, placing all fields in `groupUnnamed`.

data Mode a Source #

A mode. Do not use the `Mode` constructor directly, instead use `mode` to construct the `Mode` and then record updates. Each mode has three main features:

- A list of submodes (`modeGroupModes`)
- A list of flags (`modeGroupFlags`)
- Optionally an unnamed argument (`modeArgs`)

To produce the help information for a mode, either use `helpText` or `show`.

Constructors

Mode |

Fields

- modeGroupModes :: Group (Mode a)

  The available sub-modes

- modeNames :: [Name]

  The names assigned to this mode (for the root mode, this name is used as the program name)

- modeValue :: a

  Value to start with

- modeCheck :: a -> Either String a

  Check the value reprsented by a mode is correct, after applying all flags

- modeReform :: a -> Maybe [String]

  Given a value, try to generate the input arguments.

- modeExpandAt :: Bool

  Expand `@` arguments with `expandArgsAt`, defaults to `True`, only applied if using an `IO` processing function. Only the root `Mode`s value will be used.

- modeHelp :: Help

  Help text

- modeHelpSuffix :: [String]

  A longer help suffix displayed after a mode

- modeArgs :: ([Arg a], Maybe (Arg a))

  The unnamed arguments, a series of arguments, followed optionally by one for all remaining slots

- modeGroupFlags :: Group (Flag a)

  Groups of flags

Instances

Remap Mode Source # |
Methods remap :: (a -> b) -> (b -> (a, a -> b)) -> Mode a -> Mode b Source #

modeModes :: Mode a -> [Mode a] Source #

Extract the modes from a `Mode`

modeFlags :: Mode a -> [Flag a] Source #

Extract the flags from a `Mode`

data FlagInfo Source #

The `FlagInfo` type has the following meaning:

                 FlagReq     FlagOpt      FlagOptRare/FlagNone
    -xfoo        -x=foo      -x=foo       -x -foo
    -x foo       -x=foo      -x foo       -x foo
    -x=foo       -x=foo      -x=foo       -x=foo
    --xx foo     --xx=foo    --xx foo     --xx foo
    --xx=foo     --xx=foo    --xx=foo     --xx=foo

Constructors

FlagReq | Required argument
FlagOpt String | Optional argument
FlagOptRare String | Optional argument that requires an = before the value
FlagNone | No argument

Instances

Eq FlagInfo Source # |
Methods (==) :: FlagInfo -> FlagInfo -> Bool # (/=) :: FlagInfo -> FlagInfo -> Bool #
Ord FlagInfo Source # |
Methods compare :: FlagInfo -> FlagInfo -> Ordering # (<) :: FlagInfo -> FlagInfo -> Bool # (<=) :: FlagInfo -> FlagInfo -> Bool # (>) :: FlagInfo -> FlagInfo -> Bool # (>=) :: FlagInfo -> FlagInfo -> Bool # max :: FlagInfo -> FlagInfo -> FlagInfo # min :: FlagInfo -> FlagInfo -> FlagInfo #
Show FlagInfo Source # |
Methods showsPrec :: Int -> FlagInfo -> ShowS # show :: FlagInfo -> String # showList :: [FlagInfo] -> ShowS #

fromFlagOpt :: FlagInfo -> String Source #

Extract the value from inside a `FlagOpt` or `FlagOptRare`, or raises an error.

type Update a = String -> a -> Either String a Source #

A function to take a string, and a value, and either produce an error message (`Left`), or a modified value (`Right`).

data Flag a Source #

A flag, consisting of a list of flag names and other information.

Constructors

Flag |

Fields

- flagNames :: [Name]

  The names for the flag.

- flagInfo :: FlagInfo

  Information about a flag's arguments.

- flagValue :: Update a

  The way of processing a flag.

- flagType :: FlagHelp

  The type of data for the flag argument, i.e. FILE/DIR/EXT

- flagHelp :: Help

  The help message associated with this flag.

Instances

Remap Flag Source # |
Methods remap :: (a -> b) -> (b -> (a, a -> b)) -> Flag a -> Flag b Source #

data Arg a Source #

An unnamed argument. Anything not starting with `-` is considered an argument, apart from `"-"` which is considered to be the argument `"-"`, and any arguments following `"--"`. For example:

    programname arg1 -j - --foo arg3 -- -arg4 --arg5=1 arg6

Would have the arguments:

    ["arg1","-","arg3","-arg4","--arg5=1","arg6"]

Constructors

Arg |

Fields

- argValue :: Update a

  A way of processing the argument.

- argType :: FlagHelp

  The type of data for the argument, i.e. FILE/DIR/EXT

- argRequire :: Bool

  Is at least one of these arguments required, the command line will fail if none are set

Instances

Remap Arg Source # |
Methods remap :: (a -> b) -> (b -> (a, a -> b)) -> Arg a -> Arg b Source #

checkMode :: Mode a -> Maybe String Source #

Check that a mode is well formed.

class Remap m where Source #

Like functor, but where the the argument isn't just covariant.

Minimal complete definition

remap

Methods

remap :: (a -> b) -> (b -> (a, a -> b)) -> m a -> m b Source #

Convert between two values.

Instances

Remap Arg Source # |
Methods remap :: (a -> b) -> (b -> (a, a -> b)) -> Arg a -> Arg b Source #
Remap Flag Source # |
Methods remap :: (a -> b) -> (b -> (a, a -> b)) -> Flag a -> Flag b Source #
Remap Mode Source # |
Methods remap :: (a -> b) -> (b -> (a, a -> b)) -> Mode a -> Mode b Source #

remap2 :: Remap m => (a -> b) -> (b -> a) -> m a -> m b Source #

Restricted version of `remap` where the values are isomorphic.

remapUpdate :: (a -> b) -> (b -> (a, a -> b)) -> Update a -> Update b Source #

Version of `remap` for the `Update` type alias.

modeEmpty :: a -> Mode a Source #

Create an empty mode specifying only `modeValue`. All other fields will usually be populated using record updates.

mode :: Name -> a -> Help -> Arg a -> [Flag a] -> Mode a Source #

Create a mode with a name, an initial value, some help text, a way of processing arguments and a list of flags.

modes :: String -> a -> Help -> [Mode a] -> Mode a Source #

Create a list of modes, with a program name, an initial value, some help text and the child modes.

flagNone :: [Name] -> (a -> a) -> Help -> Flag a Source #

Create a flag taking no argument value, with a list of flag names, an update function and some help text.

flagOpt :: String -> [Name] -> Update a -> FlagHelp -> Help -> Flag a Source #

Create a flag taking an optional argument value, with an optional value, a list of flag names, an update function, the type of the argument and some help text.

flagReq :: [Name] -> Update a -> FlagHelp -> Help -> Flag a Source #

Create a flag taking a required argument value, with a list of flag names, an update function, the type of the argument and some help text.

flagArg :: Update a -> FlagHelp -> Arg a Source #

Create an argument flag, with an update function and the type of the argument.

flagBool :: [Name] -> (Bool -> a -> a) -> Help -> Flag a Source #

Create a boolean flag, with a list of flag names, an update function and some help text.

flagHelpSimple :: (a -> a) -> Flag a Source #

Create a help flag triggered by `-?`/`--help`.

flagHelpFormat :: (HelpFormat -> TextFormat -> a -> a) -> Flag a Source #

Create a help flag triggered by `-?`/`--help`. The user may optionally modify help by specifying the format, such as:

    --help=all          - help for all modes
    --help=html         - help in HTML format
    --help=100          - wrap the text at 100 characters
    --help=100,one      - full text wrapped at 100 characters

flagVersion :: (a -> a) -> Flag a Source #

Create a version flag triggered by `-V`/`--version`.

flagNumericVersion :: (a -> a) -> Flag a Source #

Create a version flag triggered by `--numeric-version`.

flagsVerbosity :: (Verbosity -> a -> a) -> [Flag a] Source #

Create verbosity flags triggered by `-v`/`--verbose` and `-q`/`--quiet`

# Displaying help

data HelpFormat Source #

Specify the format to output the help.

Constructors

HelpFormatDefault | Equivalent to `HelpFormatAll` if there is not too much text, otherwise `HelpFormatOne`.
HelpFormatOne | Display only the first mode.
HelpFormatAll | Display all modes.
HelpFormatBash | Bash completion information
HelpFormatZsh | Z shell completion information

Instances

Bounded HelpFormat Source # |
Methods minBound :: HelpFormat # maxBound :: HelpFormat #
Enum HelpFormat Source # |
Methods succ :: HelpFormat -> HelpFormat # pred :: HelpFormat -> HelpFormat # toEnum :: Int -> HelpFormat # fromEnum :: HelpFormat -> Int # enumFrom :: HelpFormat -> [HelpFormat] # enumFromThen :: HelpFormat -> HelpFormat -> [HelpFormat] # enumFromTo :: HelpFormat -> HelpFormat -> [HelpFormat] # enumFromThenTo :: HelpFormat -> HelpFormat -> HelpFormat -> [HelpFormat] #
Eq HelpFormat Source # |
Methods (==) :: HelpFormat -> HelpFormat -> Bool # (/=) :: HelpFormat -> HelpFormat -> Bool #
Ord HelpFormat Source # |
Methods compare :: HelpFormat -> HelpFormat -> Ordering # (<) :: HelpFormat -> HelpFormat -> Bool # (<=) :: HelpFormat -> HelpFormat -> Bool # (>) :: HelpFormat -> HelpFormat -> Bool # (>=) :: HelpFormat -> HelpFormat -> Bool # max :: HelpFormat -> HelpFormat -> HelpFormat # min :: HelpFormat -> HelpFormat -> HelpFormat #
Read HelpFormat Source # |
Methods readsPrec :: Int -> ReadS HelpFormat # readList :: ReadS [HelpFormat] # readPrec :: ReadPrec HelpFormat # readListPrec :: ReadPrec [HelpFormat] #
Show HelpFormat Source # |
Methods showsPrec :: Int -> HelpFormat -> ShowS # show :: HelpFormat -> String # showList :: [HelpFormat] -> ShowS #
Default HelpFormat Source # |
Methods def :: HelpFormat Source #

helpText :: [String] -> HelpFormat -> Mode a -> [Text] Source #

Generate a help message from a mode. The first argument is a prefix, which is prepended when not using `HelpFormatBash` or `HelpFormatZsh`.

# Utilities for working with command lines

expandArgsAt :: [String] -> IO [String] Source #

Expand `@` directives in a list of arguments, usually obtained from `getArgs`. As an example, given the file `test.txt` with the lines `hello` and `world`:

    expandArgsAt ["@test.txt","!"] == ["hello","world","!"]

Any `@` directives in the files will be recursively expanded (raising an error if there is infinite recursion).

To supress `@` expansion, pass any `@` arguments after `--`.

splitArgs :: String -> [String] Source #

Given a string, split into the available arguments. The inverse of `joinArgs`.

joinArgs :: [String] -> String Source #

Given a sequence of arguments, join them together in a manner that could be used on the command line, giving preference to the Windows `cmd` shell quoting conventions.

For an alternative version, intended for actual running the result in a shell, see "System.Process.showCommandForUser"

data Complete Source #

How to complete a command line option. The `Show` instance is suitable for parsing from shell scripts.

Constructors

CompleteValue String | Complete to a particular value
CompleteFile String FilePath | Complete to a prefix, and a file
CompleteDir String FilePath | Complete to a prefix, and a directory

Instances

Eq Complete Source # |
Methods (==) :: Complete -> Complete -> Bool # (/=) :: Complete -> Complete -> Bool #
Ord Complete Source # |
Methods compare :: Complete -> Complete -> Ordering # (<) :: Complete -> Complete -> Bool # (<=) :: Complete -> Complete -> Bool # (>) :: Complete -> Complete -> Bool # (>=) :: Complete -> Complete -> Bool # max :: Complete -> Complete -> Complete # min :: Complete -> Complete -> Complete #
Show Complete Source # |
Methods showsPrec :: Int -> Complete -> ShowS # show :: Complete -> String # showList :: [Complete] -> ShowS #

complete Source #

Arguments

:: Mode a | Mode specifying which arguments are allowed
-> [String] | Arguments the user has already typed
-> (Int, Int) | 0-based index of the argument they are currently on, and the position in that argument
-> [Complete] |

Given a current state, return the set of commands you could type now, in preference order.