Adding tests, shellcheck cleanup, update docs, release 2.2.0

This commit is contained in:
Tyler Akins 2020-08-05 15:44:04 -05:00
parent 65f12277e6
commit dcd9d7738b
19 changed files with 285 additions and 194 deletions

194
API.md
View File

@ -4,21 +4,49 @@ API / Function Documentation
This documentation is generated automatically from the source of [mo] thanks to [tomdoc.sh].
mo()
----
`mo()`
------
Public: Template parser function. Writes templates to stdout.
* $0 - Name of the mo file, used for getting the help message.
* --fail-not-set - Fail upon expansion of an unset variable. Default behavior is to silently ignore and expand into empty string.
* --false - Treat "false" as an empty value. You may set the MO_FALSE_IS_EMPTY environment variable instead to a non-empty value to enable this behavior.
* --help - Display a help message.
* --source=FILE - Source a file into the environment before processint template files.
* -- - Used to indicate the end of options. You may optionally use this when filenames may start with two hyphens.
* $@ - Filenames to parse.
Options:
--allow-function-arguments
Permit functions in templates to be called with additional arguments. This puts template data directly in to the path of an eval statement. Use with caution. Not listed in the help because it only makes sense when mo is sourced.
-u, --fail-not-set
Fail upon expansion of an unset variable. Default behavior is to silently ignore and expand into empty string.
-x, --fail-on-function
Fail when a function used by a template returns an error status code. Alternately, ou may set the MO_FAIL_ON_FUNCTION environment variable to a non-empty value to enable this behavior.
-e, --false
Treat "false" as an empty value. You may set the MO_FALSE_IS_EMPTY environment variable instead to a non-empty value to enable this behavior.
-h, --help
Display a help message.
-s=FILE, --source=FILE
Source a file into the environment before processing template files.
--
Used to indicate the end of options. You may optionally use this when filenames may start with two hyphens.
Mo uses the following environment variables:
* MO_ALLOW_FUNCTION_ARGUMENTS - When set to a non-empty value, this allows functions referenced in templates to receive additional options and arguments. This puts the content from the template directly into an eval statement. Use with extreme care.
* MO_FUNCTION_ARGS - Arguments passed to the function
* MO_FAIL_ON_FUNCTION - If a function returns a non-zero status code, abort with an error.
* MO_FAIL_ON_UNSET - When set to a non-empty value, expansion of an unset env variable will be aborted with an error.
* MO_FALSE_IS_EMPTY - When set to a non-empty value, the string "false" will be treated as an empty value for the purposes of conditionals.
* MO_ORIGINAL_COMMAND - Used to find the `mo` program in order to generate a help message.
@ -26,39 +54,24 @@ Mo uses the following environment variables:
Returns nothing.
files
-----
`moCallFunction()`
------------------
After we encounter two hyphens together, all the rest of the arguments are files.
Internal: Call a function.
* $1 - Variable for output
* $2 - Function to call
* $3 - Content to pass
* $4 - Additional arguments as a single string
This can be dangerous, especially if you are using tags like {{someFunction ; rm -rf / }}
Returns nothing.
MO_FAIL_ON_UNSET
`moFindEndTag()`
----------------
shellcheck disable=SC2030
MO_FALSE_IS_EMPTY
-----------------
shellcheck disable=SC2030
doubleHyphens
-------------
Set a flag indicating we've encountered double hyphens
files
-----
Every arg that is not a flag or a option should be a file
moFindEndTag()
--------------
Internal: Scan content until the right end tag is found. Creates an array with the following members:
[0] = Content before end tag
@ -75,8 +88,8 @@ Everything using this function uses the "standalone tags" logic.
Returns nothing.
moFindString()
--------------
`moFindString()`
----------------
Internal: Find the first index of a substring. If not found, sets the index to -1.
@ -87,8 +100,8 @@ Internal: Find the first index of a substring. If not found, sets the index to
Returns nothing.
moFullTagName()
---------------
`moFullTagName()`
-----------------
Internal: Generate a dotted name based on current context and target name.
@ -99,8 +112,8 @@ Internal: Generate a dotted name based on current context and target name.
Returns nothing.
moGetContent()
--------------
`moGetContent()`
----------------
Internal: Fetches the content to parse into a variable. Can be a list of partials for files or the content from stdin.
@ -110,8 +123,8 @@ Internal: Fetches the content to parse into a variable. Can be a list of partia
Returns nothing.
moIndentLines()
---------------
`moIndentLines()`
-----------------
Internal: Indent a string, placing the indent at the beginning of every line that has any content.
@ -122,8 +135,8 @@ Internal: Indent a string, placing the indent at the beginning of every line tha
Returns nothing.
moIndirect()
------------
`moIndirect()`
--------------
Internal: Send a variable up to the parent of the caller of this function.
@ -141,8 +154,8 @@ Examples
Returns nothing.
moIndirectArray()
-----------------
`moIndirectArray()`
-------------------
Internal: Send an array as a variable up to caller of a function
@ -161,8 +174,8 @@ Examples
Returns nothing.
moIsArray()
-----------
`moIsArray()`
-------------
Internal: Determine if a given environment variable exists and if it is an array.
@ -173,16 +186,16 @@ Be extremely careful. Even if strict mode is enabled, it is not honored in newe
Examples
var=(abc)
if moIsArray var; the
if moIsArray var; then
echo "This is an array"
echo "Make sure you don't accidentally use $var"
echo "Make sure you don't accidentally use \$var"
fi
Returns 0 if the name is not empty, 1 otherwise.
moIsFunction()
--------------
`moIsFunction()`
----------------
Internal: Determine if the given name is a defined function.
@ -202,8 +215,8 @@ Examples
Returns 0 if the name is a function, 1 otherwise.
moIsStandalone()
----------------
`moIsStandalone()`
------------------
Internal: Determine if the tag is a standalone tag based on whitespace before and after the tag.
@ -223,8 +236,8 @@ Examples
Returns nothing.
moJoin()
--------
`moJoin()`
----------
Internal: Join / implode an array
@ -235,19 +248,19 @@ Internal: Join / implode an array
Returns nothing.
moLoadFile()
------------
`moLoadFile()`
--------------
Internal: Read a file into a variable.
* $1 - Variable name to receive the file's content
* $2 - Filename to load
* $2 - Filename to load - if empty, defaults to /dev/stdin
Returns nothing.
moLoop()
--------
`moLoop()`
----------
Internal: Process a chunk of content some number of times. Writes output to stdout.
@ -258,8 +271,8 @@ Internal: Process a chunk of content some number of times. Writes output to std
Returns nothing.
moParse()
---------
`moParse()`
-----------
Internal: Parse a block of text, writing the result to stdout.
@ -270,8 +283,14 @@ Internal: Parse a block of text, writing the result to stdout.
Returns nothing.
moPartial()
-----------
`moArgs`
--------
Split arguments from the tag name. Arguments are passed to functions.
`moPartial()`
-------------
Internal: Process a partial.
@ -291,8 +310,8 @@ Prefix all variables.
Returns nothing.
moShow()
--------
`moShow()`
----------
Internal: Show an environment variable or the output of a function to stdout.
@ -300,12 +319,13 @@ Limit/prefix any variables used.
* $1 - Name of environment variable or function
* $2 - Current context
* $3 - Arguments string if $1 is a function
Returns nothing.
moSplit()
---------
`moSplit()`
-----------
Internal: Split a larger string into an array.
@ -317,8 +337,8 @@ Internal: Split a larger string into an array.
Returns nothing.
moStandaloneAllowed()
---------------------
`moStandaloneAllowed()`
-----------------------
Internal: Handle the content for a standalone tag. This means removing whitespace (not newlines) before a tag and whitespace and a newline after a tag. That is, assuming, that the line is otherwise empty.
@ -331,8 +351,8 @@ Internal: Handle the content for a standalone tag. This means removing whitespa
Returns nothing.
moStandaloneDenied()
--------------------
`moStandaloneDenied()`
----------------------
Internal: Handle the content for a tag that is never "standalone". No adjustments are made for newlines and whitespace.
@ -344,8 +364,8 @@ Internal: Handle the content for a tag that is never "standalone". No adjustmen
Returns nothing.
moTest()
--------
`moTest()`
----------
Internal: Determines if the named thing is a function or if it is a non-empty environment variable. When MO_FALSE_IS_EMPTY is set to a non-empty value, then "false" is also treated is an empty value.
@ -358,8 +378,8 @@ Do not use variables without prefixes here if possible as this needs to check if
Returns 0 if the name is not empty, 1 otherwise. When MO_FALSE_IS_EMPTY is set, this returns 1 if the name is "false".
moTestVarSet()
--------------
`moTestVarSet()`
----------------
Internal: Determine if a variable is assigned, even if it is assigned an empty value.
@ -368,8 +388,8 @@ Internal: Determine if a variable is assigned, even if it is assigned an empty v
Returns true (0) if the variable is set, 1 if the variable is unset.
moTrimChars()
-------------
`moTrimChars()`
---------------
Internal: Trim the leading whitespace only.
@ -382,8 +402,8 @@ Internal: Trim the leading whitespace only.
Returns nothing.
moTrimWhitespace()
------------------
`moTrimWhitespace()`
--------------------
Internal: Trim leading and trailing whitespace from a string.
@ -393,8 +413,8 @@ Internal: Trim leading and trailing whitespace from a string.
Returns nothing.
moUsage()
---------
`moUsage()`
-----------
Internal: Displays the usage for mo. Pulls this from the file that contained the `mo` function. Can only work when the right filename comes is the one argument, and that only happens when `mo` is called with `$0` set to this file.
@ -403,11 +423,11 @@ Internal: Displays the usage for mo. Pulls this from the file that contained th
Returns nothing.
MO_ORIGINAL_COMMAND
-------------------
`MO_ORIGINAL_COMMAND`
---------------------
Save the original command's path for usage later
[mo]: ./mo
[tomdoc.sh]: https://github.com/mlafeldt/tomdoc.sh
[tomdoc.sh]: https://github.com/tests-always-included/tomdoc.sh

View File

@ -10,11 +10,12 @@
# diagnose what's not working and fix those low-level functions first.
PARENT_PID=$$
cd "$(dirname "$0")"
cd "$(dirname "$0")" || exit 1
rm -f diagnostic.test
rm -f diagnostic.partial
# Load mo's functions
# shellcheck disable=SC1091
. ./mo
fail() {
@ -75,21 +76,20 @@ echo "ok"
echo -n "moIsArray ... "
(
TEST=1
moIsArray TEST && fail "Wrongly said number was an array"
export TEST_NUM=1
moIsArray TEST_NUM && fail "Wrongly said number was an array"
)
(
TEST=()
moIsArray TEST || fail "Wrongly said array was not an array"
export TEST_ARR=()
moIsArray TEST_ARR || fail "Wrongly said array was not an array"
)
(
# shellcheck disable=SC2034
TEST=""
moIsArray TEST && fail "Wrongly said string was an array"
export TEST_EMPTY=""
moIsArray TEST_EMPTY && fail "Wrongly said string was an array"
)
(
unset TEST
moIsArray TEST && fail "Wrongly said undefined was an array"
unset TEST_UNSET
moIsArray TEST_UNSET && fail "Wrongly said undefined was an array"
)
echo "ok"

View File

@ -1,9 +1,9 @@
#!/bin/bash
#
# This requires tomdoc.sh to be in your PATH.
# https://github.com/mlafeldt/tomdoc.sh
# https://github.com/tests-always-included/tomdoc.sh
cd "${0%/*}"
cd "${0%/*}" || exit 1
cat <<'EOF'
API / Function Documentation
@ -13,8 +13,8 @@ This documentation is generated automatically from the source of [mo] thanks to
EOF
tomdoc.sh -m mo
sed 's/# shellcheck.*//' mo | tomdoc.sh -m
cat <<'EOF'
[mo]: ./mo
[tomdoc.sh]: https://github.com/mlafeldt/tomdoc.sh
[tomdoc.sh]: https://github.com/tests-always-included/tomdoc.sh
EOF

165
mo
View File

@ -16,13 +16,15 @@
#/ Options:
#/
#/ -u, --fail-not-set
#/ - Fail upon expansion of an unset variable.
#/ Fail upon expansion of an unset variable.
#/ -x, --fail-on-function
#/ Fail when a function returns a non-zero status code.
#/ -e, --false
#/ - Treat the string "false" as empty for conditionals.
#/ Treat the string "false" as empty for conditionals.
#/ -h, --help
#/ - This message.
#/ This message.
#/ -s=FILE, --source=FILE
#/ - Load FILE into the environment before processing templates.
#/ Load FILE into the environment before processing templates.
#
# Mo is under a MIT style licence with an additional non-advertising clause.
# See LICENSE.md for the full text.
@ -35,41 +37,62 @@
# Public: Template parser function. Writes templates to stdout.
#
# $0 - Name of the mo file, used for getting the help message.
# --allow-function-arguments
# - Permit functions in templates to be called with additional
# arguments. This puts template data directly in to the path
# of an eval statement. Use with caution. Not listed in the
# help because it only makes sense when mo is sourced.
# -u, --fail-not-set
# - Fail upon expansion of an unset variable. Default behavior
# is to silently ignore and expand into empty string.
# -e, --false - Treat "false" as an empty value. You may set the
# MO_FALSE_IS_EMPTY environment variable instead to a non-empty
# value to enable this behavior.
# -h, --help - Display a help message.
# -s=FILE, --source=FILE
# - Source a file into the environment before processint
# template files.
# -- - Used to indicate the end of options. You may optionally
# use this when filenames may start with two hyphens.
# $@ - Filenames to parse.
#
# Options:
#
# --allow-function-arguments
#
# Permit functions in templates to be called with additional arguments. This
# puts template data directly in to the path of an eval statement. Use with
# caution. Not listed in the help because it only makes sense when mo is
# sourced.
#
# -u, --fail-not-set
#
# Fail upon expansion of an unset variable. Default behavior is to silently
# ignore and expand into empty string.
#
# -x, --fail-on-function
#
# Fail when a function used by a template returns an error status code.
# Alternately, ou may set the MO_FAIL_ON_FUNCTION environment variable to a
# non-empty value to enable this behavior.
#
# -e, --false
#
# Treat "false" as an empty value. You may set the MO_FALSE_IS_EMPTY
# environment variable instead to a non-empty value to enable this behavior.
#
# -h, --help
#
# Display a help message.
#
# -s=FILE, --source=FILE
#
# Source a file into the environment before processing template files.
#
# --
#
# Used to indicate the end of options. You may optionally use this when
# filenames may start with two hyphens.
#
# Mo uses the following environment variables:
#
# MO_ALLOW_FUNCTION_ARGUMENTS
# - When set to a non-empty value, this allows functions
# referenced in templates to receive additional
# MO_ALLOW_FUNCTION_ARGUMENTS - When set to a non-empty value, this allows
# functions referenced in templates to receive additional
# options and arguments. This puts the content from the
# template directly into an eval statement. Use with
# extreme care.
# template directly into an eval statement. Use with extreme
# care.
# MO_FUNCTION_ARGS - Arguments passed to the function
# MO_FAIL_ON_UNSET - When set to a non-empty value, expansion of an unset
# env variable will be aborted with an error.
# MO_FALSE_IS_EMPTY - When set to a non-empty value, the string "false"
# will be treated as an empty value for the purposes
# of conditionals.
# MO_ORIGINAL_COMMAND - Used to find the `mo` program in order to generate
# a help message.
# MO_FAIL_ON_FUNCTION - If a function returns a non-zero status code, abort
# with an error.
# MO_FAIL_ON_UNSET - When set to a non-empty value, expansion of an unset env
# variable will be aborted with an error.
# MO_FALSE_IS_EMPTY - When set to a non-empty value, the string "false" will be
# treated as an empty value for the purposes of conditionals.
# MO_ORIGINAL_COMMAND - Used to find the `mo` program in order to generate a
# help message.
#
# Returns nothing.
mo() (
@ -84,8 +107,8 @@ mo() (
if [[ $# -gt 0 ]]; then
for arg in "$@"; do
if $doubleHyphens; then
# After we encounter two hyphens together, all the rest
# of the arguments are files.
#: After we encounter two hyphens together, all the rest
#: of the arguments are files.
files=("${files[@]}" "$arg")
else
case "$arg" in
@ -104,6 +127,11 @@ mo() (
MO_FAIL_ON_UNSET=true
;;
-x | --fail-on-function)
# shellcheck disable=SC2030
MO_FAIL_ON_FUNCTION=true
;;
-e | --false)
# shellcheck disable=SC2030
MO_FALSE_IS_EMPTY=true
@ -126,12 +154,12 @@ mo() (
;;
--)
# Set a flag indicating we've encountered double hyphens
#: Set a flag indicating we've encountered double hyphens
doubleHyphens=true
;;
*)
# Every arg that is not a flag or a option should be a file
#: Every arg that is not a flag or a option should be a file
files=(${files[@]+"${files[@]}"} "$arg")
;;
esac
@ -146,34 +174,41 @@ mo() (
# Internal: Call a function.
#
# $1 - Function to call
# $2 - Content to pass
# $3 - Additional arguments as a single string
# $1 - Variable for output
# $2 - Function to call
# $3 - Content to pass
# $4 - Additional arguments as a single string
#
# This can be dangerous, especially if you are using tags like
# {{someFunction ; rm -rf / }}
#
# Returns nothing.
moCallFunction() {
local moArgs moFunctionArgs moFunctionResult
local moArgs moContent moFunctionArgs moFunctionResult
moArgs=()
moTrimWhitespace moFunctionArgs "$3"
moTrimWhitespace moFunctionArgs "$4"
# shellcheck disable=SC2031
if [[ -n "${MO_ALLOW_FUNCTION_ARGUMENTS-}" ]]; then
moArgs=$3
# Intentionally bad behavior
# shellcheck disable=SC2206
moArgs=($4)
fi
echo -n "$2" | MO_FUNCTION_ARGS="$moFunctionArgs" eval "$1" "$moArgs"
moContent=$(echo -n "$3" | MO_FUNCTION_ARGS="$moFunctionArgs" eval "$2" "${moArgs[@]}") || {
moFunctionResult=$?
# shellcheck disable=SC2031
if [[ -n "${MO_FAIL_ON_FUNCTION-}" && "$moFunctionResult" != 0 ]]; then
echo "Function '$1' with args '${moArgs@}' failed with status code $moFunctionResult"
exit $moFunctionResult
echo "Function '$2' with args (${moArgs[*]+"${moArgs[@]}"}) failed with status code $moFunctionResult"
exit "$moFunctionResult"
fi
}
# shellcheck disable=SC2031
local "$1" && moIndirect "$1" "$moContent"
}
# Internal: Scan content until the right end tag is found. Creates an array
# with the following members:
@ -223,6 +258,7 @@ moFindEndTag() {
if [[ -z "${4-}" ]] && moIsStandalone standaloneBytes "$scanned" "${content[2]}" true; then
#: This is also a standalone tag - clean up whitespace
#: and move those whitespace bytes to the "tag" element
# shellcheck disable=SC2206
standaloneBytes=( $standaloneBytes )
content[1]="${scanned:${standaloneBytes[0]}}${content[1]}${content[2]:0:${standaloneBytes[1]}}"
scanned="${scanned:0:${standaloneBytes[0]}}"
@ -294,22 +330,22 @@ moFullTagName() {
#
# Returns nothing.
moGetContent() {
local content filename target
local moContent moFilename moTarget
target=$1
moTarget=$1
shift
if [[ "${#@}" -gt 0 ]]; then
content=""
moContent=""
for filename in "$@"; do
for moFilename in "$@"; do
#: This is so relative paths work from inside template files
content="$content"'{{>'"$filename"'}}'
moContent="$moContent"'{{>'"$moFilename"'}}'
done
else
moLoadFile content /dev/stdin || return 1
moLoadFile moContent || return 1
fi
local "$target" && moIndirect "$target" "$content"
local "$moTarget" && moIndirect "$moTarget" "$moContent"
}
@ -484,6 +520,7 @@ moIsFunction() {
local functionList functionName
functionList=$(declare -F)
# shellcheck disable=SC2206
functionList=( ${functionList//declare -f /} )
for functionName in "${functionList[@]}"; do
@ -575,7 +612,7 @@ moJoin() {
# Internal: Read a file into a variable.
#
# $1 - Variable name to receive the file's content
# $2 - Filename to load
# $2 - Filename to load - if empty, defaults to /dev/stdin
#
# Returns nothing.
moLoadFile() {
@ -586,7 +623,7 @@ moLoadFile() {
# As a future optimization, it would be worth considering removing
# cat and replacing this with a read loop.
content=$(cat -- "$2" && echo '.') || return 1
content=$(cat -- "${2:-/dev/stdin}" && echo '.') || return 1
len=$((${#content} - 1))
content=${content:0:$len} # Remove last dot
@ -658,9 +695,7 @@ moParse() {
if moTest "$moTag"; then
# Show / loop / pass through function
if moIsFunction "$moTag"; then
#: Consider piping the output to moGetContent
#: so the lambda does not execute in a subshell?
moContent=$(moCallFunction "$moTag" "${moBlock[0]}" "$moArgs")
moCallFunction moContent "$moTag" "${moBlock[0]}" "$moArgs"
moParse "$moContent" "$moCurrent" false
moContent="${moBlock[2]}"
elif moIsArray "$moTag"; then
@ -793,6 +828,7 @@ moPartial() {
local moContent moFilename moIndent moIsBeginning moPartial moStandalone moUnindented
if moIsStandalone moStandalone "$2" "$4" "$5"; then
# shellcheck disable=SC2206
moStandalone=( $moStandalone )
echo -n "${2:0:${moStandalone[0]}}"
moIndent=${2:${moStandalone[0]}}
@ -846,11 +882,11 @@ moPartial() {
# Returns nothing.
moShow() {
# Namespace these variables
local moJoined moNameParts
local moJoined moNameParts moContent
if moIsFunction "$1"; then
CONTENT=$(moCallFunction "$1" "" "$3")
moParse "$CONTENT" "$2" false
moCallFunction moContent "$1" "" "$3"
moParse "$moContent" "$2" false
return 0
fi
@ -925,6 +961,7 @@ moStandaloneAllowed() {
local bytes
if moIsStandalone bytes "$2" "$4" "$5"; then
# shellcheck disable=SC2206
bytes=( $bytes )
echo -n "${2:0:${bytes[0]}}"
local "$1" && moIndirect "$1" "${4:${bytes[1]}}"
@ -1052,13 +1089,13 @@ moTrimWhitespace() {
moUsage() {
grep '^#/' "${MO_ORIGINAL_COMMAND}" | cut -c 4-
echo ""
set | grep ^MO_VERSION=
echo "MO_VERSION=$MO_VERSION"
}
# Save the original command's path for usage later
MO_ORIGINAL_COMMAND="$(cd "${BASH_SOURCE[0]%/*}" || exit 1; pwd)/${BASH_SOURCE[0]##*/}"
MO_VERSION="2.1.0"
MO_VERSION="2.2.0"
# If sourced, load all functions.
# If executed, perform the actions as expected.

View File

@ -1,7 +1,8 @@
#!/usr/bin/env bash
cd "${0%/*}"
cd "${0%/*}" || exit 1
# shellcheck disable=SC1091
. ./mo
PASS=0
FAIL=0
@ -18,13 +19,16 @@ for TEST in tests/*.expected; do
"${BASE}.sh"
else
# Fall back to using .env and .template
# shellcheck disable=SC1090
. "${BASE}.env"
echo "Do not read this input" | mo "${BASE}.template"
fi
) | diff -U5 - "${TEST}" > "${BASE}.diff"
if [[ $? -ne 0 ]]; then
echo "FAIL"
statusCode=$?
if [[ $statusCode -ne 0 ]]; then
echo "FAIL (status code $statusCode)"
FAIL=$(( FAIL + 1 ))
else
echo "ok"

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
# This should display a message indicating that the file --help
# could not be found. It should not display a help messsage.
cd "${0%/*}"
cd "${0%/*}" || exit 1
../mo -- --help 2>&1

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash
cd "${0%/*}"
cd "${0%/*}" || exit 1
unset __NO_SUCH_VAR
POPULATED="words" EMPTY="" ../mo --fail-not-set ./fail-not-set-file.template 2>&1

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash
cd "${0%/*}"
cd "${0%/*}" || exit 1
unset __NO_SUCH_VAR
POPULATED="words" EMPTY="" ../mo --fail-not-set 2>&1 <<EOF
Populated: {{POPULATED}};

View File

@ -0,0 +1 @@
Fail on function? Function 'failFunction' with args () failed with status code 1

18
tests/fail-on-function.sh Executable file
View File

@ -0,0 +1,18 @@
#!/usr/bin/env bash
cd "${0%/*}" || exit 1
failFunction() {
false
}
# Must be sourced to use functions
# shellcheck disable=SC1091
. ../mo
mo --fail-on-function 2>&1 <<EOF
Fail on function? {{failFunction}}
EOF
if [[ $? -ne 1 ]]; then
echo "Did not return 1"
fi

View File

@ -1,4 +1,4 @@
#!/usr/bin/env bash
cd "${0%/*}"
cd "${0%/*}" || exit 1
USER=j.doe ADMIN=false ../mo --false false-is-empty-arg.template

View File

@ -9,9 +9,19 @@ Learn more about mustache templates at https://mustache.github.io/
Simple usage:
mo [--false] [--help] [--source=FILE] filenames...
mo [OPTIONS] filenames...
--fail-not-set - Fail upon expansion of an unset variable.
--false - Treat the string "false" as empty for conditionals.
--help - This message.
--source=FILE - Load FILE into the environment before processing templates.
Options:
-u, --fail-not-set
- Fail upon expansion of an unset variable.
-x, --fail-on-function
- Fail when a function returns a non-zero status code.
-e, --false
- Treat the string "false" as empty for conditionals.
-h, --help
- This message.
-s=FILE, --source=FILE
- Load FILE into the environment before processing templates.
MO_VERSION=2.2.0

View File

@ -1,4 +1,4 @@
#!/usr/bin/env bash
cd "${0%/*}"
cd "${0%/*}" || exit 1
../mo --help

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
# This should display a message indicating that the file --something
# could not be found.
cd "${0%/*}"
cd "${0%/*}" || exit 1
../mo --something 2>&1

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash
cd "${0%/*}"
cd "${0%/*}" || exit 1
../mo partial-missing.template 2>&1
if [[ $? -ne 1 ]]; then

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash
cd "${0%/*}"
cd "${0%/*}" || exit 1
echo "Do not display this" | ../mo --source=invalid 2>&1
if [[ $? -ne 1 ]]; then

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash
cd "${0%/*}"
cd "${0%/*}" || exit 1
echo "Do not display this" | ../mo --source= 2>&1
if [[ $? -ne 1 ]]; then

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash
cd "${0%/*}"
cd "${0%/*}" || exit 1
cat <<EOF | ../mo --source=source.vars
{{VAR}}
{{#ARR}}

View File

@ -1,4 +1,5 @@
export VAR=value
export ARR=(1 2 3)
declare -A ASSOC_ARR
export ASSOC_ARR=([a]=AAA [b]=BBB)
# Can not export associative arrays, otherwise they turn into indexed arrays
ASSOC_ARR=([a]=AAA [b]=BBB)