shell-monad 0.0.3 → 0.1.0
raw patch · 4 files changed
+82/−11 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Control.Monad.Shell: Val :: v -> Val v
+ Control.Monad.Shell: instance CmdArg String
+ Control.Monad.Shell: instance Show v => CmdArg (Val v)
+ Control.Monad.Shell: newtype Val v
+ Control.Monad.Shell: positionalParameters :: Var
+ Control.Monad.Shell: takeParameter :: Script Var
- Control.Monad.Shell: cmd :: ShellCmd result => Text -> result
+ Control.Monad.Shell: cmd :: ShellCmd params => Text -> params
- Control.Monad.Shell: func :: Script () -> Script (Script ())
+ Control.Monad.Shell: func :: ShellCmd callfunc => Script () -> Script callfunc
Files
- CHANGELOG +8/−0
- Control/Monad/Shell.hs +63/−5
- examples/santa.hs +10/−5
- shell-monad.cabal +1/−1
CHANGELOG view
@@ -1,3 +1,11 @@+shell-monad (0.1.0) UNRELEASED; urgency=medium++ * Added positionalParameters and takeParameter.+ * Shell functions can be called with parameters.+ * String is now an instance of CmdArg++ -- Joey Hess <id@joeyh.name> Thu, 25 Dec 2014 12:17:23 -0400+ shell-monad (0.0.3) unstable; urgency=medium * Added Output data type, which alows cmd to accept (Output (Script ()))
Control/Monad/Shell.hs view
@@ -18,10 +18,13 @@ cmd, CmdArg, Output(..),+ Val(..), comment, newVar, newVarContaining, globalVar,+ positionalParameters,+ takeParameter, func, (-|-), forCmd,@@ -180,7 +183,7 @@ -- > name <- newVar "name" -- > readVar name -- > cmd "echo" "hello" name-cmd :: (ShellCmd result) => L.Text -> result+cmd :: (ShellCmd params) => L.Text -> params cmd c = cmdAll c [] class CmdArg a where@@ -190,6 +193,15 @@ instance CmdArg L.Text where toTextArg = getQ . quote +-- | String arguments are automatically quoted.+instance CmdArg String where+ toTextArg = toTextArg . L.pack++-- | Any value that can be shown can be passed to 'cmd'; just wrap it+-- inside a Val.+instance (Show v) => CmdArg (Val v) where+ toTextArg (Val v) = L.pack (show v)+ -- | Var arguments cause the (quoted) value of a shell variable to be -- passed to the command. instance CmdArg Var where@@ -199,6 +211,7 @@ instance CmdArg (Quoted L.Text) where toTextArg (Q v) = v +-- | Allows passing the output of a command as a parameter. instance CmdArg Output where toTextArg (Output s) = "\"$(" <> linearScript s <> ")\"" @@ -220,6 +233,9 @@ -- > cmd "echo" "root's pwent" (Output (cmd "cat" "/etc/passwd" -|- cmd "grep" "root")) newtype Output = Output (Script ()) +-- | An arbitrary value.+newtype Val v = Val v+ -- | Adds an Expr to the script. add :: Expr -> Script () add expr = Script $ \env -> ([expr], env, ())@@ -259,11 +275,54 @@ globalVar :: L.Text -> Script Var globalVar name = Script $ \env -> let v = Var name in ([], modifyEnvVars env (S.insert v), v) +-- | 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 :: Var+positionalParameters = Var "@"++-- | 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, an error will be thrown at+-- runtime.+--+-- For example:+--+-- > removefirstfile = script $ do+-- > cmd "rm" =<< takeParameter+-- > cmd "echo" "remaining parameters:" positionalParameters+takeParameter :: Script Var+takeParameter = do+ p@(Var name) <- newVar "param"+ Script $ \env -> ([Cmd (name <> "=\"$1\""), Cmd "shift"], env, p)+ -- | Defines a shell function, and returns an action that can be run to -- call the function. ----- TODO parameter passing to the function-func :: Script () -> Script (Script ())+-- The action is variadic; it can be passed any number of CmdArgs.+-- Typically, it will make sense to specify a more concrete type+-- when defining the shell function.+--+-- For example:+--+-- > demo = script $ do+-- > hohoho <- mkHohoho+-- > hohoho (Val 1)+-- > echo "And I heard him exclaim, ere he rode out of sight ..."+-- > hohoho (Val 3)+-- > +-- > mkHohoho :: Script (Val Int -> Script ())+-- > mkHohoho = func $ do+-- > num <- takeParameter+-- > forCmd (cmd "seq" "1" num) $ \_n ->+-- > cmd "echo" "Ho, ho, ho!" "Merry xmas!"+func :: ShellCmd callfunc => Script () -> Script callfunc func s = Script $ \env -> let f = go env (0 :: Integer) env' = modifyEnvFuncs env (S.insert f)@@ -279,8 +338,7 @@ definefunc (Func f) ls = (Cmd $ f <> " () { :") : map indent ls ++ [ Cmd "}" ] - callfunc :: Func -> Script ()- callfunc (Func f) = add $ Cmd f+ callfunc (Func f) = cmd f -- | Pipes together two Scripts. (-|-) :: Script () -> Script () -> Script ()
examples/santa.hs view
@@ -8,18 +8,23 @@ main :: IO () main = T.writeFile "santa.sh" $ script $ do- hohoho <- func $- cmd "echo" "Ho, ho, ho!" "Merry xmas!"- hohoho+ hohoho <- mkHohoho+ hohoho (Val 1) promptFor "What's your name?" $ \name -> pipeLess $ do cmd "echo" "Let's see what's in" (val name <> quote "'s") "stocking!" forCmd (cmd "ls" "-1" (quote "/home/" <> val name)) $ \f -> do cmd "echo" "a shiny new" f- hohoho+ hohoho (Val 1) cmd "rm" "/table/cookies" "/table/milk"- hohoho+ hohoho (Val 3)++mkHohoho :: Script (Val Int -> Script ())+mkHohoho = func $ do+ num <- takeParameter+ forCmd (cmd "seq" "1" num) $ \_n ->+ cmd "echo" "Ho, ho, ho!" "Merry xmas!" pipeLess :: Script () -> Script () pipeLess c = c -|- cmd "less"
shell-monad.cabal view
@@ -1,5 +1,5 @@ Name: shell-monad-Version: 0.0.3+Version: 0.1.0 Cabal-Version: >= 1.8 License: BSD3 Maintainer: Joey Hess <id@joeyh.name>