packages feed

optparse-applicative 0.13.0.0 → 0.13.1.0

raw patch · 12 files changed

+907/−224 lines, 12 filesdep ~QuickCheckdep ~process

Dependency ranges changed: QuickCheck, process

Files

CHANGELOG.md view
@@ -1,3 +1,11 @@+## Version 0.13.1.0 (10 Feb 2017)++- Updated dependency bounds.++- Add required test files to cabal package.++- Doc+ ## Version 0.13.0.0 (15 Aug 2016)  - Implement command groups, which allow subcommands to have their own
Options/Applicative/Builder.hs view
@@ -145,6 +145,9 @@ -- do not use it with combinators such as 'some' or 'many', as -- these combinators continue until a failure occurs. -- Careless use will thus result in a hang.+--+-- To display the default value, combine with showDefault or+-- showDefaultWith. value :: HasValue f => a -> Mod f a value x = Mod id (DefaultProp (Just x) Nothing) id @@ -235,6 +238,10 @@ -- -- A flag that switches from a \"default value\" to an \"active value\" when -- encountered. For a simple boolean value, use `switch` instead.+--+-- /Note/: Because this parser will never fail, it can not be used with+-- combinators such as 'some' or 'many', as these combinators continue until+-- a failure occurs. See @flag'@. flag :: a                         -- ^ default value      -> a                         -- ^ active value      -> Mod FlagFields a          -- ^ option modifier@@ -250,7 +257,12 @@ -- -- > length <$> many (flag' () (short 't')) ----- is a parser that counts the number of "-t" arguments on the command line.+-- is a parser that counts the number of "-t" arguments on the command line,+-- alternatively+--+-- > flag' True (long "on") <|> flag' False (long "off")+--+-- will require the user to enter '--on' or '--off' on the command line. flag' :: a                         -- ^ active value       -> Mod FlagFields a          -- ^ option modifier       -> Parser a@@ -262,6 +274,10 @@  -- | Builder for a boolean flag. --+-- /Note/: Because this parser will never fail, it can not be used with+-- combinators such as 'some' or 'many', as these combinators continue until+-- a failure occurs. See @flag'@.+-- -- > switch = flag False True switch :: Mod FlagFields Bool -> Parser Bool switch = flag False True@@ -291,6 +307,12 @@ nullOption = option  -- | Builder for an option using the given reader.+--+-- This is a regular option, and should always have either a @long@ or+-- @short@ name specified in the modifiers (or both).+--+-- > nameParser = option str ( long "name" <> short 'n' )+-- option :: ReadM a -> Mod OptionFields a -> Parser a option r m = mkParser d g rdr   where
Options/Applicative/Common.hs view
@@ -56,7 +56,6 @@ import Control.Monad.Trans.State (StateT(..), get, put, runStateT) import Data.List (isPrefixOf) import Data.Maybe (maybeToList, isJust)-import Data.Semigroup hiding (Option) import Prelude  import Options.Applicative.Internal@@ -80,24 +79,11 @@ liftOpt :: Option a -> Parser a liftOpt = OptP -data MatchResult-  = NoMatch-  | Match (Maybe String)--instance Monoid MatchResult where-  mempty = NoMatch-  mappend = (<>)--instance Semigroup MatchResult where-  m@(Match _) <> _ = m-  _           <> m = m- argMatches :: MonadP m => OptReader a -> String            -> Maybe (StateT Args m a) argMatches opt arg = case opt of-  ArgReader rdr -> Just $ do-    result <- lift $ runReadM (crReader rdr) arg-    return result+  ArgReader rdr -> Just . lift $+    runReadM (crReader rdr) arg   CmdReader _ _ f ->     flip fmap (f arg) $ \subp -> StateT $ \args -> do       prefs <- getPrefs
Options/Applicative/Internal.hs view
@@ -81,7 +81,7 @@    missingArgP e _ = errorP e   tryP (P p) = P $ lift $ runExceptT p-  exitP i p = P . (maybe (throwE . MissingError i . SomeParser $ p) return)+  exitP i p = P . maybe (throwE . MissingError i . SomeParser $ p) return   errorP = P . throwE  hoistMaybe :: MonadPlus m => Maybe a -> m a
README.md view
@@ -1,132 +1,389 @@-# Applicative option parser--This package contains utilities and combinators to define command line option-parsers.+# optparse-applicative  [![Continuous Integration status][status-png]][status] [![Hackage page (downloads and API reference)][hackage-png]][hackage] +optparse-applicative is a haskell library for parsing options on+the command line, providing a powerful [applicative] interface+for composing these options.++optparse-applicative takes care of reading and validating the+arguments passed to the command line, handling and reporting errors,+generating a usage line, a comprehensive help screen, and enabling+context-sensitive bash completions.+ **Table of Contents** -- [Getting started](#getting-started)-- [Supported options](#supported-options)+- [Introduction](#introduction)+- [Quick Start](#quick-start)+- [Basics](#Basics)+    - [Parsers](#parsers)+    - [Applicative](#applicative)+    - [Alternative](#alternative)+    - [Running parsers](#running-parsers)+- [Builders](#builders)     - [Regular options](#regular-options)     - [Flags](#flags)     - [Arguments](#arguments)     - [Commands](#commands)-- [Option builders](#option-builders)-- [Advanced features](#advanced-features)+    - [Modifiers](#modifiers)+- [Custom parsing and error handling](#custom-parsing-and-error-handling)+    - [Parser runners](#parser-runners)+    - [Option readers](#option-readers)+    - [Preferences](#preferences)+    - [Disambiguation](#disambiguation)+    - [Customising the help screen](#customising-the-help-screen)+    - [Command Groups](#command-groups)+- [Bash completion](#bash-completion)+    - [Actions and completers](#actions-and-completers)+    - [Internals](#internals)+- [Arrow interface](#arrow-interface)+- [Applicative Do](#applicative-do)+- [FAQ](#faq) - [How it works](#how-it-works) -## Getting started+## Introduction -Install with+The core type in optparse-applicative is a `Parser` -```sh-cabal install optparse-applicative+```haskell+data Parser a++instance Functor Parser+instance Applicative Parser+instance Alternative Parser ``` -Here is a simple example of an applicative option parser:+A value of type `Parser a` represents a specification for a set of+options, which will yield a value of type `a` when the command line+arguments are successfully parsed. +If you are familiar with parser combinator libraries like [parsec],+[attoparsec], or the json parser [aeson] you will feel right at+home with optparse-applicative.++If not, don't worry! All you really need to learn are a few basic+parsers, and how to compose them as instances of `Applicative` and+`Alternative`.++## Quick Start++Here's a simple example of a parser.+ ```haskell import Options.Applicative+import Data.Semigroup ((<>))  data Sample = Sample-  { hello :: String-  , quiet :: Bool }+  { hello  :: String+  , quiet  :: Bool+  , repeat :: Int }  sample :: Parser Sample sample = Sample-     <$> strOption-         ( long "hello"-        <> metavar "TARGET"-        <> help "Target for the greeting" )-     <*> switch-         ( long "quiet"-        <> help "Whether to be quiet" )+      <$> strOption+          ( long "hello"+         <> metavar "TARGET"+         <> help "Target for the greeting" )+      <*> switch+          ( long "quiet"+         <> short 'q'+         <> help "Whether to be quiet" )+      <*> option auto+          ( long "repeat"+         <> help "Repeats for greeting"+         <> showDefault+         <> value 1+         <> metavar "INT" ) ``` -The parser is built using [applicative style][applicative] starting from a set-of basic combinators. In this example, `hello` is defined as an option with a-`String` argument, while `quiet` is a boolean flag (called `switch`).+The parser is built using an [applicative] style starting from a+set of basic combinators. In this example, hello is defined as an+option with a `String` argument, while quiet is a boolean flag+(called switch) and repeat gets parsed as an `Int` with help of the+`Read` type class. -A parser can be used like this: -```haskell-greet :: Sample -> IO ()-greet (Sample h False) = putStrLn $ "Hello, " ++ h-greet _ = return ()+The parser can be used like this: +```haskell main :: IO ()-main = execParser opts >>= greet+main = greet =<< execParser opts   where-    opts = info (helper <*> sample)+    opts = info (sample <**> helper)       ( fullDesc      <> progDesc "Print a greeting for TARGET"      <> header "hello - a test for optparse-applicative" )++greet :: Sample -> IO ()+greet (Sample h False n) = replicateM_ n . putStrLn $ "Hello, " ++ h+greet _ = return () ``` -The `greet` function is the entry point of the program, while `opts` is a-complete description of the program, used when generating a help text. The-`helper` combinator takes any parser, and adds a `help` option to it.+The `greet` function is the entry point of the program, while `opts`+is a complete description of the program, used when generating a+help text. The `helper` combinator takes any parser, and adds a+`help` option to it. -The `hello` option in this example is mandatory (since it doesn't have a-default value), so running the program without any argument will display a-short option summary:+The `hello` option in this example is mandatory since it doesn't+have a default value, so running the program without any argument+will display an appropriate error message and a short option summary: -    Usage: hello --hello TARGET [--quiet]+    Missing: --hello TARGET -Running the program with the `--help` option will display the full help text:+    Usage: hello --hello TARGET [-q|--quiet] [--repeat INT]+      Print a greeting for TARGET +Running the program with the `--help` option will display the full help text+containing a detailed list of options with descriptions++```     hello - a test for optparse-applicative -    Usage: hello --hello TARGET [--quiet]+    Usage: hello --hello TARGET [-q|--quiet] [--repeat INT]       Print a greeting for TARGET      Available options:-      -h,--help                Show this help text       --hello TARGET           Target for the greeting-      --quiet                  Whether to be quiet+      -q,--quiet               Whether to be quiet+      --repeat INT             Repeats for greeting (default: 1)+      -h,--help                Show this help text+``` -containing a detailed list of options with descriptions.+## Basics+### Parsers -The specified metavars are used as placeholders for the option arguments, and-can be referred to in the program description.  This makes it possible to-explicitly describe the connection between the options and the behaviour of the-program.+optparse-applicative provides a number of primitive parsers,+corresponding to different posix style options, through its *Builder*+interface. These are detailed in their [own section](#builders)+below, for now, here's a look at a few more examples to get a feel+for how parsers can be defined. -Parsers are instances of both `Applicative` and `Alternative`, and work with-any generic combinator, like `many` and `some`. For example, to make a option-return `Nothing` instead of failing when it's not supplied, you can use the-`optional` combinator in `Control.Applicative`: +Here is a parser for a mandatory option with an argument:+ ```haskell-optional $ strOption-   ( long "output"-  <> metavar "DIRECTORY" )+target :: Parser String+target = strOption+  (  long "target"+  <> metavar "TARGET"+  <> help "Target for the greeting" ) ``` - [applicative]: http://www.soi.city.ac.uk/~ross/papers/Applicative.html+One can see that we are defining an option parser for a `String`+argument, with *long* option name "hello", *metavariable* "TARGET",+and the given help text. This means that the `target` parser defined+above will require an option like -## Supported options+    --target world -`optparse-applicative` supports four kinds of options: regular options, flags,-arguments and commands.+on the command line. The metavariable and the help text will appear+in the generated help text, but don't otherwise affect the behaviour+of the parser. +The attributes passed to the option are called *modifiers*, and are+composed using the [semigroup] operation `(<>)`.++Options with an argument such as `target` are referred to as *regular+options*, and are very common.  Another type of option is a *flag*,+the simplest of which is a boolean *switch*, for example:++```haskell+quiet :: Parser Bool+quiet = switch ( long "quiet" <> short 'q' <> help "Whether to be quiet" )+```++Here we used a `short` modifier to specify a one-letter name for+the option.  This means that this switch can be set either with+`--quiet` or `-q`.++Flags, unlike regular options, have no arguments. They simply return+a predetermined value. For the simple switch above, this is `True`+if the user types the flag, and `False` otherwise.++There are other kinds of basic parsers, and several ways to configure+them.  These are covered in the [Builders](#builders) section.++### Applicative++Now we may combine the `target` and `quiet` into a single parser that+accepts both options and returns a combined value. Given a type++```haskell+data Options = Options+  { optTarget :: String+  , optQuiet :: Bool }+```++and now it's just a matter of using `Applicative`'s apply operator `(<*>)`+to combine the two previously defined parsers++```haskell+opts :: Parser Options+opts = Options <$> target <*> quiet+```++No matter which parsers appear first in the sequence, options will+still be parsed in whatever order they appear in the command line.+A parser with such a property is sometimes called a *permutation+parser*.++In our example, a command line like:++    --target world -q++will give the same result as++    -q --target world++It is this property which leads us to an Applicative interface+instead of a Monadic one, as all option must be considered in+parallel, and can not depend on the output of other options.++Note, however, that the order of sequencing is still somewhat+significant, in that it affects the generated help text. Customisation+can be achieved easily through a lambda abstraction, with [Arrow+notation](#arrow-interface), or by taking advantage of GHC 8's+[ApplicativeDo](#applicative-do) extension.++### Alternative++It is also common to find programs that can be configured in different+ways through the command line.  A typical example is a program that+can be given a text file as input, or alternatively read it directly+from the standard input.++We can model this easily and effectively in Haskell using *sum types*:++```haskell+data Input+  = FileInput FilePath+  | StdInput++run :: Input -> IO ()+run = ...+```++We can now define two basic parsers for the components of the sum type:++```haskell+fileInput :: Parser Input+fileInput = FileInput <$> strOption+  (  long "file"+  <> short 'f'+  <> metavar "FILENAME"+  <> help "Input file" )++stdInput :: Parser Input+stdInput = flag' StdInput+  (  long "stdin"+  <> help "Read from stdin" )+```++As the `Parser` type constructor is an instance of `Alternative`, we can+compose these parsers with a choice operator `(<|>)`++```haskell+input :: Parser Input+input = fileInput <|> stdInput+```++Now `--file "foo.txt"` will be parsed as `FileInput "foo.txt"`, `--stdin`+will be parsed as `StdInput`, but a command line containing both options,+like++    --file "foo.txt" --stdin++will be rejected.++Having `Applicative` and `Alternative` instances, optparse-applicative+parsers are also able to be composed with standard combinators. For+example: `optional :: Alternative f => f a -> f (Maybe a)` will+mean the user is not required to provide input for the affected+`Parser`.++### Running parsers++Before we can run a `Parser`, we need to wrap it into a `ParserInfo`+structure, that specifies a number of properties that only apply+to top level parsers, such as a header describing what the program+does, to be displayed in the help screen.++The function `info` will help with this step.  In the [Quick Start](#quick-start)+we saw++```haskell+opts :: ParserInfo Sample+opts = info (sample <**> helper)+  ( fullDesc+  <> progDesc "Print a greeting for TARGET"+  <> header "hello - a test for optparse-applicative" )+```++The `helper` parser that we added after `opts` just creates a dummy+`--help` option that displays the help text.  Besides that, we just+set some of the fields of the `ParserInfo` structure with meaningful+values.  Now that we have a `ParserInfo`, we can finally run the+parser.  The simplest way to do so is to simply call the `execParser`+function in your `main`:++```haskell+main :: IO ()+main = do+  options <- execParser opts+  ...+```++The `execParser` function takes care of everything, including getting+the arguments from the command line, displaying errors and help+screens to the user, and exiting with an appropriate exit code.++There are other ways to run a `ParserInfo`, in situations where you+need finer control over the behaviour of your parser, or if you+want to use it in pure code. They will be covered in [Custom parsing+and error handling](#custom-parsing-and-error-handling).++## Builders++Builders allow you to define parsers using a convenient combinator-based+syntax. We have already seen examples of builders in action, like+`strOption` and `switch`, which we used to define the `opts` parser+for our "hello" example.++Builders always take a [modifier](#modifiers) argument, which is+essentially a composition of functions acting on the option, setting+values for properties or adding features.++Builders work by building the option from scratch, and eventually+lifting it to a single-option parser, ready to be combined with+other parsers using normal `Applicative` and `Alternative` combinators.++See the [haddock documentation][hackage] for `Options.Applicative.Builder`+for a full list of builders and modifiers.++There are four different kinds of options in `optparse-applicative`:+regular options, flags, arguments, and commands. In the following,+we will go over each one of these and describe the builders that+can be used to create them.+ ### Regular options -A **regular option** is an option which takes a single argument, parses it, and-returns a value.+A *regular option* is an option which takes a single argument,+parses it, and returns a value. -A regular option can have a default value, which is used as the result if the-option is not found in the command line. An option without a default value is-considered mandatory, and produces an error when not found.+A regular option can have a default value, which is used as the+result if the option is not found in the command line. An option+without a default value is considered mandatory, and produces an+error when not found. -Regular options can have **long** names, or **short** (one-character) names,-which determine when the option matches and how the argument is extracted.+Regular options can have *long* names, or *short* (one-character)+names, which determine when the option matches and how the argument+is extracted. -An option with a long name (say "output") is specified on the command line as+An option with a long name (say "output") is specified on the command+line as +     --output filename.txt  or@@ -141,29 +398,30 @@      -ofilename.txt -Options can have more than one name, usually one long and one short, although-you are free to create options with an arbitrary combination of long and short-names.+Options can have more than one name, usually one long and one short,+although you are free to create options with an arbitrary combination+of long and short names. -Regular options returning strings are the most common, and they can be created-using the `strOption` builder. For example,+Regular options returning strings are the most common, and they can+be created using the `strOption` builder. For example,  ```haskell strOption    ( long "output"   <> short 'o'   <> metavar "FILE"+  <> value "out.txt"   <> help "Write output to FILE" ) ``` -creates a regular option with a string argument (which can be referred to as-`FILE` in the help text and documentation), a long name "output" and a short-name "o". See below for more information on the builder syntax and modifiers.+creates a regular option with a string argument (which can be+referred to as `FILE` in the help text and documentation), default+value "out.txt", a long name "output" and a short name "o". -A regular option can return an object of any type, and takes a *reader*-parameter which specifies how the argument should be parsed.  A common reader is-`auto`, which assumes a `Read` instance for the return type and uses it to parse-its argument. For example:+A regular `option` can return an object of any type, and takes a+*reader* parameter which specifies how the argument should be parsed.+A common reader is `auto`, which requires a `Read` instance for the+return type and uses it to parse its argument. For example:  ```haskell lineCount :: Parser Int@@ -174,39 +432,22 @@            <> help "Output the last K lines" ) ``` -specifies a regular option with an `Int` argument. We added an explicit type-annotation here, since without it the parser would have been polymorphic in the-output type. There's usually no need to add type annotations, however, because-the type will be normally inferred from the context in which the parser is-used.--One can also create a custom reader that doesn't use the `Read` typeclass, and-use it to parse option arguments. A custom reader is a value in the `ReadM`-monad. We provide `eitherReader :: (String -> Either String a) -> ReadM a`-to help create these values, where a `Left` will hold the error message-for a failure.--```haskell-data FluxCapacitor = ...--parseFluxCapacitor :: ReadM FluxCapacitor-parseFluxCapacitor = eitherReader $ \s -> ...--option parseFluxCapacitor ( long "flux-capacitor" )-```+specifies a regular option with an `Int` argument. We added an+explicit type annotation here, since without it the parser would+have been polymorphic in the output type. There's usually no need+to add type annotations, however, because the type will be normally+inferred from the context in which the parser is used. -One can also use `ReadM` directly, using `str` to obtain the command line string,-and `readerAbort` or `readerError` within the `ReadM` monad to exit with an-error message.+Further information on *readers* is available [below](#option-readers).  ### Flags -A **flag** is just like a regular option, but it doesn't take any arguments: it is-either present in the command line or not.+A *flag* is just like a regular option, but it doesn't take any+arguments, it is either present in the command line or not. -A flag has a default value and an **active value**. If the flag is found on the-command line, the active value is returned, otherwise the default value is-used. For example:+A flag has a default value and an *active value*. If the flag is+found on the command line, the active value is returned, otherwise+the default value is used. For example:  ```haskell data Verbosity = Normal | Verbose@@ -227,80 +468,87 @@  <> help "Retain all intermediate temporary files" ) ``` -There is also a `flag'` builder, which has no default value. For example, to-add a `--version` switch to a program, you could write:+There is also a `flag'` builder, which has no default value. This+was demonstrated earlier for our `--stdin` flag example, and is+usually used as one side of an alternative. +Another interesting use for the `flag'` builder is to count the+number of instances on the command line, for example, verbosity+settings could be specified on a scale; the following parser with+count the number of of instances of `-v` on the command line.+ ```haskell-flag' Nothing (long "version" <> hidden) <|> (Just <$> normal_options)+length <$> many (flag' () (short 'v')) ``` +Flags can be used together after a single hyphen, so  `-vvv` and+`-v -v -v` will both yield 3 for the above parser.+ ### Arguments -An **argument** parser specifies a positional command line argument.+An *argument* parser specifies a positional command line argument. -The `argument` builder takes a reader parameter, and creates a parser which-will return the parsed value every time it is passed a command line argument-for which the reader succeeds. For example+The `argument` builder takes a reader parameter, and creates a+parser which will return the parsed value every time it is passed+a command line argument for which the reader succeeds. For example  ```haskell argument str (metavar "FILE") ``` -creates an argument accepting any string.  To accept an arbitrary number of-arguments, combine the `argument` builder with either the `many` or `some`-combinator:+creates an argument accepting any string.  To accept an arbitrary+number of arguments, combine the `argument` builder with either the+`many` or `some` combinator:  ```haskell some (argument str (metavar "FILES...")) ``` -Arguments are only displayed in the brief help text, so there's no need to-attach a description to them. They should be manually documented in the program-description.+Note that arguments starting with `-` are considered options by+default, and will not be considered by an `argument` parser. -Note that arguments starting with `-` are considered options by default, and-will not be considered by an `argument` parser.+However, parsers always accept a special argument: `--`. When a+`--` is found on the command line, all the following words are+considered by `argument` parsers, regardless of whether they start+with `-` or not. -However, parsers always accept a special argument: `--`. When a `--` is found on-the command line, all the following words are considered by `argument` parsers,-regardless of whether they start with `-` or not.+Arguments use the same *readers* as regular options.  ### Commands -A **command** can be used to specify a sub-parser to be used when a certain-string is encountered in the command line.+A *command* can be used to specify a sub-parser to be used when a+certain string is encountered in the command line. -Commands are useful to implement command line programs with multiple functions,-each with its own set of options, and possibly some global options that apply-to all of them. Typical examples are version control systems like `git`, or-build tools like `cabal`.+Commands are useful to implement command line programs with multiple+functions, each with its own set of options, and possibly some+global options that apply to all of them. Typical examples are+version control systems like `git`, or build tools like `cabal`. -A command can be created using the `subparser` builder, and commands can be-added with the `command` modifier. For example+A command can be created using the `subparser` builder (or `hsubparser`,+which is identical but for an additional `--help` option on each+command), and commands can be added with the `command` modifier.+For example  ```haskell subparser-  ( command "add" (info addOptions-      ( progDesc "Add a file to the repository" ))- <> command "commit" (info commitOptions-      ( progDesc "Record changes to the repository" ))-)+  ( command "add" (info addOptions ( progDesc "Add a file to the repository" ))+ <> command "commit" (info commitOptions ( progDesc "Record changes to the repository" ))+  ) ``` -Each command takes a full `ParserInfo` structure, which will be used to extract-a description for this command when generating a help text.+Each command takes a full `ParserInfo` structure, which will be+used to extract a description for this command when generating a+help text. -Note that all the parsers appearing in a command need to have the same type.-For this reason, it is often best to use a sum type which has the same-structure as the command itself. For example, for the parser above, you would-define a type like:+Note that all the parsers appearing in a command need to have the+same type.  For this reason, it is often best to use a sum type+which has the same structure as the command itself. For example,+for the parser above, you would define a type like:  ```haskell data Options = Options-  { optGlobalOpt :: String-  , optGlobalFlag :: Bool-  ...-  , optCommand :: Command }+  { optCommand :: Command+  , ... }  data Command   = Add AddOptions@@ -308,8 +556,8 @@   ... ``` -Alternatively, you can directly return an `IO` action from a parser, and-execute it using `join` from `Control.Monad`.+Alternatively, you can directly return an `IO` action from a parser,+and execute it using `join` from `Control.Monad`.  ```haskell start :: String -> IO ()@@ -324,47 +572,438 @@ main = join $ execParser (info opts idm) ``` -## Option builders+### Modifiers -Builders allow you to define parsers using a convenient combinator-based-syntax. Each builder takes a **modifier** as parameter, and returns a parser.+*Modifiers* are instances of the `Semigroup` and `Monoid` typeclasses,+so they can be combined using the composition function `mappend`+(or simply `(<>)`).  Since different builders accept different sets+of modifiers, modifiers have a type parameter that specifies which+builders support it. -A modifier is a composition of functions which act on the option, setting-values for properties or adding features, and is used to build the option from-scratch and finally lift it to a single-option parser, which can then be-combined with other parsers using normal `Applicative` combinators.+For example, -Modifiers are instances of the `Monoid` typeclass, so they can be combined-using the composition function `mappend` (or simply `(<>)`).+```haskell+command :: String -> ParserInfo a -> Mod CommandFields a+``` -See the [haddock documentation][builder-documentation] for `Options.Applicative.Builder`-for a full list of builders and modifiers.+can only be used with [commands](#commands), as the `CommandFields`+type argument of `Mod` will prevent it from being passed to builders+for other types of options. -## Advanced features+Many modifiers are polymorphic in this type argument, which means+that they can be used with any builder. -* [Bash completion]-* [Arrow interface]-* [Disambiguation]+## Custom parsing and error handling - [Bash completion]: https://github.com/pcapriotti/optparse-applicative/wiki/Bash-Completion- [Arrow interface]: https://github.com/pcapriotti/optparse-applicative/wiki/Arrows- [Disambiguation]: https://github.com/pcapriotti/optparse-applicative/wiki/Disambiguation+### Parser runners+Parsers are run with the `execParser` family of functions — from+easiest to use to most flexible these are: +```haskell+execParser       :: ParserInfo a -> IO a+customExecParser :: ParserPrefs -> ParserInfo a -> IO a+execParserPure   :: ParserPrefs -> ParserInfo a -> [String] -> ParserResult a+```++When using the `IO` functions, retrieving command line arguments+and handling exit codes and failure will be done automatically.+When using `execParserPure`, the functions++```haskell+handleParseResult :: ParserResult a -> IO a+overFailure :: (ParserHelp -> ParserHelp) -> ParserResult a -> ParserResult a+```++can be used to correctly set exit codes and display the help message;+and modify the help message in the event of a failure (adding+additional information for example).++### Option readers++Options and Arguments require a way to interpret the string passed+on the command line to the type desired. The `str` and `auto`+*readers* are the most common way, but one can also create a custom+reader that doesn't use the `Read` type class or return a `String`,+and use it to parse the option. A custom reader is a value in the+`ReadM` monad.++We provide the `eitherReader :: (String -> Either String a) -> ReadM a`+convenience function to help create these values, where a `Left` will+hold the error message for a parse failure.++```haskell+data FluxCapacitor = ...++parseFluxCapacitor :: ReadM FluxCapacitor+parseFluxCapacitor = eitherReader $ \s -> ...++option parseFluxCapacitor ( long "flux-capacitor" )+```++One can also use `ReadM` directly, using `readerAsk` to obtain the+command line string, and `readerAbort` or `readerError` within the+`ReadM` monad to exit with an error message.++One nice property of `eitherReader` is how well it composes with+[attoparsec] parsers with++```haskell+import qualified Data.Attoparsec.Text as A+attoReadM :: A.Parser a -> ReadM a+attoReadM p = eitherReader (A.parseOnly p . T.pack)+```++### Preferences+`PrefsMod`s can be used to customise the look of the usage text and+control when it is displayed; turn off backtracking of subparsers;+and turn on [disambiguation](#disambiguation).++To use these modifications, provide them to the `prefs` builder,+and pass the resulting preferences to one of the parser runners+that take an `ParserPrefs` parameter, like `customExecParser`.+++### Disambiguation++It is possible to configure optparse-applicative to perform automatic+disambiguation of prefixes of long options. For example, given a+program `foo` with options `--filename` and `--filler`, typing++    $ foo --fil test.txt++fails, whereas typing++    $ foo --file test.txt++succeeds, and correctly identifies `"file"` as an unambiguous prefix+of the `filename` option.++Option disambiguation is *off* by default. To enable it, use the+`disambiguate` `PrefsMod` modifier as described above.++Here is a minimal example:++```haskell+import Options.Applicative++sample :: Parser ()+sample = () <$+  switch (long "filename") <*+  switch (long "filler")++main :: IO ()+main = customExecParser p opts+  where+    opts = info (helper <*> sample) idm+    p = prefs disambiguate++```++### Customising the help screen++optparse-applicative has a number of combinators to help customise+the usage text, and determine when it should be displayed.++The `progDesc`, `header`, and `footer` functions can be used to+specify a brief description or tagline for the program, and detailed+information surrounding the generated option and command descriptions.++Internally we actually use the [ansi-wl-pprint][ansi-wl-pprint]+library, and one can use the `headerDoc` combinator and friends if+additional customisation is required.++To display the usage text, the user may type `--help` if the `helper`+combinator has been applied to the `Parser`.++Authors can also use the preferences `showHelpOnError` or+`showHelpOnEmpty` to show the help text on any parser failure or+when a command is not complete and at the beginning of the parse+of the main program or one of its subcommands respectively.++Even if the help text is not shown for an error, a specific error+message will be, indicating what's missing, or what was unable to+be parsed.++```haskell+myParser :: Parser ()+myParser = ...++main :: IO ()+main = customExecParser p opts+  where+    opts = info (myParser <**> helper) idm+    p = prefs showHelpOnEmpty+```++### Command groups++One experimental feature which may be useful for programs with many+subcommands is command group separation.++```haskell+data Sample+  = Hello [String]+  | Goodbye+  deriving (Eq, Show)++hello :: Parser Sample+hello = Hello <$> many (argument str (metavar "TARGET..."))++sample :: Parser Sample+sample = subparser+       ( command "hello" (info hello (progDesc "Print greeting"))+      <> command "goodbye" (info (pure Goodbye) (progDesc "Say goodbye"))+       )+      <|> subparser+       ( command "bonjour" (info hello (progDesc "Print greeting"))+      <> command "au-revoir" (info (pure Goodbye) (progDesc "Say goodbye"))+      <> commandGroup "French commands:"+      <> hidden+       )+```++This will logically separate the usage text for the two subparsers+(these would normally appear together if the `commandGroup` modifier+was not used). The `hidden` modifier suppresses the metavariable+for the second subparser being show in the brief usage line, which+is desirable in some cases.++In this example we have essentially created synonyms for our parser,+but one could use this to separate common commands from rare ones,+or safe from dangerous.++The usage text for the preceding example is:+```+Usage: commands COMMAND++Available options:+  -h,--help                Show this help text++Available commands:+  hello                    Print greeting+  goodbye                  Say goodbye++French commands:+  bonjour                  Print greeting+  au-revoir                Say goodbye+```++## Bash completion++`optparse-applicative` has built-in support for bash completion of+command line options and arguments. Any parser, when run using+`execParser` (and similar functions), is automatically extended+with a few (hidden) options for bash completion:++ - `--bash-completion-script`: this takes the full path of the program as+   argument, and prints a bash script, which, when sourced into a bash session,+   will install the necessary machinery to make bash completion work. For a+   quick test, you can run something like (for a program called `foo` on the+   `PATH`):++   ```console+   $ source <(foo --bash-completion-script `which foo`)+   ```++   Normally, the output of `--bash-completion-script` should be shipped with+   the program and copied to the appropriate directory (usually+   `/etc/bash_completion.d/`) during installation.++ - `--bash-completion-index`, `--bash-completion-word`: internal options used+   by the completion script to obtain a list of possible completions for a+   given command line.++### Actions and completers++By default, options and commands are always completed. So, for example, if the+program `foo` has an option with a long name `output`, typing++```console+$ foo --ou<TAB>+```++will complete `--output` automatically.++Arguments (either of regular options, or top-level) are not completed by+default. To enable completion for arguments, use one of the following modifiers+on a regular option or argument:++ - `completeWith`: specifies a list of possible completions to choose from;+ - `action`: specifies a completion "action". An action dynamically determines+   a list of possible completions. A full list of actions can be found in the+   [bash documentation];+ - `completer`: a completer is a function `String -> IO [String]`, returning+   all possible completions for a given string. You can use this modifier to+   specify a custom completion for an argument.++Completion modifiers can be used multiple times: the resulting completions will+call all of them and join the results.++### Internals++When running a parser with `execParser`, the parser is extended with+`bashCompletionParser`, which defines the above options.++When completion is triggered, the completion script calls the executable with+the special `--bash-completion-index` and `--bash-completion-word` options.++The original parser is therefore run in *completion mode*, i.e. `runParser` is+called on a different monad, which keeps track of the current state of the+parser, and exits when all arguments have been processed.++The completion monad returns, on failure, either the last state of the parser+(if no option could be matched), or the completer associated to an option (if+it failed while fetching the argument for that option).++From that we generate a list of possible completions, and print them to+standard output. They are then read by the completion script and put into the+`COMPREPLY` variable.++## Arrow interface++It is also possible to use the [Arrow syntax][arrows] to combine basic parsers.++This can be particularly useful when the structure holding parse results is+deeply nested, or when the order of fields differs from the order in which the+parsers should be applied.++Using functions from the `Options.Applicative.Arrows` module, one can write,+for example:++```haskell+data Options = Options+  { optArgs :: [String]+  , optVerbose :: Bool }++opts :: Parser Options+opts = runA $ proc () -> do+  verbosity  <- asA (option auto (short 'v' <> value 0)) -< ()+  let verbose = verbosity > 0+  args       <- asA (many (argument str idm)) -< ()+  returnA -< Options args verbose+```++where parsers are converted to arrows using `asA`, and the resulting+composed arrow is converted back to a `Parser` with `runA`.++See `tests/Examples/Cabal.hs` for a slightly more elaborate example+using the arrow syntax for defining parsers.++Note that the `Arrow` interface is provided only for convenience. The+API based on `Applicative` is just as expressive, although it might be+cumbersome to use in certain cases.++## Applicative do++Some may find using optparse-applicative easier using do notation.+However, as `Parser` is not an instance of `Monad`, this can only+be done in recent versions of GHC using the *ApplicativeDo* extension.+For example, a parser specified in this manner might be++```haskell+{-# LANGUAGE RecordWildCards            #-}+{-# LANGUAGE ApplicativeDo              #-}++data Options = Options+  { optArgs :: [String]+  , optVerbose :: Bool }++opts :: Parser Options+opts = do+  optVerbose    <- switch (short 'v')+  optArgs       <- many (argument str idm)+  pure Options {..}+```++Here we've also used the *RecordWildCards* extension to make the+parser specification cleaner. Compilation errors referring to `Monad`+instances not being found are likely because the `Parser` specified+can not be implemented entirely with `Applicative` (Note however,+there were a few desugaring bugs regarding ApplicativeDo in GHC+8.0.1, function application with `($)` in particular may not work,+and the `pure` value should instead be wrapped parenthetically).++## FAQ++* Monadic parsing?++  If a Monadic style were to be used, there would be no possible+  way to traverse the parser and generate a usage string, or for+  us to allow for options to be parsed in any order. Therefore it+  is intentionally unsupported to write a `Parser` in this manner+  with optparse-applicative, and the `Parser` type does not have+  an instance for `Monad`.++* Overlapping flags and options / options with optional arguments?++  This is not supported as it can lead to an ambiguous parse.++  For example, if we supported and had an optional value option+  "--foo" and a flag "--bar", is "--foo --bar" the option with value+  "--bar", or the default value with the flag switched on? What if+  instead of a switch we had many positional string arguments, is+  the first string the option's value or the first positional?++  It is suggested to instead use the `Alternative` instance of+  `Parser` and create a flag', an option, and a pure value for the+  default (with different names for the flag and option).++* Backtracking on `ReadM` errors?++  Parser structures are predetermined at parse time. This means+  that if a `ReadM` fails, the whole parse must also fail, we can't+  consider any alternatives, as there can be no guarantee that the+  remaining structure will fit.  One occasionally confusing side+  effect of this is that two positional arguments for different+  constructors of a sum type can't be composed at the parser level;+  rather, this must be done at the `ReadM` level. For example:++  ```haskell+  import Options.Applicative++  data S3orFile = S3 BucketKey | File FilsePath++  s3Read, fileRead :: ReadM S3orFile+  s3Read = S3 <$> ...+  fileRead = File <$> ...++  correct :: Parser S3orFile+  correct = argument (s3Read <|> fileRead) idm++  incorrect :: Parser S3orFile+  incorrect = argument s3Read idm <|> argument fileRead idm+  ```+ ## How it works+An applicative `Parser` is essentially a heterogeneous list or tree+of `Option`s, implemented with existential types. -A `Parser a` is essentially a heterogeneous list of `Option`s, implemented with-existential types.+All options are therefore known statically (i.e. before parsing,+not necessarily before runtime), and can, for example, be traversed+to generate a help text. Indeed, when displaying the usage text for+a parser, we use an intermediate tree structure. -All options are therefore known statically (i.e. before parsing, not-necessarily before runtime), and can, for example, be traversed to generate a-help text.+When we examine the user's input, each argument is examined to+determine if it's an option or flag, or a positional argument. The+parse tree is then searched for a matching term, and if it finds+one, that leaf of the tree is replaced with the value itself. When+all input has been processed, we see if we can generate the complete+value, and if not issue an error.  See [this blog post][blog] for a more detailed explanation based on a simplified implementation. - [status-png]: https://api.travis-ci.org/pcapriotti/optparse-applicative.svg- [status]: http://travis-ci.org/pcapriotti/optparse-applicative?branch=master+ [aeson]: http://hackage.haskell.org/package/aeson+ [applicative]: http://hackage.haskell.org/package/base/docs/Control-Applicative.html+ [arrows]: http://www.haskell.org/arrows/syntax.html+ [attoparsec]: http://hackage.haskell.org/package/attoparsec+ [bash documentation]: http://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html  [blog]: http://paolocapriotti.com/blog/2012/04/27/applicative-option-parser/- [builder-documentation]: http://hackage.haskell.org/package/optparse-applicative/docs/Options-Applicative-Builder.html- [hackage-png]: http://img.shields.io/hackage/v/optparse-applicative.svg  [hackage]: http://hackage.haskell.org/package/optparse-applicative+ [hackage-png]: http://img.shields.io/hackage/v/optparse-applicative.svg+ [monoid]: http://hackage.haskell.org/package/base/docs/Data-Monoid.html+ [semigroup]: http://hackage.haskell.org/package/base/docs/Data-Semigroup.html+ [parsec]: http://hackage.haskell.org/package/parsec+ [status]: http://travis-ci.org/pcapriotti/optparse-applicative?branch=master+ [status-png]: https://api.travis-ci.org/pcapriotti/optparse-applicative.svg?branch=master+ [ansi-wl-pprint]: http://hackage.haskell.org/package/ansi-wl-pprint
optparse-applicative.cabal view
@@ -1,5 +1,5 @@ name:                optparse-applicative-version:             0.13.0.0+version:             0.13.1.0 synopsis:            Utilities and combinators for parsing command line options description:     Here is a simple example of an applicative option parser:@@ -63,9 +63,9 @@     descriptions. license:             BSD3 license-file:        LICENSE-author:              Paolo Capriotti+author:              Paolo Capriotti, Huw Campbell maintainer:          paolo@capriotti.io-copyright:           (c) 2012-2014 Paolo Capriotti <paolo@capriotti.io>+copyright:           (c) 2012-2017 Paolo Capriotti <paolo@capriotti.io> category:            System build-type:          Simple cabal-version:       >= 1.8@@ -78,13 +78,18 @@                      tests/Examples/Formatting.hs                      tests/alt.err.txt                      tests/cabal.err.txt+                     tests/carry.err.txt                      tests/commands.err.txt                      tests/commands_header.err.txt                      tests/commands_header_full.err.txt+                     tests/dropback.err.txt                      tests/hello.err.txt+                     tests/helponempty.err.txt+                     tests/helponemptysub.err.txt                      tests/formatting.err.txt                      tests/nested.err.txt                      tests/subparsers.err.txt+ homepage:            https://github.com/pcapriotti/optparse-applicative bug-reports:         https://github.com/pcapriotti/optparse-applicative/issues @@ -118,7 +123,7 @@   build-depends:       base                            == 4.*                      , transformers                    >= 0.2 && < 0.6                      , transformers-compat             >= 0.3 && < 0.6-                     , process                         >= 1.0 && < 1.5+                     , process                         >= 1.0 && < 1.6                      , ansi-wl-pprint                  >= 0.6.6 && < 0.7    if !impl(ghc >= 8)@@ -137,7 +142,7 @@    build-depends:       base                      , optparse-applicative-                     , QuickCheck                      == 2.8.*+                     , QuickCheck                      >= 2.8 && < 2.11    if !impl(ghc >= 8)     build-depends:     semigroups
tests/Examples/Hello.hs view
@@ -1,38 +1,42 @@ {-# LANGUAGE CPP #-} module Examples.Hello where -import Data.Monoid import Options.Applicative--#if __GLASGOW_HASKELL__ <= 702-(<>) :: Monoid a => a -> a -> a-(<>) = mappend-#endif+import Data.Semigroup ((<>))+import Control.Monad (replicateM_)  data Sample = Sample-  { hello :: String-  , quiet :: Bool }+  { hello  :: String+  , quiet  :: Bool+  , repeat :: Int }   deriving Show  sample :: Parser Sample sample = Sample-     <$> strOption-         ( long "hello"-        <> metavar "TARGET"-        <> help "Target for the greeting" )-     <*> switch-         ( long "quiet"-        <> help "Whether to be quiet" )--greet :: Sample -> IO ()-greet (Sample h False) = putStrLn $ "Hello, " ++ h-greet _ = return ()+      <$> strOption+          ( long "hello"+         <> metavar "TARGET"+         <> help "Target for the greeting" )+      <*> switch+          ( long "quiet"+         <> short 'q'+         <> help "Whether to be quiet" )+      <*> option auto+          ( long "repeat"+         <> help "Repeats for greeting"+         <> showDefault+         <> value 1+         <> metavar "INT" )  main :: IO ()-main = execParser opts >>= greet+main = greet =<< execParser opts  opts :: ParserInfo Sample opts = info (sample <**> helper)   ( fullDesc- <> progDesc "Print a greeting for TARGET"- <> header "hello - a test for optparse-applicative" )+  <> progDesc "Print a greeting for TARGET"+  <> header "hello - a test for optparse-applicative" )++greet :: Sample -> IO ()+greet (Sample h False n) = replicateM_ n . putStrLn $ "Hello, " ++ h+greet _ = return ()
+ tests/carry.err.txt view
@@ -0,0 +1,3 @@+Missing: -a A++Usage: carry c -a A
+ tests/dropback.err.txt view
@@ -0,0 +1,3 @@+Missing: C++Usage: dropback B C
tests/hello.err.txt view
@@ -1,9 +1,10 @@ hello - a test for optparse-applicative -Usage: hello --hello TARGET [--quiet]+Usage: hello --hello TARGET [-q|--quiet] [--repeat INT]   Print a greeting for TARGET  Available options:   --hello TARGET           Target for the greeting-  --quiet                  Whether to be quiet+  -q,--quiet               Whether to be quiet+  --repeat INT             Repeats for greeting (default: 1)   -h,--help                Show this help text
+ tests/helponempty.err.txt view
@@ -0,0 +1,8 @@+Usage: helponempty B C++Available options:+  -h,--help                Show this help text++Available commands:+  b                        +  c                        
+ tests/helponemptysub.err.txt view
@@ -0,0 +1,4 @@+Usage: helponemptysub c -a A++Available options:+  -a A                     both commands require this