shelly 0.13.3 → 0.13.4
raw patch · 4 files changed
+55/−22 lines, 4 filesdep +bytestring
Dependencies added: bytestring
Files
- Shelly.hs +45/−16
- Shelly/Base.hs +1/−0
- Shelly/Find.hs +6/−5
- shelly.cabal +3/−1
Shelly.hs view
@@ -25,15 +25,15 @@ module Shelly ( -- * Entering Sh.- Sh, ShIO, shelly, sub, silently, verbosely, escaping, print_stdout, print_commands, tracing+ Sh, ShIO, shelly, sub, silently, verbosely, escaping, print_stdout, print_commands, tracing, errExit -- * Running external commands.- , run, run_, runFoldLines, cmd, (-|-), lastStderr, setStdin+ , run, run_, runFoldLines, cmd, (-|-), lastStderr, setStdin, lastExitCode , command, command_, command1, command1_ , sshPairs, sshPairs_ -- * Modifying and querying environment.- , setenv, get_env, get_env_text, getenv, getenv_def, appendToPath+ , setenv, set_env, get_env, get_env_text, getenv, getenv_def, appendToPath -- * Environment directory , cd, chdir, pwd@@ -53,7 +53,7 @@ , mv, rm, rm_f, rm_rf, cp, cp_r, mkdir, mkdir_p -- * reading/writing Files- , readfile, writefile, appendfile, touchfile, withTmpDir+ , readfile, readBinary, writefile, appendfile, touchfile, withTmpDir -- * exiting the program , exit, errorExit, quietExit, terror@@ -95,13 +95,16 @@ import Data.Time.Clock( getCurrentTime, diffUTCTime ) import qualified Data.Text.Lazy.IO as TIO-import qualified Data.Text.IO as STIO+import qualified Data.Text.Encoding as TE+import qualified Data.Text.Encoding.Error as TE import System.Process( CmdSpec(..), StdStream(CreatePipe), CreateProcess(..), createProcess, waitForProcess, ProcessHandle ) import System.IO.Error (isPermissionError) import qualified Data.Text.Lazy as LT import qualified Data.Text.Lazy.Builder as B import qualified Data.Text as T+import qualified Data.ByteString as BS+import Data.ByteString (ByteString) import Data.Monoid (mappend) import Filesystem.Path.CurrentOS hiding (concat, fromText, (</>), (<.>))@@ -457,10 +460,15 @@ -- TODO: better error message for removeFile (give filename) canonic f >>= liftIO . removeFile +-- | deprecated in favor of 'set_env'+setenv :: Text -> Text -> Sh ()+setenv = set_env+{-# DEPRECATED setenv "use set_env" #-}+ -- | Set an environment variable. The environment is maintained in Sh -- internally, and is passed to any external commands to be executed.-setenv :: Text -> Text -> Sh ()-setenv k v =+set_env :: Text -> Text -> Sh ()+set_env k v = let (kStr, vStr) = (LT.unpack k, LT.unpack v) wibble environment = (kStr, vStr) : filter ((/=kStr).fst) environment in modify $ \x -> x { sEnvironment = wibble $ sEnvironment x }@@ -470,8 +478,8 @@ appendToPath :: FilePath -> Sh () appendToPath = absPath >=> \filepath -> do tp <- toTextWarn filepath- pe <- getenv path_env- setenv path_env $ pe `mappend` ":" `mappend` tp+ pe <- get_env_text path_env+ set_env path_env $ pe `mappend` ":" `mappend` tp where path_env = "PATH" @@ -484,6 +492,7 @@ Nothing -> Nothing j@(Just val) -> if LT.null val then Nothing else j +-- | deprecated getenv :: Text -> Sh Text getenv k = getenv_def k "" {-# DEPRECATED getenv "use get_env or get_env_text" #-}@@ -491,7 +500,7 @@ -- | Fetch the current value of an environment variable. Both empty and -- non-existent variables give empty string as a result. get_env_text :: Text -> Sh Text-get_env_text k = getenv_def k ""+get_env_text = getenv_def "" -- | Fetch the current value of an environment variable. Both empty and -- non-existent variables give the default Text value as a result@@ -555,6 +564,14 @@ } action +-- | named after bash -e errexit. Defaults to True.+-- When True, throw an exception on a non-zero exit code.+-- Not recommended to set to False unless you are specifically checking the error code with 'lastExitCode'.+errExit :: Bool -> Sh a -> Sh a+errExit shouldExit action = sub $ do+ modify $ \st -> st { sErrExit = shouldExit }+ action+ -- | Enter a Sh from (Monad)IO. The environment and working directories are -- inherited from the current process-wide values. Any subsequent changes in -- processwide working directory or environment are not reflected in the@@ -572,7 +589,9 @@ , sEnvironment = environment , sTracing = True , sTrace = B.fromText ""- , sDirectory = dir }+ , sDirectory = dir+ , sErrExit = True+ } stref <- liftIO $ newIORef def let caught = action `catches_sh` [@@ -763,14 +782,19 @@ put $ state { sStderr = errs , sCode = code } - liftIO $ case ex of- ExitSuccess -> takeMVar outV- ExitFailure n -> throwIO $ RunFailed exe args n errs+ liftIO $ case (sErrExit state, ex) of+ (True, ExitFailure n) -> throwIO $ RunFailed exe args n errs+ _ -> takeMVar outV -- | The output of last external command. See "run". lastStderr :: Sh Text lastStderr = gets sStderr +-- | The exit code from the last command.+-- Unless you set 'errExit' to False you won't get a chance to use this: a non-zero exit code will throw an exception.+lastExitCode :: Sh Int+lastExitCode = gets sCode+ -- | set the stdin to be used and cleared by the next "run". setStdin :: Text -> Sh () setStdin input = modify $ \st -> st { sStdin = Just input }@@ -852,11 +876,16 @@ -- | (Strictly) read file into a Text. -- All other functions use Lazy Text.--- So Internally this reads a file as strict text and then converts it to lazy text, which is inefficient+-- Internally this reads a file as strict text and then converts it to lazy text, which is inefficient readfile :: FilePath -> Sh Text readfile = absPath >=> \fp -> do trace $ "readfile " `mappend` toTextIgnore fp- (fmap LT.fromStrict . liftIO . STIO.readFile . unpack) fp+ readBinary fp >>=+ return . LT.fromStrict . TE.decodeUtf8With TE.lenientDecode++-- | wraps ByteSting readFile+readBinary :: FilePath -> Sh ByteString+readBinary = absPath >=> liftIO . BS.readFile . unpack -- | flipped hasExtension for Text hasExt :: Text -> FilePath -> Bool
Shelly/Base.hs view
@@ -64,6 +64,7 @@ , sEnvironment :: [(String, String)] , sTracing :: Bool , sTrace :: B.Builder+ , sErrExit :: Bool } -- | A monadic-conditional version of the "when" guard.
Shelly/Find.hs view
@@ -63,10 +63,11 @@ (rPaths, aPaths) <- lsRelAbs dir foldM traverse startValue (zip rPaths aPaths) where- traverse acc (relPath, absPath) = do+ traverse acc (relativePath, absolutePath) = do -- optimization: don't use Shelly API since our path is already good- isDir <- liftIO $ isDirectory absPath- sym <- liftIO $ fmap isSymbolicLink $ getSymbolicLinkStatus (unpack absPath)+ isDir <- liftIO $ isDirectory absolutePath+ sym <- liftIO $ fmap isSymbolicLink $ getSymbolicLinkStatus (unpack absolutePath)+ newAcc <- folder acc relativePath if isDir && not sym- then findFold folder acc relPath- else folder acc relPath+ then findFold folder newAcc relativePath+ else return newAcc
shelly.cabal view
@@ -1,6 +1,6 @@ Name: shelly -Version: 0.13.3+Version: 0.13.4 Synopsis: shell-like (systems) programming in Haskell Description: Shelly provides convenient systems programming in Haskell,@@ -41,6 +41,7 @@ , unix-compat < 0.4 , system-filepath < 0.5 , system-fileio < 0.4+ , bytestring ghc-options: -Wall @@ -54,6 +55,7 @@ , unix-compat < 0.4 , system-filepath < 0.5 , system-fileio < 0.4+ , bytestring , hspec-discover , hspec >= 1.1 , HUnit