mirror of
https://github.com/tests-always-included/mo.git
synced 2026-04-08 08:50:38 +02:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
26ca5059d8 | ||
|
|
6e57510ba9 | ||
|
|
54b2184b70 | ||
|
|
84d17268c9 | ||
|
|
68306c4c6d | ||
|
|
6cc72acde0 |
@@ -117,9 +117,11 @@ There are more scripts available in the [demos directory](demo/) that could help
|
|||||||
|
|
||||||
There are additional features that the program supports. Try using `mo --help` to see what is available.
|
There are additional features that the program supports. Try using `mo --help` to see what is available.
|
||||||
|
|
||||||
|
Please note that this command is written in Bash and pulls data from either the environment or (when using `--source`) from a text file that will be sourced and loaded into the environment, which means you will need to have Bash-style variables defined. Please see the examples in `demo/` for different ways you can use `mo`.
|
||||||
|
|
||||||
|
|
||||||
Enhancements
|
Enhancements
|
||||||
-----------
|
------------
|
||||||
|
|
||||||
In addition to many of the features built-in to Mustache, `mo` includes a number of unique features that make it a bit more powerful.
|
In addition to many of the features built-in to Mustache, `mo` includes a number of unique features that make it a bit more powerful.
|
||||||
|
|
||||||
|
|||||||
63
mo
63
mo
@@ -38,7 +38,8 @@
|
|||||||
#/ This message.
|
#/ This message.
|
||||||
#/ -s=FILE, --source=FILE
|
#/ -s=FILE, --source=FILE
|
||||||
#/ Load FILE into the environment before processing templates.
|
#/ Load FILE into the environment before processing templates.
|
||||||
#/ Can be used multiple times.
|
#/ Can be used multiple times. The file must be a valid shell script
|
||||||
|
#/ and should only contain variable assignments.
|
||||||
#/ -o=DELIM, --open=DELIM
|
#/ -o=DELIM, --open=DELIM
|
||||||
#/ Set the opening delimiter. Default is "{{".
|
#/ Set the opening delimiter. Default is "{{".
|
||||||
#/ -c=DELIM, --close=DELIM
|
#/ -c=DELIM, --close=DELIM
|
||||||
@@ -155,7 +156,7 @@ mo() (
|
|||||||
moSource="${arg#-s=}"
|
moSource="${arg#-s=}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -f "$moSource" ]]; then
|
if [[ -e "$moSource" ]]; then
|
||||||
# shellcheck disable=SC1090
|
# shellcheck disable=SC1090
|
||||||
. "$moSource"
|
. "$moSource"
|
||||||
else
|
else
|
||||||
@@ -205,7 +206,7 @@ mo() (
|
|||||||
mo::debug "Debug enabled"
|
mo::debug "Debug enabled"
|
||||||
MO_OPEN_DELIMITER="$MO_OPEN_DELIMITER_DEFAULT"
|
MO_OPEN_DELIMITER="$MO_OPEN_DELIMITER_DEFAULT"
|
||||||
MO_CLOSE_DELIMITER="$MO_CLOSE_DELIMITER_DEFAULT"
|
MO_CLOSE_DELIMITER="$MO_CLOSE_DELIMITER_DEFAULT"
|
||||||
mo::content moContent "${moFiles[@]}" || return 1
|
mo::content moContent ${moFiles[@]+"${moFiles[@]}"} || return 1
|
||||||
mo::parse moParsed "$moContent"
|
mo::parse moParsed "$moContent"
|
||||||
echo -n "$moParsed"
|
echo -n "$moParsed"
|
||||||
)
|
)
|
||||||
@@ -429,19 +430,29 @@ mo::indirectArray() {
|
|||||||
#
|
#
|
||||||
# Returns nothing.
|
# Returns nothing.
|
||||||
mo::trimUnparsed() {
|
mo::trimUnparsed() {
|
||||||
local moLast moR moN moT
|
local moLastLen moR moN moT
|
||||||
|
|
||||||
moLast=""
|
moLastLen=0
|
||||||
moR=$'\r'
|
moR=$'\r'
|
||||||
moN=$'\n'
|
moN=$'\n'
|
||||||
moT=$'\t'
|
moT=$'\t'
|
||||||
|
|
||||||
while [[ "$MO_UNPARSED" != "$moLast" ]]; do
|
while [[ "${#MO_UNPARSED}" != "$moLastLen" ]]; do
|
||||||
moLast=$MO_UNPARSED
|
moLastLen=${#MO_UNPARSED}
|
||||||
MO_UNPARSED=${MO_UNPARSED# }
|
|
||||||
MO_UNPARSED=${MO_UNPARSED#"$moR"}
|
# These conditions are necessary for a significant speed increase
|
||||||
MO_UNPARSED=${MO_UNPARSED#"$moN"}
|
while [[ "${MO_UNPARSED:0:1}" == " " ]]; do
|
||||||
MO_UNPARSED=${MO_UNPARSED#"$moT"}
|
MO_UNPARSED=${MO_UNPARSED# }
|
||||||
|
done
|
||||||
|
while [[ "${MO_UNPARSED:0:1}" == "$moR" ]]; do
|
||||||
|
MO_UNPARSED=${MO_UNPARSED#"$moR"}
|
||||||
|
done
|
||||||
|
while [[ "${MO_UNPARSED:0:1}" == "$moN" ]]; do
|
||||||
|
MO_UNPARSED=${MO_UNPARSED#"$moN"}
|
||||||
|
done
|
||||||
|
while [[ "${MO_UNPARSED:0:1}" == "$moT" ]]; do
|
||||||
|
MO_UNPARSED=${MO_UNPARSED#"$moT"}
|
||||||
|
done
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1061,7 +1072,7 @@ mo::evaluate() {
|
|||||||
;;
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
moStack=("${moStack[@]}" "$1" "$2")
|
moStack=(${moStack[@]+"${moStack[@]}"} "$1" "$2")
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@@ -1077,7 +1088,7 @@ mo::evaluate() {
|
|||||||
else
|
else
|
||||||
#: Concatenate
|
#: Concatenate
|
||||||
mo::debug "Concatenating ${#moStack[@]} stack items"
|
mo::debug "Concatenating ${#moStack[@]} stack items"
|
||||||
mo::evaluateListOfSingles moResult "${moStack[@]}"
|
mo::evaluateListOfSingles moResult ${moStack[@]+"${moStack[@]}"}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local "$moTarget" && mo::indirect "$moTarget" "$moResult"
|
local "$moTarget" && mo::indirect "$moTarget" "$moResult"
|
||||||
@@ -1310,10 +1321,12 @@ mo::evaluateFunction() {
|
|||||||
if [[ -n "${MO_ALLOW_FUNCTION_ARGUMENTS-}" ]]; then
|
if [[ -n "${MO_ALLOW_FUNCTION_ARGUMENTS-}" ]]; then
|
||||||
mo::debug "Function arguments are allowed"
|
mo::debug "Function arguments are allowed"
|
||||||
|
|
||||||
for moTemp in "${moArgs[@]}"; do
|
if [[ ${#moArgs[@]} -gt 0 ]]; then
|
||||||
mo::escape moTemp "$moTemp"
|
for moTemp in "${moArgs[@]}"; do
|
||||||
moFunctionCall="$moFunctionCall $moTemp"
|
mo::escape moTemp "$moTemp"
|
||||||
done
|
moFunctionCall="$moFunctionCall $moTemp"
|
||||||
|
done
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mo::debug "Calling function: $moFunctionCall"
|
mo::debug "Calling function: $moFunctionCall"
|
||||||
@@ -1321,7 +1334,7 @@ mo::evaluateFunction() {
|
|||||||
#: Call the function in a subshell for safety. Employ the trick to preserve
|
#: Call the function in a subshell for safety. Employ the trick to preserve
|
||||||
#: whitespace at the end of the output.
|
#: whitespace at the end of the output.
|
||||||
moContent=$(
|
moContent=$(
|
||||||
export MO_FUNCTION_ARGS=("${moArgs[@]}")
|
export MO_FUNCTION_ARGS=(${moArgs[@]+"${moArgs[@]}"})
|
||||||
echo -n "$moContent" | eval "$moFunctionCall ; moFunctionResult=\$? ; echo -n '.' ; exit \"\$moFunctionResult\""
|
echo -n "$moContent" | eval "$moFunctionCall ; moFunctionResult=\$? ; echo -n '.' ; exit \"\$moFunctionResult\""
|
||||||
) || {
|
) || {
|
||||||
moFunctionResult=$?
|
moFunctionResult=$?
|
||||||
@@ -1767,7 +1780,7 @@ mo::tokenizeTagContents() {
|
|||||||
|
|
||||||
"$moTerminator"*)
|
"$moTerminator"*)
|
||||||
mo::debug "Found terminator"
|
mo::debug "Found terminator"
|
||||||
local "$1" && mo::indirectArray "$1" "$moTokenCount" "${moResult[@]}"
|
local "$1" && mo::indirectArray "$1" "$moTokenCount" ${moResult[@]+"${moResult[@]}"}
|
||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
|
|
||||||
@@ -1775,7 +1788,7 @@ mo::tokenizeTagContents() {
|
|||||||
#: Do not tokenize the open paren - treat this as RPL
|
#: Do not tokenize the open paren - treat this as RPL
|
||||||
MO_UNPARSED=${MO_UNPARSED:1}
|
MO_UNPARSED=${MO_UNPARSED:1}
|
||||||
mo::tokenizeTagContents moTemp ')'
|
mo::tokenizeTagContents moTemp ')'
|
||||||
moResult=("${moResult[@]}" "${moTemp[@]:1}" PAREN "${moTemp[0]}")
|
moResult=(${moResult[@]+"${moResult[@]}"} "${moTemp[@]:1}" PAREN "${moTemp[0]}")
|
||||||
MO_UNPARSED=${MO_UNPARSED:1}
|
MO_UNPARSED=${MO_UNPARSED:1}
|
||||||
;;
|
;;
|
||||||
|
|
||||||
@@ -1783,7 +1796,7 @@ mo::tokenizeTagContents() {
|
|||||||
#: Do not tokenize the open brace - treat this as RPL
|
#: Do not tokenize the open brace - treat this as RPL
|
||||||
MO_UNPARSED=${MO_UNPARSED:1}
|
MO_UNPARSED=${MO_UNPARSED:1}
|
||||||
mo::tokenizeTagContents moTemp '}'
|
mo::tokenizeTagContents moTemp '}'
|
||||||
moResult=("${moResult[@]}" "${moTemp[@]:1}" BRACE "${moTemp[0]}")
|
moResult=(${moResult[@]+"${moResult[@]}"} "${moTemp[@]:1}" BRACE "${moTemp[0]}")
|
||||||
MO_UNPARSED=${MO_UNPARSED:1}
|
MO_UNPARSED=${MO_UNPARSED:1}
|
||||||
;;
|
;;
|
||||||
|
|
||||||
@@ -1793,17 +1806,17 @@ mo::tokenizeTagContents() {
|
|||||||
|
|
||||||
"'"*)
|
"'"*)
|
||||||
mo::tokenizeTagContentsSingleQuote moTemp
|
mo::tokenizeTagContentsSingleQuote moTemp
|
||||||
moResult=("${moResult[@]}" "${moTemp[@]}")
|
moResult=(${moResult[@]+"${moResult[@]}"} "${moTemp[@]}")
|
||||||
;;
|
;;
|
||||||
|
|
||||||
'"'*)
|
'"'*)
|
||||||
mo::tokenizeTagContentsDoubleQuote moTemp
|
mo::tokenizeTagContentsDoubleQuote moTemp
|
||||||
moResult=("${moResult[@]}" "${moTemp[@]}")
|
moResult=(${moResult[@]+"${moResult[@]}"} "${moTemp[@]}")
|
||||||
;;
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
mo::tokenizeTagContentsName moTemp
|
mo::tokenizeTagContentsName moTemp
|
||||||
moResult=("${moResult[@]}" "${moTemp[@]}")
|
moResult=(${moResult[@]+"${moResult[@]}"} "${moTemp[@]}")
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@@ -1947,7 +1960,7 @@ mo::tokenizeTagContentsSingleQuote() {
|
|||||||
|
|
||||||
# Save the original command's path for usage later
|
# Save the original command's path for usage later
|
||||||
MO_ORIGINAL_COMMAND="$(cd "${BASH_SOURCE[0]%/*}" || exit 1; pwd)/${BASH_SOURCE[0]##*/}"
|
MO_ORIGINAL_COMMAND="$(cd "${BASH_SOURCE[0]%/*}" || exit 1; pwd)/${BASH_SOURCE[0]##*/}"
|
||||||
MO_VERSION="3.0.0"
|
MO_VERSION="3.0.5"
|
||||||
|
|
||||||
# If sourced, load all functions.
|
# If sourced, load all functions.
|
||||||
# If executed, perform the actions as expected.
|
# If executed, perform the actions as expected.
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ cd "${0%/*}" || exit 1
|
|||||||
. ../run-tests
|
. ../run-tests
|
||||||
|
|
||||||
declare -A repo
|
declare -A repo
|
||||||
repo[resque]="Resque"
|
# The order of the array elements can be shuffled depending on the version of
|
||||||
|
# Bash. Keeping this to a minimal set and alphabetized seems to help.
|
||||||
repo[hub]="Hub"
|
repo[hub]="Hub"
|
||||||
repo[rip]="Rip"
|
repo[rip]="Rip"
|
||||||
export repo
|
export repo
|
||||||
@@ -18,7 +19,6 @@ expected() {
|
|||||||
cat <<EOF
|
cat <<EOF
|
||||||
<b>hub - Hub</b>
|
<b>hub - Hub</b>
|
||||||
<b>rip - Rip</b>
|
<b>rip - Rip</b>
|
||||||
<b>resque - Resque</b>
|
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,21 @@ testArgs() {
|
|||||||
local args
|
local args
|
||||||
# shellcheck disable=SC2031
|
# shellcheck disable=SC2031
|
||||||
args=$(declare -p MO_FUNCTION_ARGS)
|
args=$(declare -p MO_FUNCTION_ARGS)
|
||||||
echo -n "${args#*=}"
|
|
||||||
|
# The output from declare -p could look like these
|
||||||
|
# declare -a MO_FUNCTION_ARGS=([0]="one")
|
||||||
|
# declare -ax MO_FUNCTION_ARGS='([0]="one")'
|
||||||
|
# Trim leading declare statement and variable name
|
||||||
|
args="${args#*=}"
|
||||||
|
|
||||||
|
# If there are any quotes, remove them. The function arguments will always
|
||||||
|
# be an array.
|
||||||
|
if [[ "${args:0:1}" == "'" ]]; then
|
||||||
|
args=${args#\'}
|
||||||
|
args=${args%\'}
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -n "$args"
|
||||||
}
|
}
|
||||||
template() {
|
template() {
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
|
|||||||
@@ -43,7 +43,8 @@ Options:
|
|||||||
This message.
|
This message.
|
||||||
-s=FILE, --source=FILE
|
-s=FILE, --source=FILE
|
||||||
Load FILE into the environment before processing templates.
|
Load FILE into the environment before processing templates.
|
||||||
Can be used multiple times.
|
Can be used multiple times. The file must be a valid shell script
|
||||||
|
and should only contain variable assignments.
|
||||||
-o=DELIM, --open=DELIM
|
-o=DELIM, --open=DELIM
|
||||||
Set the opening delimiter. Default is "{{".
|
Set the opening delimiter. Default is "{{".
|
||||||
-c=DELIM, --close=DELIM
|
-c=DELIM, --close=DELIM
|
||||||
@@ -93,7 +94,7 @@ This is open source! Please feel free to contribute.
|
|||||||
|
|
||||||
https://github.com/tests-always-included/mo
|
https://github.com/tests-always-included/mo
|
||||||
|
|
||||||
MO_VERSION=3.0.0
|
MO_VERSION=3.0.5
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user