packages feed

multiarg 0.8.0.0 → 0.10.0.0

raw patch · 5 files changed

+255/−58 lines, 5 filesdep ~containersPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: containers

API changes (from Hackage documentation)

+ System.Console.MultiArg.SimpleParser: instance Functor ArgWrap
+ System.Console.MultiArg.SimpleParser: mHelp :: Mode result -> String -> String
+ System.Console.MultiArg.SimpleParser: modesWithHelp :: (String -> String) -> [OptSpec a] -> ([a] -> Either ([String] -> result) [Mode result]) -> IO result
+ System.Console.MultiArg.SimpleParser: simpleWithHelp :: (String -> String) -> Intersperse -> [OptSpec a] -> (String -> a) -> IO [a]
- System.Console.MultiArg.SimpleParser: Mode :: String -> Intersperse -> [OptSpec b] -> (String -> b) -> ([b] -> result) -> Mode result
+ System.Console.MultiArg.SimpleParser: Mode :: String -> Intersperse -> [OptSpec b] -> (String -> b) -> ([b] -> result) -> (String -> String) -> Mode result
- System.Console.MultiArg.SimpleParser: modes :: [OptSpec a] -> ([a] -> Exceptional String b) -> (b -> Either (String -> c) [Mode result]) -> [String] -> Exceptional Error (b, Either [c] result)
+ System.Console.MultiArg.SimpleParser: modes :: [OptSpec a] -> ([a] -> Either ([String] -> result) [Mode result]) -> [String] -> Exceptional Error result

Files

NEWS view
@@ -64,3 +64,15 @@   System.Console.MultiArg. So fixing that is just a matter of changing   imports in client code. Other breakage will be limited to error   handling code.++Release 0.10.0.0, March 7, 2013+Changes since release 0.8.0.0:++* Added the simpleWithHelp and modesWithHelp pre-built parsers to+  the SimpleParser module++* Added the mHelp field to the Mode record to allow for the+  modesWithHelp pre-built parser++* Changed the modes function in the SimpleParser module. The new+  function has a simpler type. It will however break old code.
System/Console/MultiArg/Combinator.hs view
@@ -315,7 +315,9 @@         (_, a):[] -> return a         _ -> Nothing --- | Formats error messages for nice display.+-- | Formats error messages for nice display. Returns a multi-line+-- string (there is no need to append a newline to the end of the+-- string returned). formatError   :: String   -- ^ Pass the name of your program here. Displayed at the beginning
System/Console/MultiArg/Prim.hs view
@@ -128,6 +128,8 @@ data Description = Unknown | General String | Expected String   deriving (Eq, Show, Ord) +-- | Error messages. To format error messages for nice display, see+-- 'System.Console.MultiArg.Combinator.formatError'. data Error = Error InputDesc [Description]   deriving (Eq, Show, Ord) 
System/Console/MultiArg/SimpleParser.hs view
@@ -1,23 +1,33 @@ {-# LANGUAGE ExistentialQuantification #-}--- | A simple command line parser that can parse options that take an--- optional argument, one or two arguments, or a variable number of--- arguments. For sample code that uses this parser, see+-- | Some pre-built command line parsers. One is a simple command line+-- parser that can parse options that take an optional argument, one+-- or two arguments, or a variable number of arguments. For sample+-- code that uses this parser, see -- "System.Console.MultiArg.SampleParser".+--+-- Another parser is provided for multi-mode programs that are similar+-- to @git@ or @darcs@. module System.Console.MultiArg.SimpleParser (   -- * Interspersion control   Intersperse (Intersperse, StopOptions)      -- * The parser   , simple+  , simpleWithHelp      -- * Parsing multi-mode command lines   , Mode(..)   , modes+  , modesWithHelp   ) where -import qualified System.Console.MultiArg.Prim as P+import Data.Either (partitionEithers) import qualified System.Console.MultiArg.Combinator as C+import qualified System.Console.MultiArg.GetArgs as GetArgs+import qualified System.Console.MultiArg.Prim as P import qualified Control.Monad.Exception.Synchronous as Ex+import System.Exit (exitFailure, exitSuccess)+import qualified System.IO as IO import Control.Applicative ( many, (<|>), optional,                              (<$), (<*>), (<*), (<$>)) import Data.List (find)@@ -99,6 +109,90 @@       parser = po <|> ps <|> pa   in catMaybes <$> P.manyTill parser P.end +--+-- simpleWithHelp+--++-- | Wraps the OptSpec passed into to simpleWithHelp. +data ArgWrap a+  = HelpArg+  | OtherArg a++data ArgWrapResult a+  = NeedsHelp String+  | NoHelp a++instance Functor ArgWrap where+  fmap _ HelpArg = HelpArg+  fmap f (OtherArg a) = OtherArg $ f a++partitionHelp :: [ArgWrap a] -> (DoHelp, [a])+partitionHelp xs = (not . null . fst $ r, snd r)+  where+    toEither h = case h of+      HelpArg -> Left ()+      OtherArg a -> Right a+    r = partitionEithers . map toEither $ xs++-- | Shows help and exits successfully if that was requested;+-- otherwise, returns the parsed command line options.+extractOpts :: String -> (String -> String) -> [ArgWrap a] -> IO [a]+extractOpts pn hlp opts =+  let (doHelp, os) = partitionHelp opts+  in if doHelp+      then putStr (hlp pn) >> exitSuccess+      else return os+++-- | Parses a simple command line (that is, one without modes) in the+-- IO monad. Gets the arguments for you using 'getArgs'.  In addition+-- to the arguments you provide for 'simple', you also provide online+-- help. This function adds @-h@ and @--help@ options and shows help+-- if the user entered one of these options anywhere on the command+-- line. If help is shown, the program exits successfully. In+-- addition, it will print a message to standard error if parsing the+-- command line fails and then exit unsuccessfully.+simpleWithHelp+  :: (String -> String)+  -- ^ Help message. Printed as is, so it can be one line or have many+  -- lines. It should however have a final end-of-line character. The+  -- function is applied to the name of the program (which is+  -- retrieved at runtime.)++  -> Intersperse+  -- ^ What to do after encountering the first positional argument++  -> [C.OptSpec a]+  -- ^ All possible options. Do not add a @-h@ or @--help@ option;+  -- these are added for you.++  -> (String -> a)+  -- ^ How to handle positional arguments. This function is applied to+  -- the appropriate string every time the parser encounters a+  -- positional argument.++  -> IO [a]+  -- ^ If help is requested, the program will print it and exit+  -- successfully. If there was an error parsing the command line, the+  -- program will print an error message and exit+  -- unsuccessfully. Otherwise, the parsed arguments are returned.+simpleWithHelp h i os p = do+  let os' = addHelpOpt os+  as <- GetArgs.getArgs+  pn <- GetArgs.getProgName+  let exResult = simple i os' (fmap OtherArg p) as+  rs <- case exResult of+    Ex.Exception e -> do+      IO.hPutStr IO.stderr (C.formatError pn e)+      exitFailure+    Ex.Success g -> return g+  extractOpts pn h rs+++--+-- Mode parsing+--+ -- | Provides information on each mode that you wish to parse. data Mode result = forall b. Mode   { mName :: String@@ -117,78 +211,165 @@    , mProcess :: [b] -> result     -- ^ Processes the options after they have been parsed.++  , mHelp :: String -> String+    -- ^ Help string for this mode. This is used only in+    -- 'modesWithHelp'; 'modes' ignores this. This is displayed on+    -- screen exactly as is, so be sure to include the necessary+    -- trailing newline. The function is applied to the name of the+    -- program (which is retrieved at runtime.)      }  instance Functor Mode where-  fmap f (Mode nm i os pa p) =-    Mode nm i os pa (f . p)+  fmap f (Mode nm i os pa p h) =+    Mode nm i os pa (f . p) h -processModeArgs :: Mode result -> P.Parser result-processModeArgs (Mode _ i os pa p) = do+type DoHelp = Bool++modesWithHelpPure+  :: String+  -- ^ Program name+  -> (String -> String)+  -- ^ Global help+  -> [C.OptSpec a]+  -> ([a] -> Either ([String] -> result) [Mode result])+  -> [String]+  -> Ex.Exceptional P.Error (ArgWrapResult (ArgWrapResult result))+modesWithHelpPure pn getHlp globals lsToEi ss = P.parse ss $ do+  let globals' = addHelpOpt globals+  gs <- P.manyTill (C.parseOption globals') endOrNonOpt+  let (needsHelp, gblOs) = partitionHelp gs+  if needsHelp then return (NeedsHelp (getHlp pn)) else NoHelp <$>+    case lsToEi gblOs of+      Left parsePosArgs ->+            (NoHelp . parsePosArgs) <$> many P.nextWord <* P.end+      Right mds -> do+        let modeWords = Set.fromList . map mName $ mds+        (_, w) <- P.matchApproxWord modeWords+        let cmd = fromJust . find (\c -> mName c == w) $ mds+        processModeWithHelp pn cmd++modesNoHelp+  :: [C.OptSpec a]+  -> ([a] -> Either ([String] -> result) [Mode result])+  -> [String]+  -> Ex.Exceptional P.Error result+modesNoHelp globals lsToEi ss = P.parse ss $ do+  gs <- P.manyTill (C.parseOption globals) endOrNonOpt+  case lsToEi gs of+    Left parsePosArgs ->+          parsePosArgs <$> many P.nextWord <* P.end+    Right mds -> do+      let modeWords = Set.fromList . map mName $ mds+      (_, w) <- P.matchApproxWord modeWords+      let cmd = fromJust . find (\c -> mName c == w) $ mds+      processModeNoHelp cmd++processModeWithHelp+  :: String+  -- ^ Program name+   -> Mode result+   -> P.Parser (ArgWrapResult result)+processModeWithHelp pn (Mode _ i os pa p h) = do   let prsr = case i of         Intersperse -> parseIntersperse         StopOptions -> parseStopOpts+      os' = addHelpOpt os+  rs <- prsr (C.parseOption os') (fmap OtherArg pa) <* P.end+  let (needsHelp, parsedOpts) = partitionHelp rs+  return $ if needsHelp then NeedsHelp (h pn) else NoHelp $ p parsedOpts+++processModeNoHelp+   :: Mode result+   -> P.Parser result+processModeNoHelp (Mode _ i os pa p _) = do+  let prsr = case i of+        Intersperse -> parseIntersperse+        StopOptions -> parseStopOpts   rs <- prsr (C.parseOption os) pa <* P.end   return $ p rs ++addHelpOpt :: [C.OptSpec a] -> [C.OptSpec (ArgWrap a)]+addHelpOpt os =+  let helpOpt = C.OptSpec ["help"] "h" (C.NoArg HelpArg)+      origOpts = fmap (fmap OtherArg) os+  in helpOpt : origOpts+ -- | Parses a command line that may feature options followed by a -- mode followed by more options and then followed by positional -- arguments. modes   :: [C.OptSpec a]-     -- ^ Global options. These come after the program name but before-     -- the mode name.--  -> ([a] -> Ex.Exceptional String b)-     -- ^ This function is applied to all the global options after-     -- they are parsed. To indicate a failure, return an Exception-     -- String; otherwise, return a successful value. This allows you-     -- to process the global options before the mode is parsed. (If-     -- you don't need to do any preprocessing, pass @return@ here.)-     -- If you indicate a failure here, parsing of the command line-     -- will stop and this error message will be returned.+  -- ^ Global options. These come after the program name but before+  -- the mode name. -  -> (b -> Either (String -> c) [Mode result])-     -- ^ This function determines whether modes will be parsed and,-     -- if so, which ones. The function is applied to the result of-     -- the pre-processing of the global options, so which modes are-     -- parsed and the behavior of those modes can vary depending on-     -- the global options. Return a Left to indicate that you do not-     -- want to parse modes at all. For instance, if the user passed a-     -- @--help@ option, you may not want to look for a mode after-     -- that. Otherwise, to parse modes, return a Right with a list of-     -- the modes.+  -> ([a] -> Either ([String] -> result) [Mode result])+  -- ^ This function will be applied to the result of parsing the+  -- global options. The function must return a @Left@ if you do not+  -- want to parse any modes at all. This can be useful if one of the+  -- global options was something like @--help@ or @--version@ and so+  -- you do not need to see any mode. The function returned in the+  -- @Left@ will be applied to a list of all remaining command-line+  -- arguments after the global options.    -> [String]-     -- ^ The command line to parse (presumably from 'getArgs')+  -- ^ The command line to parse (presumably from 'getArgs') -  -> Ex.Exceptional P.Error (b, Either [c] result)-     -- ^ Returns an Exception if an error was encountered when-     -- parsing the command line (including if the global options-     -- procesor returned an Exception.) Otherwise, returns a-     -- pair. The first element of the pair is the result of the-     -- global options processor. The second element of the pair is an-     -- Either. It is Left if no modes were parsed, with a list of the-     -- positional arguments. It is a Right if modes were parsed, with-     -- the result of parsing the arguments to the mode.+  -> Ex.Exceptional P.Error result+  -- ^ Returns an Exception if an error was encountered when parsing+  -- any part of the command line (either the global options or the+  -- mode.) Otherwise, returns the result.+modes = modesNoHelp -modes globals lsToB getCmds ss = P.parse ss $ do-  gs <- P.manyTill (C.parseOption globals) endOrNonOpt-  b <- case lsToB gs of-    Ex.Exception e -> fail e-    Ex.Success g -> return g-  let cmds = getCmds b-  case cmds of-    Left fPa -> do-      posArgs <- (fmap (fmap fPa) $ many P.nextWord) <* P.end-      return (b, Left posArgs)-    Right cds -> do-      let cmdWords = Set.fromList . map mName $ cds-      (_, w) <- P.matchApproxWord cmdWords-      let cmd = fromJust . find (\c -> mName c == w) $ cds-      r <- processModeArgs cmd-      return (b, Right r)+-- | Like 'modes', but runs in the IO monad. Gets the command line+-- arguments for you.  This function adds the options @-h@ and+-- @--help@, both in the global options and in the options for each+-- mode. If @-h@ or @--help@ is entered in the global options, the+-- global help is shown and the program exits successfully; similarly,+-- if help is requested for a particular mode, that mode's help is+-- shown and the program exits successfully.+--+-- If an error occurs in the processing of the command line, an error+-- message is printed and the program exits with a failure.+modesWithHelp+  :: (String -> String)+  -- ^ Global help. This is a function that, when applied to the name+  -- of the program (which is retrieved at runtime), returns a help+  -- string. This is output exactly as is, so include any necessary+  -- trailing newlines.++  -> [C.OptSpec a]+  -- ^ Global options. These come after the program name but before+  -- the mode name. Do not add options for @-h@ or @--help@; these are+  -- added automatically.++  -> ([a] -> Either ([String] -> result) [Mode result])+  -- ^ This function will be applied to the result of parsing the+  -- global options. The function must return a @Left@ if you do not+  -- want to parse any modes at all. This can be useful if one of the+  -- global options was something like @--version@ and so+  -- you do not need to see any mode. The function returned in the+  -- @Left@ will be applied to a list of all remaining command-line+  -- arguments after the global options.++  -> IO result++modesWithHelp hlp glbls lsToEi = do+  as <- GetArgs.getArgs+  pn <- GetArgs.getProgName+  case modesWithHelpPure pn hlp glbls lsToEi as of+    Ex.Exception e -> do+      IO.hPutStr IO.stderr $ C.formatError pn e+      exitFailure+    Ex.Success g -> case g of+      NeedsHelp h -> putStr h >> exitSuccess+      NoHelp g2 -> case g2 of+        NeedsHelp h -> putStr h >> exitSuccess+        NoHelp g3 -> return g3+  -- | Looks at the next word. Succeeds if it is a non-option, or if we -- are at the end of input. Fails otherwise.
multiarg.cabal view
@@ -1,5 +1,5 @@ Name: multiarg-Version: 0.8.0.0+Version: 0.10.0.0 Cabal-version: >=1.8 Build-Type: Simple License: BSD3@@ -39,7 +39,7 @@ Library     Build-depends:         explicit-exception ==0.1.*,-        containers ==0.4.*+        containers ==0.5.*       -- See documentation in System.Console.MultiArg.GetArgs for details