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

Misleading error reports for two sub-parsers #92

Closed
amigalemming opened this issue Jul 18, 2014 · 3 comments
Closed

Misleading error reports for two sub-parsers #92

amigalemming opened this issue Jul 18, 2014 · 3 comments
Labels

Comments

@amigalemming
Copy link

I have a tool that runs in two phases, both phases share some options and have additional custom options. I want to run

$ tool --phase1 --max-num=4 --verbose --phase2 --max-num=3 --special

Here max-num=4 and verbose belong to phase 1 and max-num=3 and
special belong to phase 2. The order of options within a phase, like max-num=4 and verbose, is irrelevant.

Mr. Capriotti suggested to define two subparsers each with a command. This is what I did. It means that phase1 and phase2 don't start with dashes and that they can appear in any order.

See the attached module which is an extension of the example from the Hackage front page of optparse-applicative. There the sub-commands are called add and commit. I hope it is not too confusing.

Now the following problem arises:

$ runhaskell example-complex --hello you add myfile
Usage: example-complex add FILE
  Add a file to the repository

That is, the add command is completely specified and the commit command is missing. However the parser suggests that there is something wrong with the add command.

@amigalemming
Copy link
Author

$ cat example-complex.hs
import Options.Applicative

data Sample = Sample
  { hello :: String
  , quiet :: Bool
  , verbose :: Bool
  , multi :: [String]
  , cmdAdd :: String
  , cmdCommit :: String }
  deriving (Show)

sample :: Parser Sample
sample = pure Sample
  <*> strOption
      (  long "hello"
      <> metavar "TARGET"
      <> help "Target for the greeting" )
  <*> switch
      (  long "quiet"
      <> help "Whether to be quiet" )
  <*> switch
      (  long "verbose"
      <> help "Whether to be verbose" )
  <*> many
         (strOption
             (  long "multi"
             <> metavar "NAME" 
             <> help "Specify multiple things" ))
  <*> subAdd
  <*> subCommit

subAdd :: Parser String
subAdd =
   subparser
      (command "add" (info
           ( argument str (metavar "FILE") )
           ( progDesc "Add a file to the repository" )))

subCommit :: Parser String
subCommit =
   subparser
      (command "commit" (info
           ( commitOptions )
           ( progDesc "Record changes to the repository" )))

sub :: Parser (Bool, String)
sub =
   subparser
     ( (command "add" (info
           ( fmap ((,) False) addOptions )
           ( progDesc "Add a file to the repository" )))
    <> (command "commit" (info
           ( fmap ((,) True) commitOptions )
           ( progDesc "Record changes to the repository" )))
   )

addOptions, commitOptions :: Parser String
addOptions =
   strOption
      (  long "file"
      <> metavar "PATH" )
commitOptions =
   strOption
      (  long "message"
      <> metavar "TEXT" )

main :: IO ()
main = execParser opts >>= print
  where
    opts = info (helper <*> sample)
      (  fullDesc
      <> progDesc "Print a greeting for TARGET"
      <> header "hello - a test for optparse-applicative" )

@HuwCampbell
Copy link
Collaborator

#162
Although the Missing arguments feature will make this better in 0.12, this PR should fix it completely.

@HuwCampbell
Copy link
Collaborator

Merged, please reopen if there's any issues.

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

No branches or pull requests

3 participants