shelly 1.3.0.5 → 1.3.0.6
raw patch · 4 files changed
+45/−25 lines, 4 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Shelly: get :: MonadState s m => m s
+ Shelly: get :: Sh State
- Shelly: put :: MonadState s m => s -> m ()
+ Shelly: put :: State -> Sh ()
Files
- shelly.cabal +1/−1
- src/Shelly.hs +16/−7
- src/Shelly/Base.hs +27/−16
- src/Shelly/Find.hs +1/−1
shelly.cabal view
@@ -1,6 +1,6 @@ Name: shelly -Version: 1.3.0.5+Version: 1.3.0.6 Synopsis: shell-like (systems) programming in Haskell Description: Shelly provides convenient systems programming in Haskell,
src/Shelly.hs view
@@ -86,7 +86,7 @@ import Shelly.Find import Control.Monad ( when, unless, void, forM, filterM ) import Control.Monad.Trans ( MonadIO )-import Control.Monad.State (get, gets, modify, put)+import Control.Monad.Reader (ask) #if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ < 706 import Prelude hiding ( readFile, FilePath, catch) #else@@ -94,6 +94,7 @@ #endif import Data.Char ( isAlphaNum, isSpace ) import Data.Typeable+import Data.IORef import Data.Sequence (Seq, (|>)) import Data.Foldable (toList) import Data.Maybe@@ -286,6 +287,11 @@ trace msg action +put :: State -> Sh ()+put newState = do+ stateVar <- ask+ liftIO (writeIORef stateVar newState)+ runCommandNoEscape :: [StdHandle] -> State -> FilePath -> [Text] -> Sh (Handle, Handle, Handle, ProcessHandle) runCommandNoEscape handles st exe args = liftIO $ shellyProcess handles st $ ShellCommand $ T.unpack $ T.intercalate " " (toTextIgnore exe : args)@@ -374,13 +380,13 @@ -- | Same as a normal 'catch' but specialized for the Sh monad. catch_sh :: (Exception e) => Sh a -> (e -> Sh a) -> Sh a catch_sh action handle = do- ref <- get+ ref <- ask liftIO $ catch (runSh action ref) (\e -> runSh (handle e) ref) -- | Same as a normal 'finally' but specialized for the 'Sh' monad. finally_sh :: Sh a -> Sh b -> Sh a finally_sh action handle = do- ref <- get+ ref <- ask liftIO $ finally (runSh action ref) (runSh handle ref) @@ -390,7 +396,7 @@ -- | Same as a normal 'catches', but specialized for the 'Sh' monad. catches_sh :: Sh a -> [ShellyHandler a] -> Sh a catches_sh action handlers = do- ref <- get+ ref <- ask let runner a = runSh a ref liftIO $ catches (runner action) $ map (toHandler runner) handlers where@@ -720,10 +726,10 @@ -- The original state will be restored when the sub-Sh completes. -- Exceptions are propagated normally. sub :: Sh a -> Sh a-sub action = do+sub a = do oldState <- get modify $ \st -> st { sTrace = T.empty }- action `finally_sh` restoreState oldState+ a `finally_sh` restoreState oldState where restoreState oldState = do newState <- get@@ -803,6 +809,7 @@ , sPathExecutables = Nothing , sErrExit = True }+ stref <- liftIO $ newIORef def let caught = action `catches_sh` [ ShellyHandler (\ex ->@@ -814,7 +821,7 @@ QuietExit n -> liftIO $ throwIO $ ExitFailure n) , ShellyHandler (\(ex::SomeException) -> throwExplainedException ex) ]- liftIO $ runSh caught def+ liftIO $ runSh caught stref where throwExplainedException :: Exception exception => exception -> Sh a throwExplainedException ex = get >>= errorMsg >>= liftIO . throwIO . ReThrownException ex@@ -881,6 +888,8 @@ -- Commands are in the same form as 'run', but given as pairs -- -- > sshPairs "server-name" [("cd", "dir"), ("rm",["-r","dir2"])]+--+-- This interface is crude, but it works for now. -- -- Please note this sets 'escaping' to False: the commands will not be shell escaped. -- Internally the list of commands are combined with the string @&&@ before given to ssh.
src/Shelly/Base.hs view
@@ -9,7 +9,7 @@ Sh, ShIO, unSh, runSh, State(..), StdHandle(..), FilePath, Text, relPath, path, absPath, canonic, canonicalize, test_d, test_s,- trace,+ unpack, gets, get, modify, trace, ls, lsRelAbs, toTextIgnore, echo, echo_n, echo_err, echo_n_err, inspect, inspect_err,@@ -38,13 +38,14 @@ import Filesystem.Path.CurrentOS (FilePath, encodeString, relative) import qualified Filesystem.Path.CurrentOS as FP import qualified Filesystem as FS+import Data.IORef (readIORef, modifyIORef, IORef) import Data.Monoid (mappend) import qualified Data.Text as T import qualified Data.Text.IO as TIO import Control.Exception (SomeException, catch) import Data.Maybe (fromMaybe) import Control.Monad.Trans ( MonadIO, liftIO )-import Control.Monad.State (MonadState, evalStateT, modify, StateT, gets)+import Control.Monad.Reader (MonadReader, runReaderT, ask, ReaderT) import qualified Data.Set as S -- | ShIO is Deprecated in favor of 'Sh', which is easier to type.@@ -52,33 +53,27 @@ {-# DEPRECATED ShIO "Use Sh instead of ShIO" #-} newtype Sh a = Sh {- unSh :: StateT State IO a- } deriving (Applicative, Monad, MonadIO, MonadState State, Functor)+ unSh :: ReaderT (IORef State) IO a+ } deriving (Applicative, Monad, MonadIO, MonadReader (IORef State), Functor) -runSh :: Sh a -> State -> IO a-runSh = evalStateT . unSh+runSh :: Sh a -> IORef State -> IO a+runSh = runReaderT . unSh -data State = State- -- state for the currently ran command+data State = State { sCode :: Int -- ^ exit code for command that ran , sStdin :: Maybe Text -- ^ stdin for the command to be run , sStderr :: Text -- ^ stderr for command that ran-- -- state for the envrionment , sDirectory :: FilePath -- ^ working directory- , sEnvironment :: [(String, String)]- , sPathExecutables :: Maybe [(FilePath, S.Set FilePath)] -- ^ cache of executables in the PATH-- -- state for the options , sPrintStdout :: Bool -- ^ print stdout 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+ , sEnvironment :: [(String, String)]+ , sPathExecutables :: Maybe [(FilePath, S.Set FilePath)] -- ^ cache of executables in the PATH , sTracing :: Bool -- ^ should we trace command execution , sTrace :: Text -- ^ the trace of command execution , sErrExit :: Bool -- ^ should we exit immediately on any error- , 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 } - data StdHandle = InHandle StdStream | OutHandle StdStream | ErrorHandle StdStream@@ -182,6 +177,22 @@ test_s = absPath >=> liftIO . \f -> do stat <- getSymbolicLinkStatus (encodeString f) return $ isSymbolicLink stat++unpack :: FilePath -> String+unpack = encodeString++gets :: (State -> a) -> Sh a+gets f = f <$> get++get :: Sh State+get = do+ stateVar <- ask + liftIO (readIORef stateVar)++modify :: (State -> State) -> Sh ()+modify f = do+ state <- ask + liftIO (modifyIORef state f) -- | internally log what occurred. -- Log will be re-played on failure.
src/Shelly/Find.hs view
@@ -14,7 +14,7 @@ import Data.Monoid (mappend) import System.PosixCompat.Files( getSymbolicLinkStatus, isSymbolicLink ) import Filesystem (isDirectory)-import Filesystem.Path.CurrentOS (encodeString)+import Filesystem.Path.CurrentOS (FilePath, encodeString) -- | List directory recursively (like the POSIX utility "find"). -- listing is relative if the path given is relative.