-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Simple interface for shell scripting in Haskell.
--
-- Aims to simplify development of cross-platform shell scripts and
-- similar things.
@package shellmate
@version 0.3.4.1
-- | Simple interface for shell scripting-like tasks.
module Control.Shell
-- | A shell command: either an IO computation or a pipeline of at least
-- one step.
data Shell a
-- | Why did the computation terminate?
data ExitReason
Success :: ExitReason
Failure :: !String -> ExitReason
-- | Run a shell computation. If part of the computation fails, the whole
-- computation fails. The computation's environment is initially that of
-- the whole process.
shell :: Shell a -> IO (Either ExitReason a)
-- | Run a shell computation and return its result. If the computation
-- calls exit, the return value will be undefined. If the
-- computation fails, an error will be thrown.
shell_ :: Shell a -> IO a
-- | Convert an ExitReason into a String. Successful
-- termination yields the empty string, while abnormal termination yields
-- the termination error message. If the program terminaged abnormally
-- but without an error message - i.e. the error message is empty string
-- - the error message will be shown as "abnormal termination".
exitString :: ExitReason -> String
-- | Connect the standard output of the first argument to the standard
-- input of the second argument, and run the two computations in
-- parallel.
(|>) :: Shell () -> Shell () -> Shell ()
infixl 5 |>
-- | Perform the given computation and return its standard output.
capture :: Shell () -> Shell String
-- | Perform the given computation and return its standard error.
captureStdErr :: Shell () -> Shell String
-- | Perform the given computation and return its standard output and
-- error, in that order.
capture2 :: Shell () -> Shell (String, String)
-- | Perform the given computation and return its standard output and
-- error, as well as its exit reason, in that order.
capture3 :: Shell () -> Shell (String, String, ExitReason)
-- | Lift a pure function to a computation over standard input/output.
-- Similar to interact.
stream :: (String -> String) -> Shell ()
-- | Lift a shell computation to a function over stdin and stdout. Similar
-- to interact.
lift :: (String -> Shell String) -> Shell ()
-- | Attempt to run a computation. If the inner computation fails, the
-- outer computations returns its error message, otherwise its result is
-- returned.
try :: Shell a -> Shell (Either String a)
-- | Attempt to run the first command. If the first command fails, run the
-- second. Forces serialization of the first command.
orElse :: Shell a -> Shell a -> Shell a
-- | Terminate the program successfully.
exit :: Shell a
class Guard guard where type Result guard where {
type family Result guard;
}
-- | Perform a Shell computation; if the computation succeeds but returns a
-- false-ish value, the outer Shell computation fails with the given
-- error message.
assert :: Guard guard => String -> guard -> Shell (Result guard)
-- | Perform a Shell computation; if the computation succeeds but returns a
-- false-ish value, the outer Shell computation fails. Corresponds to
-- guard.
guard :: Guard g => g -> Shell (Result g)
-- | Perform the given computation if the given guard passes, otherwise do
-- nothing.The guard raising an error counts as failure as far as this
-- function is concerned. Corresponds to when.
when :: Guard g => g -> Shell () -> Shell ()
-- | Perform the given computation if the given guard fails, otherwise do
-- nothing. The guard raising an error counts as failure as far as this
-- function is concerned. Corresponds to unless.
unless :: Guard g => g -> Shell () -> Shell ()
-- | Run a computation with the given environment variable set.
withEnv :: String -> String -> Shell a -> Shell a
-- | Run a computation with the given environment variable unset.
withoutEnv :: String -> Shell a -> Shell a
-- | Get the value of an environment variable. Returns Nothing if the
-- variable doesn't exist.
lookupEnv :: String -> Shell (Maybe String)
-- | Get the value of an environment variable. Returns the empty string if
-- the variable doesn't exist.
getEnv :: String -> Shell String
-- | The executable's command line arguments.
cmdline :: [String]
-- | Monads in which IO computations may be embedded. Any monad
-- built by applying a sequence of monad transformers to the IO
-- monad will be an instance of this class.
--
-- Instances should satisfy the following laws, which state that
-- liftIO is a transformer of monads:
--
--
class Monad m => MonadIO (m :: * -> *)
-- | Lift a computation from the IO monad.
liftIO :: MonadIO m => IO a -> m a
-- | A shell environment: consists of the current standard input, output
-- and error handles used by the computation, as well as the current
-- working directory and set of environment variables.
data Env
Env :: !Handle -> !Handle -> !Handle -> !FilePath -> ![(String, String)] -> Env
[envStdIn] :: Env -> !Handle
[envStdOut] :: Env -> !Handle
[envStdErr] :: Env -> !Handle
[envWorkDir] :: Env -> !FilePath
[envEnvVars] :: Env -> ![(String, String)]
-- | Execute an external command. No globbing, escaping or other external
-- shell magic is performed on either the command or arguments. The
-- program's stdout will be written to stdout.
run :: FilePath -> [String] -> Shell ()
-- | Run a command with elevated privileges.
sudo :: FilePath -> [String] -> Shell ()
-- | Lift an IO computation into a shell. The lifted computation is not
-- thread-safe, and should thus absolutely not use environment variables,
-- relative paths or standard input/output.
unsafeLiftIO :: IO a -> Shell a
-- | Create an absolute path from the environment and a potentially
-- relative path. Has no effect if the path is already absolute.
absPath :: Env -> FilePath -> FilePath
-- | Get the current global shell environment, including standard input,
-- output and error handles. Only safe to call within a computation
-- lifted into Shell by liftIO.
shellEnv :: IO Env
-- | Get the complete environment for the current computation.
getShellEnv :: Shell Env
-- | Propagate an explicit ExitResult through the computation.
joinResult :: Shell (Either ExitReason a) -> Shell a
runSh :: Env -> Shell a -> IO (Either ExitReason a)
-- | Recursively copy a directory. If the target is a directory that
-- already exists, the source directory is copied into that directory
-- using its current name.
cpdir :: FilePath -> FilePath -> Shell ()
-- | Get the current working directory.
pwd :: Shell FilePath
-- | List the contents of a directory, sans . and ...
ls :: FilePath -> Shell [FilePath]
-- | Create a directory. Optionally create any required missing directories
-- as well.
mkdir :: Bool -> FilePath -> Shell ()
-- | Recursively remove a directory. Follows symlinks, so be careful.
rmdir :: FilePath -> Shell ()
-- | Execute a command in the given working directory, then restore the
-- previous working directory.
inDirectory :: FilePath -> Shell a -> Shell a
-- | Does the given path lead to a directory?
isDirectory :: FilePath -> Shell Bool
-- | Do something with the user's home directory.
withHomeDirectory :: (FilePath -> Shell a) -> Shell a
-- | Perform an action with the user's home directory as the working
-- directory.
inHomeDirectory :: Shell a -> Shell a
-- | Do something with the given application's data directory.
withAppDirectory :: String -> (FilePath -> Shell a) -> Shell a
-- | Do something with the given application's data directory as the
-- working directory.
inAppDirectory :: FilePath -> Shell a -> Shell a
-- | Perform an action on each file in the given directory. This function
-- will traverse any subdirectories of the given as well. File paths are
-- given relative to the given directory; the current working directory
-- is not affected.
forEachFile :: FilePath -> (FilePath -> Shell a) -> Shell [a]
-- | Like forEachFile but only performs a side effect.
forEachFile_ :: FilePath -> (FilePath -> Shell ()) -> Shell ()
-- | Recursively perform an action on each subdirectory of the given
-- directory. The path passed to the callback is relative to the given
-- directory. The action will *not* be performed on the given directory
-- itself.
forEachDirectory :: FilePath -> (FilePath -> Shell a) -> Shell [a]
-- | Like forEachDirectory, but discards its result.
forEachDirectory_ :: FilePath -> (FilePath -> Shell ()) -> Shell ()
-- | Does the given path lead to a file?
isFile :: FilePath -> Shell Bool
-- | Remove a file.
rm :: FilePath -> Shell ()
-- | Rename a file or directory. If the target is a directory, then the
-- source will be moved into that directory.
mv :: FilePath -> FilePath -> Shell ()
-- | Copy a file. Fails if the source is a directory. If the target is a
-- directory, the source file is copied into that directory using its
-- current name.
cp :: FilePath -> FilePath -> Shell ()
-- | Lazily read a file.
input :: FilePath -> Shell String
-- | Lazily write a file.
output :: FilePath -> String -> Shell ()
-- | Perform a computation over a file.
withFile :: FilePath -> IOMode -> (Handle -> Shell a) -> Shell a
-- | Perform a computation over a binary file.
withBinaryFile :: FilePath -> IOMode -> (Handle -> Shell a) -> Shell a
-- | Open a file, returning a handle to it.
openFile :: FilePath -> IOMode -> Shell Handle
-- | Open a file in binary mode, returning a handle to it.
openBinaryFile :: FilePath -> IOMode -> Shell Handle
-- | Perform a file operation in binary or text mode?
data FileMode
BinaryMode :: FileMode
TextMode :: FileMode
-- | Create a temp file in the standard system temp directory, do something
-- with it, then remove it.
withTempFile :: FileMode -> (FilePath -> Handle -> Shell a) -> Shell a
-- | Create a temp file in the standard system temp directory, do something
-- with it, then remove it.
withCustomTempFile :: FileMode -> FilePath -> (FilePath -> Handle -> Shell a) -> Shell a
-- | Create a temp directory in the standard system temp directory, do
-- something with it, then remove it.
withTempDirectory :: (FilePath -> Shell a) -> Shell a
-- | Create a temp directory in given directory, do something with it, then
-- remove it.
withCustomTempDirectory :: FilePath -> (FilePath -> Shell a) -> Shell a
-- | Performs a command inside a temporary directory. The directory will be
-- cleaned up after the command finishes.
inTempDirectory :: Shell a -> Shell a
-- | Performs a command inside a temporary directory. The directory will be
-- cleaned up after the command finishes.
inCustomTempDirectory :: FilePath -> Shell a -> Shell a
-- | Haskell defines operations to read and write characters from and to
-- files, represented by values of type Handle. Each value of
-- this type is a handle: a record used by the Haskell run-time
-- system to manage I/O with file system objects. A handle has at
-- least the following properties:
--
--
-- - whether it manages input or output or both;
-- - whether it is open, closed or
-- semi-closed;
-- - whether the object is seekable;
-- - whether buffering is disabled, or enabled on a line or block
-- basis;
-- - a buffer (whose length may be zero).
--
--
-- Most handles will also have a current I/O position indicating where
-- the next input or output operation will occur. A handle is
-- readable if it manages only input or both input and output;
-- likewise, it is writable if it manages only output or both
-- input and output. A handle is open when first allocated. Once
-- it is closed it can no longer be used for either input or output,
-- though an implementation cannot re-use its storage while references
-- remain to it. Handles are in the Show and Eq classes.
-- The string produced by showing a handle is system dependent; it should
-- include enough information to identify the handle for debugging. A
-- handle is equal according to == only to itself; no attempt is
-- made to compare the internal state of different handles for equality.
data Handle :: *
-- | See openFile
data IOMode :: *
ReadMode :: IOMode
WriteMode :: IOMode
AppendMode :: IOMode
ReadWriteMode :: IOMode
-- | Three kinds of buffering are supported: line-buffering,
-- block-buffering or no-buffering. These modes have the following
-- effects. For output, items are written out, or flushed, from
-- the internal buffer according to the buffer mode:
--
--
-- - line-buffering: the entire output buffer is flushed
-- whenever a newline is output, the buffer overflows, a hFlush is
-- issued, or the handle is closed.
-- - block-buffering: the entire buffer is written out whenever
-- it overflows, a hFlush is issued, or the handle is closed.
-- - no-buffering: output is written immediately, and never
-- stored in the buffer.
--
--
-- An implementation is free to flush the buffer more frequently, but not
-- less frequently, than specified above. The output buffer is emptied as
-- soon as it has been written out.
--
-- Similarly, input occurs according to the buffer mode for the handle:
--
--
-- - line-buffering: when the buffer for the handle is not
-- empty, the next item is obtained from the buffer; otherwise, when the
-- buffer is empty, characters up to and including the next newline
-- character are read into the buffer. No characters are available until
-- the newline character is available or the buffer is full.
-- - block-buffering: when the buffer for the handle becomes
-- empty, the next block of data is read into the buffer.
-- - no-buffering: the next input item is read and returned. The
-- hLookAhead operation implies that even a no-buffered handle may
-- require a one-character buffer.
--
--
-- The default buffering mode when a handle is opened is
-- implementation-dependent and may depend on the file system object
-- which is attached to that handle. For most implementations, physical
-- files will normally be block-buffered and terminals will normally be
-- line-buffered.
data BufferMode :: *
-- | buffering is disabled if possible.
NoBuffering :: BufferMode
-- | line-buffering should be enabled if possible.
LineBuffering :: BufferMode
-- | block-buffering should be enabled if possible. The size of the buffer
-- is n items if the argument is Just n and is
-- otherwise implementation-dependent.
BlockBuffering :: Maybe Int -> BufferMode
-- | Flush a handle.
hFlush :: Handle -> Shell ()
-- | Close a handle.
hClose :: Handle -> Shell ()
-- | Is the handle ready for reading?
hReady :: Handle -> Shell Bool
-- | Get the buffering mode of the given handle.
hGetBuffering :: Handle -> Shell BufferMode
-- | Set the buffering mode of the given handle.
hSetBuffering :: Handle -> BufferMode -> Shell ()
-- | Get the standard input, output and error handle respectively.
getStdIn :: Shell Handle
-- | Get the standard input, output and error handle respectively.
getStdOut :: Shell Handle
-- | Get the standard input, output and error handle respectively.
getStdErr :: Shell Handle
-- | Write a string to a handle.
hPutStr :: Handle -> String -> Shell ()
-- | Write a string to a handle, followed by a newline.
hPutStrLn :: Handle -> String -> Shell ()
-- | Write a string to standard output, followed by a newline.
echo :: String -> Shell ()
-- | Write a string to standard output, without appending a newline.
echo_ :: String -> Shell ()
-- | Read a line of text from standard input.
ask :: Shell String
-- | Get the contents of the computation's standard input.
stdin :: Shell String
-- | Read a line of input from a handle.
hGetLine :: Handle -> Shell String
-- | Lazily read all remaining input from a handle.
hGetContents :: Handle -> Shell String
data Color
Black :: Color
Red :: Color
Green :: Color
Yellow :: Color
Blue :: Color
Purple :: Color
Magenta :: Color
White :: Color
-- | Apply the given color to the given string.
color :: Color -> String -> String
-- | Apply the given background color to the given string.
background :: Color -> String -> String
-- | Apply the terminal's default highlighting to the given string.
highlight :: String -> String
-- | Output the given string in bold font.
bold :: String -> String
-- | Underline the given string.
underline :: String -> String
-- | Read n bytes from a handle.
hGetBytes :: Handle -> Int -> Shell ByteString
-- | Write a ByteString to a handle. Newline is not appended.
hPutBytes :: Handle -> ByteString -> Shell ()
-- | Read a line of input from a handle and return it as a
-- ByteString.
hGetByteLine :: Handle -> Shell ByteString
-- | Read all remaining input from a handle and return it as a
-- ByteString.
hGetByteContents :: Handle -> Shell ByteString
-- | Concurrency for Shellmate programs.
module Control.Shell.Concurrent
-- | A future is a computation which is run in parallel with a program's
-- main thread and which may at some later point finish and return a
-- value.
--
-- Note that future computations are killed when their corresponding
-- Future is garbage collected. This means that a future should
-- *always* be awaited at some point or otherwise kept alive, to
-- ensure that the computation finishes.
--
-- Note that all any code called in a future using unsafeLiftIO
-- must refrain from using environment variables, standard input/output,
-- relative paths and the current working directory, in order to avoid
-- race conditions. Code within the Shell monad, code imported
-- using liftIO and external processes spawned from within
-- Shell is perfectly safe.
data Future a
-- | A ThreadId is an abstract type representing a handle to a
-- thread. ThreadId is an instance of Eq, Ord and
-- Show, where the Ord instance implements an arbitrary
-- total ordering over ThreadIds. The Show instance lets
-- you convert an arbitrary-valued ThreadId to string form;
-- showing a ThreadId value is occasionally useful when debugging
-- or diagnosing the behaviour of a concurrent program.
--
-- Note: in GHC, if you have a ThreadId, you essentially
-- have a pointer to the thread itself. This means the thread itself
-- can't be garbage collected until you drop the ThreadId. This
-- misfeature will hopefully be corrected at a later date.
data ThreadId :: *
-- | Run a computation in a separate thread. If the thread throws an error,
-- it will simply die; the error will not propagate to its parent thread.
forkIO :: Shell () -> Shell ThreadId
-- | Terminate a thread spawned by forkIO.
killThread :: ThreadId -> Shell ()
-- | Run a computation in a separate thread, with its standard input and
-- output provided by the first and second handles returned respectively.
-- The handles are line buffered by default.
fork2 :: Shell () -> Shell (Handle, Handle, ThreadId)
-- | Like fork2, but adds a third handle for standard error.
fork3 :: Shell () -> Shell (Handle, Handle, Handle, ThreadId)
-- | Create a future value.
future :: Shell a -> Shell (Future a)
-- | Wait for a future value.
await :: Future a -> Shell a
-- | Check whether a future value has arrived or not.
check :: Future a -> Shell (Maybe a)
-- | Perform the given computations in parallel. The race condition warning
-- for Future when modifying environment variables or using
-- relative paths still applies.
parallel :: [Shell a] -> Shell [a]
-- | Like parallel, but discards any return values.
parallel_ :: [Shell a] -> Shell ()
-- | Break a list into chunks. This is quite useful for when performing
-- *every* computation in parallel is too much. For instance, to download
-- a list of files three at a time, one would do mapM_ (parallel_
-- downloadFile) (chunks 3 files).
chunks :: Int -> [a] -> [[a]]
-- | Working with daemons, users, groups, file permissions and file
-- ownerships. Not present on Windows unless shellmate is installed with
-- the with-posix flag.
module Control.Shell.Posix
type User = String
type Group = String
-- | Get the currently effective user name.
getCurrentUser :: Shell String
-- | Get the list of groups associated with the current process.
getCurrentGroups :: Shell [String]
-- | Get the owner of the given file.
getOwner :: FilePath -> Shell User
-- | Get the group of the given file.
getGroup :: FilePath -> Shell Group
-- | Get the owner and group of the given file.
getOwnership :: FilePath -> Shell (User, Group)
-- | Set the owner of the given file.
setOwner :: User -> FilePath -> Shell ()
-- | Set the group of the given file.
setGroup :: Group -> FilePath -> Shell ()
-- | Set the owner and group of the given file.
setOwnership :: User -> Group -> FilePath -> Shell ()
data CMode :: *
-- | Combines the two file modes into one that contains modes that appear
-- in either.
unionFileModes :: FileMode -> FileMode -> FileMode
-- | Combines two file modes into one that only contains modes that appear
-- in both.
intersectFileModes :: FileMode -> FileMode -> FileMode
-- | No permissions.
nullFileMode :: FileMode
-- | Owner has read permission.
ownerReadMode :: FileMode
-- | Owner has write permission.
ownerWriteMode :: FileMode
-- | Owner has execute permission.
ownerExecuteMode :: FileMode
-- | Owner has read, write and execute permission.
ownerModes :: FileMode
-- | Group has read permission.
groupReadMode :: FileMode
-- | Group has write permission.
groupWriteMode :: FileMode
-- | Group has execute permission.
groupExecuteMode :: FileMode
-- | Group has read, write and execute permission.
groupModes :: FileMode
-- | Others have read permission.
otherReadMode :: FileMode
-- | Others have write permission.
otherWriteMode :: FileMode
-- | Others have execute permission.
otherExecuteMode :: FileMode
-- | Others have read, write and execute permission.
otherModes :: FileMode
-- | Owner, group and others have read and write permission.
stdFileMode :: FileMode
-- | Owner, group and others have read, write and execute permission.
accessModes :: FileMode
-- | Set the mode (permissions, etc.) of the given file.
setFileMode :: FilePath -> CMode -> Shell ()
-- | Get the mode of the given file.
getFileMode :: FilePath -> Shell CMode
-- | Set the file creation mask of this process.
setFileCreationMask :: CMode -> Shell CMode
-- | Daemonize a shellmate computation. This should be the last thing a
-- computation does, as this function will terminate the parent
-- computation. In short, daemonizing a computation involves setting the
-- file creation mask to 0, closing standard input, output and error file
-- descriptors, blocking sighup and changing the working directory to
-- /.
--
-- On Windows without Cygwin, daemonize is a no-op. Consider
-- running any program intended to be deamonized using START /B
-- your_app, or better yet, rewriting it as a Windows service.
daemonize :: Shell () -> Shell ()