Conveniently run child processes:
{-# LANGUAGE ScopedTypeVariables #-}
import Cradle
main :: IO ()
main = do
StdoutTrimmed stdout <- run $ cmd "echo" & addArgs ["Hello, World!"]
print stdout
-- prints "Hello, World!"
-- `run` is polymorphic on the return type. Just by adding it to the pattern
-- match, you can get things like the exit code and stderr:
(exitCode :: ExitCode, StderrRaw stderr) <- run $ cmd "ls" & addArgs ["does-not-exist"]
print exitCode
-- prints ExitFailure 2
print stderr
-- prints "ls: cannot access 'does-not-exist': No such file or directory\n"
It does not run the processes through a shell, but rather is meant as a high-level interface to fork
& exec
.
process
:process
is substantially lower level thancradle
. That is, it allows for more control, and more options, but at the cost of a more complicated interface. (cradle
usesprocess
under the hood.)typed-process
: A safer version ofprocess
. Still lower-level thancradle
.turtle
:turtle
is a more ambitious library, including a number of system-related functionality (such as changing directories, looking up environment variables, etc.), as well as providing convenient functions for running common executables such asdate
andrm
.cradle
by contrast only runs specified processes.shake
'scmd
. This was the basis forcradle
, which indeed started it's life as a factoring-out of thecmd
logic into a separate library. Since then, the API has been cleaned up and generalized. Notable changes are separatingcmd
fromrun
so functions can be more easily applied to the command; not being variadic in the arguments for better type inference; and removingCmdArguments
class altogether in favor of a composition ofProcessConfiguration -> ProcessConfiguration
functions.