Giter Club home page Giter Club logo

optparse-applicative's People

Contributors

andreasabel avatar benjaminselfridge avatar bergmark avatar bgamari avatar bodigrim avatar bos avatar dag avatar damncabbage avatar flip111 avatar gwils avatar huwcampbell avatar hvr avatar ibotty avatar justusadam avatar michaelt avatar myode avatar neilmayhew avatar nh2 avatar pcapriotti avatar phadej avatar psibi avatar roberth avatar ryantm avatar ryo1kato avatar sjakobi avatar thielema avatar tmcgilchrist avatar trespaul avatar trofi avatar yuhangwang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

optparse-applicative's Issues

"arguments" swallows options

If "arguments" isn't the last argument in the applicative declaration it swallows all options (including --hyphenated ones etc). I'm not sure whether this is a bug or a limitation of applicative?

I suppose a work around if you don't want to reorder your data structure is to use some helper function instead of applying your data constructor directly. But if this isn't about a limitation of applicative it would be nice to need no such workarounds! :)

Mixing program-wide and command-specific options may fail depending on their order

import Options.Applicative
import Control.Applicative

data Program = Program { progOption :: String
                       , progCommand :: Command
                       }
  deriving (Show)

data Command = Command { commandOption :: String }
  deriving (Show)

commandOpts :: Parser Command
commandOpts = Command <$> strOption ( long "command-option" )

options :: Parser Program
options = pure Program
  <*> strOption ( long "program-option" )
  <*> subparser ( command "command" ( info commandOpts idm ) )

main :: IO ()
main = execParser (info options idm) >>= print

Example of the order-specific behaviour:

$ runghc Test.hs command --program-option=foo --command-option=bar
Usage: Test.hs command --command-option ARG
$ runghc Test.hs command --command-option=bar --program-option=foo
Program {progOption = "foo", progCommand = Command {commandOption = "bar"}}

I would expect both of these to work, given that there's no ambiguity in the option names.

Backtracking on commands

I think that there should be possibility to disable backtracking on commands (or even make it the default).

What I mean is, if a program can be run with a subcommand or without one, supplying the subcommand should commit to that choice. Currently, if the subcommand parser fails, control is passed to the non-subcommand parser.

(If this description is not very clear, I can write a small example.)

Use (<>) instead of (&) in documentation

This kind of an issue of style, but I think it would be less confusing if you changed the documentation to use (<>) instead of (&). That's one less combinator to learn, and it also makes it more obvious to users that options are monoids, so that they know they can use other monoid combinators like mconcat to collect options.

You don't really need to remove the (&) combinator if you are worried about backwards compatibility, although my understanding is that the libraries mailing list has been discussing appropriating (&) for postfix function application.

Artifacts of "hidden"

So now that I managed to implement --version properly, the usage looks like this:

Usage: kibr (--version | [--language TAG] [--output MODE] COMMAND)

I'm impressed that it figured this out, but I actually don't want it in this case, so I add hidden to the version parser. Now the usage looks like this:

Usage: kibr ([--language TAG] [--output MODE] COMMAND)

Problem is the parenthesis that got added with the version parser remain. That is, before adding the version flag the usage looked like this:

Usage: kibr [--language TAG] [--output MODE] COMMAND

Specific error message

When I enter a wrong argument the example program responds with the general usage pattern:

$ example --hello
Usage: args --hello TARGET [--quiet]

An error message like "missing parameter for option 'hello'" would be more helpful.
Or "option X required", "unknown option", "option parameter must be integer" etc.

"argument" swallows --help

I feel like we had a ticket for this already but can't find it ...

$ kibr import 
Usage: kibr import [--trace-level 0..4] FILE
  Import words from an XML export

Available options:
  -h,--help                Show this help text
  --trace-level 0..4       Set the tracing level for the XML parser

$ kibr import --help

fatal error: file read error: "file not found" when accessing "/home/dag/Haskell/kibr/--help"
Importing...
Finished importing 0 words.

$ ghc-pkg field kibr depends | grep optparse
         optparse-applicative-0.4.2-4eac8083032f7394d98da97b11b17bb7
parseOptions :: Config -> Parser Options
parseOptions config = Options
    <$> [...]
    <*> Opt.subparser
          ( mkcmd "import"     parseImport          "Import words from an XML export"
         <> [...]
          )
  where
    mkcmd name parser desc = Opt.command name $ Opt.info (Opt.helper <*> parser) $ Opt.progDesc desc

parseImport :: Parser Command
parseImport = Import
    <$> Opt.option
          ( Opt.long "trace-level"
         <> Opt.metavar "0..4"
         <> Opt.value 0
         <> Opt.help "Set the tracing level for the XML parser"
          )
    <*> Opt.argument Opt.str (Opt.metavar "FILE" <> Opt.action "file")

The bash completions break too, duno if it's a separate bug? Here I'm hitting tab after --tr:

$ kibr import --trbash: line 0: compgen: --: invalid option
compgen: usage: compgen [-abcdefgjksuv] [-o option]  [-A action] [-G globpat] [-W wordlist]  [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]
ace-level ^C

Add context information to error messages

Currently, if an option parser fails on some argument it will report only Cannot parse value and a user will be confused about what exactly went wrong. Consider this situation:

$ ./mbus-server --port dsf --key dsf
mbus-server: Cannot parse value

In this case you should figure out on your own whether you mistyped port or it was key. I believe some context information would help, e. g. an option/argument on which parser failed and a relevant piece of input.

"arguments" can no longer take a list as a default

This code now produces a type error with the 0.2 release:

parseServe = Serve
    <$> arguments (`lookup` services)
          ( metavar "dict|irc|state|web..."
          . value [minBound..]
          )
src/Kibr/CLI.hs:149:19:
    Couldn't match expected type `Service' with actual type `[t0]'
    In the first argument of `value', namely `[minBound .. ]'
    In the second argument of `(.)', namely `value [minBound .. ]'
    In the second argument of `arguments', namely
      `(metavar "dict|irc|state|web..." . value [minBound .. ])'

Help output when no arguments are provided.

Hi! I havent found a way to print to user the output of myprog --help when no options are provided and such solution is very important to me.
I do not know if it is implemented, but I did not managed to do it.
Is it possible at the moment or would it be possible in the future?

Thank you.

Specialized support for "enum" values

I have a lot of code like this:

data Service = DICT | IRC | State | Web deriving (Eq, Bounded, Enum)

parseServe :: Parser Command
parseServe = Serve
    <$> arguments (`lookup` services)
          ( metavar "dict|irc|state|web..."
          . value [minBound..]
          )
  where
    services = [("dict",DICT), ("irc",IRC), ("state",State), ("web",Web)]

This could probably be automated more. If there is a fixed set of valid values, the "reader" could be automatic, and the valid values could be displayed in the help output.

Possibly the valid set of values could even be generated for algebraic types with instances of Bounded, Enum, Show. My services definition could be generated by mapping toLower . show over [minBound..].

I should add that I have this pattern not just for "arguments" but also for options. In that case my default tends to be simply the minBound rather than [minBound..].

data OutputMode = TTY | Colored | Plain | Quiet

parseOptions = Options
    <$> nullOption
          ( reader (`lookup` outputModes)
          . long "output"
          . metavar "MODE"
          . value TTY
          . help "Control how output is printed (tty|colored|plain|quiet)"
          )
  where
    outputModes = [("tty",TTY), ("colored",Colored), ("plain",Plain), ("quiet",Quiet)]

Since one might not want a default value these two could be provided as Modifiers:

parseOptions = Options <$> enumOption (long "output" . metavar "MODE" . valueFirst)
parseServe = Serve <$> enumArguments (valueAll)

Parsing CPP-style options

Can optparse-applicative parse CPP-style options, like

-DFOO

? Note that there's no space betwee -D and the parameter, and the list of possible parameter values is not known in advance.

Improve docs for the `Arrow` interface

Henning Thielemann observes that the README doesn't make it clear that the Arrow interface is completely optional, and it's actually possible to write any sort of parser using just the Applicative (and Alternative) instance.

Current master prints help text instead of error

optparse-applicative-0.5.2.1:

% ./program --my-option=asdf
program: Cannot parse value

optparse-applicative-0.6.0:

% ./program --my-option=asdf
Usage: program [--my-option ARG]

Something eats the error message.

Help page formatting

Possibly related to #10.

The CmdTheLine package supports formatting the help page in many ways: normal plain text, pager, man page, groff markup. I tried this package and really liked the man-page-like help page, but ended up with optparse-applicative in the end because I found CmdTheLine awkward in other areas (specifically the subcommands handling). Also it uses some weird custom string interpolation for writing these help pages.

Would be nice if optparse-applicative could do this as well, but using something like ansi-wl-pprint for the "markup" instead.

I'm also thinking that when possible it could find out the width of the terminal window and wrap lines nicely to that margin. This is easy with ansi-wl-pprint. For example I have this in my program, and it's longer than a normal terminal width of 80 columns:

  --output MODE            Control how output is printed (tty|colored|plain|quiet)

Using smart wrapping this could render as something like, pretending we have a really narrow terminal window:

  --output MODE            Control how output is
                           printed (tty|colored|plain|quiet)

Also if a line in the column where the flags are listed is longer than that column, the description could be pushed down to a new line instead of indented further, like,

  -h,--help                Show this help text
  --trace-level SOME_INSANELY_LONG_METAVAR
                           Set the tracing level for the XML parser

I suspect (but baseless-assertion.jpg) that this sort of thing is also easy with ansi-wl-pprint.

It would also remove the need for the Options.Applicative.Utils module.

Possible memory leak?

With a program like this:

import Options.Applicative
parser = arguments Just idm
main = execParser (info parser fullDesc) >> return ()

I run it like this:

$ cat /usr/share/dict/words | xargs -d'\n' optparse --
optparse: out of memory (requested 1048576 bytes)

If I change the program to simply,

main = getArgs >>= print

It runs just fine.

Optparse hanging infinitely & support for multiple usage of the same flag

Hi!
Would it be possible to add support for multiple usage of the same flag?
I would love to allow users to use arguments like this myprog --dump ast --dump va --dump test and I would like to get array of String's as a result.

And here is what I was trying (what was natural to me, because I have some Parsec background) and it hanged optparse when printing help:

[...] many (strOption (long "dump" <> value "" <> metavar "DUMP")) [...]

Thank you.

Help for subcommands

It would be very nice to be able to add a --help option to all subcommands. This --help option would print the usage information for that subcommand.

"lexical error (UTF-8 decoding error)" with runhaskell & windows

Given the following program :

data Configuration = Configuration
    { configDropCount      :: Int
    , configOutputFilename :: String
    , configInputFilename  :: String
    }

configParser :: Parser Configuration
configParser = Configuration
    <$> option (long "dropcount" & short 'd' & metavar "COUNT" & help "Drop count frequency")
    <*> strOption (long "outputfilename" & short 'o' & metavar "OUTFILENAME" & help "output ts filename")
    <*> argument str ( metavar "FILE")


runner :: Configuration -> IO ()
runner = return ()

main :: IO ()
main = execParser opts >>= runner
    where opts = info (helper <*> configParser)
                    ( fullDesc
                    & progDesc "Corrupt a ts file"
                    & header "TSBreaker")

Trying to execute it under windows with runhaskell give the following error :

C:\...>runhaskell.exe .\tsbreaker.exe -d=500 -o=pouet jdajdoa

tsbreaker.exe:1:3: lexical error (UTF-8 decoding error)

But it works if compiled with ghc

Allow for using Maybe in options types to specify optional arguments

I don't know how easy it'd be to implement this, but it'd be nice to be able to something like this:

data Opts = Opts
  { inputDb :: String
  , optKeywords :: Maybe String  -- Maybe here means this is optional
  }

Then the parser:

options :: Parser Opts
options = Opts
       <$> strOption (long "input-db"
                      & metavar "FILE"
                      & help "Input database file")
       <*> strOption (long "keywords"
                      & help "Comma-delimited list of bug keywords")

If the type of the strOption being used is a Maybe, then it'd automatically mean that particular option is optional. Right now I think the only way to specify optional arguments is to provide them a default value with "value". It'd be much nicer to use Maybe directly.

Any chance something like this could work? Or would it be possible to add something like "strMaybeOption" that would mean optional arguments and would return Maybe String values..?

I'm sorry if this is a FAQ, I didn't see a link to a mailing list on the github page, so I filed a feature req instead. Feel free to close if there's a trivial way to do this already. If there is, perhaps it'd make sense to have that in the usage examples - I think this is a fairly common use-case.

Counterintuitive behavior for switch Mod

value and option have type ... -> Mod f a. Since they are polymorphic in f you can apply these to switch and some strange behaviour results:

% cat test.hs && ghc test.hs
import Options.Applicative
import Data.Monoid (mempty)

main :: IO ()
main = execParser (info a_switch mempty) >>= main'

main' :: Bool -> IO ()
main' a = putStrLn $ "a was set to " ++ show a


a_switch :: Parser Bool
a_switch = switch (short 'a'
                   <> metavar "NOSUCHARGUMENT"
                   <> value True)
[1 of 1] Compiling Main             ( test.hs, test.o )
Linking test ...
% ./test -a an_argument
Usage: test [-a NOSUCHARGUMENT]
% ./test -a
a was set to True
% ./test 
a was set to True

Supplying a metavar to switch leads to misleading "Usage" output and allowing a default value renders it useless. It would be better if a way were found to make it impossible to specify these on switch.

Can we have an eitherReader convenience function?

For parsing simple arguments, I often define functions of type parseFoo :: String -> Either String a, which are used in multiple places, and then I want to use them with reader.

Could we have a convenience function like this?

eitherReader str2either = reader (either (Left . ErrorMsg) Right . str2either)

This would not be necessary if the fail instance of Either String was not an exception, but it is and fail isn't a realy thing in Monad either (no pun intended).

Thanks :)

Help formatting for "arguments" misleading

I have this code:

arguments service (metavar "SERVICE" . value [minBound..])

The help for this renders as such:

Usage: kibr serve [SERVICE]

This format suggests that SERVICE is a scalar, optional positional argument. However, the conventional format for repeated arguments, looking at existing programs, seems to be for example:

ls [OPTION]... [FILE]...

Long options not disambiguated

In most option parsers, if I have the long option --trace-level, I should be able to type just --trace provided it's unambiguous.

Readme uses old reader API

data FluxCapacitor = ...

parseFluxCapacitor :: String -> Maybe FluxCapacitor

option
  ( long "flux-capacitor"
 <> reader parseFluxCapacitor )

reader now takes something that returns an Either.

Regression

I was using Optparse successfully, but upgraded and the following code no longer works:

import Options.Applicative

data Params = Params
{ pMHoliday :: Maybe String -- Just date of holiday or Nothing
, pUpdateFile :: String -- file with raw trade data for a day
} deriving Show

getParams :: Parser Params
getParams = Params
<$> option
( long "holiday"
& value Nothing
& reader (Just . str)
& metavar "HOLIDAY-DATE"
& help "Create holiday records for HOLIDAY-DATE using close from UPDATE-FILE"
)
<*> argument str
( metavar "UPDATE-FILE"
& help "The XCHG_YYYYMMDD.txt file for the update"
)

main = execParser opts >>= print
where opts = info (helper <*> getParams)
( fullDesc
& progDesc "Perform daily update to the stock DB from UPDATE-FILE."
)

The part that fails is trying to input a value for the optional "--holiday". It seems to regard this as invalid and just outputs the help text.

BTW, it took me a while to figure out how to get an option with a maybe value in the previous version. Maybe a new option type would make this simpler, since i think it would be a common need.

No simple/obvious way to add a --version switch

So the problem is if I parse it together with the rest of my options it will fail (and print the help page) because other required options (specifically commands) are missing, but if I parse it separately and try to use Alternative it will always print the version because builders like switch always succeed.

Perhaps a utility similar to helper could be added specifically for dealing with versions, but in the more general case I think i need something that would let me write something like,

options :: Parser (Maybe Options)
options = Nothing <$ alternative (long "version") <|> Just . Options <$> ...

Or maybe something like (but this is less general)

options = maybeSwitch (long "version") $ Options <$> ...

Or am I missing something and there's already a straight-forward way to deal with this?

Can the build input restriction process == 1.1.* be relaxed?

Hi, is there any chance that the requirement on process == 1.1.* can be relaxed? This restrictions means that optparse-applicative can effectively not be used with GHC 7.0.4, because process 1.0.1.5 is a base library of that compiler. This means that no other program that depends on optparse-applicative can be copmiled with GHC 7.0.4 either.

Parse at least one argument

I'm writing a program that takes multiple arguments and performs an operation on each. Unfortunately, the arguments parser succeeds even when I supply no arguments, even though it doesn't make sense for my application.

Is there a way to force arguments to parse at least one argument?

Possibility to create hidden commands

Right now we are able to create hidden options (not displayed in the help), but as far as I know we cannot create hidden commands - would it be possible to add such feature please?

thank you.

Document Mod

Currently I'm mostly copy-pasting examples from README and adjusting them to my needs.

But I would like to understand what exactly I'm writing.

A lot of functions, for instance, return the Mod type. But neither its meaning nor meaning of the type arguments are documented. I would find it very useful to have some semantic model for Mod.

Error installing with cabal

Not sure if I have a bad version of something, but I get:

$ cabal install optparse-applicative
Resolving dependencies...
Downloading optparse-applicative-0.4.1...
Configuring optparse-applicative-0.4.1...
Preprocessing library optparse-applicative-0.4.1...
Preprocessing test suites for optparse-applicative-0.4.1...
Building optparse-applicative-0.4.1...
[ 1 of 11] Compiling Options.Applicative.Utils ( Options/Applicative/Utils.hs, dist/build/Options/Applicative/Utils.o )
[ 2 of 11] Compiling Options.Applicative.Types ( Options/Applicative/Types.hs, dist/build/Options/Applicative/Types.o )
[ 3 of 11] Compiling Options.Applicative.Internal ( Options/Applicative/Internal.hs, dist/build/Options/Applicative/Internal.o )

Options/Applicative/Internal.hs:54:10:
    Illegal instance declaration for `MonadP P'
      (All instance types must be of the form (T t1 ... tn)
       where T is not a synonym.
       Use -XTypeSynonymInstances if you want to disable this.)
    In the instance declaration for `MonadP P'

Options/Applicative/Internal.hs:105:10:
    Illegal instance declaration for `MonadP Completion'
      (All instance types must be of the form (T t1 ... tn)
       where T is not a synonym.
       Use -XTypeSynonymInstances if you want to disable this.)
    In the instance declaration for `MonadP Completion'
cabal: Error: some packages failed to install:
optparse-applicative-0.4.1 failed during the building phase. The exception
was:
ExitFailure 1


$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.0.4

$ cabal --version
cabal-install version 0.10.2
using version 1.10.2.0 of the Cabal library 

Unfortunately I'm largely at the mercy of fedora 17 packaging for these versions, as I'm not too comfortable building either ghc or cabal from source (unless there's an easier way).

Extra empty lines around command list

dag reports:

Also to bike shed, the extra empty lines around the list of commands make the help page rather ugly, and inconsistent with most other programs. ☺

unexpected behavior with 2 subcommands

I have a subcommand parser that looks like

data CLICommands = Featurize  FeatureConfig 
    | TrainModel TrainingConfig 
    -- | EvaluatePredictions PredictionConfig

data FeatureConfig = FeatureConfig {yesEventsName :: Maybe String
                                    ,noEventsName :: Maybe String
                                    ,yesWeightFt :: Double
                                    ,noWeightFt :: Double
                                    ,featureMapFileName :: Maybe String
                                    ,bitWidth :: Int  }

featureParser = Featurize<$> (FeatureConfig <$>
        (optional . strOption) (long "yesEvents" <> metavar "FILE"
                <> help "input json array of positive events") <*>
        (optional . strOption) (long "noEvents"  <> metavar "FILE"   
                <> help "input json array of positive events") <*>
        option (long "yesWeight" <> value 1.0 <> metavar "positiveFloat" 
                <> help "training weight for yes examples. Defaults to 1.0" ) <*>
        option (long "noWeight" <> value 1.0 <> metavar "positiveFloat" 
                <> help "training weight for no examples. Defaults to 1.0" ) <*>
        (optional . strOption) (long "featureMap"  <> metavar "FILE"   
                <> help "map between features and hashes, needed to interpret models directly") <*>
        option (long "hashWidth" <> value 18 <> metavar "Int" <> help "how many bits of feature hash to keep")        )


data TrainingConfig = TrainingConfig {humanModelVW ::  String 
                                        ,featureHashFile ::  String 
                                        ,vwExtraOptions :: [String]
                                        }

trainingParser = TrainModel<$> (TrainingConfig <$>
            (strOption) (long "readable_model" <> metavar "FILE" <>
                help "save a human readable vowpal model file") <*>
            strOption (long "featureHashFile" <> metavar "FILE" 
                    <> help "mapping from hashe numbers to feature names") <*>
            arguments Just  (metavar "options" <> help "options to pass to VW" ) )

betterCLI :: Parser CLICommands
betterCLI = subparser $  (command "featurize"  (info featureParser (progDesc "Generate vowpal feature training file")) )  
    <> (command "train" (info trainingParser (progDesc "Train vowpal model and export ")))

when i call the app with help flags, it behaves correctly on "featurize" subcommand, but not on "train"



carter raven-ad-code/vw-setup ‹master*› » ./dist/build/pw/pw featurize --help                                                  1 ↵
Usage: pw featurize [--yesEvents FILE] [--noEvents FILE] [--yesWeight positiveFloat] [--noWeight positiveFloat] [--featureMap FILE] [--hashWidth Int]
  Generate vowpal feature training file

Available options:
  --yesEvents FILE         input json array of positive events
  --noEvents FILE          input json array of positive events
  --yesWeight positiveFloat training weight for yes examples. Defaults to 1.0
  --noWeight positiveFloat training weight for no examples. Defaults to 1.0
  --featureMap FILE        map between features and hashes, needed to interpret models directly
  --hashWidth Int          how many bits of feature hash to keep
carter raven-ad-code/vw-setup ‹master*› » ./dist/build/pw/pw train --help                                                      1 ↵
Invalid option `--help'

Usage: pw train --readable_model FILE --featureHashFile FILE [options]

dash '-' in strOption value doesn't work

It seems like the options parser cannot handle '-' characters in strOption argument values. E.g.,

options :: Parser Opts
options = Opts
       <$> strOption (long "bindings"
                      & metavar "LIBRARY"
                      & help "Which sqlite library to benchmark (direct-sqlite or sqlite-simple)")


main :: IO ()
main =
  options <- execParser $ info (helper <*> options)
             (fullDesc
                & progDesc "Generate test database")

if I run this program with

$ ./cabal-dev/bin/bench --bindings=sqlite-simple
Error: unrecognized option `--bindings=sqlite-simple'

But if I don't use a dash:

$ ./cabal-dev/bin/bench --bindings=sqlite_simple

it works.

This is with optparse-applicative 0.4.2

Test suites on Hackage do not compile

Related to snoyberg/stackage#2.

When I try to build the test suites from Hackage, I get:

tests/Tests.hs:7:18:
    Could not find module `Examples.Alternatives'
    Use -v to see a list of the files searched for.

It seems like the Github version of this library is already past version 0.4, so I wasn't sure how to send a pull request most effectively. Would it be possible to release a new version in the 0.4 series that adds the missing test files?

Thank you

No help for subparsers

I get the "Available commands" list with descriptions, but there's no prog cmd --help listing flags for the specific command. If the command fails, I get the normal help page for the whole program, and if I try to add helper to a command I get --help for commands but that too only shows the normal help page.

So far all my subparsers only take positional arguments, don't know if that matters.

Wrap usage information

% gen-iface --help 
Usage: gen-iface ([--version] | [--numeric-version] | [--hspkg-version] | [--supported-extensions] | [COMMAND] | [-i PATH] [--build-dir PATH] [-X extension] ([-D sym[=var]] | [-I PATH]) ([--global] | [--user] | [--package-db PATH]) [--package-id ARG] [MODULE])

Available options:
  -h,--help                Show this help text

Available commands:
  pkg                      

The long line is not very aesthetic. It would be great if it was wrapped nicely.

Internal types leaking into public API

With 0.5, I had to

import           Options.Applicative.Builder.Internal (ArgumentFields, Mod,
                                                       OptionFields)

because I have things like

valueAll :: (Bounded a, Enum a) => Mod f [a]
valueAll = Opt.value [minBound..]

Previously these types were exported from Options.Applicative, which I think is useful because it allows you to write type signatures for reusable pieces of code.

In order parsing problems.

In version 0.6 in order argument parsing was introduced and my code stopped working and I do not know if it is fixable now. There are 2 main problems:

  1. If you want to create parser, which parses an positional argument INPUT and has got flag -v and we want the user to be able to use it before OR after the INPUT, how can we do it now?
  2. If we define many1 p = (:) <$> p <*> many p and use it like:
[...]
<$> many1   ( argument str ( metavar "INPUTS" ))
<*> switch    ( long "version" <> short 'V'  )
[...]

Than the option --version is unreachable - even if we provide the input parameter, parser does not parse --version after it (probably waiting for next inputs args)

hang when providing default for [String] arguments

in 0.5.2.1 i could have a ["string with spaces", "another one"] default for an arguments str. now in 0.7.0.2 that doesn't compile, i have to have ""string with spaces", "another one"", but that hangs (on one computer, another OOM's) when i execParser it!

also, it wasn't clear from the docs that i can't use auto for [String] arguments, took me a while to figure out i had to use str...

Strict (no-intersperse) arguments

I'd like the ability to have option parsing stop on the first non-flag argument encountered, to prevent having to always use "--" for a command that is a runner for other programs with their own arguments.

(like python's optparse, when `disable_interspersed_args() is called):
http://docs.python.org/library/optparse.html#optparse.OptionParser.disable_interspersed_args

I had a go at adding a strict version of arguments and arguments1, but had trouble with the tests and wasn't sure how to best integrate it. Here's what I came up with which only supports non-interspersed mode, if that's useful:

arguments_ allow_empty p m = set_default <$> fromM args1
    where
        Mod f (DefaultProp def sdef) g = m
        show_def = sdef <*> def

        props = mkProps mempty g
        props' = (mkProps mempty g) { propShowDefault = show_def }

        args1 | allow_empty = args
                    | otherwise = do
            mx <- oneM arg_or_ddash
            case mx of
                Nothing -> someM arg
                Just x  -> (x:) <$> manyM arg

        args = do
            mx <- oneM $ optional arg_or_ddash
            case mx of
                Nothing       -> return []
                Just Nothing  -> manyM arg
                Just (Just x) -> (x:) <$> manyM arg

        arg_or_ddash = (ddash *> pure Nothing) <|> (p <$> nonOpt)
        set_default [] = fromMaybe [] def
        set_default xs = xs

        arg = liftOpt (Option (ArgReader (CReader compl p)) props)

        ddash :: Parser ()
        ddash = argument' (guard . (== "--")) internal

        nonOpt = argument' nonOpt' internal
        nonOpt' ('-':_) = Nothing
        nonOpt' a = Just a

        ArgumentFields compl = f (ArgumentFields mempty)

caveat: this could be wrong, I don't fully understand the code yet ;). Seems to work in the cases I threw at it though.

It could be a better idea to have this flag be over the whole of argument parsing, rather than built into the arguments parser. But I'm not even sure if that's possible with the current structure of parsers.

Be more verbose in parse failures

Currently an invalid or missing argument will cause the library to simply display the usage message. It would be nice if we could tell the user specifically what he did wrong as well.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.