packages feed

shell-conduit 4.5.2 → 4.6.0

raw patch · 8 files changed

+169/−48 lines, 8 filesdep +hspecdep +hspec-expectationsdep +shell-conduitdep ~basedep ~processnew-uploader

Dependencies added: hspec, hspec-expectations, shell-conduit

Dependency ranges changed: base, process

Files

+ CHANGELOG.md view
@@ -0,0 +1,6 @@+# 4.6.0++* Add basic tests code+* Accept list as variadic command line arguments+  `mkdir "-p" ["folder1", "folder2"]` works now.+* TRAVIS CI added
README.md view
@@ -1,9 +1,9 @@-shell-conduit [![Hackage](https://img.shields.io/hackage/v/shell-conduit.svg?style=flat)](https://hackage.haskell.org/package/shell-conduit)+shell-conduit [![Hackage](https://img.shields.io/hackage/v/shell-conduit.svg?style=flat)](https://hackage.haskell.org/package/shell-conduit) [![Build Status](https://travis-ci.org/psibi/shell-conduit.svg?branch=master)](https://travis-ci.org/psibi/shell-conduit) =====  Write shell scripts with Conduit. Still in the experimental phase. -[Haddock API documentation](http://chrisdone.github.io/shell-conduit/).+[Haddock API documentation](https://www.stackage.org/package/shell-conduit).  ### Examples 
shell-conduit.cabal view
@@ -1,17 +1,18 @@ name:                shell-conduit-version:             4.5.2+version:             4.6.0 synopsis:            Write shell scripts with Conduit description:         Write shell scripts with Conduit. See "Data.Conduit.Shell" for documentation. license:             BSD3 license-file:        LICENSE author:              Chris Done-maintainer:          chrisdone@gmail.com-copyright:           2014 Chris Done+maintainer:          Sibi Prabakaran <sibi@psibi.in>+copyright:           2014-2017 Chris Done category:            Conduit, Scripting build-type:          Simple cabal-version:       >=1.8-homepage:            https://github.com/chrisdone/shell-conduit-extra-source-files:  README.md+homepage:            https://github.com/psibi/shell-conduit+extra-source-files:  CHANGELOG.md README.md+bug-reports:         https://github.com/psibi/shell-conduit/issues  library   hs-source-dirs:    src/@@ -33,7 +34,7 @@                    , filepath                    , monad-control                    , monads-tf-                   , process+                   , process >= 1.2.1.0                    , resourcet                    , semigroups                    , split@@ -43,6 +44,18 @@                    , transformers-base                    , unix >= 2.7.0.1 +test-suite test+ type:            exitcode-stdio-1.0+ ghc-options:     -Wall+ hs-source-dirs:  test/+ main-is:         Spec.hs+    + build-depends:   base >= 4.5 && < 5,+                  shell-conduit,+                  hspec >= 2.1 && < 3,+                  hspec-expectations,+                  template-haskell+ source-repository head   type:     git-  location: https://github.com/chrisdone/shell-conduit.git+  location: http://github.com/psibi/shell-conduit
src/Data/Conduit/Shell/PATH.hs view
@@ -1,24 +1,29 @@ {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE NoMonomorphismRestriction #-} {-# LANGUAGE QuasiQuotes #-}-{-# OPTIONS_GHC -fno-warn-missing-signatures -fno-warn-unused-imports #-}+{-# OPTIONS_GHC+  -fno-warn-missing-signatures -fno-warn-unused-imports #-}  -- | All binaries in PATH.- module Data.Conduit.Shell.PATH where -import           Control.Monad-import           Control.Monad.IO.Class-import           Data.Conduit.Shell.Process-import           Data.Conduit.Shell.TH-import           Data.Conduit.Shell.Variadic-import           Data.List+import Control.Monad+import Control.Monad.IO.Class+import Data.Conduit.Shell.Process+import Data.Conduit.Shell.TH+import Data.Conduit.Shell.Variadic+import Data.List import qualified Data.Text as T (unpack)-import           Prelude-import           System.Directory+import Prelude+import System.Directory  -- | Helpful CD command.-cd :: (MonadIO m,CmdArg arg) => arg -> m ()-cd fp = liftIO (setCurrentDirectory (T.unpack (toTextArg fp)))+cd+  :: (MonadIO m, CmdArg arg)+  => arg -> m ()+cd fp =+  case (toTextArg fp) of+    [] -> return ()+    (path:_) -> liftIO $ setCurrentDirectory (T.unpack path)  $(generateBinaries)
src/Data/Conduit/Shell/Process.hs view
@@ -31,21 +31,18 @@ import           Control.Exception import           Control.Monad import           Control.Monad.IO.Class-import           Control.Monad.Trans.Resource import           Data.ByteString (ByteString) import qualified Data.ByteString as S import           Data.Conduit import           Data.Conduit.Binary import qualified Data.Conduit.List as CL-import           Data.Conduit.Text (Codec)-import qualified Data.Conduit.Text as T+import           Data.Conduit.Text (encodeUtf8, decodeUtf8) import           Data.Text (Text) import           Data.Typeable import           System.Exit import           System.IO import           System.Posix.IO (createPipe, fdToHandle) import           System.Process hiding (createPipe)-import           System.Process.Internals (createProcess_)  -- | A pipeable segment. Either a conduit or a process. data Segment r@@ -77,7 +74,7 @@     do ex <- tryS this        case ex of          Right x -> pure x-         Left (e :: ProcessException) -> that+         Left (_ :: ProcessException) -> that   empty = throw ProcessEmpty  -- | Try something in a segment.@@ -104,6 +101,7 @@ instance Exception ProcessException  instance Show ProcessException where+  show ProcessEmpty = "empty process"   show (ProcessException cp ec) =     concat ["The "            ,case cmdspec cp of@@ -166,7 +164,7 @@  -- | Work on the stream as 'Text' values from UTF-8. text :: (r ~ (),m ~ IO) => ConduitM Text Text m r -> Segment r-text conduit = bytes (T.decodeUtf8 $= conduit $= T.encodeUtf8)+text conduit' = bytes (decodeUtf8 $= conduit' $= encodeUtf8)  -- | Lift a conduit into a segment. bytes :: (a ~ ByteString,m ~ IO) => ConduitM a ByteString m r -> Segment r
src/Data/Conduit/Shell/TH.hs view
@@ -57,7 +57,7 @@   do inScope <- recover (return False)                         (do void (reify (mkName candidate))                             return True)-     if inScope || candidate == "import"+     if inScope || candidate == "import" || candidate == "type"         then getUniqueName (candidate ++ "'")         else return (mkName candidate) 
src/Data/Conduit/Shell/Variadic.hs view
@@ -2,24 +2,25 @@ {-# LANGUAGE TypeFamilies #-}  -- | Variadic process calling.- module Data.Conduit.Shell.Variadic-  (ProcessType(..)-  ,variadicProcess-  ,CmdArg(..))-  where+  ( ProcessType(..)+  , variadicProcess+  , CmdArg(..)+  ) where  import qualified Data.ByteString as SB import qualified Data.ByteString.Lazy as LB-import           Data.Conduit.Shell.Process+import Data.Conduit.Shell.Process import qualified Data.Text as ST import qualified Data.Text.Encoding as ST import qualified Data.Text.Lazy as LT import qualified Data.Text.Lazy.Encoding as LT+import Control.Applicative (pure)  -- | A variadic process maker.-variadicProcess :: (ProcessType r)-                => String -> r+variadicProcess+  :: (ProcessType r)+  => String -> r variadicProcess name = spr name []  -- | Make the final conduit.@@ -27,31 +28,48 @@ makeProcessLauncher name args = proc name (map ST.unpack args)  -- | Process return type.-class ProcessType t where-    spr :: String -> [ST.Text] -> t+class ProcessType t  where+  spr :: String -> [ST.Text] -> t -instance (r ~ ()) => ProcessType (Segment r) where-    spr name args = makeProcessLauncher name (reverse args)+instance (r ~ ()) =>+         ProcessType (Segment r) where+  spr name args = makeProcessLauncher name args  -- | Accept strings as arguments.-instance (ProcessType r,CmdArg a) => ProcessType (a -> r) where-    spr name args = \a -> spr name (toTextArg a : args)+instance (ProcessType r, CmdArg a) =>+         ProcessType (a -> r) where+  spr name args = \a -> spr name (args ++ toTextArg a)  -- | Command line argument. class CmdArg a  where-  toTextArg :: a -> ST.Text+  toTextArg :: a -> [ST.Text]  instance CmdArg ST.Text where-  toTextArg = id+  toTextArg = pure . id  instance CmdArg LT.Text where-  toTextArg = LT.toStrict+  toTextArg = pure . LT.toStrict  instance CmdArg SB.ByteString where-  toTextArg = ST.decodeUtf8+  toTextArg = pure . ST.decodeUtf8  instance CmdArg LB.ByteString where-  toTextArg = LT.toStrict . LT.decodeUtf8+  toTextArg = pure . LT.toStrict . LT.decodeUtf8  instance CmdArg String where-  toTextArg = ST.pack+  toTextArg = pure . ST.pack++instance CmdArg [String] where+  toTextArg = map ST.pack++instance CmdArg [ST.Text] where+  toTextArg = map id++instance CmdArg [LT.Text] where+  toTextArg = map LT.toStrict++instance CmdArg [SB.ByteString] where+  toTextArg = map ST.decodeUtf8++instance CmdArg [LB.ByteString] where+  toTextArg = map (LT.toStrict . LT.decodeUtf8)
+ test/Spec.hs view
@@ -0,0 +1,81 @@+{-# LANGUAGE ExtendedDefaultRules #-}+{-# LANGUAGE CPP #-}++import Test.Hspec+import Data.Conduit.Shell+import Data.Conduit.Shell.PATH (true, false)+import Data.Conduit.Shell.Segments (strings, ignore)+import Control.Applicative++main :: IO ()+main =+  hspec $+  do describe "SHELL path functions" $+       do it "false" $+            do val <- run $ strings (false <|> echo "failed")+               val `shouldBe` ["failed"]+          it "true" $+            do val <- run $ strings (true <|> echo "passed")+               val `shouldBe` []+     describe "ls" $+       do it "home directory check" $+            do val <- run $ strings (ls "/")+               val `shouldContain` ["home"]+          it "long option" $+            do val <- run $ strings (ls "-a" ["/"])+               val `shouldContain` ["home"]+     describe "multiple string usage" $+       do it "make two directory" $+            do val <-+                 run $+                 do ignore $ mkdir "-p" "mtest1" "mtest2" "mtest3"+                    strings $ ls "."+               run $ rmdir ["mtest1", "mtest2", "mtest3"]+               val `shouldContain` ["mtest1", "mtest2", "mtest3"]+     describe "list usage in variadic" $+       do it "two directory" $+            do val <-+                 run $+                 do ignore $ mkdir "-p" ["test1", "test2"]+                    strings $ ls "."+               run $ rmdir ["test1", "test2"]+               val `shouldContain` ["test1", "test2"]+     describe "shell calls" $+       do it "shell ls" $+            do val <- run $ do strings $ shell "ls /"+               val `shouldContain` ["home"]+     describe "ordering of arguments" $+       do it "echo -e" $+            do val <- run $ do strings $ echo "-e" "hello\n" "haskell"+#ifdef darwin_HOST_OS+               val `shouldBe` ["-e hello", " haskell"]+#else+               val `shouldBe` ["hello", " haskell"]+#endif+          it "mixed variant" $+            do val <- run $ strings $ echo "-e" ["hello\n", "haskell"]+#ifdef darwin_HOST_OS+               val `shouldBe` ["-e hello", " haskell"]+#else+               val `shouldBe` ["hello", " haskell"]+#endif+          it "list variant" $+            do val <- run $ strings $ echo ["-e", "hello\n", "haskell"]+#ifdef darwin_HOST_OS+               val `shouldBe` ["-e hello", " haskell"]+#else+               val `shouldBe` ["hello", " haskell"]+#endif+     describe "cd" $+       do it "cd /" $+            do val <-+                 run $+                 do ignore $ cd "/"+                    strings pwd+               val `shouldBe` ["/"]+          it "cd /home" $+            do val <-+                 run $+                 do ignore $ cd ["/home", undefined]+                    strings pwd+               val `shouldBe` ["/home"]