packages feed

bash 0.0.0 → 0.1.1

raw patch · 6 files changed

+175/−77 lines, 6 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Language.Bash: Keys :: Identifier -> Expression t
+ Language.Bash: Tilde :: Expression t
+ Language.Bash: Trim :: Trim -> VarName -> (Expression t) -> Expression t
+ Language.Bash.Lib: sudo_write :: Monoid m => Expression m -> Statement m
+ Language.Bash.PrettyPrinter: trimPrinter :: Trim -> ByteString
+ Language.Bash.Syntax: DollarBang :: SpecialVar
+ Language.Bash.Syntax: DollarDollar :: SpecialVar
+ Language.Bash.Syntax: DollarHyphen :: SpecialVar
+ Language.Bash.Syntax: DollarUnderscore :: SpecialVar
+ Language.Bash.Syntax: Keys :: Identifier -> Expression t
+ Language.Bash.Syntax: LongestLeading :: Trim
+ Language.Bash.Syntax: LongestTrailing :: Trim
+ Language.Bash.Syntax: ShortestLeading :: Trim
+ Language.Bash.Syntax: ShortestTrailing :: Trim
+ Language.Bash.Syntax: Tilde :: Expression t
+ Language.Bash.Syntax: Trim :: Trim -> VarName -> (Expression t) -> Expression t
+ Language.Bash.Syntax: VarIdent :: Identifier -> VarName
+ Language.Bash.Syntax: VarSpecial :: SpecialVar -> VarName
+ Language.Bash.Syntax: data Trim
+ Language.Bash.Syntax: data VarName
+ Language.Bash.Syntax: instance Eq Trim
+ Language.Bash.Syntax: instance Eq VarName
+ Language.Bash.Syntax: instance IsString VarName
+ Language.Bash.Syntax: instance Ord Trim
+ Language.Bash.Syntax: instance Ord VarName
+ Language.Bash.Syntax: instance Show Trim
+ Language.Bash.Syntax: instance Show VarName
+ Language.Bash.Syntax: varName :: ByteString -> Maybe VarName
- Language.Bash: Length :: (Either SpecialVar Identifier) -> Expression t
+ Language.Bash: Length :: VarName -> Expression t
- Language.Bash: ReadVar :: (Either SpecialVar Identifier) -> Expression t
+ Language.Bash: ReadVar :: VarName -> Expression t
- Language.Bash: ReadVarSafe :: (Either SpecialVar Identifier) -> Expression t
+ Language.Bash: ReadVarSafe :: VarName -> Expression t
- Language.Bash.Syntax: Length :: (Either SpecialVar Identifier) -> Expression t
+ Language.Bash.Syntax: Length :: VarName -> Expression t
- Language.Bash.Syntax: ReadVar :: (Either SpecialVar Identifier) -> Expression t
+ Language.Bash.Syntax: ReadVar :: VarName -> Expression t
- Language.Bash.Syntax: ReadVarSafe :: (Either SpecialVar Identifier) -> Expression t
+ Language.Bash.Syntax: ReadVarSafe :: VarName -> Expression t

Files

Language/Bash/Lib.hs view
@@ -61,6 +61,16 @@                                                     , "-o", "pipefail" ]  +{-| 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+sudo_write path              =  Redirect (ann_ tee) Out 1 (Left "/dev/null")+ where+  tee                        =  SimpleCommand "sudo" ["tee", path]++ {-| Annotate a statement with the 0 value of a monoid.  -} ann_                        ::  (Monoid m) => Statement m -> Annotated m
Language/Bash/PrettyPrinter.hs view
@@ -11,9 +11,9 @@ module Language.Bash.PrettyPrinter where  import qualified Data.List as List-import Data.Word (Word8) import Data.ByteString.Char8 import Data.Binary.Builder (Builder)+import Data.Monoid import Prelude hiding (concat, length, replicate, lines, drop, null) import Control.Monad.State.Strict @@ -49,11 +49,14 @@   pp (Literal lit)           =  word (Esc.bytes lit)   pp Asterisk                =  word "*"   pp QuestionMark            =  word "?"-  pp (ReadVar var)           =  (word . quote . ('$' `cons`) . identpart) var+  pp Tilde                   =  word "~"+  pp (ReadVar var) = (word . quote) (if s == "$!" then "${!}" else s)+   where -- Need to be careful to avoid history expansion of @"@.+    s                        =  (('$' `cons`) . identpart) var   pp (ReadVarSafe var)       =  (word . quote . braces0 . identpart) var-  pp (ReadArray ident expr)  =  (word . braces)+  pp (ReadArray ident expr)  =  (word . quote . braces)                                 (bytes ident `append` brackets (bytes expr))-  pp (ReadArraySafe ident expr) = (word . braces0)+  pp (ReadArraySafe ident expr) = (word . quote . braces0)                                   (bytes ident `append` brackets (bytes expr))   -- Examples that all work for nasty arguments containing brackets:   --   echo "${array[$1]}"@@ -64,8 +67,12 @@   pp (ARGVLength)            =  word "$#"   pp (Elements ident)        =  (word . quote . braces)                                 (bytes ident `append` "[@]")+  pp (Keys ident)            =  (word . quote . braces)+                                ('!' `cons` bytes ident `append` "[@]")   pp (Length ident)          =  (word . quote . braces)                                 ('#' `cons` identpart ident)+  pp (Trim trim var expr)    =  (word . quote . braces . mconcat)+                                [identpart var, trimPrinter trim, bytes expr]   pp (ArrayLength ident)     =  (word . quote . braces)                                 ('#' `cons` bytes ident `append` "[@]")   pp (Concat expr0 expr1)    =  wordcat [bytes expr0, bytes expr1]@@ -111,7 +118,7 @@     Until t t'              ->  do hang "until" >> pp t >> outdent >> nl                                    inword "do" >> pp t' >> outword "done" --  BraceBrace _            ->  error "[[ ]]"-    VarAssign var val       ->  pp var >> word "=" >> pp val+    VarAssign var val       ->  wordcat [bytes var, "=", bytes val]     ArrayDecl var exprs     ->  do hangcat ["declare -a ", bytes var, "=("]                                    array_pp pp exprs >> word ")"                                    nl >> outdent@@ -122,8 +129,8 @@     DictDecl var pairs      ->  do hangcat ["declare -A ", bytes var, "=("]                                    array_pp keyset pairs >> word ")"                                    nl >> outdent-    DictUpdate var key val  ->  do hangcat [bytes var, "[", bytes key, "]="]-                                   pp val >> outdent+    DictUpdate var key val  ->  wordcat+                                [bytes var, "[", bytes key, "]=", bytes val]     DictAssign var pairs    ->  do hangcat [bytes var, "=("]                                    array_pp keyset pairs                                    nl >> outdent >> word ")"@@ -132,12 +139,12 @@  hangcat                      =  hang . concat -array_pp ppF [   ]           =  return ()+array_pp _   [   ]           =  return () array_pp ppF (h:t)           =  ppF h >> mapM_ ppFNL t  where   ppFNL x                    =  nl >> ppF x -keyset (key, val) = word "[" >> pp key >> word "]=" >> pp val+keyset (key, val)            =  wordcat ["[", bytes key, "]=", bytes val]  case_clause (ptrn, stmt)     =  do hang (bytes ptrn `append` ") ")                                    pp stmt >> word ";;" >> outdent >> nl@@ -157,9 +164,15 @@  brackets b                   =  '[' `cons` b `snoc` ']' -identpart (Left special)     =  (drop 1 . bytes) special-identpart (Right ident)      =  bytes ident+identpart (VarSpecial special) = (drop 1 . bytes) special+identpart (VarIdent ident)   =  bytes ident +trimPrinter                 ::  Trim -> ByteString+trimPrinter ShortestLeading  =  "#"+trimPrinter LongestLeading   =  "##"+trimPrinter ShortestTrailing = "%"+trimPrinter LongestTrailing  =  "%%"+ binGrp a@(Annotated _ stmt)  =  case stmt of   Bang _                    ->  curlyOpen >> pp a >> curlyClose   AndAnd _ _                ->  curlyOpen >> pp a >> curlyClose@@ -200,5 +213,4 @@   pp ann   word close   outdent >> outdent- 
Language/Bash/Script.hs view
@@ -81,7 +81,7 @@  tokenFGREPq                 ::  ByteString -> Statement t tokenFGREPq token-  = SimpleCommand "fgrep" ["-q", literal token, ReadVar (Left Dollar0)]+  = SimpleCommand "fgrep" ["-q", literal token, ReadVar (VarSpecial Dollar0)]  {-| Scan @$0@ the SHA1 of the statement before running.  -}
Language/Bash/Syntax.hs view
@@ -12,7 +12,9 @@ module Language.Bash.Syntax where  import Prelude hiding (all)+import Control.Applicative import Control.Arrow ((***))+import Control.Monad import Data.Char import Data.String import Data.Maybe@@ -144,14 +146,17 @@ data Expression t            =  Literal Esc.Bash                              |  Asterisk                              |  QuestionMark-                             |  ReadVar (Either SpecialVar Identifier)-                             |  ReadVarSafe (Either SpecialVar Identifier)+                             |  Tilde+                             |  ReadVar VarName+                             |  ReadVarSafe VarName                              |  ReadArray Identifier (Expression t)                              |  ReadArraySafe Identifier (Expression t)                              |  ARGVElements                              |  ARGVLength                              |  Elements Identifier-                             |  Length (Either SpecialVar Identifier)+                             |  Keys Identifier+                             |  Length VarName+                             |  Trim Trim VarName (Expression t)                              |  ArrayLength Identifier                              |  Concat (Expression t) (Expression t)                              |  Eval (Annotated t)@@ -170,6 +175,7 @@     Literal esc             ->  Literal esc     Asterisk                ->  Asterisk     QuestionMark            ->  QuestionMark+    Tilde                   ->  Tilde     ReadVar v               ->  ReadVar v     ReadVarSafe v           ->  ReadVarSafe v     ReadArray ident expr    ->  ReadArray ident (fmap f expr)@@ -177,7 +183,9 @@     ARGVElements            ->  ARGVElements     ARGVLength              ->  ARGVLength     Elements ident          ->  Elements ident+    Keys ident              ->  Keys ident     Length ident            ->  Length ident+    Trim trim v expr        ->  Trim trim v (fmap f expr)     ArrayLength ident       ->  ArrayLength ident     Concat expr expr'       ->  Concat (fmap f expr) (fmap f expr')     Eval ann                ->  Eval (fmap f ann)@@ -189,6 +197,7 @@     Literal _               ->  mempty     Asterisk                ->  mempty     QuestionMark            ->  mempty+    Tilde                   ->  mempty     ReadVar _               ->  mempty     ReadVarSafe _           ->  mempty     ReadArray _ expr        ->  foldMap f expr@@ -196,7 +205,9 @@     ARGVElements            ->  mempty     ARGVLength              ->  mempty     Elements _              ->  mempty+    Keys _                  ->  mempty     Length _                ->  mempty+    Trim _ _ expr           ->  foldMap f expr     ArrayLength _           ->  mempty     Concat expr expr'       ->  foldMap f expr `mappend` foldMap f expr'     Eval ann                ->  foldMap f ann@@ -209,6 +220,17 @@ literal                     ::  ByteString -> Expression t literal                      =  Literal . Esc.bash +data VarName                 =  VarIdent Identifier | VarSpecial SpecialVar+deriving instance Eq VarName+deriving instance Ord VarName+deriving instance Show VarName+instance IsString VarName where+  fromString                 =  fromJust . varName . fromString++varName                     ::  ByteString -> Maybe VarName+varName bytes                =  (VarSpecial <$> specialVar bytes) `mplus`+                                (VarIdent <$> identifier bytes)+ {-| The type of legal Bash identifiers, strings beginning with letters or @_@     and containing letters, @_@ and digits.  -}@@ -231,6 +253,64 @@   okayTail c                 =  (isAlphaNum c || c == '_') && isAscii c   okayHead c                 =  (isAlpha c || c == '_') && isAscii c +{-| The names of special variables, with otherwise illegal identifiers, are+    represented by this type.+ -}+data SpecialVar+  = DollarQuestion | DollarHyphen      | DollarDollar+                   | DollarBang        | DollarUnderscore+                   | Dollar0 | Dollar1 | Dollar2 | Dollar3 | Dollar4+                   | Dollar5 | Dollar6 | Dollar7 | Dollar8 | Dollar9+deriving instance Eq SpecialVar+deriving instance Ord SpecialVar+deriving instance Show SpecialVar+instance IsString SpecialVar where+  fromString                 =  fromJust . specialVar . fromString++{-| Try to render a 'SpecialVar' from a 'ByteString'.+ -}+specialVar                  ::  ByteString -> Maybe SpecialVar+specialVar b | "$?" == b     =  Just DollarQuestion+             | "$-" == b     =  Just DollarHyphen+             | "$$" == b     =  Just DollarDollar+             | "$!" == b     =  Just DollarBang+             | "$_" == b     =  Just DollarUnderscore+             | "$0" == b     =  Just Dollar0+             | "$1" == b     =  Just Dollar1+             | "$2" == b     =  Just Dollar2+             | "$3" == b     =  Just Dollar3+             | "$4" == b     =  Just Dollar4+             | "$5" == b     =  Just Dollar5+             | "$6" == b     =  Just Dollar6+             | "$7" == b     =  Just Dollar7+             | "$8" == b     =  Just Dollar8+             | "$9" == b     =  Just Dollar9+             | otherwise     =  Nothing++specialVarBytes             ::  SpecialVar -> ByteString+specialVarBytes DollarQuestion = "$?"+specialVarBytes DollarHyphen =  "$-"+specialVarBytes DollarDollar =  "$$"+specialVarBytes DollarBang   =  "$!"+specialVarBytes DollarUnderscore = "$_"+specialVarBytes Dollar0      =  "$0"+specialVarBytes Dollar1      =  "$1"+specialVarBytes Dollar2      =  "$2"+specialVarBytes Dollar3      =  "$3"+specialVarBytes Dollar4      =  "$4"+specialVarBytes Dollar5      =  "$5"+specialVarBytes Dollar6      =  "$6"+specialVarBytes Dollar7      =  "$7"+specialVarBytes Dollar8      =  "$8"+specialVarBytes Dollar9      =  "$9"+++data Trim                    =  ShortestLeading  | LongestLeading+                             |  ShortestTrailing | LongestTrailing+deriving instance Eq Trim+deriving instance Ord Trim+deriving instance Show Trim+ {-| A file descriptor in Bash is simply a number between 0 and 255.  -} newtype FileDescriptor       =  FileDescriptor Word8@@ -296,44 +376,4 @@ deriving instance (Ord t) => Ord (ConditionalExpression t) deriving instance (Show t) => Show (ConditionalExpression t) -{-| The names of special variables, with otherwise illegal identifiers, are-    represented by this type.- -}-data SpecialVar-  = DollarQuestion | Dollar0 | Dollar1 | Dollar2 | Dollar3 | Dollar4-                   | Dollar5 | Dollar6 | Dollar7 | Dollar8 | Dollar9-deriving instance Eq SpecialVar-deriving instance Ord SpecialVar-deriving instance Show SpecialVar-instance IsString SpecialVar where-  fromString                 =  fromJust . specialVar . fromString--{-| Try to render a 'SpecialVar' from a 'ByteString'.- -}-specialVar                  ::  ByteString -> Maybe SpecialVar-specialVar b | "$?" == b     =  Just DollarQuestion-             | "$0" == b     =  Just Dollar0-             | "$1" == b     =  Just Dollar1-             | "$2" == b     =  Just Dollar2-             | "$3" == b     =  Just Dollar3-             | "$4" == b     =  Just Dollar4-             | "$5" == b     =  Just Dollar5-             | "$6" == b     =  Just Dollar6-             | "$7" == b     =  Just Dollar7-             | "$8" == b     =  Just Dollar8-             | "$9" == b     =  Just Dollar9-             | otherwise     =  Nothing--specialVarBytes             ::  SpecialVar -> ByteString-specialVarBytes DollarQuestion = "$?"-specialVarBytes Dollar0      =  "$0"-specialVarBytes Dollar1      =  "$1"-specialVarBytes Dollar2      =  "$2"-specialVarBytes Dollar3      =  "$3"-specialVarBytes Dollar4      =  "$4"-specialVarBytes Dollar5      =  "$5"-specialVarBytes Dollar6      =  "$6"-specialVarBytes Dollar7      =  "$7"-specialVarBytes Dollar8      =  "$8"-specialVarBytes Dollar9      =  "$9" 
bash.cabal view
@@ -1,5 +1,5 @@ name                          : bash-version                       : 0.0.0+version                       : 0.1.1 category                      : Language license                       : BSD3 license-file                  : LICENSE
tests.bash view
@@ -56,17 +56,21 @@  #> let ls = Annotated () . SimpleCommand "ls" . (:[]) #> let echo = Annotated () . SimpleCommand "echo"+#> let vRANDOM = VarIdent "RANDOM"+#> let randomLT_ n = SimpleCommand "[" [ReadVar vRANDOM), "-lt", n, "]"]+#> let randomLT n = Annotated () (randomLT_ n) #> let commented a b = Annotated (Lines a b) -#> let ifStmt = Annotated () (IfThenElse (ls ".") (ls ".") (ls "/"))+#> let ifAnn a b c = Annotated () (IfThenElse a b c)+#> let ifStmt = ifAnn (randomLT "40000") (randomLT "10000") (randomLT "45000") #> let whileStmt = Annotated () (While ifStmt (echo ["ok"])) #> let redirectStmt = Annotated () (Redirect whileStmt Append 1 (Left "fo&o")) #> render redirectStmt-while if ls .+while if $'[' "$RANDOM" -lt 40000 $']'       then-        ls .+        $'[' "$RANDOM" -lt 10000 $']'       else-        ls /+        $'[' "$RANDOM" -lt 45000 $']'       fi do   echo ok@@ -79,7 +83,7 @@   echo dudes. ;} 1>msg  #> let (varX :: Identifier) = "x"-#> let readX = ReadVarSafe (Right varX)+#> let readX = ReadVarSafe (VarIdent varX) #> let lsX = Annotated () (SimpleCommand "ls" [readX]) #> let lsMsg = Annotated () (SimpleCommand "echo" ["Failed to `ls':", readX]) #> let lsErr = Annotated () (Redirect lsMsg Out 1 (Right 2))@@ -100,11 +104,11 @@ #> let wfStmt = Annotated () lsWWW `AndAnd` forStmt #> render wfStmt { cd /var/www-  while if ls .+  while if $'[' "$RANDOM" -lt 40000 $']'         then-          ls .+          $'[' "$RANDOM" -lt 10000 $']'         else-          ls /+          $'[' "$RANDOM" -lt 45000 $']'         fi   do     echo ok@@ -117,11 +121,11 @@  #> let redirected = Annotated () $ Redirect whileStmt Out 2 (Left "/err") #> render $ OrOr redirected forStmt-while if ls .+while if $'[' "$RANDOM" -lt 40000 $']'       then-        ls .+        $'[' "$RANDOM" -lt 10000 $']'       else-        ls /+        $'[' "$RANDOM" -lt 45000 $']'       fi do   echo ok@@ -141,7 +145,7 @@ #> let clause1 = clause "second" #> let clause_ = (Asterisk, echoRem ["?"]) #> let clauses = [clause0, clause1, clause_]-#> let caseStmt = noRem $ Case (ReadVarSafe (Left Dollar1)) clauses+#> let caseStmt = noRem $ Case (ReadVarSafe (VarSpecial Dollar1)) clauses #> render caseStmt case "${1:-}" in   first)  # Remark.@@ -199,15 +203,15 @@          )" "$( # Comment.                 while # Comment.                       if # Comment.-                         ls .+                         $'[' "$RANDOM" -lt 40000 $']'                          # Comment.                       then                         # Comment.-                        ls .+                        $'[' "$RANDOM" -lt 10000 $']'                         # Comment.                       else                         # Comment.-                        ls /+                        $'[' "$RANDOM" -lt 45000 $']'                         # Comment.                       fi                       # Comment.@@ -220,15 +224,15 @@                 )" mid <( # Comment.                           while # Comment.                                 if # Comment.-                                   ls .+                                   $'[' "$RANDOM" -lt 40000 $']'                                    # Comment.                                 then                                   # Comment.-                                  ls .+                                  $'[' "$RANDOM" -lt 10000 $']'                                   # Comment.                                 else                                   # Comment.-                                  ls /+                                  $'[' "$RANDOM" -lt 45000 $']'                                   # Comment.                                 fi                                 # Comment.@@ -242,8 +246,8 @@ #-echo  #> let (varX :: Identifier) = "x"-#> let readX = ReadVar (Right varX)-#> let lengthX = Length (Right varX)+#> let readX = ReadVar (VarIdent varX)+#> let lengthX = Length (VarIdent varX) #> let echoX = Annotated () (SimpleCommand "echo" [readX, "----", lengthX]) #> let seq4 = Annotated () (SimpleCommand "seq" ["1","4"]) #> let forSeq = For varX [Eval seq4, EvalUnquoted seq4] echoX@@ -252,4 +256,36 @@ do   echo "$x" ---- "${#x}" done++#> let lsRoot = ls (Concat Tilde "root")+#> render lsRoot+ls ~root++#> let (patterns :: Identifier) = "patterns"+#> let (string :: Identifier) = "string"+#> let identSTRING = VarIdent string+#> let readSTRING = ReadVar identSTRING+#> let readPATTERN0 = ReadArray patterns (literal "leading")+#> let readPATTERN1 = ReadArray patterns (literal "trailing")+#> let setSTRING = Annotated () (VarAssign string "ab/cd/ef")+#> let setPATTERNS = Annotated () (DictDecl patterns [("leading", "ab")])+#> let setPATTERN1 = Annotated () (DictUpdate patterns "trailing" "ef")+#> let trimLFixed = Trim ShortestLeading identSTRING readPATTERN0+#> let trimTFixed = Trim ShortestTrailing identSTRING readPATTERN1+#> let glob0 :: Expression () = Concat Asterisk "/"+#> let glob1 :: Expression () = Concat "/" Asterisk+#> let trimSL = Trim ShortestLeading identSTRING glob0+#> let trimLL = Trim LongestLeading identSTRING glob0+#> let trimST = Trim ShortestTrailing identSTRING glob1+#> let trimLT = Trim LongestTrailing identSTRING glob1+#> let trims = [trimLFixed, trimTFixed, trimSL, trimLL, trimST, trimLT]+#> let sequence a b = Annotated () (Sequence a b)+#> let set_ = setSTRING `sequence` setPATTERNS `sequence` setPATTERN1+#> let echoSubs = Annotated () (SimpleCommand "echo" trims)+#> render (set_ `sequence` echoSubs)+string=ab/cd/ef+declare -A patterns=( [leading]=ab )+patterns[trailing]=ef+echo "${string#"${patterns[leading]}"}" "${string%"${patterns[trailing]}"}" \+     "${string#*/}" "${string##*/}" "${string%/*}" "${string%%/*}"