Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duplicate option displays wrong error message... #395

Open
mgajda opened this issue Jun 6, 2020 · 3 comments
Open

Duplicate option displays wrong error message... #395

mgajda opened this issue Jun 6, 2020 · 3 comments

Comments

@mgajda
Copy link

mgajda commented Jun 6, 2020

I have a parser accepting --request option, and when user accidentally uses it twice, the error message says:

Invalid option `--request'

It should probably report:

Duplicated option is not allowed `--request'

Otherwise user things that the option name is wrong.

@HuwCampbell
Copy link
Collaborator

I don't think the current behaviour is wrong per se, the option really is invalid at that stage in the parse – maybe sub-optimal.

I did write something to test for this; but it couldn't distinguish between an option which has been used and an option which is not accessible due to an alternative being used. So the message could be something more like "the option --request can no longer be accessed".

Haven't merged it or put it anywhere yet though.

@andreasabel
Copy link
Contributor

I also hit this problem and think there should be a better error message if a valid option is supplied too often.

Here is a popular instance:

$ cabal-plan --ascii info --ascii
Invalid option `--ascii'

$ cabal-plan --help
Usage: cabal-plan [--version] [--show-builtin | --hide-builtin] 
                  [--show-global | --hide-global] [--show-setup | --hide-setup] 
                  [--show-exes | --hide-exes] [--color always|never|auto] 
                  [--ascii | --unicode | --ascii-auto] [COMMAND]

So the option is not "invalid".

Here is a reproducer:

import Options.Applicative

main :: IO ()
main = print =<< do
  execParser $ (`info` header "Try options -o 1 -o 2") $ helper <*> optionO

optionO :: Parser (Maybe String)
optionO =
  optional $ strOption $ mconcat
    [ short 'o'
    , metavar "STRING"
    , help "Output STRING."
    ]
$ ./Main -o 1 -o 2
Invalid option `-o'

@dylant-da
Copy link

Commenting here for others facing a similar issue: I've opted to create two parsers, the first of which is the legitimate one, and the second of which throws an error instantly if invoked.

By chaining them with const, if the flag is ever specified a second time, the second parser is invoked and errors out with a custom message.

myOption :: Parser String
myOption = const <$> actualParser <*> errorIfTwiceParser
  where
    nameMod = long "my-option"
    actualParser = option str nameMod
    errorIfTwiceParser = option (readerError errMsg) (nameMod <> hidden <> value (error "optionOnce: should not happen!"))

It's a bit of a hack, but it works and conveniently avoids mucking around with any optparse internals.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants