{-# LANGUAGE FlexibleInstances, TypeSynonymInstances,
             TypeFamilies, ExistentialQuantification #-}

-- | This module is a wrapper for the module "Shelly".
-- The only difference is a main type 'Sh'. In this module
-- 'Sh' contains a list of results. Actual definition of the type 'Sh' is:
--
-- > import qualified Shelly as S
-- >
-- > newtype Sh a = Sh { unSh :: S.Sh [a] }
--
-- This definition can simplify some filesystem commands.
-- A monad bind operator becomes a pipe operator and we can write
--
-- > findExt ext = findWhen (pure . hasExt ext)
-- >
-- > main :: IO ()
-- > main = shs $ do
-- >     mkdir "new"
-- >     findExt "hs"  "." >>= flip cp "new"
-- >     findExt "cpp" "." >>= rm_f
-- >     liftIO $ putStrLn "done"
--
-- Documentation in this module mostly just reference documentation from
-- the main "Shelly" module.
--
-- > {-# LANGUAGE OverloadedStrings #-}
-- > {-# LANGUAGE ExtendedDefaultRules #-}
-- > {-# OPTIONS_GHC -fno-warn-type-defaults #-}
-- > import Shelly
-- > import Data.Text as T
-- > default (T.Text)

module Shelly.Pipe
       (
         -- * Entering Sh
         Sh, shs, shelly, shellyFailDir, shsFailDir, sub, silently, verbosely, escaping, print_stdout, print_commands, tracing, errExit, log_stdout_with, log_stderr_with
         -- * List functions
         , roll, unroll, liftSh
         -- * Running external commands
         , FoldCallback
         , run, run_, runFoldLines, cmd
         , (-|-), lastStderr, setStdin, lastExitCode
         , command, command_, command1, command1_
         , sshPairs, sshPairs_

         -- * Modifying and querying environment
         , setenv, get_env, get_env_text, get_env_def, appendToPath, prependToPath

         -- * Environment directory
         , cd, chdir, pwd

         -- * Printing
         , echo, echo_n, echo_err, echo_n_err, inspect, inspect_err
         , tag, trace, show_command

         -- * Querying filesystem
         , ls, lsT, test_e, test_f, test_d, test_s, which

         -- * Filename helpers
         , absPath, (</>), (<.>), canonic, canonicalize, relPath, relativeTo
         , hasExt

         -- * Manipulating filesystem
         , mv, rm, rm_f, rm_rf, cp, cp_r, mkdir, mkdir_p, mkdirTree

         -- * reading/writing Files
         , readfile, readBinary, writefile, appendfile, touchfile, withTmpDir

         -- * exiting the program
         , exit, errorExit, quietExit, terror

         -- * Exceptions
         , catchany, catch_sh, finally_sh
         , ShellyHandler(..), catches_sh
         , catchany_sh

         -- * convert between Text and FilePath
         , toTextIgnore, toTextWarn, S.fromText

         -- * Utilities
         , (<$>), whenM, unlessM, time

         -- * Re-exported for your convenience
         , liftIO, when, unless, FilePath

         -- * internal functions for writing extensions
         , get, put

         -- * find functions
         , find, findWhen, findFold
         , findDirFilter, findDirFilterWhen, findFoldDirFilter
         , followSymlink
         ) where

import qualified Shelly as S

import Shelly
    ( (</>), (<.>), hasExt
    , whenM, unlessM, toTextIgnore
    , catchany
    , FoldCallback
    )
import Shelly.Base (State)

import Control.Applicative
import Control.Monad
import Control.Monad.Trans
import Control.Exception

import Data.Maybe      ( fromMaybe )
import Data.ByteString ( ByteString )
import Data.Tree       ( Tree )
import Data.Text as T hiding (concat, all, find, cons)

-- | This type is a simple wrapper for a type @Shelly.Sh@.
-- 'Sh' contains a list of results.

newtype Sh a = Sh { forall a. Sh a -> Sh [a]
unSh :: S.Sh [a] }

instance Functor Sh where
    fmap :: forall a b. (a -> b) -> Sh a -> Sh b
fmap a -> b
f = Sh [b] -> Sh b
forall a. Sh [a] -> Sh a
Sh (Sh [b] -> Sh b) -> (Sh a -> Sh [b]) -> Sh a -> Sh b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([a] -> [b]) -> Sh [a] -> Sh [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f) (Sh [a] -> Sh [b]) -> (Sh a -> Sh [a]) -> Sh a -> Sh [b]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sh a -> Sh [a]
forall a. Sh a -> Sh [a]
unSh

instance Applicative Sh where
    pure :: forall a. a -> Sh a
pure  = Sh [a] -> Sh a
forall a. Sh [a] -> Sh a
Sh (Sh [a] -> Sh a) -> (a -> Sh [a]) -> a -> Sh a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Sh [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([a] -> Sh [a]) -> (a -> [a]) -> a -> Sh [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure
    <*> :: forall a b. Sh (a -> b) -> Sh a -> Sh b
(<*>) = Sh (a -> b) -> Sh a -> Sh b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap
    Sh a
a *> :: forall a b. Sh a -> Sh b -> Sh b
*> Sh b
b  = Sh [b] -> Sh b
forall a. Sh [a] -> Sh a
Sh (Sh [b] -> Sh b) -> Sh [b] -> Sh b
forall a b. (a -> b) -> a -> b
$ Sh a -> Sh [a]
forall a. Sh a -> Sh [a]
unSh Sh a
a Sh [a] -> Sh [b] -> Sh [b]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Sh b -> Sh [b]
forall a. Sh a -> Sh [a]
unSh Sh b
b

instance Monad Sh where
    return :: forall a. a -> Sh a
return  = a -> Sh a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
    Sh a
a >>= :: forall a b. Sh a -> (a -> Sh b) -> Sh b
>>= a -> Sh b
f = Sh [b] -> Sh b
forall a. Sh [a] -> Sh a
Sh (Sh [b] -> Sh b) -> Sh [b] -> Sh b
forall a b. (a -> b) -> a -> b
$ ([[b]] -> [b]) -> Sh [[b]] -> Sh [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [[b]] -> [b]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (Sh [[b]] -> Sh [b]) -> Sh [[b]] -> Sh [b]
forall a b. (a -> b) -> a -> b
$ (a -> Sh [b]) -> [a] -> Sh [[b]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Sh b -> Sh [b]
forall a. Sh a -> Sh [a]
unSh (Sh b -> Sh [b]) -> (a -> Sh b) -> a -> Sh [b]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Sh b
f) ([a] -> Sh [[b]]) -> Sh [a] -> Sh [[b]]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Sh a -> Sh [a]
forall a. Sh a -> Sh [a]
unSh Sh a
a
    >> :: forall a b. Sh a -> Sh b -> Sh b
(>>)    = Sh a -> Sh b -> Sh b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
(*>)

instance Alternative Sh where
    empty :: forall a. Sh a
empty = Sh a
forall (m :: * -> *) a. MonadPlus m => m a
mzero
    <|> :: forall a. Sh a -> Sh a -> Sh a
(<|>) = Sh a -> Sh a -> Sh a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
mplus

instance MonadPlus Sh where
    mzero :: forall a. Sh a
mzero = Sh [a] -> Sh a
forall a. Sh [a] -> Sh a
Sh (Sh [a] -> Sh a) -> Sh [a] -> Sh a
forall a b. (a -> b) -> a -> b
$ [a] -> Sh [a]
forall (m :: * -> *) a. Monad m => a -> m a
return []
    mplus :: forall a. Sh a -> Sh a -> Sh a
mplus Sh a
a Sh a
b = Sh [a] -> Sh a
forall a. Sh [a] -> Sh a
Sh (Sh [a] -> Sh a) -> Sh [a] -> Sh a
forall a b. (a -> b) -> a -> b
$ ([a] -> [a] -> [a]) -> Sh [a] -> Sh [a] -> Sh [a]
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
(++) (Sh a -> Sh [a]
forall a. Sh a -> Sh [a]
unSh Sh a
a) (Sh a -> Sh [a]
forall a. Sh a -> Sh [a]
unSh Sh a
b)

instance MonadIO Sh where
    liftIO :: forall a. IO a -> Sh a
liftIO = (IO a -> Sh a) -> IO a -> Sh a
forall a b. (a -> Sh b) -> a -> Sh b
sh1 IO a -> Sh a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO

-------------------------------------------------------
-- converters

sh0 :: S.Sh a -> Sh a
sh0 :: forall a. Sh a -> Sh a
sh0 = Sh [a] -> Sh a
forall a. Sh [a] -> Sh a
Sh (Sh [a] -> Sh a) -> (Sh a -> Sh [a]) -> Sh a -> Sh a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> [a]) -> Sh a -> Sh [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> [a]
forall (m :: * -> *) a. Monad m => a -> m a
return

sh1 :: (a -> S.Sh b) -> (a -> Sh b)
sh1 :: forall a b. (a -> Sh b) -> a -> Sh b
sh1 a -> Sh b
f = \a
a -> Sh b -> Sh b
forall a. Sh a -> Sh a
sh0 (a -> Sh b
f a
a)

sh2 :: (a1 -> a2 -> S.Sh b) -> (a1 -> a2 -> Sh b)
sh2 :: forall a1 a2 b. (a1 -> a2 -> Sh b) -> a1 -> a2 -> Sh b
sh2 a1 -> a2 -> Sh b
f = \a1
a a2
b -> Sh b -> Sh b
forall a. Sh a -> Sh a
sh0 (a1 -> a2 -> Sh b
f a1
a a2
b)

sh3 :: (a1 -> a2 -> a3 -> S.Sh b) -> (a1 -> a2 -> a3 -> Sh b)
sh3 :: forall a1 a2 a3 b.
(a1 -> a2 -> a3 -> Sh b) -> a1 -> a2 -> a3 -> Sh b
sh3 a1 -> a2 -> a3 -> Sh b
f = \a1
a a2
b a3
c -> Sh b -> Sh b
forall a. Sh a -> Sh a
sh0 (a1 -> a2 -> a3 -> Sh b
f a1
a a2
b a3
c)

sh4 :: (a1 -> a2 -> a3 -> a4 -> S.Sh b) -> (a1 -> a2 -> a3 -> a4 -> Sh b)
sh4 :: forall a1 a2 a3 a4 b.
(a1 -> a2 -> a3 -> a4 -> Sh b) -> a1 -> a2 -> a3 -> a4 -> Sh b
sh4 a1 -> a2 -> a3 -> a4 -> Sh b
f = \a1
a a2
b a3
c a4
d -> Sh b -> Sh b
forall a. Sh a -> Sh a
sh0 (a1 -> a2 -> a3 -> a4 -> Sh b
f a1
a a2
b a3
c a4
d)

sh0s :: S.Sh [a] -> Sh a
sh0s :: forall a. Sh [a] -> Sh a
sh0s = Sh [a] -> Sh a
forall a. Sh [a] -> Sh a
Sh

sh1s :: (a -> S.Sh [b]) -> (a -> Sh b)
sh1s :: forall a b. (a -> Sh [b]) -> a -> Sh b
sh1s a -> Sh [b]
f = \a
a -> Sh [b] -> Sh b
forall a. Sh [a] -> Sh a
sh0s (a -> Sh [b]
f a
a)

{-  Just in case ...
sh2s :: (a1 -> a2 -> S.Sh [b]) -> (a1 -> a2 -> Sh b)
sh2s f = \a b -> sh0s (f a b)

sh3s :: (a1 -> a2 -> a3 -> S.Sh [b]) -> (a1 -> a2 -> a3 -> Sh b)
sh3s f = \a b c -> sh0s (f a b c)
-}

lift1 :: (S.Sh a -> S.Sh b) -> (Sh a -> Sh b)
lift1 :: forall a b. (Sh a -> Sh b) -> Sh a -> Sh b
lift1 Sh a -> Sh b
f = Sh [b] -> Sh b
forall a. Sh [a] -> Sh a
Sh (Sh [b] -> Sh b) -> (Sh a -> Sh [b]) -> Sh a -> Sh b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a -> Sh b) -> [a] -> Sh [b]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Sh a -> Sh b
f (Sh a -> Sh b) -> (a -> Sh a) -> a -> Sh b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Sh a
forall (m :: * -> *) a. Monad m => a -> m a
return) ([a] -> Sh [b]) -> Sh [a] -> Sh [b]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ) (Sh [a] -> Sh [b]) -> (Sh a -> Sh [a]) -> Sh a -> Sh [b]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sh a -> Sh [a]
forall a. Sh a -> Sh [a]
unSh

lift2 :: (S.Sh a -> S.Sh b -> S.Sh c) -> (Sh a -> Sh b -> Sh c)
lift2 :: forall a b c. (Sh a -> Sh b -> Sh c) -> Sh a -> Sh b -> Sh c
lift2 Sh a -> Sh b -> Sh c
f Sh a
a Sh b
b = Sh [c] -> Sh c
forall a. Sh [a] -> Sh a
Sh (Sh [c] -> Sh c) -> Sh [c] -> Sh c
forall a b. (a -> b) -> a -> b
$ Sh (Sh [c]) -> Sh [c]
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (Sh (Sh [c]) -> Sh [c]) -> Sh (Sh [c]) -> Sh [c]
forall a b. (a -> b) -> a -> b
$ ([a] -> [b] -> Sh [c]) -> Sh [a] -> Sh [b] -> Sh (Sh [c])
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 ((a -> b -> Sh c) -> [a] -> [b] -> Sh [c]
forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
mapM2 a -> b -> Sh c
f') (Sh a -> Sh [a]
forall a. Sh a -> Sh [a]
unSh Sh a
a) (Sh b -> Sh [b]
forall a. Sh a -> Sh [a]
unSh Sh b
b)
    where f' :: a -> b -> Sh c
f' = \a
x b
y -> Sh a -> Sh b -> Sh c
f (a -> Sh a
forall (m :: * -> *) a. Monad m => a -> m a
return a
x) (b -> Sh b
forall (m :: * -> *) a. Monad m => a -> m a
return b
y)

mapM2 :: Monad m => (a -> b -> m c)-> [a] -> [b] -> m [c]
mapM2 :: forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
mapM2 a -> b -> m c
f [a]
as [b]
bs = [m c] -> m [c]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence ([m c] -> m [c]) -> [m c] -> m [c]
forall a b. (a -> b) -> a -> b
$ (a -> b -> m c) -> [a] -> [b] -> [m c]
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> b -> m c
f [a]
as [b]
bs

-----------------------------------------------------------

-- | Unpack list of results.
unroll :: Sh a -> Sh [a]
unroll :: forall a. Sh a -> Sh [a]
unroll = Sh [[a]] -> Sh [a]
forall a. Sh [a] -> Sh a
Sh (Sh [[a]] -> Sh [a]) -> (Sh a -> Sh [[a]]) -> Sh a -> Sh [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([a] -> [[a]]) -> Sh [a] -> Sh [[a]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [a] -> [[a]]
forall (m :: * -> *) a. Monad m => a -> m a
return (Sh [a] -> Sh [[a]]) -> (Sh a -> Sh [a]) -> Sh a -> Sh [[a]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sh a -> Sh [a]
forall a. Sh a -> Sh [a]
unSh

-- | Pack list of results. It performs @concat@ inside 'Sh'.
roll :: Sh [a] -> Sh a
roll :: forall a. Sh [a] -> Sh a
roll = Sh [a] -> Sh a
forall a. Sh [a] -> Sh a
Sh (Sh [a] -> Sh a) -> (Sh [a] -> Sh [a]) -> Sh [a] -> Sh a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([[a]] -> [a]) -> Sh [[a]] -> Sh [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [[a]] -> [a]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (Sh [[a]] -> Sh [a]) -> (Sh [a] -> Sh [[a]]) -> Sh [a] -> Sh [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sh [a] -> Sh [[a]]
forall a. Sh a -> Sh [a]
unSh

-- | Transform result as list. It can be useful for filtering.
liftSh :: ([a] -> [b]) -> Sh a -> Sh b
liftSh :: forall a b. ([a] -> [b]) -> Sh a -> Sh b
liftSh [a] -> [b]
f = Sh [b] -> Sh b
forall a. Sh [a] -> Sh a
Sh (Sh [b] -> Sh b) -> (Sh a -> Sh [b]) -> Sh a -> Sh b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([a] -> [b]) -> Sh [a] -> Sh [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [a] -> [b]
f (Sh [a] -> Sh [b]) -> (Sh a -> Sh [a]) -> Sh a -> Sh [b]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sh a -> Sh [a]
forall a. Sh a -> Sh [a]
unSh

------------------------------------------------------------------
-- Entering Sh

-- | see 'S.shelly'
shelly :: MonadIO m => Sh a -> m [a]
shelly :: forall (m :: * -> *) a. MonadIO m => Sh a -> m [a]
shelly = Sh [a] -> m [a]
forall (m :: * -> *) a. MonadIO m => Sh a -> m a
S.shelly (Sh [a] -> m [a]) -> (Sh a -> Sh [a]) -> Sh a -> m [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sh a -> Sh [a]
forall a. Sh a -> Sh [a]
unSh

-- | Performs 'shelly' and then an empty action @return ()@.
shs :: MonadIO m => Sh () -> m ()
shs :: forall (m :: * -> *). MonadIO m => Sh () -> m ()
shs Sh ()
x = Sh () -> m [()]
forall (m :: * -> *) a. MonadIO m => Sh a -> m [a]
shelly Sh ()
x m [()] -> m () -> m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

-- | see 'S.shellyFailDir'
shellyFailDir :: MonadIO m => Sh a -> m [a]
shellyFailDir :: forall (m :: * -> *) a. MonadIO m => Sh a -> m [a]
shellyFailDir = Sh [a] -> m [a]
forall (m :: * -> *) a. MonadIO m => Sh a -> m a
S.shellyFailDir (Sh [a] -> m [a]) -> (Sh a -> Sh [a]) -> Sh a -> m [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sh a -> Sh [a]
forall a. Sh a -> Sh [a]
unSh

-- | Performs 'shellyFailDir' and then an empty action @return ()@.
shsFailDir :: MonadIO m => Sh () -> m ()
shsFailDir :: forall (m :: * -> *). MonadIO m => Sh () -> m ()
shsFailDir Sh ()
x = Sh () -> m [()]
forall (m :: * -> *) a. MonadIO m => Sh a -> m [a]
shellyFailDir Sh ()
x m [()] -> m () -> m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

-- | see 'S.sub'
sub :: Sh a -> Sh a
sub :: forall a. Sh a -> Sh a
sub = (Sh a -> Sh a) -> Sh a -> Sh a
forall a b. (Sh a -> Sh b) -> Sh a -> Sh b
lift1 Sh a -> Sh a
forall a. Sh a -> Sh a
S.sub

-- See 'S.siliently'
silently :: Sh a -> Sh a
silently :: forall a. Sh a -> Sh a
silently = (Sh a -> Sh a) -> Sh a -> Sh a
forall a b. (Sh a -> Sh b) -> Sh a -> Sh b
lift1 Sh a -> Sh a
forall a. Sh a -> Sh a
S.silently

-- See 'S.verbosely
verbosely :: Sh a -> Sh a
verbosely :: forall a. Sh a -> Sh a
verbosely = (Sh a -> Sh a) -> Sh a -> Sh a
forall a b. (Sh a -> Sh b) -> Sh a -> Sh b
lift1 Sh a -> Sh a
forall a. Sh a -> Sh a
S.verbosely

-- | see 'S.escaping'
escaping :: Bool -> Sh a -> Sh a
escaping :: forall a. Bool -> Sh a -> Sh a
escaping Bool
b = (Sh a -> Sh a) -> Sh a -> Sh a
forall a b. (Sh a -> Sh b) -> Sh a -> Sh b
lift1 (Bool -> Sh a -> Sh a
forall a. Bool -> Sh a -> Sh a
S.escaping Bool
b)

-- | see 'S.log_stdout_with'
log_stdout_with :: (Text -> IO ()) -> Sh a -> Sh a
log_stdout_with :: forall a. (Text -> IO ()) -> Sh a -> Sh a
log_stdout_with Text -> IO ()
logger = (Sh a -> Sh a) -> Sh a -> Sh a
forall a b. (Sh a -> Sh b) -> Sh a -> Sh b
lift1 ((Text -> IO ()) -> Sh a -> Sh a
forall a. (Text -> IO ()) -> Sh a -> Sh a
S.log_stdout_with Text -> IO ()
logger)

-- | see 'S.log_stderr_with'
log_stderr_with :: (Text -> IO ()) -> Sh a -> Sh a
log_stderr_with :: forall a. (Text -> IO ()) -> Sh a -> Sh a
log_stderr_with Text -> IO ()
logger = (Sh a -> Sh a) -> Sh a -> Sh a
forall a b. (Sh a -> Sh b) -> Sh a -> Sh b
lift1 ((Text -> IO ()) -> Sh a -> Sh a
forall a. (Text -> IO ()) -> Sh a -> Sh a
S.log_stdout_with Text -> IO ()
logger)

-- | see 'S.print_stdout'
print_stdout :: Bool -> Sh a -> Sh a
print_stdout :: forall a. Bool -> Sh a -> Sh a
print_stdout Bool
b = (Sh a -> Sh a) -> Sh a -> Sh a
forall a b. (Sh a -> Sh b) -> Sh a -> Sh b
lift1 (Bool -> Sh a -> Sh a
forall a. Bool -> Sh a -> Sh a
S.print_stdout Bool
b)

-- | see 'S.print_commands
print_commands :: Bool -> Sh a -> Sh a
print_commands :: forall a. Bool -> Sh a -> Sh a
print_commands Bool
b = (Sh a -> Sh a) -> Sh a -> Sh a
forall a b. (Sh a -> Sh b) -> Sh a -> Sh b
lift1 (Bool -> Sh a -> Sh a
forall a. Bool -> Sh a -> Sh a
S.print_commands Bool
b)

-- | see 'S.tracing'
tracing :: Bool -> Sh a -> Sh a
tracing :: forall a. Bool -> Sh a -> Sh a
tracing Bool
b = (Sh a -> Sh a) -> Sh a -> Sh a
forall a b. (Sh a -> Sh b) -> Sh a -> Sh b
lift1 (Bool -> Sh a -> Sh a
forall a. Bool -> Sh a -> Sh a
S.tracing Bool
b)

-- | see 'S.errExit'
errExit :: Bool -> Sh a -> Sh a
errExit :: forall a. Bool -> Sh a -> Sh a
errExit Bool
b = (Sh a -> Sh a) -> Sh a -> Sh a
forall a b. (Sh a -> Sh b) -> Sh a -> Sh b
lift1 (Bool -> Sh a -> Sh a
forall a. Bool -> Sh a -> Sh a
S.errExit Bool
b)

-- | see 'S.followSymlink'
followSymlink :: Bool -> Sh a -> Sh a
followSymlink :: forall a. Bool -> Sh a -> Sh a
followSymlink Bool
b = (Sh a -> Sh a) -> Sh a -> Sh a
forall a b. (Sh a -> Sh b) -> Sh a -> Sh b
lift1 (Bool -> Sh a -> Sh a
forall a. Bool -> Sh a -> Sh a
S.followSymlink Bool
b)

-- | see 'S.run'
run :: FilePath -> [Text] -> Sh Text
run :: FilePath -> [Text] -> Sh Text
run FilePath
a [Text]
b = Sh Text -> Sh Text
forall a. Sh a -> Sh a
sh0 (Sh Text -> Sh Text) -> Sh Text -> Sh Text
forall a b. (a -> b) -> a -> b
$ FilePath -> [Text] -> Sh Text
S.run FilePath
a [Text]
b

-- | see 'S.run_'
run_ :: FilePath -> [Text] -> Sh ()
run_ :: FilePath -> [Text] -> Sh ()
run_ FilePath
a [Text]
b = Sh () -> Sh ()
forall a. Sh a -> Sh a
sh0 (Sh () -> Sh ()) -> Sh () -> Sh ()
forall a b. (a -> b) -> a -> b
$ FilePath -> [Text] -> Sh ()
S.run_ FilePath
a [Text]
b

-- | see 'S.runFoldLines'
runFoldLines :: a -> FoldCallback a -> FilePath -> [Text] -> Sh a
runFoldLines :: forall a. a -> FoldCallback a -> FilePath -> [Text] -> Sh a
runFoldLines a
a FoldCallback a
cb FilePath
fp [Text]
ts = Sh a -> Sh a
forall a. Sh a -> Sh a
sh0 (Sh a -> Sh a) -> Sh a -> Sh a
forall a b. (a -> b) -> a -> b
$ a -> FoldCallback a -> FilePath -> [Text] -> Sh a
forall a. a -> FoldCallback a -> FilePath -> [Text] -> Sh a
S.runFoldLines a
a FoldCallback a
cb FilePath
fp [Text]
ts

-- | see 'S.-|-'
(-|-) :: Sh Text -> Sh b -> Sh b
-|- :: forall b. Sh Text -> Sh b -> Sh b
(-|-) = (Sh Text -> Sh b -> Sh b) -> Sh Text -> Sh b -> Sh b
forall a b c. (Sh a -> Sh b -> Sh c) -> Sh a -> Sh b -> Sh c
lift2 Sh Text -> Sh b -> Sh b
forall b. Sh Text -> Sh b -> Sh b
(S.-|-)

-- | see 'S.lastStderr'
lastStderr :: Sh Text
lastStderr :: Sh Text
lastStderr = Sh Text -> Sh Text
forall a. Sh a -> Sh a
sh0 Sh Text
S.lastStderr

-- | see 'S.setStdin'
setStdin :: Text -> Sh ()
setStdin :: Text -> Sh ()
setStdin = (Text -> Sh ()) -> Text -> Sh ()
forall a b. (a -> Sh b) -> a -> Sh b
sh1 Text -> Sh ()
S.setStdin

-- | see 'S.lastExitCode'
lastExitCode :: Sh Int
lastExitCode :: Sh Int
lastExitCode = Sh Int -> Sh Int
forall a. Sh a -> Sh a
sh0 Sh Int
S.lastExitCode

-- | see 'S.command'
command :: FilePath -> [Text] -> [Text] -> Sh Text
command :: FilePath -> [Text] -> [Text] -> Sh Text
command = (FilePath -> [Text] -> [Text] -> Sh Text)
-> FilePath -> [Text] -> [Text] -> Sh Text
forall a1 a2 a3 b.
(a1 -> a2 -> a3 -> Sh b) -> a1 -> a2 -> a3 -> Sh b
sh3 FilePath -> [Text] -> [Text] -> Sh Text
S.command

-- | see 'S.command_'
command_ :: FilePath -> [Text] -> [Text] -> Sh ()
command_ :: FilePath -> [Text] -> [Text] -> Sh ()
command_ = (FilePath -> [Text] -> [Text] -> Sh ())
-> FilePath -> [Text] -> [Text] -> Sh ()
forall a1 a2 a3 b.
(a1 -> a2 -> a3 -> Sh b) -> a1 -> a2 -> a3 -> Sh b
sh3 FilePath -> [Text] -> [Text] -> Sh ()
S.command_


-- | see 'S.command1'
command1 :: FilePath -> [Text] -> Text -> [Text] -> Sh Text
command1 :: FilePath -> [Text] -> Text -> [Text] -> Sh Text
command1 = (FilePath -> [Text] -> Text -> [Text] -> Sh Text)
-> FilePath -> [Text] -> Text -> [Text] -> Sh Text
forall a1 a2 a3 a4 b.
(a1 -> a2 -> a3 -> a4 -> Sh b) -> a1 -> a2 -> a3 -> a4 -> Sh b
sh4 FilePath -> [Text] -> Text -> [Text] -> Sh Text
S.command1

-- | see 'S.command1_'
command1_ :: FilePath -> [Text] -> Text -> [Text] -> Sh ()
command1_ :: FilePath -> [Text] -> Text -> [Text] -> Sh ()
command1_ = (FilePath -> [Text] -> Text -> [Text] -> Sh ())
-> FilePath -> [Text] -> Text -> [Text] -> Sh ()
forall a1 a2 a3 a4 b.
(a1 -> a2 -> a3 -> a4 -> Sh b) -> a1 -> a2 -> a3 -> a4 -> Sh b
sh4 FilePath -> [Text] -> Text -> [Text] -> Sh ()
S.command1_

-- | see 'S.sshPairs'
sshPairs :: Text -> [(FilePath, [Text])] -> Sh Text
sshPairs :: Text -> [(FilePath, [Text])] -> Sh Text
sshPairs = (Text -> [(FilePath, [Text])] -> Sh Text)
-> Text -> [(FilePath, [Text])] -> Sh Text
forall a1 a2 b. (a1 -> a2 -> Sh b) -> a1 -> a2 -> Sh b
sh2 Text -> [(FilePath, [Text])] -> Sh Text
S.sshPairs

-- | see 'S.sshPairs_'
sshPairs_ :: Text -> [(FilePath, [Text])] -> Sh ()
sshPairs_ :: Text -> [(FilePath, [Text])] -> Sh ()
sshPairs_ = (Text -> [(FilePath, [Text])] -> Sh ())
-> Text -> [(FilePath, [Text])] -> Sh ()
forall a1 a2 b. (a1 -> a2 -> Sh b) -> a1 -> a2 -> Sh b
sh2 Text -> [(FilePath, [Text])] -> Sh ()
S.sshPairs_

-- | see 'S.setenv'
setenv :: Text -> Text -> Sh ()
setenv :: Text -> Text -> Sh ()
setenv = (Text -> Text -> Sh ()) -> Text -> Text -> Sh ()
forall a1 a2 b. (a1 -> a2 -> Sh b) -> a1 -> a2 -> Sh b
sh2 Text -> Text -> Sh ()
S.setenv

-- | see 'S.get_env'
get_env :: Text -> Sh (Maybe Text)
get_env :: Text -> Sh (Maybe Text)
get_env = (Text -> Sh (Maybe Text)) -> Text -> Sh (Maybe Text)
forall a b. (a -> Sh b) -> a -> Sh b
sh1 Text -> Sh (Maybe Text)
S.get_env

-- | see 'S.get_env_text'
get_env_text :: Text -> Sh Text
get_env_text :: Text -> Sh Text
get_env_text = (Text -> Sh Text) -> Text -> Sh Text
forall a b. (a -> Sh b) -> a -> Sh b
sh1 Text -> Sh Text
S.get_env_text

-- | see 'S.get_env_def'
get_env_def :: Text -> Text -> Sh Text
get_env_def :: Text -> Text -> Sh Text
get_env_def Text
a Text
d = Sh Text -> Sh Text
forall a. Sh a -> Sh a
sh0 (Sh Text -> Sh Text) -> Sh Text -> Sh Text
forall a b. (a -> b) -> a -> b
$ (Maybe Text -> Text) -> Sh (Maybe Text) -> Sh Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe Text
d) (Sh (Maybe Text) -> Sh Text) -> Sh (Maybe Text) -> Sh Text
forall a b. (a -> b) -> a -> b
$ Text -> Sh (Maybe Text)
S.get_env Text
a
{-# DEPRECATED get_env_def "use fromMaybe DEFAULT get_env" #-}

-- | see 'S.appendToPath'
appendToPath :: FilePath -> Sh ()
appendToPath :: FilePath -> Sh ()
appendToPath = (FilePath -> Sh ()) -> FilePath -> Sh ()
forall a b. (a -> Sh b) -> a -> Sh b
sh1 FilePath -> Sh ()
S.appendToPath

-- | see 'S.prependToPath'
prependToPath :: FilePath -> Sh ()
prependToPath :: FilePath -> Sh ()
prependToPath = (FilePath -> Sh ()) -> FilePath -> Sh ()
forall a b. (a -> Sh b) -> a -> Sh b
sh1 FilePath -> Sh ()
S.prependToPath

-- | see 'S.cd'
cd :: FilePath -> Sh ()
cd :: FilePath -> Sh ()
cd = (FilePath -> Sh ()) -> FilePath -> Sh ()
forall a b. (a -> Sh b) -> a -> Sh b
sh1 FilePath -> Sh ()
S.cd

-- | see 'S.chdir'
chdir :: FilePath -> Sh a -> Sh a
chdir :: forall a. FilePath -> Sh a -> Sh a
chdir FilePath
p = (Sh a -> Sh a) -> Sh a -> Sh a
forall a b. (Sh a -> Sh b) -> Sh a -> Sh b
lift1 (FilePath -> Sh a -> Sh a
forall a. FilePath -> Sh a -> Sh a
S.chdir FilePath
p)

-- | see 'S.pwd'
pwd :: Sh FilePath
pwd :: Sh FilePath
pwd = Sh FilePath -> Sh FilePath
forall a. Sh a -> Sh a
sh0 Sh FilePath
S.pwd

-----------------------------------------------------------------
-- Printing

-- | Echo text to standard (error, when using _err variants) output. The _n
-- variants do not print a final newline.
echo, echo_n_err, echo_err, echo_n :: Text -> Sh ()

echo :: Text -> Sh ()
echo        = (Text -> Sh ()) -> Text -> Sh ()
forall a b. (a -> Sh b) -> a -> Sh b
sh1 Text -> Sh ()
S.echo
echo_n_err :: Text -> Sh ()
echo_n_err  = (Text -> Sh ()) -> Text -> Sh ()
forall a b. (a -> Sh b) -> a -> Sh b
sh1 Text -> Sh ()
S.echo_n_err
echo_err :: Text -> Sh ()
echo_err    = (Text -> Sh ()) -> Text -> Sh ()
forall a b. (a -> Sh b) -> a -> Sh b
sh1 Text -> Sh ()
S.echo_err
echo_n :: Text -> Sh ()
echo_n      = (Text -> Sh ()) -> Text -> Sh ()
forall a b. (a -> Sh b) -> a -> Sh b
sh1 Text -> Sh ()
S.echo_n

-- | see 'S.inspect'
inspect :: Show s => s -> Sh ()
inspect :: forall s. Show s => s -> Sh ()
inspect = (s -> Sh ()) -> s -> Sh ()
forall a b. (a -> Sh b) -> a -> Sh b
sh1 s -> Sh ()
forall s. Show s => s -> Sh ()
S.inspect

-- | see 'S.inspect_err'
inspect_err :: Show s => s -> Sh ()
inspect_err :: forall s. Show s => s -> Sh ()
inspect_err = (s -> Sh ()) -> s -> Sh ()
forall a b. (a -> Sh b) -> a -> Sh b
sh1 s -> Sh ()
forall s. Show s => s -> Sh ()
S.inspect_err

-- | see 'S.tag'
tag :: Sh a -> Text -> Sh a
tag :: forall a. Sh a -> Text -> Sh a
tag Sh a
a Text
t = (Sh a -> Sh a) -> Sh a -> Sh a
forall a b. (Sh a -> Sh b) -> Sh a -> Sh b
lift1 ((Sh a -> Text -> Sh a) -> Text -> Sh a -> Sh a
forall a b c. (a -> b -> c) -> b -> a -> c
flip Sh a -> Text -> Sh a
forall a. Sh a -> Text -> Sh a
S.tag Text
t) Sh a
a

-- | see 'S.trace'
trace :: Text -> Sh ()
trace :: Text -> Sh ()
trace = (Text -> Sh ()) -> Text -> Sh ()
forall a b. (a -> Sh b) -> a -> Sh b
sh1 Text -> Sh ()
S.trace

-- | see 'S.show_command'
show_command :: FilePath -> [Text] -> Text
show_command :: FilePath -> [Text] -> Text
show_command = FilePath -> [Text] -> Text
S.show_command

------------------------------------------------------------------
-- Querying filesystem

-- | see 'S.ls'
ls :: FilePath -> Sh FilePath
ls :: FilePath -> Sh FilePath
ls = (FilePath -> Sh [FilePath]) -> FilePath -> Sh FilePath
forall a b. (a -> Sh [b]) -> a -> Sh b
sh1s FilePath -> Sh [FilePath]
S.ls

-- | see 'S.lsT'
lsT :: FilePath -> Sh Text
lsT :: FilePath -> Sh Text
lsT = (FilePath -> Sh [Text]) -> FilePath -> Sh Text
forall a b. (a -> Sh [b]) -> a -> Sh b
sh1s FilePath -> Sh [Text]
S.lsT

-- | see 'S.test_e'
test_e :: FilePath -> Sh Bool
test_e :: FilePath -> Sh Bool
test_e = (FilePath -> Sh Bool) -> FilePath -> Sh Bool
forall a b. (a -> Sh b) -> a -> Sh b
sh1 FilePath -> Sh Bool
S.test_e

-- | see 'S.test_f'
test_f :: FilePath -> Sh Bool
test_f :: FilePath -> Sh Bool
test_f = (FilePath -> Sh Bool) -> FilePath -> Sh Bool
forall a b. (a -> Sh b) -> a -> Sh b
sh1 FilePath -> Sh Bool
S.test_f

-- | see 'S.test_d'
test_d :: FilePath -> Sh Bool
test_d :: FilePath -> Sh Bool
test_d = (FilePath -> Sh Bool) -> FilePath -> Sh Bool
forall a b. (a -> Sh b) -> a -> Sh b
sh1 FilePath -> Sh Bool
S.test_d

-- | see 'S.test_s'
test_s :: FilePath -> Sh Bool
test_s :: FilePath -> Sh Bool
test_s = (FilePath -> Sh Bool) -> FilePath -> Sh Bool
forall a b. (a -> Sh b) -> a -> Sh b
sh1 FilePath -> Sh Bool
S.test_s

-- | see 'S.which
which :: FilePath -> Sh (Maybe FilePath)
which :: FilePath -> Sh (Maybe FilePath)
which = (FilePath -> Sh (Maybe FilePath))
-> FilePath -> Sh (Maybe FilePath)
forall a b. (a -> Sh b) -> a -> Sh b
sh1 FilePath -> Sh (Maybe FilePath)
S.which

---------------------------------------------------------------------
-- Filename helpers

-- | see 'S.absPath'
absPath :: FilePath -> Sh FilePath
absPath :: FilePath -> Sh FilePath
absPath = (FilePath -> Sh FilePath) -> FilePath -> Sh FilePath
forall a b. (a -> Sh b) -> a -> Sh b
sh1 FilePath -> Sh FilePath
S.absPath

-- | see 'S.canonic'
canonic :: FilePath -> Sh FilePath
canonic :: FilePath -> Sh FilePath
canonic = (FilePath -> Sh FilePath) -> FilePath -> Sh FilePath
forall a b. (a -> Sh b) -> a -> Sh b
sh1 FilePath -> Sh FilePath
S.canonic

-- | see 'S.canonicalize'
canonicalize :: FilePath -> Sh FilePath
canonicalize :: FilePath -> Sh FilePath
canonicalize = (FilePath -> Sh FilePath) -> FilePath -> Sh FilePath
forall a b. (a -> Sh b) -> a -> Sh b
sh1 FilePath -> Sh FilePath
S.canonicalize

-- | see 'S.relPath'
relPath :: FilePath -> Sh FilePath
relPath :: FilePath -> Sh FilePath
relPath = (FilePath -> Sh FilePath) -> FilePath -> Sh FilePath
forall a b. (a -> Sh b) -> a -> Sh b
sh1 FilePath -> Sh FilePath
S.relPath

-- | see 'S.relativeTo'
relativeTo :: FilePath -- ^ anchor path, the prefix
           -> FilePath -- ^ make this relative to anchor path
           -> Sh FilePath
relativeTo :: FilePath -> FilePath -> Sh FilePath
relativeTo = (FilePath -> FilePath -> Sh FilePath)
-> FilePath -> FilePath -> Sh FilePath
forall a1 a2 b. (a1 -> a2 -> Sh b) -> a1 -> a2 -> Sh b
sh2 FilePath -> FilePath -> Sh FilePath
S.relativeTo

-------------------------------------------------------------
-- Manipulating filesystem

-- | see 'S.mv'
mv :: FilePath -> FilePath -> Sh ()
mv :: FilePath -> FilePath -> Sh ()
mv = (FilePath -> FilePath -> Sh ()) -> FilePath -> FilePath -> Sh ()
forall a1 a2 b. (a1 -> a2 -> Sh b) -> a1 -> a2 -> Sh b
sh2 FilePath -> FilePath -> Sh ()
S.mv

-- | see 'S.rm'
rm :: FilePath -> Sh ()
rm :: FilePath -> Sh ()
rm = (FilePath -> Sh ()) -> FilePath -> Sh ()
forall a b. (a -> Sh b) -> a -> Sh b
sh1 FilePath -> Sh ()
S.rm

-- | see 'S.rm_f'
rm_f :: FilePath -> Sh ()
rm_f :: FilePath -> Sh ()
rm_f = (FilePath -> Sh ()) -> FilePath -> Sh ()
forall a b. (a -> Sh b) -> a -> Sh b
sh1 FilePath -> Sh ()
S.rm_f

-- | see 'S.rm_rf'
rm_rf :: FilePath -> Sh ()
rm_rf :: FilePath -> Sh ()
rm_rf = (FilePath -> Sh ()) -> FilePath -> Sh ()
forall a b. (a -> Sh b) -> a -> Sh b
sh1 FilePath -> Sh ()
S.rm_rf

-- | see 'S.cp'
cp :: FilePath -> FilePath -> Sh ()
cp :: FilePath -> FilePath -> Sh ()
cp = (FilePath -> FilePath -> Sh ()) -> FilePath -> FilePath -> Sh ()
forall a1 a2 b. (a1 -> a2 -> Sh b) -> a1 -> a2 -> Sh b
sh2 FilePath -> FilePath -> Sh ()
S.cp

-- | see 'S.cp_r'
cp_r :: FilePath -> FilePath -> Sh ()
cp_r :: FilePath -> FilePath -> Sh ()
cp_r = (FilePath -> FilePath -> Sh ()) -> FilePath -> FilePath -> Sh ()
forall a1 a2 b. (a1 -> a2 -> Sh b) -> a1 -> a2 -> Sh b
sh2 FilePath -> FilePath -> Sh ()
S.cp_r

-- | see 'S.mkdir'
mkdir :: FilePath -> Sh ()
mkdir :: FilePath -> Sh ()
mkdir = (FilePath -> Sh ()) -> FilePath -> Sh ()
forall a b. (a -> Sh b) -> a -> Sh b
sh1 FilePath -> Sh ()
S.mkdir

-- | see 'S.mkdir_p'
mkdir_p :: FilePath -> Sh ()
mkdir_p :: FilePath -> Sh ()
mkdir_p = (FilePath -> Sh ()) -> FilePath -> Sh ()
forall a b. (a -> Sh b) -> a -> Sh b
sh1 FilePath -> Sh ()
S.mkdir_p

-- | see 'S.mkdirTree'
mkdirTree :: Tree FilePath -> Sh ()
mkdirTree :: Tree FilePath -> Sh ()
mkdirTree = (Tree FilePath -> Sh ()) -> Tree FilePath -> Sh ()
forall a b. (a -> Sh b) -> a -> Sh b
sh1 Tree FilePath -> Sh ()
S.mkdirTree

-- | see 'S.readFile'
readfile :: FilePath -> Sh Text
readfile :: FilePath -> Sh Text
readfile = (FilePath -> Sh Text) -> FilePath -> Sh Text
forall a b. (a -> Sh b) -> a -> Sh b
sh1 FilePath -> Sh Text
S.readfile

-- | see 'S.readBinary'
readBinary :: FilePath -> Sh ByteString
readBinary :: FilePath -> Sh ByteString
readBinary = (FilePath -> Sh ByteString) -> FilePath -> Sh ByteString
forall a b. (a -> Sh b) -> a -> Sh b
sh1 FilePath -> Sh ByteString
S.readBinary

-- | see 'S.writeFile'
writefile :: FilePath -> Text -> Sh ()
writefile :: FilePath -> Text -> Sh ()
writefile = (FilePath -> Text -> Sh ()) -> FilePath -> Text -> Sh ()
forall a1 a2 b. (a1 -> a2 -> Sh b) -> a1 -> a2 -> Sh b
sh2 FilePath -> Text -> Sh ()
S.writefile

-- | see 'S.touchFile'
touchfile :: FilePath -> Sh ()
touchfile :: FilePath -> Sh ()
touchfile = (FilePath -> Sh ()) -> FilePath -> Sh ()
forall a b. (a -> Sh b) -> a -> Sh b
sh1 FilePath -> Sh ()
S.touchfile

-- | see 'S.appendFile'
appendfile :: FilePath -> Text -> Sh ()
appendfile :: FilePath -> Text -> Sh ()
appendfile = (FilePath -> Text -> Sh ()) -> FilePath -> Text -> Sh ()
forall a1 a2 b. (a1 -> a2 -> Sh b) -> a1 -> a2 -> Sh b
sh2 FilePath -> Text -> Sh ()
S.appendfile

-- | see 'S.withTmpDir'
withTmpDir :: (FilePath -> Sh a) -> Sh a
withTmpDir :: forall a. (FilePath -> Sh a) -> Sh a
withTmpDir FilePath -> Sh a
f = Sh [a] -> Sh a
forall a. Sh [a] -> Sh a
Sh (Sh [a] -> Sh a) -> Sh [a] -> Sh a
forall a b. (a -> b) -> a -> b
$ (FilePath -> Sh [a]) -> Sh [a]
forall a. (FilePath -> Sh a) -> Sh a
S.withTmpDir (Sh a -> Sh [a]
forall a. Sh a -> Sh [a]
unSh (Sh a -> Sh [a]) -> (FilePath -> Sh a) -> FilePath -> Sh [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> Sh a
f)

-----------------------------------------------------------------
-- find

-- | see 'S.find'
find :: FilePath -> Sh FilePath
find :: FilePath -> Sh FilePath
find = (FilePath -> Sh [FilePath]) -> FilePath -> Sh FilePath
forall a b. (a -> Sh [b]) -> a -> Sh b
sh1s FilePath -> Sh [FilePath]
S.find

-- | see 'S.findWhen'
findWhen :: (FilePath -> Sh Bool) -> FilePath -> Sh FilePath
findWhen :: (FilePath -> Sh Bool) -> FilePath -> Sh FilePath
findWhen FilePath -> Sh Bool
p FilePath
a = Sh [FilePath] -> Sh FilePath
forall a. Sh [a] -> Sh a
Sh (Sh [FilePath] -> Sh FilePath) -> Sh [FilePath] -> Sh FilePath
forall a b. (a -> b) -> a -> b
$ (FilePath -> Sh Bool) -> FilePath -> Sh [FilePath]
S.findWhen (([Bool] -> Bool) -> Sh [Bool] -> Sh Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and (Sh [Bool] -> Sh Bool)
-> (FilePath -> Sh [Bool]) -> FilePath -> Sh Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sh Bool -> Sh [Bool]
forall a. Sh a -> Sh [a]
unSh (Sh Bool -> Sh [Bool])
-> (FilePath -> Sh Bool) -> FilePath -> Sh [Bool]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> Sh Bool
p) FilePath
a

-- | see 'S.findFold'
findFold :: (a -> FilePath -> Sh a) -> a -> FilePath -> Sh a
findFold :: forall a. (a -> FilePath -> Sh a) -> a -> FilePath -> Sh a
findFold a -> FilePath -> Sh a
cons a
nil FilePath
a = Sh [a] -> Sh a
forall a. Sh [a] -> Sh a
Sh (Sh [a] -> Sh a) -> Sh [a] -> Sh a
forall a b. (a -> b) -> a -> b
$ ([a] -> FilePath -> Sh [a]) -> [a] -> FilePath -> Sh [a]
forall a. (a -> FilePath -> Sh a) -> a -> FilePath -> Sh a
S.findFold [a] -> FilePath -> Sh [a]
cons' [a]
nil' FilePath
a
    where nil' :: [a]
nil'  = a -> [a]
forall (m :: * -> *) a. Monad m => a -> m a
return a
nil
          cons' :: [a] -> FilePath -> Sh [a]
cons' [a]
as FilePath
dir = Sh a -> Sh [a]
forall a. Sh a -> Sh [a]
unSh (Sh a -> Sh [a]) -> Sh a -> Sh [a]
forall a b. (a -> b) -> a -> b
$ Sh [a] -> Sh a
forall a. Sh [a] -> Sh a
roll (Sh [a] -> Sh a) -> Sh [a] -> Sh a
forall a b. (a -> b) -> a -> b
$ (a -> Sh a) -> [a] -> Sh [a]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM ((a -> FilePath -> Sh a) -> FilePath -> a -> Sh a
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> FilePath -> Sh a
cons FilePath
dir) [a]
as

-- | see 'S.findDirFilter'
findDirFilter :: (FilePath -> Sh Bool) -> FilePath -> Sh FilePath
findDirFilter :: (FilePath -> Sh Bool) -> FilePath -> Sh FilePath
findDirFilter FilePath -> Sh Bool
p FilePath
a = Sh [FilePath] -> Sh FilePath
forall a. Sh [a] -> Sh a
Sh (Sh [FilePath] -> Sh FilePath) -> Sh [FilePath] -> Sh FilePath
forall a b. (a -> b) -> a -> b
$ (FilePath -> Sh Bool) -> FilePath -> Sh [FilePath]
S.findDirFilter (([Bool] -> Bool) -> Sh [Bool] -> Sh Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and (Sh [Bool] -> Sh Bool)
-> (FilePath -> Sh [Bool]) -> FilePath -> Sh Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sh Bool -> Sh [Bool]
forall a. Sh a -> Sh [a]
unSh (Sh Bool -> Sh [Bool])
-> (FilePath -> Sh Bool) -> FilePath -> Sh [Bool]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> Sh Bool
p) FilePath
a

-- | see 'S.findDirFilterWhen'
findDirFilterWhen :: (FilePath -> Sh Bool) -- ^ directory filter
                  -> (FilePath -> Sh Bool) -- ^ file filter
                  -> FilePath -- ^ directory
                  -> Sh FilePath
findDirFilterWhen :: (FilePath -> Sh Bool)
-> (FilePath -> Sh Bool) -> FilePath -> Sh FilePath
findDirFilterWhen FilePath -> Sh Bool
dirPred FilePath -> Sh Bool
filePred FilePath
a =
    Sh [FilePath] -> Sh FilePath
forall a. Sh [a] -> Sh a
Sh (Sh [FilePath] -> Sh FilePath) -> Sh [FilePath] -> Sh FilePath
forall a b. (a -> b) -> a -> b
$ (FilePath -> Sh Bool)
-> (FilePath -> Sh Bool) -> FilePath -> Sh [FilePath]
S.findDirFilterWhen
            (([Bool] -> Bool) -> Sh [Bool] -> Sh Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and (Sh [Bool] -> Sh Bool)
-> (FilePath -> Sh [Bool]) -> FilePath -> Sh Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sh Bool -> Sh [Bool]
forall a. Sh a -> Sh [a]
unSh (Sh Bool -> Sh [Bool])
-> (FilePath -> Sh Bool) -> FilePath -> Sh [Bool]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> Sh Bool
dirPred)
            (([Bool] -> Bool) -> Sh [Bool] -> Sh Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and (Sh [Bool] -> Sh Bool)
-> (FilePath -> Sh [Bool]) -> FilePath -> Sh Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sh Bool -> Sh [Bool]
forall a. Sh a -> Sh [a]
unSh (Sh Bool -> Sh [Bool])
-> (FilePath -> Sh Bool) -> FilePath -> Sh [Bool]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> Sh Bool
filePred)
            FilePath
a


-- | see 'S.findFoldDirFilterWhen'
findFoldDirFilter :: (a -> FilePath -> Sh a) -> a -> (FilePath -> Sh Bool) -> FilePath -> Sh a
findFoldDirFilter :: forall a.
(a -> FilePath -> Sh a)
-> a -> (FilePath -> Sh Bool) -> FilePath -> Sh a
findFoldDirFilter a -> FilePath -> Sh a
cons a
nil FilePath -> Sh Bool
p FilePath
a = Sh [a] -> Sh a
forall a. Sh [a] -> Sh a
Sh (Sh [a] -> Sh a) -> Sh [a] -> Sh a
forall a b. (a -> b) -> a -> b
$ ([a] -> FilePath -> Sh [a])
-> [a] -> (FilePath -> Sh Bool) -> FilePath -> Sh [a]
forall a.
(a -> FilePath -> Sh a)
-> a -> (FilePath -> Sh Bool) -> FilePath -> Sh a
S.findFoldDirFilter [a] -> FilePath -> Sh [a]
cons' [a]
nil' FilePath -> Sh Bool
p' FilePath
a
    where p' :: FilePath -> Sh Bool
p'    = ([Bool] -> Bool) -> Sh [Bool] -> Sh Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and (Sh [Bool] -> Sh Bool)
-> (FilePath -> Sh [Bool]) -> FilePath -> Sh Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sh Bool -> Sh [Bool]
forall a. Sh a -> Sh [a]
unSh (Sh Bool -> Sh [Bool])
-> (FilePath -> Sh Bool) -> FilePath -> Sh [Bool]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> Sh Bool
p
          nil' :: [a]
nil'  = a -> [a]
forall (m :: * -> *) a. Monad m => a -> m a
return a
nil
          cons' :: [a] -> FilePath -> Sh [a]
cons' [a]
as FilePath
dir = Sh a -> Sh [a]
forall a. Sh a -> Sh [a]
unSh (Sh a -> Sh [a]) -> Sh a -> Sh [a]
forall a b. (a -> b) -> a -> b
$ Sh [a] -> Sh a
forall a. Sh [a] -> Sh a
roll (Sh [a] -> Sh a) -> Sh [a] -> Sh a
forall a b. (a -> b) -> a -> b
$ (a -> Sh a) -> [a] -> Sh [a]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM ((a -> FilePath -> Sh a) -> FilePath -> a -> Sh a
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> FilePath -> Sh a
cons FilePath
dir) [a]
as

-----------------------------------------------------------
-- exiting the program

-- | see 'S.exit'
exit :: Int -> Sh ()
exit :: Int -> Sh ()
exit = (Int -> Sh ()) -> Int -> Sh ()
forall a b. (a -> Sh b) -> a -> Sh b
sh1 Int -> Sh ()
forall a. Int -> Sh a
S.exit

-- | see 'S.errorExit'
errorExit :: Text -> Sh ()
errorExit :: Text -> Sh ()
errorExit = (Text -> Sh ()) -> Text -> Sh ()
forall a b. (a -> Sh b) -> a -> Sh b
sh1 Text -> Sh ()
forall a. Text -> Sh a
S.errorExit

-- | see 'S.quietExit'
quietExit :: Int -> Sh ()
quietExit :: Int -> Sh ()
quietExit = (Int -> Sh ()) -> Int -> Sh ()
forall a b. (a -> Sh b) -> a -> Sh b
sh1 Int -> Sh ()
forall a. Int -> Sh a
S.quietExit

-- | see 'S.terror'
terror :: Text -> Sh a
terror :: forall a. Text -> Sh a
terror = (Text -> Sh a) -> Text -> Sh a
forall a b. (a -> Sh b) -> a -> Sh b
sh1 Text -> Sh a
forall a. Text -> Sh a
S.terror

------------------------------------------------------------
-- Utilities

-- | see 'S.catch_sh'
catch_sh :: (Exception e) => Sh a -> (e -> Sh a) -> Sh a
catch_sh :: forall e a. Exception e => Sh a -> (e -> Sh a) -> Sh a
catch_sh Sh a
a e -> Sh a
f = Sh [a] -> Sh a
forall a. Sh [a] -> Sh a
Sh (Sh [a] -> Sh a) -> Sh [a] -> Sh a
forall a b. (a -> b) -> a -> b
$ Sh [a] -> (e -> Sh [a]) -> Sh [a]
forall e a. Exception e => Sh a -> (e -> Sh a) -> Sh a
S.catch_sh (Sh a -> Sh [a]
forall a. Sh a -> Sh [a]
unSh Sh a
a) (Sh a -> Sh [a]
forall a. Sh a -> Sh [a]
unSh (Sh a -> Sh [a]) -> (e -> Sh a) -> e -> Sh [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> Sh a
f)

-- | see 'S.catchany_sh'
catchany_sh :: Sh a -> (SomeException -> Sh a) -> Sh a
catchany_sh :: forall a. Sh a -> (SomeException -> Sh a) -> Sh a
catchany_sh = Sh a -> (SomeException -> Sh a) -> Sh a
forall e a. Exception e => Sh a -> (e -> Sh a) -> Sh a
catch_sh


-- | see 'S.finally_sh'
finally_sh :: Sh a -> Sh b -> Sh a
finally_sh :: forall a b. Sh a -> Sh b -> Sh a
finally_sh = (Sh a -> Sh b -> Sh a) -> Sh a -> Sh b -> Sh a
forall a b c. (Sh a -> Sh b -> Sh c) -> Sh a -> Sh b -> Sh c
lift2 Sh a -> Sh b -> Sh a
forall a b. Sh a -> Sh b -> Sh a
S.finally_sh

-- | see 'S.time'
time :: Sh a -> Sh (Double, a)
time :: forall a. Sh a -> Sh (Double, a)
time = (Sh a -> Sh (Double, a)) -> Sh a -> Sh (Double, a)
forall a b. (Sh a -> Sh b) -> Sh a -> Sh b
lift1 Sh a -> Sh (Double, a)
forall a. Sh a -> Sh (Double, a)
S.time

-- | see 'S.ShellyHandler'
data ShellyHandler a = forall e . Exception e => ShellyHandler (e -> Sh a)

-- | see 'S.catches_sh'
catches_sh :: Sh a -> [ShellyHandler a] -> Sh a
catches_sh :: forall a. Sh a -> [ShellyHandler a] -> Sh a
catches_sh Sh a
a [ShellyHandler a]
hs = Sh [a] -> Sh a
forall a. Sh [a] -> Sh a
Sh (Sh [a] -> Sh a) -> Sh [a] -> Sh a
forall a b. (a -> b) -> a -> b
$ Sh [a] -> [ShellyHandler [a]] -> Sh [a]
forall a. Sh a -> [ShellyHandler a] -> Sh a
S.catches_sh (Sh a -> Sh [a]
forall a. Sh a -> Sh [a]
unSh Sh a
a) ((ShellyHandler a -> ShellyHandler [a])
-> [ShellyHandler a] -> [ShellyHandler [a]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ShellyHandler a -> ShellyHandler [a]
forall a. ShellyHandler a -> ShellyHandler [a]
convert [ShellyHandler a]
hs)
    where convert :: ShellyHandler a -> S.ShellyHandler [a]
          convert :: forall a. ShellyHandler a -> ShellyHandler [a]
convert (ShellyHandler e -> Sh a
f) = (e -> Sh [a]) -> ShellyHandler [a]
forall a e. Exception e => (e -> Sh a) -> ShellyHandler a
S.ShellyHandler (Sh a -> Sh [a]
forall a. Sh a -> Sh [a]
unSh (Sh a -> Sh [a]) -> (e -> Sh a) -> e -> Sh [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> Sh a
f)

------------------------------------------------------------
-- convert between Text and FilePath

-- | see 'S.toTextWarn'
toTextWarn :: FilePath -> Sh Text
toTextWarn :: FilePath -> Sh Text
toTextWarn = (FilePath -> Sh Text) -> FilePath -> Sh Text
forall a b. (a -> Sh b) -> a -> Sh b
sh1 FilePath -> Sh Text
S.toTextWarn

-------------------------------------------------------------
-- internal functions for writing extension

get :: Sh State
get :: Sh State
get = Sh State -> Sh State
forall a. Sh a -> Sh a
sh0 Sh State
S.get

put :: State -> Sh ()
put :: State -> Sh ()
put = (State -> Sh ()) -> State -> Sh ()
forall a b. (a -> Sh b) -> a -> Sh b
sh1 State -> Sh ()
S.put

--------------------------------------------------------
-- polyvariadic vodoo

-- | Converter for the variadic argument version of 'run' called 'cmd'.
class ShellArg a where toTextArg :: a -> Text
instance ShellArg Text     where toTextArg :: Text -> Text
toTextArg = Text -> Text
forall a. a -> a
id
instance ShellArg FilePath where toTextArg :: FilePath -> Text
toTextArg = FilePath -> Text
toTextIgnore


-- Voodoo to create the variadic function 'cmd'
class ShellCommand t where
    cmdAll :: FilePath -> [Text] -> t

instance ShellCommand (Sh Text) where
    cmdAll :: FilePath -> [Text] -> Sh Text
cmdAll FilePath
fp [Text]
args = FilePath -> [Text] -> Sh Text
run FilePath
fp [Text]
args

instance (s ~ Text, Show s) => ShellCommand (Sh s) where
    cmdAll :: FilePath -> [Text] -> Sh s
cmdAll FilePath
fp [Text]
args = FilePath -> [Text] -> Sh Text
run FilePath
fp [Text]
args

-- note that Sh () actually doesn't work for its case (_<- cmd) when there is no type signature
instance ShellCommand (Sh ()) where
    cmdAll :: FilePath -> [Text] -> Sh ()
cmdAll FilePath
fp [Text]
args = FilePath -> [Text] -> Sh ()
run_ FilePath
fp [Text]
args

instance (ShellArg arg, ShellCommand result) => ShellCommand (arg -> result) where
    cmdAll :: FilePath -> [Text] -> arg -> result
cmdAll FilePath
fp [Text]
acc = \arg
x -> FilePath -> [Text] -> result
forall t. ShellCommand t => FilePath -> [Text] -> t
cmdAll FilePath
fp ([Text]
acc [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [arg -> Text
forall a. ShellArg a => a -> Text
toTextArg arg
x])

-- | see 'S.cmd'
cmd :: (ShellCommand result) => FilePath -> result
cmd :: forall result. ShellCommand result => FilePath -> result
cmd FilePath
fp = FilePath -> [Text] -> result
forall t. ShellCommand t => FilePath -> [Text] -> t
cmdAll FilePath
fp []