options: Powerful and easy command-line option parser

[ console, library, mit ] [ Propose Tags ] [ Report a vulnerability ]

Lets library and application developers easily work with command-line options.


[Skip to Readme]

library options

library options:options-internal

Downloads

Note: This package has metadata revisions in the cabal description newer than included in the tarball. To unpack the package including the revisions, use 'cabal get'.

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

  • No Candidates
Versions [RSS] 0.1, 0.1.1, 1.0, 1.1, 1.2, 1.2.1, 1.2.1.1, 1.2.1.2
Change log changelog.md
Dependencies base (>=4.16 && <4.22), containers (>=0.6 && <0.8), monads-tf (>=0.3 && <0.4), options [details]
Tested with ghc ==9.12.0, ghc ==9.10.1, ghc ==9.8.2, ghc ==9.6.6, ghc ==9.4.8, ghc ==9.2.8
License MIT
Author John Millikin <john@john-millikin.com>
Maintainer Chris Martin <chris@typeclasses.com>
Revised Revision 2 made by AndreasAbel at 2024-11-13T15:08:56Z
Category Console
Home page https://github.com/typeclasses/options/
Uploaded by chris_martin at 2023-07-11T21:02:36Z
Distributions Arch:1.2.1.2, Debian:1.2.1.1, LTSHaskell:1.2.1.2, NixOS:1.2.1.2, Stackage:1.2.1.2
Reverse Dependencies 10 direct, 27 indirect [details]
Downloads 12900 total (25 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
Last success reported on 2023-07-11 [all 1 reports]

Readme for options-1.2.1.2

[back to package description]

The options package lets library and application developers easily work with command-line options.

This document discusses a handful of the utilities in this package. See the API documentation for the Options module for more.

Introductory example

The following example is a full program that can accept two options, --message and --quiet:

import Control.Applicative import Options data MainOptions = MainOptions { optMessage :: String , optQuiet :: Bool } . instance Options MainOptions where defineOptions = pure MainOptions <*> simpleOption "message" "Hello world!" "A message to show the user." <*> simpleOption "quiet" False "Whether to be quiet." main :: IO () main = runCommand $ \opts args -> if optQuiet opts then return () else putStrLn (optMessage opts) 
$ ./hello Hello world! $ ./hello --message='ciao mondo' ciao mondo $ ./hello --quiet $ 

In addition, this library will automatically create documentation options such as --help and --help-all:

$ ./hello --help Help Options: -h, --help Show option summary. --help-all Show all help options. Application Options: --message :: text A message to show the user. default: "Hello world!" --quiet :: bool Whether to be quiet. default: false 

Defining options

optionType_bool

optionType_bool stores an option as a Bool. The option's value must be either "true" or "false".

Boolean options are unary, which means that their value is optional when specified on the command line. If a flag is present, the option is set to True.

$ ./app -q $ ./app --quiet 

Boolean options may still be specified explicitly by using long flags with the --flag=value format. This is the only way to set a unary flag to "false".

$ ./app --quiet=true $ ./app --quiet=false 

optionType_enum

optionType_enum store an option as one of a set of possible values. The type must be a bounded enumeration, and the type's Show instance will be used to implement the parser.

This is a simplistic implementation, useful for quick scripts. Users with more complex requirements for enum parsing are encouraged to define their own option types using optionType.

Example:

data Action = Hello | Goodbye deriving (Bounded, Enum, Show) data MainOptions = MainOptions { optAction :: Action } instance Options MainOptions where defineOptions = pure MainOptions <*> defineOption (optionType_enum "action") (\o -> o { optionLongFlags = ["action"] , optionDefault = Hello }) main = runCommand $ \opts args -> do putStrLn ("Running action " ++ show (optAction opts)) 
$ ./app Running action Hello $ ./app --action=Goodbye Running action Goodbye 

Parsing argument lists

parseOptions

parseOptions attempts to convert a list of command-line arguments into an options value. This can be used by application developers who want finer control over error handling, or who want to perform additional validation on the options value.

The argument list must be in the same encoding as the result of System.Environment.getArgs.

Use parsedOptions, parsedArguments, parsedError, and parsedHelp to inspect the result of parseOptions.

Example:

getOptionsOrDie :: Options a => IO a getOptionsOrDie = do argv <- System.Environment.getArgs let parsed = parseOptions argv case parsedOptions parsed of Just opts -> return opts Nothing -> case parsedError parsed of Just err -> do hPutStrLn stderr (parsedHelp parsed) hPutStrLn stderr err exitFailure Nothing -> do hPutStr stdout (parsedHelp parsed) exitSuccess 

parseSubcommand

parseSubcommand attempts to convert a list of command-line arguments into a subcommand action. This can be used by application developers who want finer control over error handling, or who want subcommands that run in an unusual monad.

The argument list must be in the same encoding as the result of System.Environment.getArgs.

Use parsedSubcommand, parsedError, and parsedHelp to inspect the result of parseSubcommand.

Example:

runSubcommand :: Options cmdOpts => [Subcommand cmdOpts (IO a)] -> IO a runSubcommand subcommands = do argv <- System.Environment.getArgs let parsed = parseSubcommand subcommands argv case parsedSubcommand parsed of Just cmd -> cmd Nothing -> case parsedError parsed of Just err -> do hPutStrLn stderr (parsedHelp parsed) hPutStrLn stderr err exitFailure Nothing -> do hPutStr stdout (parsedHelp parsed) exitSuccess 

Running main with options

runCommand

runCommand retrieves System.Environment.getArgs and attempts to parse it into a valid value of an Options type plus a list of left-over arguments.

The options and arguments are then passed to the provided computation.

If parsing fails, this computation will print an error and call exitFailure.

If parsing succeeds, and the user has passed a --help flag, and the developer is using the default help flag definitions, then this computation will print documentation and call exitSuccess.

runSubcommand

runSubcommand is used to run applications that are split into subcommands. Use subcommand to define available commands and their actions, then pass them to this computation to select one and run it.

If the user specifies an invalid subcommand, this computation will print an error and call exitFailure. In handling of invalid flags or --help, runSubcommand acts like runCommand.

Example:

import Control.Applicative import Control.Monad (unless) import Options data MainOptions = MainOptions { optQuiet :: Bool } instance Options MainOptions where defineOptions = pure MainOptions <*> simpleOption "quiet" False "Whether to be quiet." data HelloOpts = HelloOpts { optHello :: String } instance Options HelloOpts where defineOptions = pure HelloOpts <*> simpleOption "hello" "Hello!" "How to say hello." data ByeOpts = ByeOpts { optName :: String } instance Options ByeOpts where defineOptions = pure ByeOpts <*> simpleOption "name" "" "The user's name." hello :: MainOptions -> HelloOpts -> [String] -> IO () hello mainOpts opts args = unless (optQuiet mainOpts) $ do putStrLn (optHello opts) bye :: MainOptions -> ByeOpts -> [String] -> IO () bye mainOpts opts args = unless (optQuiet mainOpts) $ do putStrLn ("Good bye " ++ optName opts) main :: IO () main = runSubcommand [ subcommand "hello" hello , subcommand "bye" bye ] 
$ ./app hello Hello! $ ./app hello --hello='Allo!' Allo! $ ./app bye Good bye $ ./app bye --name='Alice' Good bye Alice