Question

I'm using optparse-applicative version 0.7.0.2.

I want to write a parser that takes some mandatory options, but that when invoked with no options it shows both usage and help, as opposed to just usage (that is, I want the invocation with no options to behave as the invocation with --help).

I can't figure out how to do so, even if the documentation says it is possible:

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 help text

Is there a working example of this? The one in the main documentation doesn't work for me (it prints usage only.)

Was it helpful?

Solution 2

Currently, it looks like the only way to do this is to create your own version of customExecParser from the Options.Applicative.Extra module. There is an open issue to make this simpler.

Something like this should be pretty close to what you're looking for:

import Options.Applicative
import Options.Applicative.Help as AH
import Options.Applicative.Types as AT
import System.Environment (getArgs, getProgName)
import System.Exit (exitWith, ExitCode(..))
import System.IO (hPutStr, stderr)

execParserWithHelp :: ParserPrefs -> ParserInfo a -> IO a
execParserWithHelp pprefs pinfo = do
  args <- getArgs
  case execParserPure pprefs pinfo args of
    Right a -> return a
    Left failure -> do
      progn <- getProgName
      msg <- AT.errMessage failure progn
      let extra = if null args
                  then AH.parserHelpText pprefs pinfo
                  else ""
      let c = errExitCode failure
      case c of
        ExitSuccess -> putStr (msg ++ extra)
        _           -> hPutStr stderr (msg ++ extra)
      exitWith c

main :: IO ()
main = execParserWithHelp (prefs idm) opts >>= run

opts :: ParserInfo Command
opts = info (commands <**> helper) idm

run :: Command -> IO ()
run = ...

This is basically just customExecParser with a small block that checks if the args are empty. If they are, it displays the parser help.

OTHER TIPS

Reviving an old topic, but I've added the showHelpOnEmpty pref for this so it's now simple. Given a parser p :: ParserInfo a

run :: IO a
run = customExecParser (prefs showHelpOnEmpty) p

If you just want to print the --help output on all errors, including when the program is run with no arguments, then replace calls to execParser with calls to showHelpOnErrorExecParser, defined by

-- | A version of 'execParser' which shows full help on error.                
--                                                                            
-- The regular 'execParser' only prints usage on error, which doesn't         
-- include the options, subcommands, or mention of the help switch            
-- @--help@.                                                                  
showHelpOnErrorExecParser :: ParserInfo a -> IO a
showHelpOnErrorExecParser = customExecParser (prefs showHelpOnError)

Based on comment on issue linked in accepted answer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top