-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Bash generation library. -- -- A library for generation of Bash scripts, handling escaping, statement -- grouping and expression formation at a high level. -- -- The top-level module, Language.Bash, is all you need to import to -- access the package's functionality. The module Language.Bash.Lib -- contains some examples, as does the test script, tests.bash, included -- with the source distribution. @package bash @version 0.1.5 -- | Pretty printer state, used within a state monad computation. module Language.Bash.PrettyPrinter.State -- | State of pretty printing -- string being built, indent levels, present -- column, brace nesting. data PPState PPState :: [Word] -> [()] -> [()] -> Word -> Bool -> Builder -> PPState indents :: PPState -> [Word] curly :: PPState -> [()] round :: PPState -> [()] columns :: PPState -> Word separated :: PPState -> Bool string :: PPState -> Builder -- | Produce a builder from a pretty printer state computation. render :: PPState -> State PPState () -> Builder renderBytes :: PPState -> State PPState () -> ByteString -- | Pretty printer state starting on a new line indented to the given -- column. nlCol :: Word -> PPState -- | Operations we can perform while pretty printing. data PPOp -- | Indent by N spaces. Indent :: Word -> PPOp -- | Remove an indentation level. Outdent :: PPOp -- | Add bytes to the script. Bytes :: ByteString -> PPOp -- | Move to newline. Newline :: PPOp -- | Separate words with space. WordSeparator :: PPOp -- | Introduce a level of braces. Curly :: Bool -> PPOp -- | Introduce a level of parens. Round :: Bool -> PPOp -- | Apply an operation to a state. op :: PPState -> PPOp -> PPState opM :: [PPOp] -> State PPState () nl :: State PPState () hang :: ByteString -> State PPState () hangWord :: ByteString -> State PPState () word :: ByteString -> State PPState () wordcat :: [ByteString] -> State PPState () outdent :: State PPState () inword :: ByteString -> State PPState () outword :: ByteString -> State PPState () curlyOpen :: State PPState () curlyClose :: State PPState () roundOpen :: State PPState () roundClose :: State PPState () -- | This procedure is used in printing statements within evals, to set up -- indentation correctly for lines following the first line. It -- ensures that the second and following lines are printed aligned with -- the first character of the first line of the statement, not the first -- character of the $(, >( or <( -- enclosing the eval. indentPadToNextWord :: State PPState () cast :: (Integral a, Num b) => a -> b renderIndents :: (Eq a, Num a, IsString c, Monoid c) => [a] -> c instance Show PPState -- | Bash statements and expressions. The statement tree is a functor, -- supporting arbitrary annotations; this is intended to support analysis -- of effects and privilege levels as well as commenting and arbitrary -- code inclusion. module Language.Bash.Syntax -- | The Annotated type captures the annotatedness of a tree of Bash -- statements. It is Foldable and a Functor. data Annotated t Annotated :: t -> Statement t -> Annotated t annotation :: Annotated t -> t statement :: Annotated t -> Statement t -- | The Statement type captures the different kind of statements -- that may exist in a Bash statement tree. It is mutually recursive with -- Annotated. It is a Foldable and a Functor. data Statement t Empty :: Statement t SimpleCommand :: (Expression t) -> [Expression t] -> Statement t NoOp :: ByteString -> Statement t Bang :: (Annotated t) -> Statement t AndAnd :: (Annotated t) -> (Annotated t) -> Statement t OrOr :: (Annotated t) -> (Annotated t) -> Statement t Pipe :: (Annotated t) -> (Annotated t) -> Statement t Sequence :: (Annotated t) -> (Annotated t) -> Statement t Background :: (Annotated t) -> (Annotated t) -> Statement t Group :: (Annotated t) -> Statement t Subshell :: (Annotated t) -> Statement t Function :: Identifier -> (Annotated t) -> Statement t IfThen :: (Annotated t) -> (Annotated t) -> Statement t IfThenElse :: (Annotated t) -> (Annotated t) -> (Annotated t) -> Statement t For :: Identifier -> [Expression t] -> (Annotated t) -> Statement t Case :: (Expression t) -> [(Expression t, Annotated t)] -> Statement t While :: (Annotated t) -> (Annotated t) -> Statement t Until :: (Annotated t) -> (Annotated t) -> Statement t VarAssign :: Identifier -> (Expression t) -> Statement t Export :: Identifier -> (Expression t) -> Statement t ArrayDecl :: Identifier -> [Expression t] -> Statement t ArrayUpdate :: Identifier -> (Expression t) -> (Expression t) -> Statement t ArrayAssign :: Identifier -> [Expression t] -> Statement t DictDecl :: Identifier -> [(Identifier, Expression t)] -> Statement t DictUpdate :: Identifier -> (Expression t) -> (Expression t) -> Statement t DictAssign :: Identifier -> [(Expression t, Expression t)] -> Statement t Redirect :: (Annotated t) -> Redirection -> FileDescriptor -> (Either (Expression t) FileDescriptor) -> Statement t -- | The type of Bash expressions, handling many kinds of variable -- reference as well as eval and process substitution. It is -- Foldable and a Functor. data Expression t Literal :: Bash -> Expression t Asterisk :: Expression t QuestionMark :: Expression t Tilde :: Expression t ReadVar :: VarName -> Expression t ReadVarSafe :: VarName -> Expression t ReadArray :: Identifier -> (Expression t) -> Expression t ReadArraySafe :: Identifier -> (Expression t) -> Expression t ARGVElements :: Expression t ARGVLength :: Expression t Elements :: Identifier -> Expression t Keys :: Identifier -> Expression t Length :: VarName -> Expression t Trim :: Trim -> VarName -> (Expression t) -> Expression t ArrayLength :: Identifier -> Expression t Concat :: (Expression t) -> (Expression t) -> Expression t Eval :: (Annotated t) -> Expression t EvalUnquoted :: (Annotated t) -> Expression t ProcessIn :: (Annotated t) -> Expression t ProcessOut :: (Annotated t) -> Expression t -- | Escape a ByteString to produce a literal expression. literal :: ByteString -> Expression t data VarName VarIdent :: Identifier -> VarName VarSpecial :: SpecialVar -> VarName varName :: ByteString -> Maybe VarName -- | The type of legal Bash identifiers, strings beginning with letters or -- _ and containing letters, _ and digits. newtype Identifier Identifier :: ByteString -> Identifier -- | Produce an Identifier from a ByteString of legal format. identifier :: ByteString -> Maybe Identifier -- | The names of special variables, with otherwise illegal identifiers, -- are represented by this type. data SpecialVar DollarQuestion :: SpecialVar DollarHyphen :: SpecialVar DollarDollar :: SpecialVar DollarBang :: SpecialVar DollarUnderscore :: SpecialVar Dollar0 :: SpecialVar Dollar1 :: SpecialVar Dollar2 :: SpecialVar Dollar3 :: SpecialVar Dollar4 :: SpecialVar Dollar5 :: SpecialVar Dollar6 :: SpecialVar Dollar7 :: SpecialVar Dollar8 :: SpecialVar Dollar9 :: SpecialVar -- | Try to render a SpecialVar from a ByteString. specialVar :: ByteString -> Maybe SpecialVar specialVarBytes :: SpecialVar -> ByteString data Trim ShortestLeading :: Trim LongestLeading :: Trim ShortestTrailing :: Trim LongestTrailing :: Trim -- | A file descriptor in Bash is simply a number between 0 and 255. newtype FileDescriptor FileDescriptor :: Word8 -> FileDescriptor -- | Redirection "directions". data Redirection -- | Input redirection, <. In :: Redirection -- | Output redirection, >. Out :: Redirection -- | Appending output, >>. Append :: Redirection -- | Unused at present. data ConditionalExpression t File_a :: (Expression t) -> ConditionalExpression t File_b :: (Expression t) -> ConditionalExpression t File_c :: (Expression t) -> ConditionalExpression t File_d :: (Expression t) -> ConditionalExpression t File_e :: (Expression t) -> ConditionalExpression t File_f :: (Expression t) -> ConditionalExpression t File_g :: (Expression t) -> ConditionalExpression t File_h :: (Expression t) -> ConditionalExpression t File_k :: (Expression t) -> ConditionalExpression t File_p :: (Expression t) -> ConditionalExpression t File_r :: (Expression t) -> ConditionalExpression t File_s :: (Expression t) -> ConditionalExpression t File_t :: (Expression t) -> ConditionalExpression t File_u :: (Expression t) -> ConditionalExpression t File_w :: (Expression t) -> ConditionalExpression t File_x :: (Expression t) -> ConditionalExpression t File_O :: (Expression t) -> ConditionalExpression t File_G :: (Expression t) -> ConditionalExpression t File_L :: (Expression t) -> ConditionalExpression t File_S :: (Expression t) -> ConditionalExpression t File_N :: (Expression t) -> ConditionalExpression t File_nt :: (Expression t) -> (Expression t) -> ConditionalExpression t File_ot :: (Expression t) -> (Expression t) -> ConditionalExpression t File_ef :: (Expression t) -> (Expression t) -> ConditionalExpression t OptSet :: (Expression t) -> ConditionalExpression t StringEmpty :: (Expression t) -> ConditionalExpression t StringNonempty :: (Expression t) -> ConditionalExpression t StringEq :: (Expression t) -> (Expression t) -> ConditionalExpression t StringNotEq :: (Expression t) -> (Expression t) -> ConditionalExpression t StringLT :: (Expression t) -> (Expression t) -> ConditionalExpression t StringGT :: (Expression t) -> (Expression t) -> ConditionalExpression t StringRE :: (Expression t) -> (Expression t) -> ConditionalExpression t NumEq :: (Expression t) -> (Expression t) -> ConditionalExpression t NumNotEq :: (Expression t) -> (Expression t) -> ConditionalExpression t NumLT :: (Expression t) -> (Expression t) -> ConditionalExpression t NumLEq :: (Expression t) -> (Expression t) -> ConditionalExpression t NumGT :: (Expression t) -> (Expression t) -> ConditionalExpression t NumGEq :: (Expression t) -> (Expression t) -> ConditionalExpression t Not :: (Expression t) -> (Expression t) -> ConditionalExpression t And :: (Expression t) -> (Expression t) -> ConditionalExpression t Or :: (Expression t) -> (Expression t) -> ConditionalExpression t instance Show t => Show (ConditionalExpression t) instance Ord t => Ord (ConditionalExpression t) instance Eq t => Eq (ConditionalExpression t) instance Show Redirection instance Ord Redirection instance Eq Redirection instance Show FileDescriptor instance Num FileDescriptor instance Ord FileDescriptor instance Eq FileDescriptor instance Show Trim instance Ord Trim instance Eq Trim instance Show SpecialVar instance Ord SpecialVar instance Eq SpecialVar instance Show Identifier instance Ord Identifier instance Eq Identifier instance Show VarName instance Ord VarName instance Eq VarName instance Show t => Show (Expression t) instance Ord t => Ord (Expression t) instance Eq t => Eq (Expression t) instance Show t => Show (Statement t) instance Ord t => Ord (Statement t) instance Eq t => Eq (Statement t) instance Show t => Show (Annotated t) instance Ord t => Ord (Annotated t) instance Eq t => Eq (Annotated t) instance IsString SpecialVar instance IsString Identifier instance IsString VarName instance Foldable Expression instance Functor Expression instance IsString (Expression t) instance Foldable Statement instance Functor Statement instance Foldable Annotated instance Functor Annotated -- | Pretty printer for Bash. module Language.Bash.PrettyPrinter bytes :: PP t => t -> ByteString builder :: PP t => t -> Builder bytes_state :: State PPState () -> ByteString class Annotation t annotate :: Annotation t => t -> Statement t -> State PPState () class PP t pp :: PP t => t -> State PPState () hangcat :: [ByteString] -> State PPState () array_pp :: (a -> StateT PPState Identity b) -> [a] -> StateT PPState Identity () keyset :: (PP t, PP t1) => (t, t1) -> State PPState () case_clause :: (PP t, PP t1) => (t, t1) -> StateT PPState Identity () render_redirect :: (PP t, PP t1, PP t2) => Redirection -> t -> Either t1 t2 -> ByteString quote :: ByteString -> ByteString braces :: ByteString -> ByteString braces0 :: ByteString -> ByteString brackets :: ByteString -> ByteString identpart :: VarName -> ByteString trimPrinter :: Trim -> ByteString binGrp :: Annotation t => Annotated t -> StateT PPState Identity () redirectGrp :: Annotation t => Annotated t -> StateT PPState Identity () breakline :: PP t => t -> State PPState () hangMultiline :: PP t => t -> StateT PPState Identity () maxLineLength :: Num c => ByteString -> c finalLineLength :: Num a => ByteString -> a inlineEvalPrinter :: PP t => ByteString -> ByteString -> t -> StateT PPState Identity () instance Annotation t => PP (Statement t) instance Annotation t => PP (Annotated t) instance Annotation t => PP (Expression t) instance PP FileDescriptor instance PP SpecialVar instance PP Identifier instance Annotation () -- | Shortcuts for Bash generation that also demonstrate use of the -- library. module Language.Bash.Lib -- | Create a simple command from expressions. cmd :: Expression t -> [Expression t] -> Statement t -- | Declare or assign an array to a sed command line that will -- use extended regular expressions, checking for GNU or BSD -- sed. The Bool argument determines whether to insert -- the declaration or not. esed :: Monoid m => Identifier -> Bool -> Annotated m -- | Perform a statement for integer values ranging from the first integral -- parameter to the second, using seq. for :: (Monoid m, Integral i) => Identifier -> i -> i -> Annotated m -> Statement m -- | Evaluate seq for the given arguments. seqAZ :: Integral i => i -> i -> Statement t -- | A set statement that covers a few error handling options, setting -- errexit, nounset and pipefail. setSafe :: Statement t -- | A statement that allows one to redirect output to a file as root. This -- is what you might expect sudo echo x > privileged_file -- would do (though that does not actually work). sudo_write :: Monoid m => Expression m -> Statement m -- | Annotate a statement with the 0 value of a monoid. ann_ :: Monoid m => Statement m -> Annotated m -- | Some convenient annotations for Bash scripts, provided with example -- pretty printer typeclass instances. module Language.Bash.Annotations -- | Append some raw lines, in flow, above and below a statement. data Lines Lines :: [ByteString] -> [ByteString] -> Lines -- | Annotate a statement with statements of different types, with special -- rules for empty NoOp statements -- as long as the -- ByteString "comment" in the NoOp is empty, the -- NoOp is simply elided. data Statements a b Statements :: (Statement a) -> (Statement b) -> Statements a b instance (Show a, Show b) => Show (Statements a b) instance (Ord a, Ord b) => Ord (Statements a b) instance (Eq a, Eq b) => Eq (Statements a b) instance Show Lines instance Ord Lines instance Eq Lines instance (PP t, PP t') => Annotation (t, t') instance (Annotation a, Annotation b) => Annotation (Statements a b) instance Annotation Lines -- | Utilities for turning statements into full scripts. module Language.Bash.Script -- | Produce a script beginning with #!/bin/bash and a safe set -- statement. script :: Annotation t => Statement t -> Builder -- | Produce a script beginning with #!/bin/bash and some -- (optional) documentation. Cause the script to be scanned for SHA-1 -- hash of the setup (first statement argument) and main (second -- statement argument) before running the safe set statement and running -- the second argument. script_sha1 :: (Annotation t, Annotation t') => ByteString -> Statement t -> Statement t' -> Builder -- | Scan $0 for the token before running, producing a statement -- annotated with the initial statement. This is a bit clumsy but is used -- internally. tokenCheck :: ByteString -> Statement t -> Statement (Statements t t') -- | Scan $0 for the token before running, correctly producing -- monoidal annotations. The function argument provides an annotation for -- the fgrep check generated to search for the token. (const -- mempty would be appropriate in most cases.) mtokenCheck :: Monoid t => ByteString -> (Statement t -> t) -> Statement t -> Statement t tokenFGREPq :: ByteString -> Statement t -- | Scan $0 the SHA1 of the statement before running. sha1Check :: (Annotation t, Annotation t') => Statement t -> Statement (Statements t t') sha1 :: ByteString -> ByteString -- | The noop dance -- annotate a NoOp with a statement, essentially -- as a type coercion. dance :: Statement t -> Annotated (Statements t t') noop :: Statement any -- | Types and functions for generation of Bash scripts, with safe escaping -- and composition of a large subset of Bash statements and expressions. -- -- This module is meant to be imported qualified -- perhaps as -- Bash -- and contains everything you need to build and render -- Bash scripts. For examples of usage, look at Language.Bash.Lib. module Language.Bash -- | The Statement type captures the different kind of statements -- that may exist in a Bash statement tree. It is mutually recursive with -- Annotated. It is a Foldable and a Functor. data Statement t Empty :: Statement t SimpleCommand :: (Expression t) -> [Expression t] -> Statement t NoOp :: ByteString -> Statement t Bang :: (Annotated t) -> Statement t AndAnd :: (Annotated t) -> (Annotated t) -> Statement t OrOr :: (Annotated t) -> (Annotated t) -> Statement t Pipe :: (Annotated t) -> (Annotated t) -> Statement t Sequence :: (Annotated t) -> (Annotated t) -> Statement t Background :: (Annotated t) -> (Annotated t) -> Statement t Group :: (Annotated t) -> Statement t Subshell :: (Annotated t) -> Statement t Function :: Identifier -> (Annotated t) -> Statement t IfThen :: (Annotated t) -> (Annotated t) -> Statement t IfThenElse :: (Annotated t) -> (Annotated t) -> (Annotated t) -> Statement t For :: Identifier -> [Expression t] -> (Annotated t) -> Statement t Case :: (Expression t) -> [(Expression t, Annotated t)] -> Statement t While :: (Annotated t) -> (Annotated t) -> Statement t Until :: (Annotated t) -> (Annotated t) -> Statement t VarAssign :: Identifier -> (Expression t) -> Statement t Export :: Identifier -> (Expression t) -> Statement t ArrayDecl :: Identifier -> [Expression t] -> Statement t ArrayUpdate :: Identifier -> (Expression t) -> (Expression t) -> Statement t ArrayAssign :: Identifier -> [Expression t] -> Statement t DictDecl :: Identifier -> [(Identifier, Expression t)] -> Statement t DictUpdate :: Identifier -> (Expression t) -> (Expression t) -> Statement t DictAssign :: Identifier -> [(Expression t, Expression t)] -> Statement t Redirect :: (Annotated t) -> Redirection -> FileDescriptor -> (Either (Expression t) FileDescriptor) -> Statement t -- | The Annotated type captures the annotatedness of a tree of Bash -- statements. It is Foldable and a Functor. data Annotated t Annotated :: t -> Statement t -> Annotated t annotation :: Annotated t -> t statement :: Annotated t -> Statement t -- | The type of Bash expressions, handling many kinds of variable -- reference as well as eval and process substitution. It is -- Foldable and a Functor. data Expression t Literal :: Bash -> Expression t Asterisk :: Expression t QuestionMark :: Expression t Tilde :: Expression t ReadVar :: VarName -> Expression t ReadVarSafe :: VarName -> Expression t ReadArray :: Identifier -> (Expression t) -> Expression t ReadArraySafe :: Identifier -> (Expression t) -> Expression t ARGVElements :: Expression t ARGVLength :: Expression t Elements :: Identifier -> Expression t Keys :: Identifier -> Expression t Length :: VarName -> Expression t Trim :: Trim -> VarName -> (Expression t) -> Expression t ArrayLength :: Identifier -> Expression t Concat :: (Expression t) -> (Expression t) -> Expression t Eval :: (Annotated t) -> Expression t EvalUnquoted :: (Annotated t) -> Expression t ProcessIn :: (Annotated t) -> Expression t ProcessOut :: (Annotated t) -> Expression t -- | Escape a ByteString to produce a literal expression. literal :: ByteString -> Expression t -- | The type of legal Bash identifiers, strings beginning with letters or -- _ and containing letters, _ and digits. data Identifier -- | Produce an Identifier from a ByteString of legal format. identifier :: ByteString -> Maybe Identifier -- | The names of special variables, with otherwise illegal identifiers, -- are represented by this type. data SpecialVar -- | Try to render a SpecialVar from a ByteString. specialVar :: ByteString -> Maybe SpecialVar data VarName VarIdent :: Identifier -> VarName VarSpecial :: SpecialVar -> VarName varName :: ByteString -> Maybe VarName -- | Redirection "directions". data Redirection -- | Input redirection, <. In :: Redirection -- | Output redirection, >. Out :: Redirection -- | Appending output, >>. Append :: Redirection -- | A file descriptor in Bash is simply a number between 0 and 255. newtype FileDescriptor FileDescriptor :: Word8 -> FileDescriptor class PP t pp :: PP t => t -> State PPState () bytes :: PP t => t -> ByteString builder :: PP t => t -> Builder -- | State of pretty printing -- string being built, indent levels, present -- column, brace nesting. data PPState -- | Produce a builder from a pretty printer state computation. render :: PPState -> State PPState () -> Builder -- | Pretty printer state starting on a new line indented to the given -- column. nlCol :: Word -> PPState -- | Produce a script beginning with #!/bin/bash and a safe set -- statement. script :: Annotation t => Statement t -> Builder -- | Produce a script beginning with #!/bin/bash and some -- (optional) documentation. Cause the script to be scanned for SHA-1 -- hash of the setup (first statement argument) and main (second -- statement argument) before running the safe set statement and running -- the second argument. script_sha1 :: (Annotation t, Annotation t') => ByteString -> Statement t -> Statement t' -> Builder