packages feed

optparse-simple 0.0.3 → 0.0.4

raw patch · 5 files changed

+201/−3 lines, 5 filesdep +bytestringdep +directorydep +optparse-simpledep ~basenew-uploader

Dependencies added: bytestring, directory, optparse-simple

Dependency ranges changed: base

Files

+ ChangeLog.md view
@@ -0,0 +1,3 @@+## 0.0.4++* Support `--help` on subcommands
+ README.md view
@@ -0,0 +1,37 @@+optparse-simple+=====++Simple interface to optparse-applicative++## Usage++Typical usage with no commands:++``` haskell+do (opts,()) <-+     simpleOptions "ver"+                   "header"+                   "desc"+                   (flag () () (long "some-flag"))+                   empty+   doThings opts+```++Typical usage with commands:++``` haskell+do (opts,runCmd) <-+     simpleOptions "ver"+                   "header"+                   "desc"+                   (pure ()) $+     do addCommand "delete"+                   "Delete the thing"+                   (const deleteTheThing)+                   (pure ())+        addCommand "create"+                   "Create a thing"+                   createAThing+                   (strOption (long "hello"))+   runCmd+```
optparse-simple.cabal view
@@ -1,5 +1,5 @@ name:                optparse-simple-version:             0.0.3+version:             0.0.4 synopsis:            Simple interface to optparse-applicative description:         Simple interface to optparse-applicative license:             BSD3@@ -10,10 +10,11 @@ category:            Options build-type:          Simple cabal-version:       >=1.8+extra-source-files:  README.md ChangeLog.md  library   hs-source-dirs:    src/-  ghc-options:       -Wall -O2+  ghc-options:       -Wall   exposed-modules:   Options.Applicative.Simple   build-depends:     base >= 4 && <5                    , template-haskell@@ -21,3 +22,18 @@                    , optparse-applicative                    , gitrev                    , either++test-suite test+  type:              exitcode-stdio-1.0+  main-is:           Main.hs+  build-depends:+                     base -any+                   , optparse-simple+                   , directory -any+                   , bytestring -any+  hs-source-dirs:    test+  ghc-options:       -Wall++source-repository head+  type:              git+  location:          https://github.com/fpco/optparse-simple
src/Options/Applicative/Simple.hs view
@@ -101,7 +101,7 @@            -> EitherT b (Writer (Mod CommandFields b)) () addCommand cmd title constr inner =   lift (tell (command cmd-                      (info (constr <$> inner)+                      (info (constr <$> (helper <*> inner))                             (progDesc title))))  -- | Add a command that takes sub-commands to the options dispatcher.
+ test/Main.hs view
@@ -0,0 +1,142 @@+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE OverloadedStrings #-}++import Options.Applicative.Simple hiding(action)+import GHC.IO.Handle+import System.IO+import System.Environment+import Control.Exception+import Control.Monad+import System.Directory+import System.Exit+import Data.ByteString (ByteString)+import qualified Data.ByteString as BS+import Data.Monoid ((<>))+++shouldBe :: (Show a, Eq a) => a -> a -> IO ()+shouldBe actual expected+  | expected == actual = return ()+  | otherwise = do+    putStrLn $ "expected: " ++ show expected+    putStrLn $ "actual  : " ++ show actual+    exitFailure++catchReturn :: Exception e => IO e -> IO e+catchReturn io = io `catch` return++catchExitCode :: IO () -> IO ExitCode+catchExitCode action = catchReturn $ do+  action+  return ExitSuccess++data FakeHandles = FakeHandles+  { fakeIn  :: Handle+  , fakeOut :: Handle+  , fakeErr :: Handle+  , realIn  :: Handle+  , realOut :: Handle+  , realErr :: Handle+  }++openFile' :: FilePath -> IO Handle+openFile' path = do+  removeIfExists path+  openFile path ReadWriteMode++removeIfExists :: FilePath -> IO ()+removeIfExists path = do+  exists <- doesFileExist path+  when exists $ do+    removeFile path++stdinFile :: FilePath+stdinFile = ".tmp.stdin"++stdoutFile :: FilePath+stdoutFile = ".tmp.stdout"++stderrFile :: FilePath+stderrFile = ".tmp.stderr"++beforeFH :: IO FakeHandles+beforeFH = do+  realIn <- hDuplicate stdin+  realOut <- hDuplicate stdout+  realErr <- hDuplicate stderr++  fakeIn <- openFile stdinFile ReadWriteMode+  fakeOut <- openFile' stdoutFile+  fakeErr <- openFile' stderrFile++  hDuplicateTo fakeIn stdin+  hDuplicateTo fakeOut stdout+  hDuplicateTo fakeErr stderr++  return FakeHandles{..}++afterFH :: FakeHandles -> IO ()+afterFH FakeHandles{..} = do+  hDuplicateTo realIn stdin+  hDuplicateTo realOut stdout+  hDuplicateTo realErr stderr++  hClose fakeIn+  hClose fakeOut+  hClose fakeErr++withFakeHandles :: IO a -> IO a+withFakeHandles = bracket beforeFH afterFH . const++withStdIn :: ByteString -> IO ()+  -> IO (ByteString, ByteString, ExitCode)+withStdIn inBS action = do+  BS.writeFile stdinFile inBS+  withFakeHandles $ do+    _ <- catchExitCode action+    hFlush stdout+    hFlush stderr+  out <- BS.readFile stdoutFile+  err <- BS.readFile stderrFile++  removeIfExists stdinFile+  removeIfExists stdoutFile+  removeIfExists stderrFile++  return (out, err, ExitSuccess)+++main :: IO ()+main = do+  (out, err, exitCode) <- withStdIn ""+    $ withArgs ["--version"]+    $ simpleProg+  exitCode `shouldBe` ExitSuccess+  err `shouldBe` ""+  out `shouldBe` "version\n"++  (out', err', exitCode') <- withStdIn ""+    $ withArgs ["--summary"]+    $ summaryProg+  exitCode' `shouldBe` ExitSuccess+  err' `shouldBe` ""+  out' `shouldBe` "A program summary\n"++  return ()+++simpleProg :: IO ()+simpleProg = do+  ((), ()) <- simpleOptions "version" "header" "desc" (pure ()) empty+  return ()++parserWithSummary :: Parser ()+parserWithSummary = summaryOption <*> pure () where+  summaryOption = infoOption "A program summary"+    $ long "summary"+   <> help "Show program summary"++summaryProg :: IO ()+summaryProg = do+  ((), ()) <- simpleOptions "version" "header" "desc" parserWithSummary empty+  return ()