shelly 1.6.1.2 → 1.6.2
raw patch · 7 files changed
+213/−10 lines, 7 filesdep +HUnitdep +hspecdep +shellydep ~basedep ~bytestringdep ~containersnew-component:exe:Colornew-component:exe:drainnew-component:exe:run-handles
Dependencies added: HUnit, hspec, shelly
Dependency ranges changed: base, bytestring, containers, exceptions, monad-control, process, text
Files
- shelly.cabal +93/−1
- src/Shelly.hs +32/−7
- src/Shelly/Base.hs +18/−2
- test/examples/color.hs +12/−0
- test/examples/drain.hs +19/−0
- test/examples/run-handles.hs +8/−0
- test/src/TestMain.hs +31/−0
shelly.cabal view
@@ -1,6 +1,6 @@ Name: shelly -Version: 1.6.1.2+Version: 1.6.2 Synopsis: shell-like (systems) programming in Haskell Description: Shelly provides convenient systems programming in Haskell,@@ -72,3 +72,95 @@ source-repository head type: git location: https://github.com/yesodweb/Shelly.hs++Flag lifted+ Description: run the tests against Shelly.Lifted+ Default: False++Test-Suite shelly-testsuite+ type: exitcode-stdio-1.0+ hs-source-dirs: src test/src+ main-is: TestMain.hs+ ghc-options: -O2 -Wall -fhpc -fwarn-tabs -funbox-strict-fields -threaded+ -fno-warn-unused-do-bind -fno-warn-type-defaults++ extensions: OverloadedStrings, ExtendedDefaultRules++ if flag(lifted)+ cpp-options: -DLIFTED++ build-depends:+ base >= 4.6,+ text >= 0.11,+ async,+ bytestring >= 0.10,+ containers >= 0.5.0.0,+ directory >= 1.1.0.0 && < 1.3.0.0,+ process >= 1.1.0,+ unix-compat < 0.5,+ system-filepath >= 0.4.7 && < 0.5,+ system-fileio < 0.4,+ time >= 1.3 && < 1.6,+ mtl >= 2,+ HUnit >= 1.2,+ hspec >= 1.5,+ transformers,+ transformers-base,+ monad-control,+ lifted-base,+ lifted-async,+ enclosed-exceptions,+ exceptions == 0.6.*++ extensions:+ CPP++Flag build-examples+ Description: build some example programs+ Default: False+ Manual: True++-- demonstarated that command output in Shellish was not shown until after the command finished+-- not necessary anymore+Executable drain+ hs-source-dirs: test/examples+ main-is: drain.hs+ if flag(build-examples)+ buildable: True++ build-depends: base >= 4.6+ , shelly+ , text++ extensions:+ CPP+ else+ buildable: False++Executable run-handles+ hs-source-dirs: test/examples+ main-is: run-handles.hs+ if flag(build-examples)+ buildable: True++ build-depends: base >= 4.6+ , shelly+ , text++ extensions:+ CPP+ else+ buildable: False++Executable Color+ hs-source-dirs: test/examples+ main-is: color.hs+ if flag(build-examples)+ buildable: True++ build-depends: base >= 4.6+ , process+ , shelly+ , text+ else+ buildable: False
src/Shelly.hs view
@@ -25,6 +25,7 @@ -- * Entering Sh. Sh, ShIO, shelly, shellyNoDir, shellyFailDir, asyncSh, sub , silently, verbosely, escaping, print_stdout, print_stderr, print_commands+ , onCommandHandles , tracing, errExit , log_stdout_with, log_stderr_with @@ -39,6 +40,8 @@ , runHandle, runHandles, transferLinesAndCombine, transferFoldHandleLines , StdHandle(..), StdStream(..) + -- * Handle manipulation+ , HandleInitializer, StdInit(..), initOutputHandles, initAllHandles -- * Modifying and querying environment. , setenv, get_env, get_env_text, getenv, get_env_def, get_env_all, get_environment, appendToPath@@ -753,7 +756,22 @@ get_env_def d = get_env >=> return . fromMaybe d {-# DEPRECATED get_env_def "use fromMaybe DEFAULT get_env" #-} +-- | Apply a single initializer to the two output process handles (stdout and stderr)+initOutputHandles :: HandleInitializer -> StdInit+initOutputHandles f = StdInit (const $ return ()) f f +-- | Apply a single initializer to all three standard process handles (stdin, stdout and stderr)+initAllHandles :: HandleInitializer -> StdInit+initAllHandles f = StdInit f f f++-- | When running an external command, apply the given initializers to+-- the specified handles for that command.+-- This can for example be used to change the encoding of the+-- handles or set them into binary mode.+onCommandHandles :: StdInit -> Sh a -> Sh a+onCommandHandles initHandles a =+ sub $ modify (\x -> x { sInitCommandHandles = initHandles }) >> a+ -- | Create a sub-Sh in which external command outputs are not echoed and -- commands are not printed. -- See 'sub'.@@ -839,9 +857,7 @@ -- see the 'run' documentation. escaping :: Bool -> Sh a -> Sh a escaping shouldEscape action = sub $ do- modify $ \st -> st { sRun =- if shouldEscape then runCommand else runCommandNoEscape- }+ modify $ \st -> st { sCommandEscaping = shouldEscape } action -- | named after bash -e errexit. Defaults to @True@.@@ -887,7 +903,8 @@ , sPrintStdout = True , sPrintStderr = True , sPrintCommands = False- , sRun = runCommand+ , sInitCommandHandles = initAllHandles (const $ return ())+ , sCommandEscaping = True , sEnvironment = environment , sTracing = True , sTrace = T.empty@@ -1119,10 +1136,18 @@ when (sPrintCommands state) $ echo cmdString trace cmdString + let doRun = if sCommandEscaping state then runCommand else runCommandNoEscape+ bracket_sh- ((sRun state) reusedHandles state exe args)+ (doRun reusedHandles state exe args) (\(_,_,_,procH) -> (liftIO $ terminateProcess procH)) (\(inH,outH,errH,procH) -> do++ liftIO $ do+ inInit (sInitCommandHandles state) inH+ outInit (sInitCommandHandles state) outH+ errInit (sInitCommandHandles state) errH+ liftIO $ case mStdin of Just input -> TIO.hPutStr inH input Nothing -> return ()@@ -1251,7 +1276,7 @@ mkdir p act p `finally_sh` rm_rf p --- | Write a Lazy Text to a file.+-- | Write a Text to a file. writefile :: FilePath -> Text -> Sh () writefile f' bits = do f <- traceAbsPath ("writefile " <>) f'@@ -1261,7 +1286,7 @@ touchfile :: FilePath -> Sh () touchfile = traceAbsPath ("touch " <>) >=> flip appendfile "" --- | Append a Lazy Text to a file.+-- | Append a Text to a file. appendfile :: FilePath -> Text -> Sh () appendfile f' bits = do f <- traceAbsPath ("appendfile " <>) f'
src/Shelly/Base.hs view
@@ -12,7 +12,9 @@ -- However, Shelly went back to exposing a single module module Shelly.Base (- Sh(..), ShIO, runSh, State(..), ReadOnlyState(..), StdHandle(..), FilePath, Text,+ Sh(..), ShIO, runSh, State(..), ReadOnlyState(..), StdHandle(..),+ HandleInitializer, StdInit(..),+ FilePath, Text, relPath, path, absPath, canonic, canonicalize, test_d, test_s, unpack, gets, get, modify, trace,@@ -113,7 +115,10 @@ , sPutStderr :: Text -> IO () -- ^ by default, hPutStrLn stderr , sPrintStderr :: Bool -- ^ print stderr of command that is executed , sPrintCommands :: Bool -- ^ print command that is executed- , sRun :: [StdHandle] -> State -> FilePath -> [Text] -> Sh (Handle, Handle, Handle, ProcessHandle) -- ^ command runner, a different runner is used when escaping, probably better to just hold the escaping flag+ , sInitCommandHandles :: StdInit -- ^ initializers for the standard process handles+ -- when running a command+ , sCommandEscaping :: Bool -- ^ when running a command, escape shell characters such as '*' rather+ -- than passing to the shell for expansion , sEnvironment :: [(String, String)] , sPathExecutables :: Maybe [(FilePath, S.Set FilePath)] -- ^ cache of executables in the PATH , sTracing :: Bool -- ^ should we trace command execution@@ -125,6 +130,17 @@ data StdHandle = InHandle StdStream | OutHandle StdStream | ErrorHandle StdStream++-- | Initialize a handle before using it+type HandleInitializer = Handle -> IO ()++-- | A collection of initializers for the three standard process handles+data StdInit =+ StdInit {+ inInit :: HandleInitializer,+ outInit :: HandleInitializer,+ errInit :: HandleInitializer+ } -- | A monadic-conditional version of the "when" guard. whenM :: Monad m => m Bool -> m () -> m ()
+ test/examples/color.hs view
@@ -0,0 +1,12 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ExtendedDefaultRules #-}+import Shelly+import System.Process (rawSystem)+import Control.Monad (void)+import Data.Text (Text)++default (Text)++main = shelly $ do+ void $ liftIO $ rawSystem "ls" ["--color=auto", "../dist"]+ run_ "ls" ["--color=auto", "../dist"]
+ test/examples/drain.hs view
@@ -0,0 +1,19 @@+{-# Language OverloadedStrings, ExtendedDefaultRules #-}+import Prelude hiding (FilePath)+import Shelly+import Control.Monad (void)+import Data.Text (Text)++default (Text)++main :: IO ()+main = do+ let exDir = "examples"+ void $ shelly $ do+ let strs = ["a", "b"] :: [String]+ let texts = ["a", "b"] :: [Text]+ let inferred = ["a", "b"]+ res <- cmd (exDir </> "drain.sh") strs texts inferred+ echo "haskell done"+ echo res+ cmd $ exDir </> "printer.sh"
+ test/examples/run-handles.hs view
@@ -0,0 +1,8 @@+{-# Language OverloadedStrings, ExtendedDefaultRules #-}+import Shelly+-- This test runs, but causes this error to show up:+-- Exception: cannot access an inherited pipe+main = shelly $+ runHandles "bash" ["examples/test.sh"] handles doNothing+ where handles = [InHandle Inherit, OutHandle Inherit, ErrorHandle Inherit]+ doNothing _ _ _ = return ""
+ test/src/TestMain.hs view
@@ -0,0 +1,31 @@++module Main where++import ReadFileSpec+import WhichSpec+import WriteSpec+import MoveSpec+import RmSpec+import FindSpec+import EnvSpec+import FailureSpec+import CopySpec+import LiftedSpec+import RunSpec++import Test.Hspec++main :: IO ()+main = hspec $ do+ readFileSpec+ whichSpec+ writeSpec+ moveSpec+ rmSpec+ findSpec+ envSpec+ failureSpec+ copySpec+ liftedSpec+ runSpec+