packages feed

bash-0.1.1: tests.bash

#!/bin/bash
# This script is literate Bashkell. Lines beginning with #> are passed to
# GHCi during the test.
## Sketching quine-style test script.
## let set = SimpleCommand "set"
## let set' = set ["-o", "nounset", "-o", "errexit", "-o", "pipefail"]
set -o nounset -o errexit -o pipefail

declare -a esed=()
if sed --version | fgrep -q GNU &>/dev/null
then
  esed=(sed -r)
else
  esed=(sed -E)
fi

function body          {
  "${esed[@]}" '1,/^exit 0$/ d'
}

function ghci_commands {
  "${esed[@]}" -n '/^#> (.+)$/ { s//\1/ ; p ;} ; /^$/ { p ;}'
}

function results_filter {
  "${esed[@]}" -n '/^########!/,/^########-/ {
                     /^########[!-]/ { s/^.+$// ;}
                     p
                   }' "$@"
}

case "${1:-}" in
  commands)     cat "$0" | body | ghci_commands ;;
  ''|tests)     cat "$0" | body ;;
  filter)       results_filter "$@" ;;
  ghci)         cat "$0" | body | ghci_commands | ghci ;;
  test)         "$0" ghci 2>/dev/null | results_filter ;;
  *)            echo "Arugment error." 1>&2 ;;
esac

exit 0

#> :set prompt "#>\n"
#> :set -XOverloadedStrings
#> :set -XNoMonomorphismRestriction
#> :set -XScopedTypeVariables
#> :load ./Language/Bash.hs
#> let start = "\n########!\n"
#> let end = "\n########-\n"
#> let concatB = Data.ByteString.Char8.concat
#> let bookend b = Data.ByteString.Char8.putStr (concatB [start, b, end])
#> let render = bookend . bytes
#> let unlazy = concatB . Data.ByteString.Lazy.toChunks
#> let unbuilder = unlazy . Data.Binary.Builder.toLazyByteString
#> let buildrender = bookend . unbuilder

#> 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 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 $'[' "$RANDOM" -lt 40000 $']'
      then
        $'[' "$RANDOM" -lt 10000 $']'
      else
        $'[' "$RANDOM" -lt 45000 $']'
      fi
do
  echo ok
done 1>>$'fo&o'

#> let sqnc = Annotated () (Sequence (echo ["-n","hello "]) (echo ["dudes."]))
#> let redirectStmt = Annotated () (Redirect sqnc Out 1 (Left "msg"))
#> render redirectStmt
{ echo -n $'hello '
  echo dudes. ;} 1>msg

#> let (varX :: Identifier) = "x"
#> 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))
#> let lsOr = Annotated () (lsX `OrOr` lsErr)
#> let apacheLogs = "/var/log/apache2/" `Concat` Concat Asterisk ".log"
#> let for = For varX [apacheLogs, "/var/log/httpd"] lsOr
#> let forStmt = Annotated () for
#> render forStmt
for x in /var/log/apache2/*.log /var/log/httpd
do
  ls "${x:-}" ||
  { echo $'Failed to `ls\':' "${x:-}" 1>&2 ;}
done

#> let cdApache = Annotated () $ SimpleCommand "cd" ["/var/www"]
#> let cdWhile = Annotated () (Sequence cdApache whileStmt)
#> let lsWWW = Redirect cdWhile Append 2 (Left "/err")
#> let wfStmt = Annotated () lsWWW `AndAnd` forStmt
#> render wfStmt
{ cd /var/www
  while if $'[' "$RANDOM" -lt 40000 $']'
        then
          $'[' "$RANDOM" -lt 10000 $']'
        else
          $'[' "$RANDOM" -lt 45000 $']'
        fi
  do
    echo ok
  done ;} 2>>/err &&
for x in /var/log/apache2/*.log /var/log/httpd
do
  ls "${x:-}" ||
  echo $'Failed to `ls\':' "${x:-}" 1>&2
done

#> let redirected = Annotated () $ Redirect whileStmt Out 2 (Left "/err")
#> render $ OrOr redirected forStmt
while if $'[' "$RANDOM" -lt 40000 $']'
      then
        $'[' "$RANDOM" -lt 10000 $']'
      else
        $'[' "$RANDOM" -lt 45000 $']'
      fi
do
  echo ok
done 2>/err ||
for x in /var/log/apache2/*.log /var/log/httpd
do
  ls "${x:-}" ||
  echo $'Failed to `ls\':' "${x:-}" 1>&2
done

#> let rem = Annotated (Lines ["# Remark."] [])
#> let noRem = Annotated (Lines [] [])
#> let echoRem = Annotated (Lines ["#+echo"] ["#-echo"]) . SimpleCommand "echo"
#> let echoCase = echoRem ["-n", "case: "]
#> let clause ex = (ex, rem (Sequence echoCase (echoRem [ex])))
#> let clause0 = clause "first"
#> let clause1 = clause "second"
#> let clause_ = (Asterisk, echoRem ["?"])
#> let clauses = [clause0, clause1, clause_]
#> let caseStmt = noRem $ Case (ReadVarSafe (VarSpecial Dollar1)) clauses
#> render caseStmt
case "${1:-}" in
  first)  # Remark.
          #+echo
          echo -n $'case: '
          #-echo
          #+echo
          echo first
          #-echo
          ;;
  second)  # Remark.
           #+echo
           echo -n $'case: '
           #-echo
           #+echo
           echo second
           #-echo
           ;;
  *)  #+echo
      echo $'?'
      #-echo
      ;;
esac

#> let a = SimpleCommand "echo" ["a"] :: Statement ()
#> let b = SimpleCommand "echo" ["b"] :: Statement ()
#> let pre = script_sha1 "# Silly script." a b
#> buildrender pre
#!/bin/bash

# Silly script.

######## Setup.

echo a

######## Main.

if fgrep -q f4b85e070cfe2c7990b5fa6b0603182921430d56 "$0"
then
  set -o errexit -o nounset -o pipefail
  echo b
fi

#> let remWhile = fmap (const (Lines ["# Comment."] ["# Comment."])) whileStmt
#> let processWhile = ProcessIn remWhile
#> let evalWhile = Eval remWhile
#> let evalEcho = Eval (echoRem ["before"])
#> let echoWhile = echoRem [evalEcho, evalWhile, "mid", processWhile, "after"]
#> render echoWhile
#+echo
echo "$( #+echo
         echo before
         #-echo
         )" "$( # Comment.
                while # Comment.
                      if # Comment.
                         $'[' "$RANDOM" -lt 40000 $']'
                         # Comment.
                      then
                        # Comment.
                        $'[' "$RANDOM" -lt 10000 $']'
                        # Comment.
                      else
                        # Comment.
                        $'[' "$RANDOM" -lt 45000 $']'
                        # Comment.
                      fi
                      # Comment.
                do
                  # Comment.
                  echo ok
                  # Comment.
                done
                # Comment.
                )" mid <( # Comment.
                          while # Comment.
                                if # Comment.
                                   $'[' "$RANDOM" -lt 40000 $']'
                                   # Comment.
                                then
                                  # Comment.
                                  $'[' "$RANDOM" -lt 10000 $']'
                                  # Comment.
                                else
                                  # Comment.
                                  $'[' "$RANDOM" -lt 45000 $']'
                                  # Comment.
                                fi
                                # Comment.
                          do
                            # Comment.
                            echo ok
                            # Comment.
                          done
                          # Comment.
                          ) after
#-echo

#> let (varX :: Identifier) = "x"
#> 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
#> render (Annotated () forSeq)
for x in "$( seq 1 4 )" $( seq 1 4 )
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%%/*}"