{-# LANGUAGE RecordWildCards, PatternGuards #-}{-|
This module provides simple command line argument processing.
The main function of interest is 'cmdArgs'.
A simple example is:
@data Sample = Sample {hello :: String} deriving (Show, Data, Typeable)@
@sample = Sample{hello = 'def' '&=' 'help' \"World argument\" '&=' 'opt' \"world\"}@
@ '&=' summary \"Sample v1\"@
@main = print =<< 'cmdArgs' sample@
Attributes are used to control a number of behaviours:
* The help message: 'help', 'typ', 'details', 'summary', 'program', 'groupname'
* Flag behaviour: 'opt', 'enum', 'verbosity', 'ignore'
* Flag name assignment: 'name', 'explicit'
* Controlling non-flag arguments: 'args', 'argPos'
* multi-mode programs: 'modes', 'auto'
/Supported Types/: Each field in the record must be one of the supported
atomic types (@String@, @Int@, @Integer@, @Float@, @Double@, @Bool@, an
enumeration, a tuple of atomic types) or a list (@[]@) or @Maybe@ wrapping
at atomic type.
/Missing Fields/: If a field is shared by multiple modes, it may be omitted
in subsequent modes, and will default to the previous value.
/Purity/: Values created with annotations are not pure - the first
time they are computed they will include the annotations, but subsequently
they will not. If you wish to run the above example in a more robust way:
@sample = 'cmdArgsMode' $ Sample{hello = ... -- as before@
@main = print =<< 'cmdArgsRun' sample@
Even using this scheme, sometimes GHC's optimisations may share values who
have the same annotation. To disable sharing you may need to specify
@\{\-\# OPTIONS_GHC -fno-cse \#\-\}@ in the module you define the flags.
-}moduleSystem.Console.CmdArgs.Implicit(-- * Running command linescmdArgs,cmdArgsMode,cmdArgsRun,cmdArgs_,cmdArgsMode_,cmdArgsApply,CmdArgs(..),-- * Constructing command lines-- | Attributes can work on a flag (inside a field), on a mode (outside the record),-- or on all modes (outside the 'modes' call).moduleSystem.Console.CmdArgs.Implicit.UI,-- ** Impure(&=),modes,enum,-- ** Pure(+=),record,atom,Annotate((:=)),enum_,modes_,-- * Re-exported for convenience-- | Provides a few opaque types (for writing type signatures),-- verbosity control, default values with 'def' and the-- @Data@/@Typeable@ type classes.moduleSystem.Console.CmdArgs.Verbosity,moduleSystem.Console.CmdArgs.Default,Ann,Mode,Data,Typeable)whereimportData.DataimportData.Generics.AnyimportSystem.ExitimportSystem.Console.CmdArgs.Explicit(Mode,processArgs,remap)importSystem.Console.CmdArgs.Implicit.AnnimportSystem.Console.CmdArgs.Annotatehiding((&=))importqualifiedSystem.Console.CmdArgs.AnnotateasA((&=))importSystem.Console.CmdArgs.Implicit.TypeimportSystem.Console.CmdArgs.Implicit.LocalimportSystem.Console.CmdArgs.Implicit.GlobalimportSystem.Console.CmdArgs.Implicit.UIimportSystem.Console.CmdArgs.VerbosityimportSystem.Console.CmdArgs.Default-- | Take impurely annotated records and run the corresponding command line.-- Shortcut for @'cmdArgsRun' . 'cmdArgsMode'@.cmdArgs::Dataa=>a->IOacmdArgs=cmdArgsRun.cmdArgsMode-- | Take purely annotated records and run the corresponding command line.-- Shortcut for @'cmdArgsRun' . 'cmdArgsMode_'@.cmdArgs_::Dataa=>AnnotateAnn->IOacmdArgs_=cmdArgsRun.cmdArgsMode_cmdArgsCapture::Dataa=>CaptureAnn->Mode(CmdArgsa)cmdArgsCapture=remapembedproj.global.localwhereembed=fmapfromAnyprojx=(fmapAnyx,embed)-- | Take impurely annotated records and turn them in to a 'Mode' value, that can-- make use of the "System.Console.CmdArgs.Explicit" functions (i.e. 'process').---- Annotated records are impure, and will only contain annotations on-- their first use. The result of this function is pure, and can be reused.cmdArgsMode::Dataa=>a->Mode(CmdArgsa)cmdArgsMode=cmdArgsCapture.capture-- | Take purely annotated records and turn them in to a 'Mode' value, that can-- make use of the "System.Console.CmdArgs.Explicit" functions (i.e. 'process').cmdArgsMode_::Dataa=>AnnotateAnn->Mode(CmdArgsa)cmdArgsMode_=cmdArgsCapture.capture_-- | Run a Mode structure. This function reads the command line arguments-- and then performs as follows:---- * If invalid arguments are given, it will display the error message-- and exit.---- * If @--help@ is given, it will display the help message and exit.---- * If @--version@ is given, it will display the version and exit.---- * In all other circumstances the program will return a value.---- * Additionally, if either @--quiet@ or @--verbose@ is given (see 'verbosity')-- it will set the verbosity (see 'setVerbosity').cmdArgsRun::Mode(CmdArgsa)->IOacmdArgsRunm=cmdArgsApply=<<processArgsm-- | Perform the necessary actions dictated by a 'CmdArgs' structure.---- * If 'cmdArgsHelp' is @Just@, it will display the help message and exit.---- * If 'cmdArgsVersion' is @Just@, it will display the version and exit.---- * In all other circumstances it will return a value.---- * Additionally, if 'cmdArgsVerbosity' is @Just@ (see 'verbosity')-- it will set the verbosity (see 'setVerbosity').cmdArgsApply::CmdArgsa->IOacmdArgsApplyCmdArgs{..}|Justx<-cmdArgsHelp=doputStrLnx;exitSuccess|Justx<-cmdArgsVersion=doputStrLnx;exitSuccess|otherwise=domaybe(return())setVerbositycmdArgsVerbosityreturncmdArgsValue-- | Modes: \"I want a program with multiple modes, like darcs or cabal.\"---- Takes a list of modes, and creates a mode which includes them all.-- If you want one of the modes to be chosen by default, see 'auto'.---- > data Modes = Mode1 | Mode2 | Mode3 deriving Data-- > cmdArgs $ modes [Mode1,Mode2,Mode3]modes::Dataval=>[val]->valmodes=many-- | Flag: \"I want several different flags to set this one field to different values.\"---- This annotation takes a type which is an enumeration, and provides multiple-- separate flags to set the field to each value.---- > data State = On | Off deriving Data-- > data Mode = Mode {state :: State}-- > cmdArgs $ Mode {state = enum [On &= help "Turn on",Off &= help "Turn off"]}-- > --on Turn on-- > --off Turn offenum::Dataval=>[val]->valenum=many-- | Add an annotation to a value. Note that if the value is evaluated-- more than once the annotation will only be available the first time.{-# INLINE (&=) #-}(&=)::Dataval=>val->Ann->val(&=)=(A.&=)enum_::(Datac,Dataf)=>(c->f)->[AnnotateAnn]->AnnotateAnnenum_=(:=+)modes_::[AnnotateAnn]->AnnotateAnnmodes_=many_