Core.Program.Arguments

Description

Invoking a command-line program (be it tool or daemon) consists of listing the name of its binary, optionally supplying various options to adjust the behaviour of the program, and then supplying mandatory arguments, if any are specified.

On startup, we parse any arguments passed in from the shell into name,value pairs and incorporated into the resultant configuration stored in the program's Context.

Additionally, this module allows you to specify environment variables that, if present, will be incorporated into the stored configuration.

Synopsis

# Setup

data Config Source #

The setup for parsing the command-line arguments of your program. You build a Config with simple or complex, and pass it to configure.

A completely empty configuration, without the default debugging and logging options. Your program won't process any command-line options or arguments, which would be weird in most cases. Prefer simple.

simple :: [Options] -> Config Source #

Declare a simple (as in normal) configuration for a program with any number of optional parameters and mandatory arguments. For example:

main :: IO ()
main = do
context <- configure "1.0" None (simple
[ Option "host" (Just 'h') Empty [quote|
Specify an alternate host to connect to when performing the
frobnication. The default is "localhost".
|]
, Option "port" (Just 'p') Empty [quote|
Specify an alternate port to connect to when frobnicating.
|]
, Option "dry-run" Nothing (Value "TIME") [quote|
Perform a trial run at the specified time but don't actually
do anything.
|]
, Option "quiet" (Just 'q') Empty [quote|
Supress normal output.
|]
, Argument "filename" [quote|
The file you want to frobnicate.
|]
])

executeWith context program


which, if you build that into an executable called snippet and invoke it with --help, would result in:

$./snippet --help Usage: snippet [OPTIONS] filename Available options: -h, --host Specify an alternate host to connect to when performing the frobnication. The default is "localhost". -p, --port Specify an alternate port to connect to when frobnicating. --dry-run=TIME Perform a trial run at the specified time but don't actually do anything. -q, --quiet Supress normal output. -v, --verbose Turn on event tracing. By default the logging stream will go to standard output on your terminal. --debug Turn on debug level logging. Implies --verbose. Required arguments: filename The file you want to frobnicate.$ |


For information on how to use the multi-line string literals shown here, see quote in Core.Text.Utilities.

complex :: [Commands] -> Config Source #

Declare a complex configuration (implying a larger tool with various "[sub]commands" or "modes"} for a program. You can specify global options applicable to all commands, a list of commands, and environment variables that will be honoured by the program. Each command can have a list of local options and arguments as needed. For example:

program :: Program MusicAppStatus ()
program = ...

main :: IO ()
main = do
context <- configure (fromPackage version) mempty (complex
[ Global
[ Option "station-name" Nothing (Value "NAME") [quote|
Specify an alternate radio station to connect to when performing
actions. The default is "BBC Radio 1".
|]
, Variable "PLAYER_FORCE_HEADPHONES" [quote|
If set to 1, override the audio subsystem to force output
to go to the user's headphone jack.
|]
]
, Command "play" "Play the music."
[ Option "repeat" Nothing Empty [quote|
Request that they play the same song over and over and over
again, simulating the effect of listening to a Top 40 radio
station.
|]
]
, Command "rate" "Vote on whether you like the song or not."
[ Option "academic" Nothing Empty [quote|
The rating you wish to apply, from A+ to F. This is the
default, so there is no reason whatsoever to specify this.
But some people are obsessive, compulsive, and have time on
their hands.
|]
, Option "numeric" Nothing Empty [quote|
Specify a score as a number from 0 to 100 instead of an
not valid scores, despite how vicerally satisfying that
would be for music produced in the 1970s.
|]
, Option "unicode" (Just 'c') Empty [quote|
character.  This allows you to use emoji, so that you can
rate a piece '💩', as so many songs deserve.
|]
, Argument "score" [quote|
The rating you wish to apply.
|]
]
])

executeWith context program


is a program with one global option (in addition to the default ones) [and an environment variable] and two commands: play, with one option; and rate, with two options and a required argument. It also is set up to carry its top-level application state around in a type called MusicAppStatus (implementing Monoid and so initialized here with mempty. This is a good pattern to use given we are so early in the program's lifetime).

The resultant program could be invoked as in these examples:

$./player --station-name="KBBL-FM 102.5" play$

$./player -v rate --numeric 76$


For information on how to use the multi-line string literals shown here, see quote in Core.Text.Utilities.

Result of having processed the command-line and the environment. You get at the parsed command-line options and arguments by calling getCommandLine within a Program block.

Each option and mandatory argument parsed from the command-line is either standalone (in the case of switches and flags, such as --quiet) or has an associated value. In the case of options the key is the name of the option, and for arguments it is the implicit name specified when setting up the program. For example, in:

$./submit --username=gbmh GraceHopper_Resume.pdf  the option has parameter name "username" and value "gmbh"; the argument has parameter name "filename" (assuming that is what was declared in the Argument entry) and a value being the Admiral's CV. This would be returned as: Parameters Nothing [("username","gbmh"), ("filename","GraceHopper_Resume.pdf")] []  The case of a complex command such as git or stack, you get the specific mode chosen by the user returned in the first position: $ missiles launch --all


would be parsed as:

Parameters (Just "launch") [("all",Empty)] []


Constructors

 Parameters
Instances
 Source # Instance detailsDefined in Core.Program.Arguments Methods Source # Instance detailsDefined in Core.Program.Arguments MethodsshowList :: [Parameters] -> ShowS #

Individual parameters read in off the command-line can either have a value (in the case of arguments and options taking a value) or be empty (in the case of options that are just flags).

Constructors

 Value String Empty
Instances
 Source # Instance detailsDefined in Core.Program.Arguments Methods Source # Instance detailsDefined in Core.Program.Arguments MethodsshowList :: [ParameterValue] -> ShowS # Source # Instance detailsDefined in Core.Program.Arguments Methods

# Options and Arguments

newtype LongName Source #

The name of an option, command, or agument (omitting the "--" prefix in the case of options). This identifier will be used to generate usage text in response to --help and by you later when retreiving the values of the supplied parameters after the program has initialized.

Turn on OverloadedStrings when specifying configurations, obviously.

Constructors

 LongName String
Instances
 Source # Instance detailsDefined in Core.Program.Arguments Methods Source # Instance detailsDefined in Core.Program.Arguments Methods(<) :: LongName -> LongName -> Bool #(>) :: LongName -> LongName -> Bool # Source # Instance detailsDefined in Core.Program.Arguments MethodsshowList :: [LongName] -> ShowS # Source # Instance detailsDefined in Core.Program.Arguments Methods Source # Instance detailsDefined in Core.Program.Arguments Methodshash :: LongName -> Int # Source # Instance detailsDefined in Core.Program.Arguments Source # Instance detailsDefined in Core.Program.Arguments Methods Source # Instance detailsDefined in Core.Program.Arguments Methodspretty :: LongName -> Doc ann #prettyList :: [LongName] -> Doc ann #

type ShortName = Char Source #

Single letter "short" options (omitting the "-" prefix, obviously).

The description of an option, command, or environment variable (for use when rendering usage information in response to --help on the command-line).

data Options Source #

Declaration of an optional switch or mandatory argument expected by a program.

Option takes a long name for the option, a short single character abbreviation if offered for convenience, whether or not the option takes a value (and what label to show in help output) and a description for use when displaying usage via --help.

Argument indicates a mandatory argument and takes the long name used to identify the parsed value from the command-line, and likewise a description for --help output.

By convention option and argument names are both lower case. If the identifier is two or more words they are joined with a hyphen. Examples:

        [ Option "quiet" (Just 'q') Empty "Keep the noise to a minimum."
, Option "dry-run" Nothing (Value "TIME") "Run a simulation of what would happen at the specified time."
, Argument "username" "The user to delete from the system."
]


By convention a description is one or more complete sentences each of which ends with a full stop. For options that take values, use upper case when specifying the label to be used in help output.

Variable declares an environment variable that, if present, will be read by the program and stored in its runtime context. By convention these are upper case. If the identifier is two or more words they are joined with an underscore:

        [ ...
, Variable "CRAZY_MODE" "Specify how many crazies to activate."
, ...
]


# Programs with Commands

data Commands Source #

Description of the command-line structure of a program which has "commands" (sometimes referred to as "subcommands") representing different modes of operation. This is familiar from tools like git and docker.

Constructors

 Global [Options] Command LongName Description [Options]

# Internals

Given a program configuration schema and the command-line arguments, process them into key/value pairs in a Parameters object.

This results in InvalidCommandLine on the left side if one of the passed in options is unrecognized or if there is some other problem handling options or arguments (because at that point, we want to rabbit right back to the top and bail out; there's no recovering).

This isn't something you'll ever need to call directly; it's exposed for testing convenience. This function is invoked when you call configure or execute (which calls configure with a default Config when initializing).

Different ways parsing a simple or complex command-line can fail.

Constructors

 InvalidOption String Something was wrong with the way the user specified [usually a short] option. UnknownOption String User specified an option that doesn't match any in the supplied configuration. MissingArgument LongName Arguments are mandatory, and this one is missing. UnexpectedArguments [String] Arguments are present we weren't expecting. UnknownCommand String In a complex configuration, user specified a command that doesn't match any in the configuration. NoCommandFound In a complex configuration, user didn't specify a command. HelpRequest (Maybe LongName) In a complex configuration, usage information was requested with --help, either globally or for the supplied command. VersionRequest Display of the program version requested with --version.
Instances
 Source # Instance detailsDefined in Core.Program.Arguments Methods Source # Instance detailsDefined in Core.Program.Arguments MethodsshowList :: [InvalidCommandLine] -> ShowS # Source # Instance detailsDefined in Core.Program.Arguments Methods