cradle-0.0.0.0: README.lhs
# `cradle`
Conveniently run child processes:
```haskell
{-# 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`.
# Alternatives
- [`process`](https://hackage.haskell.org/package/process): `process` is substantially lower level than `cradle`. That is, it allows for more control, and more options, but at the cost of a more complicated interface. (`cradle` uses `process` under the hood.)
- [`typed-process`](https://hackage.haskell.org/package/typed-process): A safer version of `process`. Still lower-level than `cradle`.
- [`turtle`](https://hackage.haskell.org/package/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 as `date` and `rm`. `cradle` by contrast *only* runs specified processes.
- `shake`'s `cmd`. This was the basis for `cradle`, which indeed started it's life as a factoring-out of the `cmd` logic into a separate library. Since then, the API has been cleaned up and generalized. Notable changes are separating `cmd` from `run` so functions can be more easily applied to the command; not being variadic in the arguments for better type inference; and removing `CmdArguments` class altogether in favor of a composition of `ProcessConfiguration -> ProcessConfiguration` functions.