optparse-applicative: displaying help for programs invoked with no arguments

applicative, command-line-arguments, haskell

Solution

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.

Problem

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.)

Original source