packages feed

shell-monad 0.6.2 → 0.6.3

raw patch · 4 files changed

+82/−14 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Control.Monad.Shell: instance Applicative Script
+ Control.Monad.Shell: newVarFrom :: (NameHinted namehint, Param param) => param -> namehint -> Script (Term Var t)
+ Control.Monad.Shell.Quote: instance [overlap ok] IsString (Quoted Text)

Files

CHANGELOG view
@@ -1,3 +1,14 @@+shell-monad (0.6.3) unstable; urgency=medium++  * Add Applicative instance for Script. (Thanks, Abhinav Gupta)+  * Add IsString instance for Quoted Text. (Thanks, Abhinav Gupta)+  * Add newVarFrom. (Thanks, Abhinav Gupta)+  * Fixed "test (foo)" to generate shell code "test ( foo )", where+    before it had generated the invalid shell code "test (foo)".+    (Thanks, Ville)++ -- Joey Hess <id@joeyh.name>  Sat, 14 Mar 2015 13:38:13 -0400+ shell-monad (0.6.2) unstable; urgency=medium    * Avoid using $_ as this doesn't work in bash.
Control/Monad/Shell.hs view
@@ -1,4 +1,7 @@ -- | This is a shell monad, for generating shell scripts.+--+-- The emphasis is on generating shell code that will work in any POSIX+-- compliant shell.  {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleInstances #-}@@ -31,6 +34,7 @@ 	NameHinted, 	static, 	newVar,+	newVarFrom, 	newVarContaining, 	setVar, 	globalVar,@@ -108,7 +112,7 @@ 	deriving (Eq, Ord, Show)  simpleVar :: forall a. VarName -> Term Var a-simpleVar name = VarTerm $ V+simpleVar name = VarTerm V 	{ varName = name 	-- Used to expand the variable; can be overridden for other 	-- types of variable expansion.@@ -119,9 +123,16 @@ 	, expandVar = \_ (VarName n) -> Q ("$" <> n) 	} --- | Treats the Text as a glob, which expands to one parameter per+-- | 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.@@ -185,6 +196,13 @@ newtype Script a = Script (Env -> ([Expr], Env, a)) 	deriving (Functor) +instance Applicative Script where+	pure a = Script $ \env -> ([], env, a)+	Script f <*> Script a = Script $ \env0 ->+		let (expr1, env1, f') = f env0+		    (expr2, env2, a') = a env1+		in  (expr1 <> expr2, env2, f' a')+ instance Monad Script where         return ret = Script $ \env -> ([], env, ret)         a >>= b = Script $ \start -> let@@ -257,7 +275,7 @@ 	go (Pipe e1 e2) = go e1 <> " | " <> go e2 	go (And e1 e2) = go e1 <> " && " <> go e2 	go (Or e1 e2) = go e1 <> " || " <> go e2-	go (Redir e r) = let use = (\t -> go e <> " " <> t) in case r of+	go (Redir e r) = let use t = go e <> " " <> t in case r of 		(RedirToFile fd f) -> 			use $ redirFd fd (Just stdOutput) <> "> " <> L.pack f 		(RedirToFileAppend fd f) ->@@ -289,7 +307,7 @@ -- Redirections have a default Fd; for example, ">" defaults to redirecting -- stdout. In this case, the file descriptor number does not need to be -- included.-redirFd :: Fd -> (Maybe Fd) -> L.Text+redirFd :: Fd -> Maybe Fd -> L.Text redirFd fd deffd 	| Just fd == deffd = "" 	| otherwise = showFd fd@@ -348,7 +366,7 @@  -- | A Param is anything that can be used as the parameter of a command. class Param a where-	toTextParam :: a -> (Env -> L.Text)+	toTextParam :: a -> Env -> L.Text  -- | Text arguments are automatically quoted. instance Param L.Text where@@ -359,7 +377,7 @@ 	toTextParam = toTextParam . L.pack  instance Param UntypedVar where-	toTextParam v = \env -> "\"" <> getQ (expandVar v env (varName v)) <> "\""+	toTextParam v env = "\"" <> getQ (expandVar v env (varName v)) <> "\""  instance Param (Term Var a) where 	toTextParam (VarTerm v) = toTextParam v@@ -378,13 +396,13 @@  -- | Allows passing the output of a command as a parameter. instance Param Output where-	toTextParam (Output s) = \env ->+	toTextParam (Output s) env = 		let t = toLinearScript $ fst $ runScript env s 		in "\"$(" <> t <> ")\""  -- | Allows passing an Arithmetic Expression as a parameter. instance Param Arith where-	toTextParam a = \env -> +	toTextParam a env = 		let t = fmtArith env a 		in "\"" <> t <> "\"" @@ -440,7 +458,7 @@ -- To provide a naming hint, use either 'NamedLike'. -- -- @--- v1 <- 'newVar' ('NamedLike' "x")+-- v1 <- 'newVar' ('NamedLike' \"x\") -- @ class NameHinted h where 	hinted :: (Maybe L.Text -> a) -> h -> a@@ -472,6 +490,35 @@ 	v <- newVarUnsafe namehint 	Script $ \env -> ([Cmd (getName v <> "=" <> value)], env, v) +-- | 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 <- newVarContaining (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)+newVarFrom param namehint = do+	v <- newVarUnsafe namehint+	Script $ \env ->+		([Cmd (getName v <> "=" <> toTextParam param env)], env, v)+ -- | Creates a new shell variable, with an initial value which can -- be anything that can be shown. --@@ -729,6 +776,12 @@ -- | 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 L.Text, Script ())] -> Script () caseOf _ [] = return () caseOf v l = go True l@@ -743,7 +796,7 @@ 	-- > : ;; *) : 	-- >     echo default 	-- > : ;; esac-	go _ [] = add $ Cmd $ ";; esac"+	go _ [] = add $ Cmd ";; esac" 	go atstart ((t, s):rest) = do 		env <- getEnv 		let leader = if atstart@@ -768,7 +821,7 @@ readVar v = add $ Cmd $ "read " <> getQ (quote (getName v))  -- | By default, shell scripts continue running past commands that exit--- nonzero. Use "stopOnFailure True" to make the script stop on the first+-- nonzero. Use 'stopOnFailure True' to make the script stop on the first -- such command. stopOnFailure :: Bool -> Script () stopOnFailure b = add $ Cmd $ "set " <> (if b then "-" else "+") <> "e"@@ -915,7 +968,7 @@ 	go (TFileNonEmpty p) = unop "-s" (pv p) 	go (TFileExecutable p) = unop "-x" (pv p) -	paren t = "\\(" <> t <> "\\)"+	paren t = "\\( " <> t <> " \\)" 	 	binop a o b = paren $ a <> " " <> o <> " " <> b 	unop o v = paren $ o <> " " <> v@@ -1073,7 +1126,7 @@ 	pred a = AMinus a (ANum 1) 	toEnum = ANum . fromIntegral 	enumFrom a = a : enumFrom (succ a)-	enumFromThen a b = a : enumFromThen b ((b `AMult` (ANum 2)) `AMinus` a)+	enumFromThen a b = a : enumFromThen b ((b `AMult` ANum 2) `AMinus` a) 	fromEnum = error "fromEnum not implemented for Arith" 	enumFromTo = error "enumFromTo not implemented for Arith" 	enumFromThenTo = error "enumFromToThen not implemented for Arith"
Control/Monad/Shell/Quote.hs view
@@ -12,6 +12,7 @@ ) where  import qualified Data.Text.Lazy as L+import Data.String import Data.Monoid import Data.Char @@ -52,3 +53,6 @@  -- | An arbitrary value. newtype Val v = Val v++instance IsString (Quoted L.Text) where+	fromString = quote
shell-monad.cabal view
@@ -1,5 +1,5 @@ Name: shell-monad-Version: 0.6.2+Version: 0.6.3 Cabal-Version: >= 1.8 License: BSD3 Maintainer: Joey Hess <id@joeyh.name>