module Language.Bash.Script where
import Data.Binary.Builder (Builder, fromByteString)
import Data.ByteString.Char8 (ByteString, append)
import qualified Data.ByteString.Char8
import qualified Data.ByteString.Lazy
import Data.Foldable
import Data.Monoid
import qualified Data.Digest.Pure.SHA
import Language.Bash.Syntax
import Language.Bash.Lib
import Language.Bash.Annotations
import Language.Bash.PrettyPrinter
import Language.Bash.PrettyPrinter.State
script :: (Annotation t) => Statement t -> Builder
script statement = mconcat [ fromByteString "#!/bin/bash\n"
, builder (setSafe :: Statement ())
, fromByteString "\n\n"
, builder statement ]
script_sha1
:: forall t t'. (Annotation t, Annotation t')
=> ByteString -> Statement t -> Statement t' -> Builder
script_sha1 docs setup main = mconcat [ fromByteString "#!/bin/bash\n\n"
, remarks
, fromByteString "######## Setup."
, fromByteString "\n\n"
, fromByteString setup'
, fromByteString "\n\n"
, fromByteString "######## Main."
, fromByteString "\n\n"
, builder tokenCheck' ]
where
setup' = bytes setup
main' = bytes main
mainSafe = Sequence (dance setSafe) (dance main)
token = sha1 (append setup' main')
tokenCheck' :: Statement (Statements (Statements t' ()) ())
tokenCheck' = tokenCheck token mainSafe
remarks | docs == mempty = fromByteString ""
| otherwise = fromByteString (docs `mappend` "\n\n")
tokenCheck :: ByteString -> Statement t -> Statement (Statements t t')
tokenCheck token stmt =
IfThen (Annotated (Statements noop noop) (tokenFGREPq token))
(dance stmt)
mtokenCheck :: (Monoid t) => ByteString
-> (Statement t -> t) -> Statement t
-> Statement t
mtokenCheck token f statement = IfThen (Annotated (f check) check)
(Annotated (fold statement) statement)
where
check = tokenFGREPq token
tokenFGREPq :: ByteString -> Statement t
tokenFGREPq token
= SimpleCommand "fgrep" ["-q", literal token, ReadVar (VarSpecial Dollar0)]
sha1Check :: (Annotation t, Annotation t')
=> Statement t -> Statement (Statements t t')
sha1Check stmt = tokenCheck ((sha1 . bytes) stmt) stmt
sha1 :: ByteString -> ByteString
sha1 = Data.ByteString.Char8.pack
. Data.Digest.Pure.SHA.showDigest
. Data.Digest.Pure.SHA.sha1
. Data.ByteString.Lazy.fromChunks
. (:[])
dance :: Statement t -> Annotated (Statements t t')
dance stmt = Annotated (Statements stmt noop) noop
noop :: Statement any
noop = NoOp ""