11 Commits
2.0.3 ... 2.1.0

Author SHA1 Message Date
Tyler Akins
929ffc5b88 Merge pull request #32 from andreax79/master
Pass arguments to function as environment variable MO_ALLOW_FUNCTION_ARGUMENTS
2019-08-08 07:47:44 -05:00
Andrea Bonomi
5b8cf24068 Pass arguments to function as environment variable MO_ALLOW_FUNCTION_ARGUMENTS 2019-08-08 11:43:50 +02:00
Andrea Bonomi
fcedd32155 Pass arguments to function as environment variable MO_ARGS 2019-08-07 15:01:51 +02:00
Tyler Akins
9f6d3bcdab Adding an example
Shows how one can solve #29
2019-07-19 20:22:27 -05:00
Tyler Akins
eac2685632 Adding an example for adding a comma
This closes #26.
2019-04-14 06:25:06 -05:00
Tyler Akins
505570a57b Adding short options
Feature request #25
2019-03-13 20:38:00 -05:00
Tyler Akins
aabc62f1d6 Merge pull request #22 from mamercad/mamercad-curl-follow-redirects
curl needs to follow redirects
2018-03-13 07:25:13 -05:00
Mark Mercado
e672bda163 curl needs to follow redirects 2018-03-13 08:11:43 -04:00
Tyler Akins
dbefade193 Adding a version number
It is shown with --help. It's also available as $MO_VERSION when mo is
sourced.
2017-11-30 05:43:10 -06:00
Tyler Akins
57a8d41394 Merge pull request #21 from jas99/patch-1
Fix: Intall issue
2017-11-20 07:22:43 -06:00
Jaspreet Singh
5739ccd705 Fix: Intall issue
Added -L flag to curl; so as to allow following redirect.
2017-11-19 15:53:12 +05:30
10 changed files with 168 additions and 19 deletions

View File

@@ -41,7 +41,7 @@ There are a few ways you can install this tool. How you install it depends on h
You can install this file in `/usr/local/bin/` or `/usr/bin/` by simply downloading it, changing the permissions, then moving it to the right location. Double check that your system's PATH includes the destination folder, otherwise users may have a hard time starting the command.
# Download
curl -sS https://git.io/get-mo -o mo
curl -sSL https://git.io/get-mo -o mo
# Make executable
chmod +x mo
@@ -58,7 +58,7 @@ You can install this file in `/usr/local/bin/` or `/usr/bin/` by simply download
This is very similar to installing it globally but it does not require root privileges. It is very important that your PATH includes the destination folder otherwise it won't work. Some local folders that are typically used are `~/bin/` and `~/.local/bin/`.
# Download
curl -sS https://git.io/get-mo -o mo
curl -sSL https://git.io/get-mo -o mo
# Make executable
chmod +x mo
@@ -78,7 +78,7 @@ This is very similar to installing it globally but it does not require root priv
Bash scripts can source `mo` to include the functionality in their own routines. This usage typically would have `mo` saved to a `lib/` folder in an application and your other scripts would use `. lib/mo` to bring it into your project.
# Download
curl -sS https://git.io/get-mo -o mo
curl -sSL https://git.io/get-mo -o mo
# Move into your project folder
mv mo ~/projects/amazing-things/lib/

29
demo/function-args Executable file
View File

@@ -0,0 +1,29 @@
#!/bin/bash
#
# This sources a simple script with the env. variables needed for the template.
cd "$(dirname "$0")" # Go to the script's directory
source ../mo
export NAME="Alex"
export ARRAY=( AAA BBB CCC )
# Include an external template
INCLUDE() {
cat "$MO_FUNCTION_ARGS"
}
# Print section title
TITLE() {
echo "+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+"
echo "$MO_FUNCTION_ARGS"
echo "+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+"
}
cat <<EOF | mo -u
{{TITLE Part 1}}
{{INCLUDE function-args-part1}}
{{TITLE Part 2}}
{{INCLUDE function-args-part2}}
EOF

1
demo/function-args-part1 Normal file
View File

@@ -0,0 +1 @@
Hello, my name is {{NAME}}.

3
demo/function-args-part2 Normal file
View File

@@ -0,0 +1,3 @@
{{#ARRAY}}
* {{.}}
{{/ARRAY}}

39
demo/function-for-building-json Executable file
View File

@@ -0,0 +1,39 @@
#!/bin/bash
cd "$(dirname "$0")" # Go to the script's directory
# Detect if this is the first item and write a comma if it is.
# Normally, I would track this using a variable, like so:
#
# COMMA_IF_NOT_FIRST_FLAG=false
# COMMA_IF_NOT_FIRST() {
# $COMMA_IF_NOT_FIRST || echo ","
# COMMA_IF_NOT_FIRST_FLAG=true
# }
#
# Since this function executes in a subshell, that approach will not work.
# Instead, we peek inside mo and see what is being processed. If the variable
# name in moParse() changes, this will need to get updated as well. An
# alternate variable that is usable is context, but that is in moLoop() and is
# two levels levels deep instead of just one.
COMMA_IF_NOT_FIRST() {
[[ "${moCurrent#*.}" != "0" ]] && echo ","
}
# Create an array that will be embedded into the JSON. If you are manipulating
# JSON, might I suggest you look at using jq? It's really good at processing
# JSON.
items=(
'{"position":"one","url":"1"}'
'{"position":"two","url":"2"}'
'{"position":"three","url":"3"}'
)
. ../mo
cat <<EOF | mo
{
{{#items}}
{{COMMA_IF_NOT_FIRST}}
{{.}}
{{/items}}
}
EOF

48
demo/function-for-foreach Executable file
View File

@@ -0,0 +1,48 @@
#!/usr/bin/env bash
# Example for how #29 can get implemented.
cd "$(dirname "$0")" # Go to the script's directory
foreach() {
# Trying to use unique names
local foreachSourceName foreachIterator foreachEvalString foreachContent
foreachContent=$(cat)
if [[ "$2" != "as" && "$2" != "in" ]]; then
echo "Invalid foreach - bad format."
elif [[ "$(declare -p "$1")" != "declare -"[aA]* ]]; then
echo "$1 is not an array"
else
foreachSourceName="${1}[@]"
for foreachIterator in "${!foreachSourceName}"; do
foreachEvalString=$(declare -p "$foreachIterator")
foreachEvalString="declare -A $3=${foreachEvalString#*=}"
eval "$foreachEvalString"
echo "$foreachContent" | mo
done
fi
}
# The links are associative arrays
declare -A resque hub rip
resque=([name]=Resque [url]=http://example.com/resque)
hub=([name]=Hub [url]=http://example.com/hub)
rip=([name]=Rip [url]=http://example.com/rip)
# This is a list of the link arrays
links=(resque hub rip)
# Source mo in order to work with arrays
. ../mo
# Process the template
cat <<EOF | mo --allow-function-arguments
Here are your links:
{{#foreach links as link}}
* [{{link.name}}]({{link.url}})
{{/foreach}}
EOF

50
mo
View File

@@ -11,12 +11,18 @@
#/
#/ 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.
#/ -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 is under a MIT style licence with an additional non-advertising clause.
# See LICENSE.md for the full text.
@@ -32,14 +38,17 @@
# --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.
# --fail-not-set - Fail upon expansion of an unset variable. Default behavior
# 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.
# --false - Treat "false" as an empty value. You may set the
# -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.
# --help - Display a help message.
# --source=FILE - Source a file into the environment before processint
# -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.
@@ -53,6 +62,7 @@
# 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_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"
@@ -89,18 +99,22 @@ mo() (
MO_ALLOW_FUNCTION_ARGUMENTS=true
;;
--fail-not-set)
-u | --fail-not-set)
# shellcheck disable=SC2030
MO_FAIL_ON_UNSET=true
;;
--false)
-e | --false)
# shellcheck disable=SC2030
MO_FALSE_IS_EMPTY=true
;;
--source=*)
f2source="${arg#--source=}"
-s=* | --source=*)
if [[ "$arg" == --source=* ]]; then
f2source="${arg#--source=}"
else
f2source="${arg#-s=}"
fi
if [[ -f "$f2source" ]]; then
# shellcheck disable=SC1090
@@ -141,16 +155,17 @@ mo() (
#
# Returns nothing.
moCallFunction() {
local moArgs
local moArgs moFunctionArgs
moArgs=()
moTrimWhitespace moFunctionArgs "$3"
# shellcheck disable=SC2031
if [[ -n "${MO_ALLOW_FUNCTION_ARGUMENTS-}" ]]; then
moArgs=$3
fi
echo -n "$2" | eval "$1" "$moArgs"
echo -n "$2" | MO_FUNCTION_ARGS="$moFunctionArgs" eval "$1" "$moArgs"
}
@@ -1030,11 +1045,14 @@ moTrimWhitespace() {
# Returns nothing.
moUsage() {
grep '^#/' "${MO_ORIGINAL_COMMAND}" | cut -c 4-
echo ""
set | grep ^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.0.4"
# If sourced, load all functions.
# If executed, perform the actions as expected.

View File

@@ -0,0 +1,3 @@
testArgs() {
echo "$MO_FUNCTION_ARGS"
}

View File

@@ -0,0 +1,4 @@
No args: [] - done
One arg: [one] - done
Multiple arguments: [aa bb cc 'x' " ! {[_.|] - done
Evil: [bla; cat /etc/issue] - done

View File

@@ -0,0 +1,4 @@
No args: [{{testArgs}}] - done
One arg: [{{testArgs one}}] - done
Multiple arguments: [{{testArgs aa bb cc 'x' " ! {[_.| }}] - done
Evil: [{{testArgs bla; cat /etc/issue}}] - done