git-vendor-name: bash3boilerplate
git-vendor-dir: vendor/git.knownelement.com/ExternalVendorCode/bash3boilerplate
git-vendor-repository: https://git.knownelement.com/ExternalVendorCode/bash3boilerplate.git
git-vendor-ref: main
This commit is contained in:
2024-12-09 12:44:28 -06:00
64 changed files with 3997 additions and 0 deletions

View File

@@ -0,0 +1,232 @@
#!/usr/bin/env bash
# This file:
#
# - Executes one (or all) test scenarios
# - Replaces dynamic things like hostnames, IPs, dates, etc
# - Optionally saves the results as fixtures, that later runs will be compared against
#
# Usage:
#
# ./deploy.sh
#
# Based on a template by BASH3 Boilerplate v2.0.0
# http://bash3boilerplate.sh/#authors
#
# The MIT License (MIT)
# Copyright (c) 2013 Kevin van Zonneveld and contributors
# You are not obligated to bundle the LICENSE file with your b3bp projects as long
# as you leave these references intact in the header comments of your source files.
# Exit on error. Append || true if you expect an error.
set -o errexit
# Exit on error inside any functions or subshells.
set -o errtrace
# Do not allow use of undefined vars. Use ${VAR:-} to use an undefined VAR
set -o nounset
# Catch the error in case mysqldump fails (but gzip succeeds) in `mysqldump |gzip`
set -o pipefail
# Turn on traces, useful while debugging but commented out by default
# set -o xtrace
# Set magic variables for current file, directory, os, etc.
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
__file="${__dir}/$(basename "${BASH_SOURCE[0]}")"
__base="$(basename "${__file}" .sh)"
__root="$(cd "$(dirname "${__dir}")" && pwd)"
__sysTmpDir="${TMPDIR:-/tmp}"
__sysTmpDir="${__sysTmpDir%/}" # <-- remove trailing slash on macosx
__accptstTmpDir=$(mktemp -d "${__sysTmpDir}/${__base}.XXXXXX")
function cleanup_before_exit () { rm -r "${__accptstTmpDir:?}"; }
trap cleanup_before_exit EXIT
cmdSed="sed"
cmdTimeout="timeout"
if [[ "${OSTYPE}" = "darwin"* ]]; then
cmdSed="gsed"
cmdTimeout="gtimeout"
fi
if [[ ! "$(command -v ${cmdSed})" ]]; then
echo "Please install ${cmdSed}"
exit 1
fi
if [[ ! "$(command -v ${cmdTimeout})" ]]; then
echo "Please install ${cmdTimeout}"
exit 1
fi
__node="$(command -v node)"
__arch="amd64"
# explicitly setting NO_COLOR to false will make b3bp ignore TERM
# not being "xterm*" or "screen*" and STDERR not being connected to a terminal
# it's the opposite of NO_COLOR="true" - it forces color, no matter what
export NO_COLOR="false"
# Running prepare before other scenarios is important on Travis,
# so that stdio can diverge - and we can enforce stricter
# stdio comparison on all other tests.
while IFS=$'\n' read -r scenario; do
scenario="$(dirname "${scenario}")"
scenario="${scenario##${__dir}/scenario/}"
[[ "${scenario}" = "prepare" ]] && continue
[[ "${1:-}" ]] && [[ "${scenario}" != "${1}" ]] && continue
echo "==> Scenario: ${scenario}"
pushd "${__dir}/scenario/${scenario}" > /dev/null
# Run scenario
(${cmdTimeout} --kill-after=6m 5m bash ./run.sh \
> "${__accptstTmpDir}/${scenario}.stdio" 2>&1; \
echo "${?}" > "${__accptstTmpDir}/${scenario}.exitcode" \
) || true
# Clear out environmental specifics
for typ in stdio exitcode; do
curFile="${__accptstTmpDir}/${scenario}.${typ}"
"${cmdSed}" -i \
-e "s@${__node}@{node}@g" "${curFile}" \
-e "s@${__root}@{root}@g" "${curFile}" \
-e "s@${__sysTmpDir}@{tmpdir}@g" "${curFile}" \
-e "s@/tmp@{tmpdir}@g" "${curFile}" \
-e "s@${HOME:-/home/travis}@{home}@g" "${curFile}" \
-e "s@${USER:-travis}@{user}@g" "${curFile}" \
-e "s@travis@{user}@g" "${curFile}" \
-e "s@kvz@{user}@g" "${curFile}" \
-e "s@{root}/node_modules/\\.bin/node@{node}@g" "${curFile}" \
-e "s@{home}/build/{user}/fre{node}@{node}@g" "${curFile}" \
-e "s@${HOSTNAME}@{hostname}@g" "${curFile}" \
-e "s@${__arch}@{arch}@g" "${curFile}" \
-e "s@${OSTYPE}@{OSTYPE}@g" "${curFile}" \
-e "s@OSX@{os}@g" "${curFile}" \
-e "s@Linux@{os}@g" "${curFile}" \
|| false
if grep -q 'ACCPTST:STDIO_REPLACE_IPS' "${curFile}"; then
"${cmdSed}" -i \
-r 's@[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}@{ip}@g' \
"${curFile}"
# IPs vary in length. Ansible uses padding. {ip} does not vary in length
# so kill the padding after it for consistent output
"${cmdSed}" -i \
-r 's@\{ip\}\s+@{ip} @g' \
"${curFile}"
fi
if grep -q 'ACCPTST:STDIO_REPLACE_UUIDS' "${curFile}"; then
"${cmdSed}" -i \
-r 's@[0-9a-f\-]{32,40}@{uuid}@g' \
"${curFile}"
fi
if grep -q 'ACCPTST:STDIO_REPLACE_BIGINTS' "${curFile}"; then
# Such as: 3811298194
"${cmdSed}" -i \
-r 's@[0-9]{7,64}@{bigint}@g' \
"${curFile}"
fi
if grep -q 'ACCPTST:STDIO_REPLACE_DATETIMES' "${curFile}"; then
# Such as: 2016-02-10 15:38:44.420094
"${cmdSed}" -i \
-r 's@[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}@{datetime}@g' \
"${curFile}"
fi
if grep -q 'ACCPTST:STDIO_REPLACE_LONGTIMES' "${curFile}"; then
# Such as: 2016-02-10 15:38:44.420094
"${cmdSed}" -i \
-r 's@[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{6}@{longtime}@g' \
"${curFile}"
fi
if grep -q 'ACCPTST:STDIO_REPLACE_DURATIONS' "${curFile}"; then
# Such as: 0:00:00.001991
"${cmdSed}" -i \
-r 's@[0-9]{1,2}:[0-9]{2}:[0-9]{2}.[0-9]{6}@{duration}@g' \
"${curFile}"
fi
if grep -q 'ACCPTST:STDIO_REPLACE_REMOTE_EXEC' "${curFile}"; then
grep -Ev 'remote-exec\): [ a-zA-Z]' "${curFile}" > "${__sysTmpDir}/accptst-filtered.txt"
mv "${__sysTmpDir}/accptst-filtered.txt" "${curFile}"
fi
done
# Save these as new fixtures?
if [[ "${SAVE_FIXTURES:-}" = "true" ]]; then
for typ in stdio exitcode; do
curFile="${__accptstTmpDir}/${scenario}.${typ}"
cp -f \
"${curFile}" \
"${__dir}/fixture/${scenario}.${typ}"
done
fi
# Compare
for typ in stdio exitcode; do
curFile="${__accptstTmpDir}/${scenario}.${typ}"
echo -n " comparing ${typ}.. "
if [[ "${typ}" = "stdio" ]]; then
if grep -q 'ACCPTST:STDIO_SKIP_COMPARE' "${curFile}"; then
echo "skip"
continue
fi
fi
if ! diff --strip-trailing-cr "${__dir}/fixture/${scenario}.${typ}" "${curFile}"; then
echo -e "\\n\\n==> MISMATCH OF: ${scenario}.${typ} ---^"
echo -e "\\n\\n==> EXPECTED STDIO: "
cat "${__dir}/fixture/${scenario}.stdio" || true
echo -e "\\n\\n==> ACTUAL STDIO: "
cat "${__accptstTmpDir}/${scenario}.stdio" || true
exit 1
fi
echo "✓"
done
popd > /dev/null
done <<< "$(find "${__dir}/scenario" -type f -iname 'run.sh')"
[[ "${1:-}" ]] && exit 0
# Ensure correct syntax with all available bashes
# shellcheck disable=SC2230
# "command -v" is not a substitute for "which -a"
while IFS=$'\n' read -r bash; do
if [[ "${bash:-}" = "" ]]; then
continue
fi
# shellcheck disable=SC2016
echo "==> ${bash} -n $(${bash} -c 'echo "(${BASH_VERSION})"')"
pushd "${__root}" > /dev/null
failed="false"
while IFS=$'\n' read -r file; do
[[ "${file}" =~ ^\./node_modules/ ]] && continue
echo -n " ${file}.. "
if ! "${bash}" -n "${file}" 2>> "${__accptstTmpDir}/${bash//\//.}.err"; then
echo "✗"
failed="true"
continue
fi
echo "✓"
done <<< "$(find . -type f -iname '*.sh')"
popd > /dev/null
if [[ "${failed}" = "true" ]]; then
cat "${__accptstTmpDir}/${bash//\//.}.err"
exit 1
fi
done <<< "$(which -a bash 2>/dev/null)"
exit 0

View File

@@ -0,0 +1,25 @@
ACCPTST:STDIO_REPLACE_DATETIMES
{datetime} UTC [ debug] cli arg arg_f = () -> {tmpdir}/x
{datetime} UTC [ info] __i_am_main_script: 0
{datetime} UTC [ info] __file: {root}/example.sh
{datetime} UTC [ info] __dir: {root}
{datetime} UTC [ info] __base: example
{datetime} UTC [ info] OSTYPE: {OSTYPE}
{datetime} UTC [ info] arg_f: {tmpdir}/x
{datetime} UTC [ info] arg_d: 0
{datetime} UTC [ info] arg_v: 0
{datetime} UTC [ info] arg_h: 0
{datetime} UTC [ info] arg_i: 0
{datetime} UTC [ info] arg_x: 0
{datetime} UTC [ info] multiple lines example - line #1
{datetime} UTC [ info] multiple lines example - line #2
{datetime} UTC [ info] imagine logging the output of 'ls -al /path/'
{datetime} UTC [ debug] Info useful to developers for debugging the application, not useful during operations.
{datetime} UTC [ info] Normal operational messages - may be harvested for reporting, measuring throughput, etc. - no action required.
{datetime} UTC [ notice] Events that are unusual but not error conditions - might be summarized in an email to developers or admins to spot potential problems - no immediate action required.
{datetime} UTC [ warning] Warning messages, not an error, but indication that an error will occur if action is not taken, e.g. file system 85% full - each item must be resolved within a given time.
{datetime} UTC [ error] Non-urgent failures, these should be relayed to developers or admins; each item must be resolved within a given time.
{datetime} UTC [ critical] Should be corrected immediately, but indicates failure in a primary system, an example is a loss of a backup ISP connection.
{datetime} UTC [ alert] Should be corrected immediately, therefore notify staff who can fix the problem. An example would be the loss of a primary ISP connection.
{datetime} UTC [emergency] A "panic" condition usually affecting multiple apps/servers/sites. At this level it would usually notify all tech staff on call.
{datetime} UTC [ info] Cleaning up. Done

View File

@@ -0,0 +1 @@
0

View File

@@ -0,0 +1,42 @@
--> command: Read 3 values
exists
127.0.0.1
nginx, nodejs
--> command: Replace three values in-place and show result
[default]
orphan=no more
[connection]
host=192.168.0.1
[software]
packages=vim
[comment]
;[command] got this new comment
command=works like a chame
;[new_command] last addition will be moved downwards again after next command
new_command=commented too
--> function: Read 3 values
exists
127.0.0.1
nginx, nodejs
--> function: Replace three values in-place and show result
[default]
orphan=no more
[connection]
host=192.168.0.1
[software]
packages=vim
[comment]
;[command] got this new comment
command=works like a chame
;[new_command] last addition will be moved downwards again after next command
new_command=commented too

View File

@@ -0,0 +1,25 @@
ACCPTST:STDIO_REPLACE_DATETIMES
{datetime} UTC [ debug] cli arg arg_f = () -> {tmpdir}/x
{datetime} UTC [ info] __i_am_main_script: 1
{datetime} UTC [ info] __file: {root}/main.sh
{datetime} UTC [ info] __dir: {root}
{datetime} UTC [ info] __base: main
{datetime} UTC [ info] OSTYPE: {OSTYPE}
{datetime} UTC [ info] arg_f: {tmpdir}/x
{datetime} UTC [ info] arg_d: 0
{datetime} UTC [ info] arg_v: 0
{datetime} UTC [ info] arg_h: 0
{datetime} UTC [ info] arg_i: 0
{datetime} UTC [ info] arg_x: 0
{datetime} UTC [ info] multiple lines example - line #1
{datetime} UTC [ info] multiple lines example - line #2
{datetime} UTC [ info] imagine logging the output of 'ls -al /path/'
{datetime} UTC [ debug] Info useful to developers for debugging the application, not useful during operations.
{datetime} UTC [ info] Normal operational messages - may be harvested for reporting, measuring throughput, etc. - no action required.
{datetime} UTC [ notice] Events that are unusual but not error conditions - might be summarized in an email to developers or admins to spot potential problems - no immediate action required.
{datetime} UTC [ warning] Warning messages, not an error, but indication that an error will occur if action is not taken, e.g. file system 85% full - each item must be resolved within a given time.
{datetime} UTC [ error] Non-urgent failures, these should be relayed to developers or admins; each item must be resolved within a given time.
{datetime} UTC [ critical] Should be corrected immediately, but indicates failure in a primary system, an example is a loss of a backup ISP connection.
{datetime} UTC [ alert] Should be corrected immediately, therefore notify staff who can fix the problem. An example would be the loss of a primary ISP connection.
{datetime} UTC [emergency] A "panic" condition usually affecting multiple apps/servers/sites. At this level it would usually notify all tech staff on call.
{datetime} UTC [ info] Cleaning up. Done

View File

@@ -0,0 +1,19 @@
ACCPTST:STDIO_REPLACE_DATETIMES
Help using {root}/main.sh
-f --file [arg] Filename to process. Required.
-t --temp [arg] Location of tempfile. Default="{tmpdir}/bar"
-v Enable verbose mode, print script as it is executed
-d --debug Enables debug mode
-h --help This page
-n --no-color Disable color output
-1 --one Do just one thing
-i --input [arg] File to process. Can be repeated.
-x Specify a flag. Can be repeated.
This is Bash3 Boilerplate's help text. Feel free to add any description of your
program or elaborate more on command-line arguments. This section is not
parsed and will be added as-is to the help.
{datetime} UTC [ info] Cleaning up. Done

View File

@@ -0,0 +1,4 @@
ACCPTST:STDIO_REPLACE_DATETIMES
{datetime} UTC [ info] arg_f: {tmpdir}/x
{datetime} UTC [ info] arg_f: {tmpdir}/x
{datetime} UTC [ info] arg_f: {tmpdir}/x

View File

@@ -0,0 +1,25 @@
ACCPTST:STDIO_REPLACE_DATETIMES
{datetime} UTC [ debug] cli arg arg_f = () -> {tmpdir}/x
{datetime} UTC [ info] __i_am_main_script: 1
{datetime} UTC [ info] __file: {root}/main.sh
{datetime} UTC [ info] __dir: {root}
{datetime} UTC [ info] __base: main
{datetime} UTC [ info] OSTYPE: {OSTYPE}
{datetime} UTC [ info] arg_f: {tmpdir}/x
{datetime} UTC [ info] arg_d: 0
{datetime} UTC [ info] arg_v: 0
{datetime} UTC [ info] arg_h: 0
{datetime} UTC [ info] arg_i: 0
{datetime} UTC [ info] arg_x: 0
{datetime} UTC [ info] multiple lines example - line #1
{datetime} UTC [ info] multiple lines example - line #2
{datetime} UTC [ info] imagine logging the output of 'ls -al /path/'
{datetime} UTC [ debug] Info useful to developers for debugging the application, not useful during operations.
{datetime} UTC [ info] Normal operational messages - may be harvested for reporting, measuring throughput, etc. - no action required.
{datetime} UTC [ notice] Events that are unusual but not error conditions - might be summarized in an email to developers or admins to spot potential problems - no immediate action required.
{datetime} UTC [ warning] Warning messages, not an error, but indication that an error will occur if action is not taken, e.g. file system 85% full - each item must be resolved within a given time.
{datetime} UTC [ error] Non-urgent failures, these should be relayed to developers or admins; each item must be resolved within a given time.
{datetime} UTC [ critical] Should be corrected immediately, but indicates failure in a primary system, an example is a loss of a backup ISP connection.
{datetime} UTC [ alert] Should be corrected immediately, therefore notify staff who can fix the problem. An example would be the loss of a primary ISP connection.
{datetime} UTC [emergency] A "panic" condition usually affecting multiple apps/servers/sites. At this level it would usually notify all tech staff on call.
{datetime} UTC [ info] Cleaning up. Done

View File

@@ -0,0 +1,9 @@
ACCPTST:STDIO_REPLACE_DATETIMES
{datetime} UTC [ info] arg_i:
{datetime} UTC [ info] - simple_input
{datetime} UTC [ info] - input_in_quotes
{datetime} UTC [ info] - input with spaces
{datetime} UTC [ info] - input with "quotes"
{datetime} UTC [ info] - last_input
{datetime} UTC [ info] arg_x: 3
{datetime} UTC [ info] arg_x: 4

View File

@@ -0,0 +1,7 @@
ACCPTST:STDIO_REPLACE_DATETIMES
{datetime} UTC [ info] arg_1: 0
{datetime} UTC [ info] arg_2: 0
{datetime} UTC [ info] arg_3: 'THREE'
{datetime} UTC [ info] arg_4: "FOUR"
{datetime} UTC [ info] arg_5: OOOPS
{datetime} UTC [ info] arg_6:

View File

@@ -0,0 +1,169 @@
ACCPTST:STDIO_REPLACE_DATETIMES
# complain about -3
Option -3 (--three) requires an argument
-0 --zero Do nothing.
-1 --one Do one thing. Required.
More description.
-2 --two Do two things.
More. Required. Description.
-3 --three [arg] Do three things.
Required.
-4 --four {arg} Do four things.
-5 --five {arg} Do five things. Required. Maybe.
-6 --six [arg] Do six things. Not Required.
Required, it is not.
-7 --seven [arg] Required. Or bust.
-8 --eight [arg] Do eight things.
More.Required.Description.
-a [arg] Do A. Required.
Default="do-a"
-b {arg} Do B.Default="do-b"
-c [arg] Required. Default="do-c"
-d {arg} Default="do-d"
This is Bash3 Boilerplate's help text. Feel free to add any description of your
program or elaborate more on command-line arguments. This section is not
parsed and will be added as-is to the help.
# complain about -4
Option -4 (--four) requires an argument
-0 --zero Do nothing.
-1 --one Do one thing. Required.
More description.
-2 --two Do two things.
More. Required. Description.
-3 --three [arg] Do three things.
Required.
-4 --four {arg} Do four things.
-5 --five {arg} Do five things. Required. Maybe.
-6 --six [arg] Do six things. Not Required.
Required, it is not.
-7 --seven [arg] Required. Or bust.
-8 --eight [arg] Do eight things.
More.Required.Description.
-a [arg] Do A. Required.
Default="do-a"
-b {arg} Do B.Default="do-b"
-c [arg] Required. Default="do-c"
-d {arg} Default="do-d"
This is Bash3 Boilerplate's help text. Feel free to add any description of your
program or elaborate more on command-line arguments. This section is not
parsed and will be added as-is to the help.
# complain about -5
Option -5 (--five) requires an argument
-0 --zero Do nothing.
-1 --one Do one thing. Required.
More description.
-2 --two Do two things.
More. Required. Description.
-3 --three [arg] Do three things.
Required.
-4 --four {arg} Do four things.
-5 --five {arg} Do five things. Required. Maybe.
-6 --six [arg] Do six things. Not Required.
Required, it is not.
-7 --seven [arg] Required. Or bust.
-8 --eight [arg] Do eight things.
More.Required.Description.
-a [arg] Do A. Required.
Default="do-a"
-b {arg} Do B.Default="do-b"
-c [arg] Required. Default="do-c"
-d {arg} Default="do-d"
This is Bash3 Boilerplate's help text. Feel free to add any description of your
program or elaborate more on command-line arguments. This section is not
parsed and will be added as-is to the help.
# complain about -8 (because -7 syntax is not supported)
Option -8 (--eight) requires an argument
-0 --zero Do nothing.
-1 --one Do one thing. Required.
More description.
-2 --two Do two things.
More. Required. Description.
-3 --three [arg] Do three things.
Required.
-4 --four {arg} Do four things.
-5 --five {arg} Do five things. Required. Maybe.
-6 --six [arg] Do six things. Not Required.
Required, it is not.
-7 --seven [arg] Required. Or bust.
-8 --eight [arg] Do eight things.
More.Required.Description.
-a [arg] Do A. Required.
Default="do-a"
-b {arg} Do B.Default="do-b"
-c [arg] Required. Default="do-c"
-d {arg} Default="do-d"
This is Bash3 Boilerplate's help text. Feel free to add any description of your
program or elaborate more on command-line arguments. This section is not
parsed and will be added as-is to the help.
# complain about -d (because -d syntax is not supported)
Option -d requires an argument
-0 --zero Do nothing.
-1 --one Do one thing. Required.
More description.
-2 --two Do two things.
More. Required. Description.
-3 --three [arg] Do three things.
Required.
-4 --four {arg} Do four things.
-5 --five {arg} Do five things. Required. Maybe.
-6 --six [arg] Do six things. Not Required.
Required, it is not.
-7 --seven [arg] Required. Or bust.
-8 --eight [arg] Do eight things.
More.Required.Description.
-a [arg] Do A. Required.
Default="do-a"
-b {arg} Do B.Default="do-b"
-c [arg] Required. Default="do-c"
-d {arg} Default="do-d"
This is Bash3 Boilerplate's help text. Feel free to add any description of your
program or elaborate more on command-line arguments. This section is not
parsed and will be added as-is to the help.
# complain about nothing
{datetime} UTC [ info] arg_0: 0
{datetime} UTC [ info] arg_1: 0
{datetime} UTC [ info] arg_2: 0
{datetime} UTC [ info] arg_3: arg3
{datetime} UTC [ info] arg_4: arg4
{datetime} UTC [ info] arg_5: arg5
{datetime} UTC [ info] arg_6:
{datetime} UTC [ info] arg_7:
{datetime} UTC [ info] arg_8: arg8
{datetime} UTC [ info] arg_a: do-a
{datetime} UTC [ info] arg_b: do-b
{datetime} UTC [ info] arg_c: do-c
{datetime} UTC [ info] arg_d: argd
# test for issue #108
{datetime} UTC [ info] arg_0: 1
{datetime} UTC [ info] arg_1: 0
{datetime} UTC [ info] arg_2: 0
{datetime} UTC [ info] arg_3: arg3
{datetime} UTC [ info] arg_4: value
{datetime} UTC [ info] arg_5: arg5
{datetime} UTC [ info] arg_6:
{datetime} UTC [ info] arg_7:
{datetime} UTC [ info] arg_8: arg8
{datetime} UTC [ info] arg_a: do-a
{datetime} UTC [ info] arg_b: do-b
{datetime} UTC [ info] arg_c: do-c
{datetime} UTC [ info] arg_d: argd

View File

@@ -0,0 +1,2 @@
ERR: Unknown protocol: 'foobarfs://'
ERR: Unknown protocol: 'foobarfs://'

View File

@@ -0,0 +1,24 @@
abc123
Use second argument to return just 1 variable.
parse_url() demo:
proto: http://
user: johndoe
pass: abc123
host: example.com
port: 8080
path: index.html
abc123
Use second argument to return just 1 variable.
parse_url() demo:
proto: http://
user: johndoe
pass: abc123
host: example.com
port: 8080
path: index.html

View File

@@ -0,0 +1,14 @@
--
[connection]
host = 127.0.0.1
--
[connection]
host = 127.0.0.1
--
port = ${I_DONT_EXIST}
[connection]
host = 127.0.0.1
port = ${I_DONT_EXIST}
--
port = ${I_DONT_EXIST}
ERROR: Unable to replace the above template vars

View File

@@ -0,0 +1,15 @@
#!/usr/bin/env bash
set -o pipefail
set -o errexit
set -o nounset
# set -o xtrace
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
__root="$(cd "$(dirname "$(dirname "$(dirname "${__dir}")")")" && pwd)"
export LOG_LEVEL=7
echo "ACCPTST:STDIO_REPLACE_DATETIMES"
# shellcheck source=example.sh
source "${__root}/example.sh" -f /tmp/x

View File

@@ -0,0 +1,8 @@
[default]
orphan=exists
[connection]
host=127.0.0.1
[software]
packages=nginx, nodejs

View File

@@ -0,0 +1,54 @@
#!/usr/bin/env bash
set -o pipefail
set -o errexit
set -o nounset
# set -o xtrace
# Set magic variables for current FILE & DIR
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
__root="$(cd "$(dirname "$(dirname "$(dirname "${__dir}")")")" && pwd)"
# echo "ACCPTST:STDIO_REPLACE_DATETIMES"
# Use as standalone:
cp -f data.ini dummy.ini
echo "--> command: Read 3 values"
bash "${__root}/src/ini_val.sh" ./dummy.ini orphan
bash "${__root}/src/ini_val.sh" ./dummy.ini connection.host
bash "${__root}/src/ini_val.sh" ./dummy.ini software.packages
bash "${__root}/src/ini_val.sh" ./dummy.ini comment.command
echo "--> command: Replace three values in-place and show result"
bash "${__root}/src/ini_val.sh" ./dummy.ini orphan "no more"
bash "${__root}/src/ini_val.sh" ./dummy.ini connection.host "192.168.0.1"
bash "${__root}/src/ini_val.sh" ./dummy.ini software.packages "vim"
bash "${__root}/src/ini_val.sh" ./dummy.ini comment.command "commented" "this key is commented"
bash "${__root}/src/ini_val.sh" ./dummy.ini comment.new_command "commented too" "last addition will be moved downwards again after next command"
bash "${__root}/src/ini_val.sh" ./dummy.ini comment.command "works like a chame" "got this new comment"
cat dummy.ini
rm -f dummy.ini
# Use as include:
cp -f data.ini dummy.ini
# shellcheck source=main.sh
source "${__root}/src/ini_val.sh"
echo "--> function: Read 3 values"
ini_val ./dummy.ini orphan
ini_val ./dummy.ini connection.host
ini_val ./dummy.ini software.packages
ini_val ./dummy.ini comment.command
echo "--> function: Replace three values in-place and show result"
ini_val ./dummy.ini orphan "no more"
ini_val ./dummy.ini connection.host "192.168.0.1"
ini_val ./dummy.ini software.packages "vim"
ini_val ./dummy.ini comment.command "commented" "this key is commited"
ini_val ./dummy.ini comment.new_command "commented too" "last addition will be moved downwards again after next command"
ini_val ./dummy.ini comment.command "works like a chame" "got this new comment"
cat dummy.ini
rm -f dummy.ini

View File

@@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -o pipefail
set -o errexit
set -o nounset
# set -o xtrace
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
__root="$(cd "$(dirname "$(dirname "$(dirname "${__dir}")")")" && pwd)"
echo "ACCPTST:STDIO_REPLACE_DATETIMES"
env LOG_LEVEL=7 bash "${__root}/main.sh" -f /tmp/x

View File

@@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -o pipefail
set -o errexit
set -o nounset
# set -o xtrace
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
__root="$(cd "$(dirname "$(dirname "$(dirname "${__dir}")")")" && pwd)"
echo "ACCPTST:STDIO_REPLACE_DATETIMES"
bash "${__root}/main.sh" -f /tmp/x -h

View File

@@ -0,0 +1,16 @@
#!/usr/bin/env bash
# set -o pipefail
# set -o errexit
set -o nounset
# set -o xtrace
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
__root="$(cd "$(dirname "$(dirname "$(dirname "${__dir}")")")" && pwd)"
echo "ACCPTST:STDIO_REPLACE_DATETIMES"
(
env LOG_LEVEL=6 bash "${__root}/main.sh" --file /tmp/x;
env LOG_LEVEL=6 bash "${__root}/main.sh" --file=/tmp/x;
env LOG_LEVEL=6 bash "${__root}/main.sh" -f /tmp/x
) 2>&1 |grep arg_f

View File

@@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -o pipefail
set -o errexit
set -o nounset
# set -o xtrace
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
__root="$(cd "$(dirname "$(dirname "$(dirname "${__dir}")")")" && pwd)"
echo "ACCPTST:STDIO_REPLACE_DATETIMES"
env LOG_LEVEL=7 NO_COLOR=true bash "${__root}/main.sh" -f /tmp/x

View File

@@ -0,0 +1,19 @@
#!/usr/bin/env bash
# set -o pipefail
# set -o errexit
set -o nounset
# set -o xtrace
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
__root="$(cd "$(dirname "$(dirname "$(dirname "${__dir}")")")" && pwd)"
echo "ACCPTST:STDIO_REPLACE_DATETIMES"
(
env LOG_LEVEL="${LOG_LEVEL:-6}" bash "${__root}/main.sh" -f dummy -i simple_input -i "input_in_quotes" -i "input with spaces" -i "input with \"quotes\"" -i last_input
) 2>&1 |grep arg_i -A 5
(
env LOG_LEVEL="${LOG_LEVEL:-6}" bash "${__root}/main.sh" -x -f dummy -x -x
env LOG_LEVEL="${LOG_LEVEL:-6}" bash "${__root}/main.sh" -f dummy -xxxx
) 2>&1 |grep arg_x

View File

@@ -0,0 +1,32 @@
#!/usr/bin/env bash
set -o pipefail
set -o errexit
set -o nounset
# set -o xtrace
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
__root="$(cd "$(dirname "$(dirname "$(dirname "${__dir}")")")" && pwd)"
read -r -d '' __usage <<-'EOF' || true # exits non-zero when EOF encountered
-1 --one Do one thing. Default="ONE"
More description.
-2 --two Do two things.
More description. Default="TWO"
-3 --three [arg] Do three things. Default="'THREE'"
More description.
-4 --four [arg] Do four things.
More description. Default='"FOUR"'
-5 --five [arg] Do five things. Default="FIVE"
More description. Default='OOOPS'
-6 --six [arg] Do six things.
More description.
EOF
export __usage
echo "ACCPTST:STDIO_REPLACE_DATETIMES"
# shellcheck source=main.sh
source "${__root}/main.sh"
for argument in ${!arg_*}; do info "${argument}: ${!argument}"; done

View File

@@ -0,0 +1,64 @@
#!/usr/bin/env bash
# shellcheck source=main.sh
set -o pipefail
set -o errexit
set -o nounset
# set -o xtrace
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
__root="$(cd "$(dirname "$(dirname "$(dirname "${__dir}")")")" && pwd)"
read -r -d '' __usage <<-'EOF' || true # exits non-zero when EOF encountered
-0 --zero Do nothing.
-1 --one Do one thing. Required.
More description.
-2 --two Do two things.
More. Required. Description.
-3 --three [arg] Do three things.
Required.
-4 --four {arg} Do four things.
-5 --five {arg} Do five things. Required. Maybe.
-6 --six [arg] Do six things. Not Required.
Required, it is not.
-7 --seven [arg] Required. Or bust.
-8 --eight [arg] Do eight things.
More.Required.Description.
-a [arg] Do A. Required.
Default="do-a"
-b {arg} Do B.Default="do-b"
-c [arg] Required. Default="do-c"
-d {arg} Default="do-d"
EOF
export __usage
export NO_COLOR="true"
echo "ACCPTST:STDIO_REPLACE_DATETIMES"
echo "# complain about -3"
(source "${__root}/main.sh") || true
echo "# complain about -4"
(source "${__root}/main.sh" -3 arg3) || true
echo "# complain about -5"
(source "${__root}/main.sh" -3 arg3 -4 arg4) || true
echo "# complain about -8 (because -7 syntax is not supported)"
(source "${__root}/main.sh" -3 arg3 -4 arg4 -5 arg5) || true
echo "# complain about -d (because -d syntax is not supported)"
(source "${__root}/main.sh" -3 arg3 -4 arg4 -5 arg5 -8 arg8) || true
echo "# complain about nothing"
(
source "${__root}/main.sh" -3 arg3 -4 arg4 -5 arg5 -8 arg8 -d argd
for argument in ${!arg_*}; do info "${argument}: ${!argument}"; done
)
echo "# test for issue #108"
(
source "${__root}/main.sh" -3 arg3 -5 arg5 -8 arg8 -d argd --four value --zero
for argument in ${!arg_*}; do info "${argument}: ${!argument}"; done
)

View File

@@ -0,0 +1,21 @@
#!/usr/bin/env bash
set -o pipefail
set -o errexit
set -o nounset
# set -o xtrace
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
__root="$(cd "$(dirname "$(dirname "$(dirname "${__dir}")")")" && pwd)"
__sysTmpDir="${TMPDIR:-/tmp}"
__sysTmpDir="${__sysTmpDir%/}" # <-- remove trailing slash on macosx
# Currently I only know how to test a failing condition here since
# it's too invasive to create actual mounts to play with on a system
bash "${__root}/src/megamount.sh" 'foobarfs://janedoe:abc123@192.168.0.1/documents' "${__sysTmpDir}/mnt/documents" || true
# shellcheck source=src/megamount.sh
source "${__root}/src/megamount.sh"
megamount 'foobarfs://janedoe:abc123@192.168.0.1/documents' "${__sysTmpDir}/mnt/documents"

View File

@@ -0,0 +1,17 @@
#!/usr/bin/env bash
set -o pipefail
set -o errexit
set -o nounset
# set -o xtrace
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
__root="$(cd "$(dirname "$(dirname "$(dirname "${__dir}")")")" && pwd)"
bash "${__root}/src/parse_url.sh" 'http://johndoe:abc123@example.com:8080/index.html' pass
bash "${__root}/src/parse_url.sh" 'http://johndoe:abc123@example.com:8080/index.html'
# shellcheck source=src/parse_url.sh
source "${__root}/src/parse_url.sh"
parse_url 'http://johndoe:abc123@example.com:8080/index.html' pass
parse_url 'http://johndoe:abc123@example.com:8080/index.html'

View File

@@ -0,0 +1,2 @@
[connection]
host = ${TARGET_HOST}

View File

@@ -0,0 +1,3 @@
[connection]
host = ${TARGET_HOST}
port = ${I_DONT_EXIST}

View File

@@ -0,0 +1,36 @@
#!/usr/bin/env bash
set -o pipefail
set -o errexit
set -o nounset
# set -o xtrace
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
__file="${__dir}/$(basename "${BASH_SOURCE[0]}")"
__base="$(basename "${__file}" .sh)"
__root="$(cd "$(dirname "$(dirname "$(dirname "${__dir}")")")" && pwd)"
__templaterTmpFile=$(mktemp "${TMPDIR:-/tmp}/${__base}.XXXXXX")
function cleanup_before_exit () { rm "${__templaterTmpFile:?}"; }
trap cleanup_before_exit EXIT
echo "--"
env TARGET_HOST="127.0.0.1" bash "${__root}/src/templater.sh" ./app.template.cfg "${__templaterTmpFile}"
cat "${__templaterTmpFile}"
echo "--"
export TARGET_HOST="127.0.0.1"
# shellcheck source=src/templater.sh
source "${__root}/src/templater.sh"
templater ./app.template.cfg "${__templaterTmpFile}"
cat "${__templaterTmpFile}"
echo "--"
env ALLOW_REMAINDERS="1" TARGET_HOST="127.0.0.1" bash "${__root}/src/templater.sh" ./break.template.cfg "${__templaterTmpFile}"
cat "${__templaterTmpFile}"
echo "--"
env TARGET_HOST="127.0.0.1" bash "${__root}/src/templater.sh" ./break.template.cfg "${__templaterTmpFile}"
cat "${__templaterTmpFile}"

View File

@@ -0,0 +1,45 @@
#!/usr/bin/env perl
use strict;
use warnings;
die "usage: $0 <file>\n" if (not @ARGV);
my $rc = 0;
my $file = shift;
open(my $fh, '<', $file) or die "Cannot open \`$file' for read: $!\n";
while (<$fh>) {
next if (/^\s*#/);
my $errors = 0;
# remove everything between single quotes
# this will remove too much in case of: echo "var='$var'"
# and thus miss an opportunity to complain later on
# also it mangles the input line irreversible
s/'[^']+'/'___'/g;
# highlight unbraced variables--
# unless properly backslash'ed
$errors += s/((?:^|[^\\]))(((\\\\)+)?\$\w)/$1\033[31m$2\033[0m/g;
# highlight single square brackets
$errors += s/((?:^|\s+))\[([^\[].+[^\]])\](\s*(;|&&|\|\|))/$1\033[31m\[\033[0m$2\033[31m\]\033[0m$3/g;
# highlight double equal sign
$errors += s/(\[\[.*)(==)(.*\]\])/$1\033[31m$2\033[0m$3/g;
# highlight tabs mixed with whitespace at beginning of lines
$errors += s/^( *)(\t+ *)/\033[31m\[$2\]\033[0m/;
# highlight trailing whitespace
$errors += s/([ \t]+)$/\033[31m\[$1\]\033[0m/;
next if (not $errors);
print "${file}[$.]: $_";
$rc = 1;
}
close($fh);
exit $rc;