You build up an OptionsParser similarly to the way you build a decoder using the
elm-decode-pipeline
pattern. That is, you start the pipeline by giving it a constructor function,
and then for each argument of your constructor function, you have a corresponding
|> with (Option.someKindOfOption)in the exact same order.
For example, if we define a type alias for a record with two attributes,
Elm generates a 2-argument constructor function for that record type. Here
Elm gives us a GreetOptions function of the type String -> Maybe String -> GreetOptions
(this is just a core Elm language feature). That is, if we pass in a String and
a Maybe String as the 1st and 2nd arguments to the GreetOptions function,
it will build up a record of that type.
So in this example, we call OptionsParser.build with our GreetOptions
constructor function. Then we chain on with once for each of those two arguments.
Note that the first with will give us a String, and the second will give us
a Maybe String, so it matches up perfectly with the order of our constructor's
arguments.
import Cli.Option as Option
import Cli.OptionsParser as OptionsParser exposing (with)
import Cli.Program as Program
type alias GreetOptions =
{ name : String
, maybeGreeting : Maybe String
}
programConfig : Program.Config GreetOptions
programConfig =
Program.config
|> Program.add
(OptionsParser.build GreetOptions
|> with (Option.requiredKeywordArg "name")
|> with (Option.optionalKeywordArg "greeting")
)Start an OptionsParser pipeline with no sub-command (see
the OptionsParser terminilogy legend).
Start an OptionsParser pipeline with a sub-command (see
the OptionsParser terminilogy legend).
Cli.Option.Options To The PipelineMost options can be chained on using with. There are two exceptions,
restArgs and optionalPositionalArgs. elm-cli-options-parser enforces that
they are added in an unambiguous order (see the Cli.OptionsParser.BuilderState docs).
So instead of using with, you add them with their corresponding with...
functions.
import Cli.Option
import Cli.OptionsParser as OptionsParser exposing (with)
type GitOptionsParser
= Init
| Log LogOptions -- ...
type alias LogOptions =
{ maybeAuthorPattern : Maybe String
, maybeNumberToDisplay : Maybe Int
}
logOptionsParser =
OptionsParser.buildSubCommand "log" LogOptions
|> with (Option.optionalKeywordArg "author")
|> with
(Option.optionalKeywordArg "max-count"
|> Option.validateMapIfPresent String.toInt
)
|> with (Option.flag "stat")
|> OptionsParser.withOptionalPositionalArg
(Option.optionalPositionalArg "revision range")
|> OptionsParser.withRestArgs
(Option.restArgs "rest args")The User of the Command-Line Interface will get an error message if there is no
OptionsParser that succeeds. And an OptionsParser will only succeed if
a valid number of positional arguments is passed in, as defined by these rules:
restArgsFor chaining on any Cli.Option.Option besides a restArg or an optionalPositionalArg.
See the Cli.Option module.
For chaining on Cli.Option.optionalPositionalArgs.
For chaining on Cli.Option.restArgs.
The OptionsParser will only match if the given flag is present. Often its
best to use a subcommand in these cases.
Map the CLI options returned in the OptionsParser using the supplied map function.
This is very handy when you want a type alias for a record with options for a
a given OptionsParser, but you need all of your OptionsParser to map into
a single union type.
import Cli.Option as Option
import Cli.OptionsParser as OptionsParser
import Cli.Program as Program
import Ports
type CliOptions
= Hello HelloOptions
| Goodbye GoodbyeOptions
type alias HelloOptions =
{ name : String
, maybeHello : Maybe String
}
type alias GoodbyeOptions =
{ name : String
, maybeGoodbye : Maybe String
}
programConfig : Program.Config CliOptions
programConfig =
Program.config
|> Program.add
(OptionsParser.buildSubCommand "hello" HelloOptions
|> OptionsParser.with (Option.requiredKeywordArg "name")
|> OptionsParser.with (Option.optionalKeywordArg "greeting")
|> OptionsParser.map Hello
)
|> Program.add
(OptionsParser.buildSubCommand "goodbye" GoodbyeOptions
|> OptionsParser.with (Option.requiredKeywordArg "name")
|> OptionsParser.with (Option.optionalKeywordArg "goodbye")
|> OptionsParser.map Goodbye
)Use a fixed value for the next step in the pipeline. This doesn't use any input from the user, it just passes the supplied value through in the chain.
import Cli.Option as Option
import Cli.OptionsParser as OptionsParser
import Cli.Program as Program
type alias GreetOptions =
{ name : String
, maybeGreeting : Maybe String
, hardcodedValue : String
}
programConfig : Program.Config GreetOptions
programConfig =
Program.config
|> Program.add
(OptionsParser.build GreetOptions
|> OptionsParser.with (Option.requiredKeywordArg "name")
|> OptionsParser.with (Option.optionalKeywordArg "greeting")
|> OptionsParser.hardcoded "any hardcoded value"
)Add a description to an OptionsParser. This description appears in help output
and error messages.
import Cli.OptionsParser as OptionsParser exposing (OptionsParser, with)
type GitCommand
= Init
| Clone String
gitInitParser : OptionsParser GitCommand
gitInitParser =
OptionsParser.buildSubCommand "init" Init
|> OptionsParser.withDescription "initialize a git repository"In error messages, the description appears after # in the usage line:
git init # initialize a git repositoryWhen using subcommand-specific help (git init --help), the description
appears below the usage line.
Low-level function, for internal use.
These functions are exposed for internal use and testing. They are not part of the public API.
Low-level function, for internal use.
Low-level function, for internal use.
Low-level function, for internal use.
Low-level function, for internal use.
Low-level function, for internal use. Generate detailed help text with Usage line and Options section.
An
OptionsParserrepresents one possible way to interpret command line arguments. ACli.Program.Configcan be built up using one or moreOptionsParsers. It will try each parser in order until one succeeds. If none succeed, it will print an error message with information for the user of the Command-Line Interface.