-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | shell monad -- -- This is a shell monad, for generating shell scripts. @package shell-monad @version 0.6.10 -- | Shell quoting module Control.Monad.Shell.Quote -- | A value that is safely quoted so that it can be exposed to the shell. -- -- While the constructor is exposed, you should avoid directly -- constucting Quoted values. Instead, use quote. newtype Quoted a Q :: a -> Quoted a [getQ] :: Quoted a -> a -- | Quotes a value to allow it to be safely exposed to the shell. -- -- The method used is to replace ' with '"'"' and wrap the value inside -- single quotes. This works for POSIX shells, as well as other shells -- like csh. -- -- The single quotes are omitted for simple values that do not need any -- quoting. class Quotable t quote :: Quotable t => t -> Quoted Text -- | An arbitrary value. newtype Val v Val :: v -> Val v instance GHC.Base.Monoid a => GHC.Base.Monoid (Control.Monad.Shell.Quote.Quoted a) instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Control.Monad.Shell.Quote.Quoted a) instance GHC.Show.Show a => GHC.Show.Show (Control.Monad.Shell.Quote.Quoted a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Control.Monad.Shell.Quote.Quoted a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Control.Monad.Shell.Quote.Quoted a) instance GHC.Show.Show v => Control.Monad.Shell.Quote.Quotable (Control.Monad.Shell.Quote.Val v) instance Control.Monad.Shell.Quote.Quotable (Control.Monad.Shell.Quote.Val Data.Text.Internal.Lazy.Text) instance Control.Monad.Shell.Quote.Quotable (Control.Monad.Shell.Quote.Val GHC.Base.String) instance Control.Monad.Shell.Quote.Quotable Data.Text.Internal.Lazy.Text instance Control.Monad.Shell.Quote.Quotable GHC.Base.String instance Data.String.IsString (Control.Monad.Shell.Quote.Quoted Data.Text.Internal.Lazy.Text) -- | This is a shell monad, for generating shell scripts. -- -- The emphasis is on generating shell code that will work in any POSIX -- compliant shell and avoids many common shell pitfalls, including -- insufficient quoting, while allowing the Haskell type checker to be -- leveraged for additional safety. -- -- Here is a hello world example. -- --
--   {-# LANGUAGE OverloadedStrings, ExtendedDefaultRules #-}
--   import Control.Monad.Shell
--   import Data.Monoid
--   import qualified Data.Text.Lazy as T
--   import qualified Data.Text.Lazy.IO as T
--   default (T.Text)
--   
--   main :: IO ()
--   main = T.writeFile "hello.sh" $ script $ do
--   	cmd "echo" "hello, world"
--   	username <- newVarFrom (Output (cmd "whoami")) ()
--   	cmd "echo" "from" (WithVar username (<> "'s shell"))
--   
-- -- When run, that generates this shell code: -- --
--   #!/bin/sh
--   echo 'hello, world'
--   _v="$(whoami)"
--   echo from "$_v"''"'"'s shell'
--   
-- -- There are several other examples shipped in the examples/ directory of -- the shell-monad package. For example, protocol.hs shows how -- shell-monad can be used to implement a shell script that speaks a -- protocol that is defined using Haskell data types. module Control.Monad.Shell -- | Shell script monad. data Script a -- | Generates a shell script, including hashbang, suitable to be written -- to a file. script :: Script f -> Text -- | Generates a single line of shell code. linearScript :: Script f -> Text -- | A term that can be expanded in a shell command line. data Term t a -- | Used to represent a shell variable. data Var -- | Used for a static value. data Static -- | A value that is safely quoted so that it can be exposed to the shell. -- -- While the constructor is exposed, you should avoid directly -- constucting Quoted values. Instead, use quote. data Quoted a -- | Quotes a value to allow it to be safely exposed to the shell. -- -- The method used is to replace ' with '"'"' and wrap the value inside -- single quotes. This works for POSIX shells, as well as other shells -- like csh. -- -- The single quotes are omitted for simple values that do not need any -- quoting. class Quotable t quote :: Quotable t => t -> Quoted Text -- | Treats the Text as a glob. -- -- When used as a Param to a command, it expands to one parameter -- per matching file. -- --
--   forCmd (cmd "ls" (glob "*/*.cabal")) $ \file ->
--       cmd "echo" file
--   
-- -- When used in a caseOf, it matches text against the glob. -- -- The input is assumed to be a well-formed glob. Characters in it that -- are not alphanumeric and are not wildcard characters will be escaped -- before it is exposed to the shell. This allows eg, spaces in globs. glob :: Text -> Quoted Text -- | Adds a shell command to the script. run :: Text -> [Text] -> Script () -- | Variadic and polymorphic version of run -- -- A command can be passed any number of Params. -- --
--   demo = script $ do
--     cmd "echo" "hello, world"
--     name <- newVar ()
--     readVar name
--     cmd "echo" "hello" name
--   
-- -- For the most efficient use of cmd, add the following -- boilerplate, which will make string literals in your program default -- to being Text: -- --
--   {-# LANGUAGE OverloadedStrings, ExtendedDefaultRules #-}
--   {-# OPTIONS_GHC -fno-warn-type-defaults #-}
--   import Control.Monad.Shell
--   import qualified Data.Text.Lazy as L
--   default (L.Text)
--   
-- -- Note that the command to run is itself a Param, so it can be a Text, -- or a String, or even a Var or Output. For example, this echos "hi": -- --
--   demo = script $ do
--      echovar <- newVarContaining "echo" ()
--      cmd echovar "hi"
--   
cmd :: (Param command, CmdParams params) => command -> params -- | A Param is anything that can be used as the parameter of a command. class Param a -- | Allows a function to take any number of Params. class CmdParams t -- | The output of a command, or even a more complicated Script can be -- passed as a parameter to cmd -- -- Examples: -- --
--   cmd "echo" "hello there," (Output (cmd "whoami"))
--   cmd "echo" "root's pwent" (Output (cmd "cat" "/etc/passwd" -|- cmd "grep" "root"))
--   
newtype Output Output :: Script () -> Output -- | Suggests that a shell variable or function have its name contain the -- specified Text. newtype NamedLike NamedLike :: Text -> NamedLike -- | Class of values that provide a hint for the name to use for a shell -- variable or function. -- -- If you don't want to provide a naming hint, use (). -- --
--   v1 <- newVar ()
--   
-- -- To provide a naming hint, use NamedLike. -- --
--   v1 <- newVar (NamedLike "x")
--   
class NameHinted h -- | Makes a Static Term from any value that can be shown. static :: Quotable (Val t) => t -> Term Static t -- | Defines a new shell variable, which starts out not being set. -- -- Each call to newVar will generate a new, unique variable name. -- -- The namehint can influence this name, but is modified to ensure -- uniqueness. newVar :: NameHinted namehint => forall a. namehint -> Script (Term Var a) -- | Creates a new shell variable with an initial value coming from any -- Param. -- -- For example, -- --
--   packageName <- newVarFrom
--        (Output $
--            cmd "grep" "-i" "name\\s*:" (glob "*.cabal") -|-
--            cmd "perl" "-pe" "s/^name\\s*:\\s*//i")
--        (NamedLike "packageName")
--   
-- -- Use this with WithVar to store to modified value of a variable -- in a new variable. -- --
--   home <- globalVar "HOME"
--   cabalDir <- newVarFrom (WithVar home (<> "/.cabal")) ()
--   
-- -- Or to capture the output of an arithmetic operation. -- --
--   sum <- newVarFrom (val x `APlus` 1) ()
--   
newVarFrom :: (NameHinted namehint, Param param) => param -> namehint -> Script (Term Var t) -- | Creates a new shell variable, with an initial value which can be -- anything that can be shown. -- --
--   s <- newVarContaining "foo bar baz" (NamedLike "s")
--   i <- newVarContaining (1 :: Int) (NamedLike "i")
--   
newVarContaining :: (NameHinted namehint, Quotable (Val t)) => t -> namehint -> Script (Term Var t) -- | Sets the Var to the value of the param. setVar :: Param param => forall a. Term Var a -> param -> Script () -- | Gets a Var that refers to a global variable, such as PATH globalVar :: forall a. Text -> Script (Term Var a) -- | This special Var expands to whatever parameters were passed to the -- shell script. -- -- Inside a func, it expands to whatever parameters were passed to the -- func. -- -- (This is $@ in shell) positionalParameters :: forall a. Term Var a -- | Takes the first positional parameter, removing it from -- positionalParameters and returning a new Var that holds the value of -- the parameter. -- -- If there are no more positional parameters, the script will crash with -- an error. -- -- For example: -- --
--   removefirstfile = script $ do
--     cmd "rm" =<< takeParameter
--     cmd "echo" "remaining parameters:" positionalParameters
--   
takeParameter :: NameHinted namehint => forall a. namehint -> Script (Term Var a) -- | Generates a new Var. Expanding this Var will yield the same result as -- expanding the input Var, unless it is empty, in which case it instead -- defaults to the expansion of the param. defaultVar :: Param param => forall a. Term Var a -> param -> Script (Term Var a) -- | Generates a new Var. If the input Var is empty, then this new Var will -- likewise expand to the empty string. But if not, the new Var expands -- to the param. whenVar :: Param param => forall a. Term Var a -> param -> Script (Term Var a) -- | Generates a new Var, which expands to the length of the expansion of -- the input Var. -- -- Note that 'lengthVar positionalParameters' expands to the number of -- positional parameters. lengthVar :: forall a. Term Var a -> Script (Term Var Integer) -- | Produces a Var that is a trimmed version of the input Var. -- -- The Quoted Text is removed from the value of the Var, either from the -- beginning or from the end. -- -- If the Quoted Text was produced by glob, it could match in -- multiple ways. You can choose whether to remove the shortest or the -- longest match. -- -- The act of trimming a Var is assumed to be able to produce a new Var -- holding a different data type. trimVar :: forall a. Greediness -> Direction -> Term Var String -> Quoted Text -> Script (Term Var a) data Greediness ShortestMatch :: Greediness LongestMatch :: Greediness data Direction FromBeginning :: Direction FromEnd :: Direction -- | Allows modifying the value of a variable before it is passed to a -- command. The function is passed a Quoted Text which will expand to the -- value of the variable, and can modify it, by using eg mappend. -- --
--   cmd "rmdir" (WithVar name ("/home/" <>))
--   
data WithVar a WithVar :: Term Var a -> (Quoted Text -> Quoted Text) -> WithVar a -- | Defines a shell function, and returns an action that can be run to -- call the function. -- -- The action is variadic; it can be passed any number of CmdParams. -- Typically, it will make sense to specify a more concrete type when -- defining the shell function. -- -- The shell function will be given a unique name, that is not used by -- any other shell function. The namehint can be used to influence the -- contents of the function name, which makes for more readable generated -- shell code. -- -- For example: -- --
--   demo = script $ do
--      hohoho <- mkHohoho
--      hohoho (static 1)
--      echo "And I heard him exclaim, ere he rode out of sight ..."
--      hohoho (static 3)
--   
--   mkHohoho :: Script (Term Val Int -> Script ())
--   mkHohoho = func (NamedLike "hohoho") $ do
--      num <- takeParameter
--      forCmd (cmd "seq" "1" num) $ \_n ->
--         cmd "echo" "Ho, ho, ho!" "Merry xmas!"
--   
func :: (NameHinted namehint, CmdParams callfunc) => namehint -> Script () -> Script callfunc -- | Runs the command, and separates its output into parts (using the IFS) -- -- The action is run for each part, passed a Var containing the part. forCmd :: forall a. Script () -> (Term Var a -> Script ()) -> Script () -- | As long as the first Script exits nonzero, runs the second script. whileCmd :: Script () -> Script () -> Script () -- | if with a Script conditional. -- -- If the conditional exits 0, the first action is run, else the second. ifCmd :: Script () -> Script () -> Script () -> Script () -- | when with a monadic conditional whenCmd :: Script () -> Script () -> Script () -- | unless with a monadic conditional unlessCmd :: Script () -> Script () -> Script () -- | Matches the value of the Var against the Quoted Text (which can be -- generated by glob), and runs the Script action associated with -- the first match. -- --
--   arg <- takeParameter ()
--   caseOf arg
--     [ (quote "-h", showHelp)
--     , (glob "-*", cmd "echo" "Unknown option:" arg)
--     ]
--   
caseOf :: forall a. Term Var a -> [(Quoted Text, Script ())] -> Script () -- | Runs the script in a new subshell. subshell :: Script () -> Script () -- | Runs the script as a command group in the current subshell. group :: Script () -> Script () -- | Add a variable to the local environment of the script. withEnv :: Param value => Text -> value -> Script () -> Script () -- | Pipes together two Scripts. (-|-) :: Script () -> Script () -> Script () -- | ANDs two Scripts. (-&&-) :: Script () -> Script () -> Script () -- | ORs two Scripts. (-||-) :: Script () -> Script () -> Script () -- | Any function that takes a RedirFile can be passed a a FilePath, in -- which case the default file descriptor will be redirected to/from the -- FilePath. -- -- Or, it can be passed a tuple of (Fd, FilePath), in which case the -- specified Fd will be redirected to/from the FilePath. class RedirFile r -- | Redirects to a file, overwriting any existing file. -- -- For example, to shut up a noisy command: -- --
--   cmd "find" "/" |> "/dev/null"
--   
(|>) :: RedirFile f => Script () -> f -> Script () -- | Appends to a file. (If file doesn't exist, it will be created.) (|>>) :: RedirFile f => Script () -> f -> Script () -- | Redirects standard input from a file. (|<) :: RedirFile f => Script () -> f -> Script () -- | Redirects a script's output to stderr. toStderr :: Script () -> Script () -- | Redirects the first file descriptor to output to the second. -- -- For example, to redirect a command's stderr to stdout: -- --
--   cmd "foo" &stdError>&stdOutput
--   
(>&) :: (Script (), Fd) -> Fd -> Script () -- | Redirects the first file descriptor to input from the second. -- -- For example, to read from Fd 42: -- --
--   cmd "foo" &stdInput<&Fd 42
--   
(<&) :: (Script (), Fd) -> Fd -> Script () -- | Helper for >& and <& (&) :: Script () -> Fd -> (Script (), Fd) -- | Provides the Text as input to the Script, using a here-document. hereDocument :: Script () -> Text -> Script () -- | By default, shell scripts continue running past commands that exit -- nonzero. Use 'stopOnFailure True' to make the script stop on the first -- such command. stopOnFailure :: Bool -> Script () -- | Makes a nonzero exit status be ignored. ignoreFailure :: Script () -> Script () -- | Generates a new Var. If the input Var is empty then expanding this new -- Var will cause an error to be thrown, using the param as the error -- message. If the input Var is not empty, then the new Var expands to -- the same thing the input Var expands to. errUnlessVar :: Param param => forall a. Term Var a -> param -> Script (Term Var a) -- | Creates a Script that checks a Test and exits true (0) or false (1). -- -- Useful with ifCmd, whenCmd, etc; for example: -- --
--   ifCmd (test (FileExists "foo")) (foo, bar)
--   
test :: Test -> Script () -- | Note that this should only include things that test(1) and shell -- built-in test commands support portably. data Test [TNot] :: Test -> Test [TAnd] :: Test -> Test -> Test [TOr] :: Test -> Test -> Test [TEmpty] :: Param p => p -> Test [TNonEmpty] :: Param p => p -> Test [TStrEqual] :: (Param p, Param q) => p -> q -> Test [TStrNotEqual] :: (Param p, Param q) => p -> q -> Test [TEqual] :: (Integral p, Integral q) => Term Var p -> Term Var q -> Test [TNotEqual] :: (Integral p, Integral q) => Term Var p -> Term Var q -> Test [TGT] :: (Integral p, Integral q) => Term Var p -> Term Var q -> Test [TLT] :: (Integral p, Integral q) => Term Var p -> Term Var q -> Test [TGE] :: (Integral p, Integral q) => Term Var p -> Term Var q -> Test [TLE] :: (Integral p, Integral q) => Term Var p -> Term Var q -> Test [TFileEqual] :: (Param p, Param q) => p -> q -> Test [TFileNewer] :: (Param p, Param q) => p -> q -> Test [TFileOlder] :: (Param p, Param q) => p -> q -> Test [TBlockExists] :: Param p => p -> Test [TCharExists] :: Param p => p -> Test [TDirExists] :: Param p => p -> Test [TFileExists] :: Param p => p -> Test [TRegularFileExists] :: Param p => p -> Test [TSymlinkExists] :: Param p => p -> Test [TFileNonEmpty] :: Param p => p -> Test [TFileExecutable] :: Param p => p -> Test -- | Lifts a Term to Arith. val :: Term t Integer -> Arith -- | This data type represents shell Arithmetic Expressions. -- -- Note that in shell arithmetic, expressions that would evaluate to a -- Bool, such as ANot and AEqual instead evaluate to 1 for True and 0 for -- False. data Arith ANum :: Integer -> Arith AVar :: Term Var Integer -> Arith AStatic :: Term Static Integer -> Arith -- | negation ANegate :: Arith -> Arith -- | + APlus :: Arith -> Arith -> Arith -- | - AMinus :: Arith -> Arith -> Arith -- | * AMult :: Arith -> Arith -> Arith -- | / ADiv :: Arith -> Arith -> Arith -- | mod AMod :: Arith -> Arith -> Arith -- | not ANot :: Arith -> Arith -- | or AOr :: Arith -> Arith -> Arith -- | and AAnd :: Arith -> Arith -> Arith -- | == AEqual :: Arith -> Arith -> Arith -- | /= ANotEqual :: Arith -> Arith -> Arith -- | < ALT :: Arith -> Arith -> Arith -- | > AGT :: Arith -> Arith -> Arith -- | <= ALE :: Arith -> Arith -> Arith -- | >= AGE :: Arith -> Arith -> Arith -- | OR of the bits of the two arguments ABitOr :: Arith -> Arith -> Arith -- | XOR of the bits of the two arguments ABitXOr :: Arith -> Arith -> Arith -- | AND of the bits of the two arguments ABitAnd :: Arith -> Arith -> Arith -- | shift left (first argument's bits are shifted by the value of the -- second argument) AShiftLeft :: Arith -> Arith -> Arith -- | shift right AShiftRight :: Arith -> Arith -> Arith -- | if the first argument is non-zero, the result is the second, else the -- result is the third AIf :: Arith -> (Arith, Arith) -> Arith -- | Adds a comment that is embedded in the generated shell script. comment :: Text -> Script () -- | Fills a variable with a line read from stdin. readVar :: Term Var String -> Script () instance GHC.Show.Show Control.Monad.Shell.VarName instance GHC.Classes.Ord Control.Monad.Shell.VarName instance GHC.Classes.Eq Control.Monad.Shell.VarName instance GHC.Show.Show Control.Monad.Shell.Func instance GHC.Classes.Ord Control.Monad.Shell.Func instance GHC.Classes.Eq Control.Monad.Shell.Func instance GHC.Base.Functor Control.Monad.Shell.Script instance Control.Monad.Shell.Param Control.Monad.Shell.Arith instance GHC.Num.Num Control.Monad.Shell.Arith instance GHC.Enum.Enum Control.Monad.Shell.Arith instance Control.Monad.Shell.RedirFile GHC.IO.FilePath instance Control.Monad.Shell.RedirFile (System.Posix.Types.Fd, GHC.IO.FilePath) instance Control.Monad.Shell.NameHinted () instance Control.Monad.Shell.NameHinted Control.Monad.Shell.NamedLike instance Control.Monad.Shell.NameHinted (GHC.Maybe.Maybe Data.Text.Internal.Lazy.Text) instance Control.Monad.Shell.Param (Control.Monad.Shell.WithVar a) instance Control.Monad.Shell.Param Control.Monad.Shell.Output instance (Control.Monad.Shell.Param arg, Control.Monad.Shell.CmdParams result) => Control.Monad.Shell.CmdParams (arg -> result) instance (f GHC.Types.~ ()) => Control.Monad.Shell.CmdParams (Control.Monad.Shell.Script f) instance Control.Monad.Shell.Param Data.Text.Internal.Lazy.Text instance Control.Monad.Shell.Param GHC.Base.String instance Control.Monad.Shell.Param Control.Monad.Shell.UntypedVar instance Control.Monad.Shell.Param (Control.Monad.Shell.Term Control.Monad.Shell.Var a) instance GHC.Show.Show a => Control.Monad.Shell.Param (Control.Monad.Shell.Term Control.Monad.Shell.Static a) instance Control.Monad.Shell.Param (Control.Monad.Shell.Quote.Quoted Data.Text.Internal.Lazy.Text) instance Control.Monad.Shell.Named (Control.Monad.Shell.Term Control.Monad.Shell.Var t) instance (GHC.Show.Show a, GHC.Num.Num a) => GHC.Num.Num (Control.Monad.Shell.Term Control.Monad.Shell.Static a) instance Control.Monad.Shell.Named Control.Monad.Shell.UntypedVar instance GHC.Base.Applicative Control.Monad.Shell.Script instance GHC.Base.Monad Control.Monad.Shell.Script instance GHC.Base.Semigroup Control.Monad.Shell.Env instance GHC.Base.Monoid Control.Monad.Shell.Env instance Control.Monad.Shell.Named Control.Monad.Shell.VarName instance Control.Monad.Shell.Named Control.Monad.Shell.Func