-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | a library for command line parsing & online help -- -- A commandline parsing library, based on getopt. Comes with a powerful -- attribute system. Supports complex interfaces with many options and -- commands, with option & command grouping, with simple and -- convenient API. Even though quite powerful, it strives to keep simple -- things simple. The library uses System.Console.GetOpt as its -- backend. -- -- In comparison to the other commandline handling libraries: -- -- Compared to cmdargs, cmdlib has a pure attribute system and is based -- on GetOpt for help formatting & argument parsing. Cmdlib may also -- be more extendable due to typeclass design, and can use user-supplied -- types for option arguments. -- -- Cmdargs >= 0.4 can optionally use a pure attribute system, although -- this is clearly an add-on and the API is a second-class citizen in -- relation to the impure version. -- -- GetOpt and parseargs both require explicit flag representation, so -- they live a level below cmdlib. GetOpt is in fact used as a backend by -- cmdlib. @package cmdlib @version 0.3 -- | A library for setting up a commandline parser and help generator for -- an application. It aims for conciseness, flexibility and -- composability. It supports both non-modal and modal (with subcommands -- -- like darcs, cabal and the like) applications. -- -- The library supports two main styles of representing flags and -- commands. These are called Record and ADT, respectively, -- by the library. The Record representation is more straightforward and -- easier to use in most instances. The ADT interface is suitable for -- applications that require exact correspondence between the commandline -- and its runtime representation, or when an existing application is -- being ported to cmdlib that is using this style to represent flags. -- -- Using the Record-based interface, a simple Hello World application -- could look like this: -- --
--   {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, DeriveDataTypeable #-}
--   import System.Console.CmdLib
--   import Control.Monad
--   
--   data Main = Main { greeting :: String, again :: Bool }
--       deriving (Typeable, Data, Eq)
--   
--   instance Attributes Main where
--       attributes _ = group "Options" [
--           greeting %> [ Help "The text of the greeting.", ArgHelp "TEXT"
--                       , Default "Hello world!" ],
--           again    %> Help "Say hello twice." ]
--   
--   instance RecordCommand Main where
--       mode_summary _ = "Hello world with argument parsing."
--   
--   main = getArgs >>= executeR Main {} >>= \opts -> do
--     putStrLn (greeting opts)
--   
-- -- Then, saying ./hello --help will give us: -- --
--   Hello world with argument parsing.
--   
--   Options:
--       --greeting=TEXT   The text of the greeting. (default: Hello world!)
--       --again[=yes|no]  Say hello twice. (default: no)
--   
module System.Console.CmdLib data Attribute -- | Set a list of short flags (single character per flag, like in -- -c, -h) for an option. Without the leading -- -. Short :: [Char] -> Attribute -- | Set a list of long flags for an option. Long :: [String] -> Attribute -- | Set a list of long flags for an inversion of the option. Only used for -- boolean invertible options. See also long. InvLong :: [String] -> Attribute -- | Whether this option is invertible. Only applies to boolean options and -- defaults to True. (Invertible means that for --foo, there are --no-foo -- and --foo=no alternatives. A non-invertible option will only create -- --foo.) Invertible :: Bool -> Attribute -- | Set help string (one-line summary) for an option. Displayed in help. Help :: String -> Attribute -- | When True, this option will contain the list of non-option arguments -- passed to the command. Only applicable to [String]-typed options. -- Options marked extra will not show up in help and neither will they be -- recognized by their name on commandline. Extra :: Bool -> Attribute -- | When set, this option will not show up on help and won't create a flag -- (similar to Extra), but instead it will contain the n-th non-option -- argument. The argument used up by such a positional option will not -- show up in the list of non-option arguments. Positional :: Int -> Attribute -- | Set the help string for an argument, the FOO in -- --wibblify=FOO. ArgHelp :: String -> Attribute -- | Set default value for this option. The default is only applied when -- its type matches the option's parameter type, otherwise it is ignored. Default :: a -> Attribute -- | When this attribute is given, the flag's value will be passed to the -- provided IO action (which would presumably record the flag's value in -- a global IORef for later use). Like with Default, the attribute is -- only effective if the parameter type of the provided function matches -- the parameter type of the option to which the attribute is applied. Global :: (a -> IO ()) -> Attribute -- | Whether the option is enabled. Disabled options are not recognized and -- are not shown in help (effectively, they do not exist). Used to enable -- a subset of all available options for a given command. For -- Record-based commands (see RecordCommand), this is handled -- automatically based on fields available in the command's constructor. -- Otherwise, constructs like -- --
--   enable <% option1 +% option2 +% option3 %% disable <% option4
--   
-- -- may be quite useful. Enabled :: Bool -> Attribute -- | Set the group name for this option. The groups are used to section the -- help output (the options of a given group are shown together, under -- the heading of the group). The ordering of the groups is given by the -- first flag of each group. Flags themselves are in the order in which -- they are given in the ADT or Record in question. Group :: String -> Attribute -- | For convenience. Same as Enabled True. enable :: Attribute -- | For convenience. Same as Enabled False. disable :: Attribute -- | For convenience. Same as Long [foo] %+ InvLong -- [no-foo] long :: String -> [Attribute] -- | For convenience. Same as Short [x] short :: Char -> Attribute simple :: [Attribute] -- | Join attribute mappings. E.g. Key1 %> Attr1 %+ Attr2 %% Key2 -- %> Attr3 %+ Attr4. Also possible is [ Key1 %> Attr1, -- Key2 %> Attr2 ] %% Key3 %> Attr3, or many other variations. (%%) :: (AttributeMapLike k a, AttributeMapLike k b) => a -> b -> AttributeMap k -- | Attach a (list of) attributes to a key. The key is usually either an -- ADT constructor (for use with ADTFlag-style flags) or a record -- selector (for use with RecordFlags). -- --
--   data RFlags = Flags { wibblify :: Int, simplify :: Bool }
--   data AFlag = Simplify | Wibblify Int
--   rattr = wibblify %> Help "Add a wibblification pass." (%% ...)
--   aattr = Wibblify %> Help "Add a wibblification pass." (%% ...)
--   
-- -- %+ can be used to chain multiple attributes: -- --
--   attrs = wibblify %> Help "some help" %+ Default (3 :: Int) %+ ArgHelp "intensity"
--   
-- -- But lists work just as fine: -- --
--   attrs = wibblify %> [ Help "some help", Default (3 :: Int), ArgHelp "intensity" ]
--   
(%>) :: (ToKey k, AttributeList attr) => k -> attr -> AttributeMap Key -- | Attach an attribute to multiple keys: written from right to left, i.e. -- Attribute <% Key1 +% Key2. Useful for setting up option -- groups (although using group may be more convenient in this -- case) and option enablement. (<%) :: Keys keys => Attribute -> keys -> AttributeMap Key -- | Join multiple attributes into a list. Available for convenience (using -- [Attribute] directly works just as well if preferred, although this is -- not the case with keys, see +%). (%+) :: (AttributeList a, AttributeList b) => a -> b -> [Attribute] -- | Join multiple keys into a list, e.g. Key1 +% Key2. Useful -- with <% to list multiple (possibly -- heterogenously-typed) keys. (+%) :: (Keys a, Keys b) => a -> b -> [Key] -- | Set an attribute on all keys. everywhere :: Eq k => Attribute -> AttributeMap k -- | Create a group. This extracts all the keys that are (explicitly) -- mentioned in the body of the group and assigns the corresponding Group -- attribute to them. Normally used like this: -- --
--   group "Group name" [ option %> Help "some help"
--                      , another %> Help "some other help" ]
--   
-- -- Do not let the type confuse you too much. :) group :: AttributeMapLike k a => String -> a -> AttributeMap k -- | The ADT wrapper type allows use of classic ADTs (algebraic data types) -- for flag representation. The flags are then passed to the command as a -- list of values of this type. However, you need to make the type an -- instance of the Attributes first (if you do not wish to attach any -- attributes, you may keep the instance body empty). E.g.: -- --
--   data Flag = Simplify | Wibblify Int
--   instance Attributes where
--       attributes _ = Wibblify %> Help "Add a wibblification pass." %+ ArgHelp "intensity" %%
--                      Simplify %> Help "Enable a two-pass simplifier."
--   
-- -- The Command instances should then use (ADT Flag) for -- their second type parameter (the flag type). data Attributes adt => ADT adt -- | This wrapper type allows use of record types (single or -- multi-constructor) for handling flags. Each field of the record is -- made into a single flag of the corresponding type. The record needs to -- be made an instance of the Attributes class. That way, -- attributes can be attached to the field selectors, although when used -- with RecordCommand, its rec_options method can be used as well -- and the Attributes instance left empty. -- --
--   data Flags = Flags { wibblify :: Int, simplify :: Bool }
--   instance Attributes Flags where
--       attributes _ =
--          wibblify %> Help "Add a wibblification pass." %+ ArgHelp "intensity" %%
--          simplify %> Help "Enable a two-pass simplifier."
--   
-- -- A single value of the Flags type will then be passed to the -- Command instances (those that use Record Flags as -- their second type parameter), containing the value of the rightmost -- occurence for each of the flags. -- -- TODO: List-based option types should be accumulated instead of -- overriden. data Attributes rec => Record rec class Attributes a attributes :: Attributes a => a -> AttributeMap Key readFlag :: (Attributes a, Data b) => a -> String -> b -- | Chain commands into a list suitable for dispatch and -- helpCommands. E.g.: -- --
--   dispatch (Command1 %: Command2 %: Command3) opts
--   
(%:) :: (Commands a, Commands b) => a -> b -> [CommandWrap] commandGroup :: Commands a => String -> a -> [CommandWrap] -- | A class that describes a single (sub)command. The cmd type -- parameter is just for dispatch (and the default command name is -- derived from this type's name, but this can be overriden). It could be -- an empty data decl as far as this library is concerned, although you -- may choose to store information in it. -- -- To parse the commandline for a given command, see execute. The -- basic usage can look something like this: -- --
--   data Flag = Summary | Unified Bool | LookForAdds Bool
--   instance ADTFlag Flag
--   
--   [...]
--   
--   data Whatsnew = Whatsnew deriving Typeable
--   
--   instance Command Whatsnew (ADT Flag) where
--    options _ =  enable <% Summary +% Unified +% LookForAdds
--    summary _ = "Create a patch from unrecorded changes."
--   
--    run _ f opts = do putStrLn $ "Record."
--                      putStrLn $ "Options: " ++ show f
--                      putStrLn $ "Non-options: " ++ show opts
--   
class (Typeable cmd, FlagType flag) => Command cmd flag | cmd -> flag options :: Command cmd flag => cmd -> AttributeMap Key supercommand :: Command cmd flag => cmd -> Bool optionStyle :: Command cmd flag => cmd -> OptionStyle run :: Command cmd flag => cmd -> Folded flag -> [String] -> IO () synopsis :: Command cmd flag => cmd -> String summary :: Command cmd flag => cmd -> String help :: Command cmd flag => cmd -> String cmdname :: Command cmd flag => cmd -> String cmd :: Command cmd flag => cmd cmd_flag_empty :: Command cmd flag => cmd -> Folded flag -- | Given a list of commands (see %:) and a list of -- commandline arguments, dispatch on the command name, parse the -- commandline options (see execute) and transfer control to the -- command. This function also implements the help -- pseudocommand. dispatch :: [DispatchOpt] -> [CommandWrap] -> [String] -> IO () -- | Like dispatch but with the ability to control what happens when -- there is an error on user input dispatchOr :: (String -> IO ()) -> [DispatchOpt] -> [CommandWrap] -> [String] -> IO () -- | Parse options for and execute a single command (see Command). -- May be useful for programs that do not need command-based -- dispatch, but still make use of the Command class to -- describe themselves. Handles --help internally. You can use -- this as the entrypoint if your application is non-modal (i.e. it has -- no subcommands). execute :: Command cmd f => cmd -> [String] -> IO () helpCommands :: [CommandWrap] -> [Char] helpOptions :: Command cmd f => cmd -> String noHelp :: DispatchOpt defaultCommand :: (Command f x, Typeable (Folded x)) => f -> DispatchOpt -- | How to process options for a command. See optionStyle for -- details. data OptionStyle Permuted :: OptionStyle NonPermuted :: OptionStyle NoOptions :: OptionStyle data CommandWrap -- | This could be used to implement a disambiguation function -- -- Note that there isn't presently a notion of hidden commands, but we're -- taking them into account now for future API stability commandNames :: Bool -> [CommandWrap] -> [String] -- | A bridge that allows multi-constructor record types to be used as a -- description of a command set. In such a type, each constructor -- corresponds to a single command and its fields to its options. To -- describe a program with two commands, foo and bar, -- each taking a --wibble boolean option and bar also -- taking a --text=string option, you can write: -- --
--   data Commands = Foo { wibble :: Bool }
--                 | Bar { wibble :: Bool, text :: String }
--   
--   instance RecordCommand Commands where (...)
--   
-- -- You should at least implement run', rec_options and -- mode_summary are optional. class Data cmd => RecordCommand cmd run' :: RecordCommand cmd => cmd -> [String] -> IO () rec_options :: RecordCommand cmd => cmd -> AttributeMap Key mode_summary :: RecordCommand cmd => cmd -> String mode_help :: RecordCommand cmd => cmd -> String -- | Construct a command list (for dispatch/helpCommands) -- from a multi-constructor record data type. See also -- RecordCommand. Alternatively, you can use dispatchR -- directly. recordCommands :: (Eq cmd, Eq (Record cmd), Data cmd, RecordCommand cmd, Attributes cmd) => cmd -> [CommandWrap] -- | A command parsing & dispatch entry point for record-based -- commands. Ex. (see RecordCommand): -- --
--   main = getArgs >>= dispatchR [] >>= \x -> case x of
--     Foo {} -> putStrLn $ "You asked for foo. Wibble = " ++ show (wibble x)
--     Bar {} -> putStrLn $ "You asked for bar. ..."
--   
dispatchR :: (Eq cmd, Eq (Record cmd), Attributes cmd, RecordCommand cmd, Command (RecordMode cmd) f, (Folded f) ~ cmd) => [DispatchOpt] -> [String] -> IO cmd -- | Like execute, but you get the flags as a return value. This is -- useful to implement non-modal applications with record-based flags, -- eg.: -- --
--   data Main = Main { greeting :: String, again :: Bool }
--       deriving (Typeable, Data, Eq)
--   instance Attributes Main where -- (...)
--   instance RecordCommand Main
--   main = getArgs >>= executeR Main {} >>= \opts -> do
--      putStrLn (greeting opts) -- (...)
--   
executeR :: (Eq cmd, Eq (Record cmd), Attributes cmd, RecordCommand cmd) => cmd -> [String] -> IO cmd -- | Create a global setter/getter pair for a flag. The setter can be then -- passed to the Global attribute and the getter used globally to -- query value of that flag. Example: -- --
--   data Flag = Wibblify Int | Verbose Bool
--   (setVerbose, isVerbose) = globalFlag False
--   
--   instance Attributes Flag where
--       attributes _ = Verbose %> Global setVerbose
--   
--   putVerbose str = isVerbose >>= flip when (putStrLn str)
--   
globalFlag :: Typeable a => a -> (a -> IO (), IO a) -- | The default parser for option arguments. Handles strings, string lists -- (always produces single-element list), integers, booleans -- (yes|true|1 vs no|false|0), PathF and integer lists -- (--foo=1,2,3). readCommon :: Data a => String -> a (<+<) :: (Typeable a, Typeable b, Monad m) => m a -> m b -> m a data HelpCommand HelpCommand :: [CommandWrap] -> HelpCommand -- | Helper for dying with an error message (nicely, at least compared to -- fail in IO). die :: String -> IO a -- | The Data class comprehends a fundamental primitive -- gfoldl for folding over constructor applications, say terms. -- This primitive can be instantiated in several ways to map over the -- immediate subterms of a term; see the gmap combinators later -- in this class. Indeed, a generic programmer does not necessarily need -- to use the ingenious gfoldl primitive but rather the intuitive -- gmap combinators. The gfoldl primitive is completed by -- means to query top-level constructors, to turn constructor -- representations into proper terms, and to list all possible datatype -- constructors. This completion allows us to serve generic programming -- scenarios like read, show, equality, term generation. -- -- The combinators gmapT, gmapQ, gmapM, etc are all -- provided with default definitions in terms of gfoldl, leaving -- open the opportunity to provide datatype-specific definitions. (The -- inclusion of the gmap combinators as members of class -- Data allows the programmer or the compiler to derive -- specialised, and maybe more efficient code per datatype. Note: -- gfoldl is more higher-order than the gmap combinators. -- This is subject to ongoing benchmarking experiments. It might turn out -- that the gmap combinators will be moved out of the class -- Data.) -- -- Conceptually, the definition of the gmap combinators in terms -- of the primitive gfoldl requires the identification of the -- gfoldl function arguments. Technically, we also need to -- identify the type constructor c for the construction of the -- result type from the folded term type. -- -- In the definition of gmapQx combinators, we use -- phantom type constructors for the c in the type of -- gfoldl because the result type of a query does not involve the -- (polymorphic) type of the term argument. In the definition of -- gmapQl we simply use the plain constant type constructor -- because gfoldl is left-associative anyway and so it is readily -- suited to fold a left-associative binary operation over the immediate -- subterms. In the definition of gmapQr, extra effort is needed. We use -- a higher-order accumulation trick to mediate between left-associative -- constructor application vs. right-associative binary operation (e.g., -- (:)). When the query is meant to compute a value of type -- r, then the result type withing generic folding is r -- -> r. So the result of folding is a function to which we -- finally pass the right unit. -- -- With the -XDeriveDataTypeable option, GHC can generate -- instances of the Data class automatically. For example, given -- the declaration -- --
--   data T a b = C1 a b | C2 deriving (Typeable, Data)
--   
-- -- GHC will generate an instance that is equivalent to -- --
--   instance (Data a, Data b) => Data (T a b) where
--       gfoldl k z (C1 a b) = z C1 `k` a `k` b
--       gfoldl k z C2       = z C2
--   
--       gunfold k z c = case constrIndex c of
--                           1 -> k (k (z C1))
--                           2 -> z C2
--   
--       toConstr (C1 _ _) = con_C1
--       toConstr C2       = con_C2
--   
--       dataTypeOf _ = ty_T
--   
--   con_C1 = mkConstr ty_T "C1" [] Prefix
--   con_C2 = mkConstr ty_T "C2" [] Prefix
--   ty_T   = mkDataType "Module.T" [con_C1, con_C2]
--   
-- -- This is suitable for datatypes that are exported transparently. class Typeable a => Data a -- | The class Typeable allows a concrete representation of a type -- to be calculated. class Typeable a -- | Computation getArgs returns a list of the program's command -- line arguments (not including the program name). getArgs :: IO [String]