41 Commits

Author SHA1 Message Date
cc57b8db69 Release 1.2.0 2016-02-16 22:23:42 +01:00
2019c5146a Upgrade version 2016-02-16 22:23:28 +01:00
d365e8dcea Allow disabling colors via NO_COLOR environment variable 2016-02-16 22:19:40 +01:00
915f858d5e Add __os magic var 2016-02-16 22:19:08 +01:00
cbe70aa80e Put comments on own line 2016-02-16 22:09:28 +01:00
ff907092a3 Document caveats 2016-02-16 22:08:27 +01:00
cdc69d9e03 Update colors 2016-02-16 22:05:19 +01:00
56721e9cd5 Add test for longopt parsing 2016-02-16 22:05:11 +01:00
df3d535ab1 Make long option parsing work on OSX's BSD awk 20070501 2016-02-16 21:59:38 +01:00
894c7fe538 Wording 2016-02-16 21:58:51 +01:00
2196cc4411 Add __base magic var 2016-02-16 21:58:25 +01:00
5b4800bad8 Try sudo:false once more
For
https://github.com/travis-ci/travis-ci/issues/5638#issuecomment-18486180
0
2016-02-16 21:27:08 +01:00
472c9e3b74 Fix markdown inconsistencies 2016-02-16 21:25:59 +01:00
90ad85f419 Port back more refined colorscheme from @arathai's fork 2016-02-16 21:24:41 +01:00
d9a0c11e49 Add changelog 2016-02-16 21:04:22 +01:00
9935335ee8 Add @zbeekman as an author 2016-02-16 20:53:59 +01:00
e90ad7421f Merge pull request #3 from zbeekman/longargs
Enable long, GNU style options RE: issue-1
2016-02-16 20:50:54 +01:00
9d2bcdbfb4 Update expected test output
ATTN: @kvz I think I did this correctly, but please look through the
 Travis-CI output nonetheless.
2016-02-16 14:39:48 -05:00
bfb8d40f6c Enable long, GNU style options
- Enable long, GNU style options, fixes #1
 - *CAVEAT* A short option must be preset for every long option;
   but every short option need *not* have a long option
 - No BASH 4 features were added, works with bash 3 and standard sed and
   awk
 - `--` is still respected as the separator between options and arguments
 - Use `awk` only instead of `awk` and `sed` for parsing short options
   from usage string
 - Enable errexit, nounset and pipefail at the top
2016-02-16 14:39:10 -05:00
dd5950975d Fix popd 2016-02-16 20:25:30 +01:00
7a9d116d2c Add dependencies 2016-02-16 18:55:05 +01:00
ae074aac0c Revert Travis container infra. Thx @zbeekman 2016-02-16 18:51:49 +01:00
30cfd19fd9 Add debug test scenario 2016-02-16 15:49:37 +01:00
ecd6a9f04b Easier testing on travis 2016-02-16 15:48:48 +01:00
7a3a07989f Use containers #4 2016-02-16 15:48:32 +01:00
dbedd8f983 Update fixtures 2016-02-16 15:33:57 +01:00
dde3b70596 Also replace tmp dir on Travis 2016-02-16 15:13:40 +01:00
bdc8778b2c Update README.md 2016-02-16 15:01:51 +01:00
63cd89a659 Set up basic acceptance testing #4 2016-02-16 15:01:26 +01:00
68219d21d4 Update README.md 2016-02-15 15:52:05 +01:00
c71b6d14c4 Update README.md 2016-02-15 15:38:27 +01:00
4c256ed58d Update README.md 2016-02-15 12:04:32 +01:00
f2e8ff236a Add clarifications 2015-11-11 16:10:35 +01:00
8147ee81b5 Release 1.1.0 2015-06-29 19:46:16 +02:00
437d384815 Support for ALLOW_REMAINDERS=1 2015-06-29 19:46:08 +02:00
19fcad6851 Make PHONY 2015-06-29 19:45:14 +02:00
df0ad9fe25 Merge pull request #2 from jokajak/patch-1
Update main.sh
2015-02-20 07:40:30 +01:00
23b68a1bfc Update main.sh
Fix super trivial typo
2015-02-19 19:51:00 -05:00
5b8cf352c8 Use BASH_SOURCE[0] 2014-11-11 12:41:18 +01:00
2f4e089311 Update README.md 2014-11-04 15:23:05 +01:00
4cef357986 Update package.json 2014-11-04 14:55:37 +01:00
21 changed files with 557 additions and 71 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
npm-debug.log
node_modules

7
.travis.yml Normal file
View File

@ -0,0 +1,7 @@
language: node_js
node_js:
- "4.2.1"
script: npm run test
# For some reason, `sudo: false` broke nvm. Tried this build two times:
# https://s3.amazonaws.com/archive.travis-ci.org/jobs/109619626/log.txt
sudo: false

View File

@ -1,16 +1,40 @@
SHELL := /usr/bin/env bash
# Licensed under MIT.
# Copyright (2016) by Kevin van Zonneveld https://twitter.com/kvz
#
# https://www.npmjs.com/package/fakefile
#
# This Makefile offers convience shortcuts into any Node.js project that utilizes npm scripts.
# It functions as a wrapper around the actual listed in `package.json`
# So instead of typing:
#
# $ npm script build:assets
#
# you could also type:
#
# $ make build-assets
#
# Notice that colons (:) are replaced by dashes for Makefile compatibility.
#
# The benefits of this wrapper are:
#
# - You get to keep the the scripts package.json, which is more portable
# (Makefiles & Windows are harder to mix)
# - Offer a polite way into the project for developers coming from different
# languages (npm scripts is obviously very Node centric)
# - Profit from better autocomplete (make <TAB><TAB>) than npm currently offers.
# OSX users will have to install bash-completion
# (http://davidalger.com/development/bash-completion-on-os-x-with-brew/)
release-major:
npm version major -m "Release %s"
git push
npm publish
define npm_script_targets
TARGETS := $(shell node -e 'for (var k in require("./package.json").scripts) {console.log(k.replace(/:/g, "-"));}')
$$(TARGETS):
npm run $(subst -,:,$(MAKECMDGOALS))
release-minor:
npm version minor -m "Release %s"
git push
npm publish
.PHONY: $$(TARGETS)
endef
release-patch:
npm version patch -m "Release %s"
git push
npm publish
$(eval $(call npm_script_targets))
# These npm run scripts are available, without needing to be mentioned in `package.json`
install:
npm run install

118
README.md
View File

@ -1,18 +1,10 @@
# bash3boilerplate
<!-- badges/ -->
[![Build Status](https://secure.travis-ci.org/kvz/bash3boilerplate.png?branch=master)](http://travis-ci.org/kvz/bash3boilerplate "Check this project's build status on TravisCI")
[![Gittip donate button](http://img.shields.io/gittip/kvz.png)](https://www.gittip.com/kvz/ "Sponsor the development of bash3boilerplate via Gittip")
[![Flattr donate button](http://img.shields.io/flattr/donate.png?color=yellow)](https://flattr.com/submit/auto?user_id=kvz&url=https://github.com/kvz/bash3boilerplate&title=bash3boilerplate&language=&tags=github&category=software "Sponsor the development of bash3boilerplate via Flattr")
[![PayPayl donate button](http://img.shields.io/paypal/donate.png?color=yellow)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=kevin%40vanzonneveld%2enet&lc=NL&item_name=Open%20source%20donation%20to%20Kevin%20van%20Zonneveld&currency_code=USD&bn=PP-DonationsBF%3abtn_donate_SM%2egif%3aNonHosted "Sponsor the development of bash3boilerplate via Paypal")
[![BitCoin donate button](http://img.shields.io/bitcoin/donate.png?color=yellow)](https://coinbase.com/checkouts/19BtCjLCboRgTAXiaEvnvkdoRyjd843Dg2 "Sponsor the development of bash3boilerplate via BitCoin")
<!-- /badges -->
[![Build Status](https://travis-ci.org/kvz/bash3boilerplate.svg?branch=master)](https://travis-ci.org/kvz/bash3boilerplate)
When hacking up BASH scripts, I often find there are some
higherlevel things like logging, configuration, commandline argument
higher level things like logging, configuration, command-line argument
parsing that:
- I need everytime
- I need every time
- Take quite some effort to get right
- Keep you from your actual work
@ -20,7 +12,34 @@ Here's an attempt to bundle those things in a generalized way so that
they are reusable as-is in most of my (and hopefully your, if not ping
me) programs.
An up to date [intro is found on my blog](http://kvz.io/blog/2013/02/26/introducing-bash3boilerplate/).
## Goals
Delete-key-friendly. I propose people use `main.sh` as a base and remove the
parts they don't need, rather than introducing a ton of packages, includes, compilers, etc.
Aiming for portability, I'm targeting Bash 3 (OSX still ships
with 3 for instance). If you're going to ask people to install
Bash 4 first, you might as well pick a more advanced language as a
dependency.
## Features
- Structure
- Configuration by environment variables
- Configuration by command-line arguments (definitions parsed from help info,
so no duplication needed)
- Magic variables like `__file` and `__dir`
- Logging that supports colors and is compatible with [Syslog Severity levels](http://en.wikipedia.org/wiki/Syslog#Severity_levels)
## Installation
There are 3 ways you can install (parts of) b3bp:
1. Just get the main template: `wget https://raw.githubusercontent.com/kvz/bash3boilerplate/master/main.sh`
2. Clone the entire project: `git clone git@github.com:kvz/bash3boilerplate.git`
3. As of `v1.0.3`, b3bp can be installed as a `package.json` dependency via: `npm install --save bash3boilerplate`
Although `3` introduces a node.js dependency, this does allow for easy version pinning & distrubtions in environments that already have this prerequisite. But nothing prevents you from just using `curl` and keep your project or build system low on external dependencies.
## Versioning
@ -32,13 +51,80 @@ Releases will be numbered with the following format:
And constructed with the following guidelines:
* Breaking backward compatibility bumps the major (and resets the minor and patch)
* New additions without breaking backward compatibility bumps the minor (and resets the patch)
* Bug fixes and misc changes bumps the patch
- Breaking backward compatibility bumps the major (and resets the minor and patch)
- New additions without breaking backward compatibility bumps the minor (and resets the patch)
- Bug fixes and misc changes bumps the patch
For more information on SemVer, please visit [http://semver.org](http://semver.org).
## Changelog
### v1.2.0 (Unreleased)
- Allow disabling colors via `NO_COLOR` environment variable
- Enable errexit, nounset and pipefail at the top
- More refined colors (thanks @arathai)
- Add Changelog
- Add `__os` magic var
- Add `__base` magic var
- Enable long, GNU style options (thanks @zbeekman)
### v1.1.0 (2015-06-29)
- Add `ALLOW_REMAINDERS` configuration to templater
- Fix typo: 'debugmdoe' to 'debugmode' (thanks @jokajak)
- Use `${BASH_SOURCE[0]}` for `__file` instead of `${0}`
### v1.0.3 (2014-11-02)
- Add `ini_val`, `megamount`, `parse_url`
- Add re-usable libraries in `./src`
- Use npm for distribution
## Best practices
As of `v1.0.3`, b3bp adds some nice re-usable libraries in `./src`. Later on we'll be using snippets inside this directory to build custom packages. In order to make the snippets in `./src` more useful, we recommend these guidelines.
### Library exports
It's nice to have a bash package that can be used in the terminal and also be invoked as a command line function. To achieve this the exporting of your functionality *should* follow this pattern:
```bash
if [ "${BASH_SOURCE[0]}" != ${0} ]; then
export -f my_script
else
my_script "${@}"
exit $?
fi
```
This allows a user to `source` your script or invoke as a script.
```bash
# Running as a script
$ ./my_script.sh some args --blah
# Sourcing the script
$ source my_script.sh
$ my_script some more args --blah
```
(taken from the [bpkg](https://raw.githubusercontent.com/bpkg/bpkg/master/README.md) project)
## Todo
- [ ] Make `src` libs adhere to Best practices
- [ ] `make build` system for generating custom builds
- [ ] tests & releases via Travis
## Sponsoring
<!-- badges/ -->
[![Gittip donate button](http://img.shields.io/gittip/kvz.png)](https://www.gittip.com/kvz/ "Sponsor the development of bash3boilerplate via Gittip")
[![Flattr donate button](http://img.shields.io/flattr/donate.png?color=green)](https://flattr.com/submit/auto?user_id=kvz&url=https://github.com/kvz/bash3boilerplate&title=bash3boilerplate&language=&tags=github&category=software "Sponsor the development of bash3boilerplate via Flattr")
[![PayPayl donate button](http://img.shields.io/paypal/donate.png?color=green)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=kevin%40vanzonneveld%2enet&lc=NL&item_name=Open%20source%20donation%20to%20Kevin%20van%20Zonneveld&currency_code=USD&bn=PP-DonationsBF%3abtn_donate_SM%2egif%3aNonHosted "Sponsor the development of bash3boilerplate via Paypal")
[![BitCoin donate button](http://img.shields.io/bitcoin/donate.png?color=green)](https://coinbase.com/checkouts/19BtCjLCboRgTAXiaEvnvkdoRyjd843Dg2 "Sponsor the development of bash3boilerplate via BitCoin")
<!-- /badges -->
## License
Copyright (c) 2013 Kevin van Zonneveld, [http://kvz.io](http://kvz.io)

140
main.sh
View File

@ -9,10 +9,12 @@
# - https://github.com/kvz/bash3boilerplate
# - http://kvz.io/blog/2013/02/26/introducing-bash3boilerplate/
#
# Version 1.0.0
# Version 1.2.0
#
# Authors:
# - Kevin van Zonneveld (http://kvz.io)
# - Izaak Beekman (https://izaakbeekman.com/)
# - Alexander Rathai (Alexander.Rathai@gmail.com)
#
# Usage:
# LOG_LEVEL=7 ./main.sh -f /tmp/x -d
@ -24,37 +26,62 @@
### Configuration
#####################################################################
# Exit on error. Append ||true if you expect an error.
# `set` is safer than relying on a shebang like `#!/bin/bash -e` because that is neutralized
# when someone runs your script as `bash yourscript.sh`
set -o errexit
set -o nounset
# Bash will remember & return the highest exitcode in a chain of pipes.
# This way you can catch the error in case mysqldump fails in `mysqldump |gzip`
set -o pipefail
# set -o xtrace
# Environment variables and their defaults
LOG_LEVEL="${LOG_LEVEL:-6}" # 7 = debug -> 0 = emergency
NO_COLOR="${NO_COLOR:-}" # true = disable color. otherwise autodetected
# Commandline options. This defines the usage page, and is used to parse cli
# opts & defaults from. The parsing is unforgiving so be precise in your syntax
read -r -d '' usage <<-'EOF'
-f [arg] Filename to process. Required.
-t [arg] Location of tempfile. Default="/tmp/bar"
-d Enables debug mode
-h This page
# - A short option must be preset for every long option; but every short option
# need not have a long option
# - `--` is respected as the separator between options and arguments
read -r -d '' usage <<-'EOF' || true # exits non-zero when EOF encountered
-f --file [arg] Filename to process. Required.
-t --temp [arg] Location of tempfile. Default="/tmp/bar"
-v Enable verbose mode, print script as it is executed
-d --debug Enables debug mode
-h --help This page
EOF
# Set magic variables for current FILE & DIR
# Set magic variables for current file and its directory.
# BASH_SOURCE[0] is used so we can display the current file even if it is sourced by a parent script.
# If you need the script that was executed, consider using $0 instead.
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
__file="${__dir}/$(basename "${0}")"
__file="${__dir}/$(basename "${BASH_SOURCE[0]}")"
__base="$(basename ${__file} .sh)"
__os="Linux"
if [[ "${OSTYPE:-}" == "darwin"* ]]; then
__os="OSX"
fi
### Functions
#####################################################################
function _fmt () {
local color_ok="\x1b[32m"
local color_bad="\x1b[31m"
local color="${color_bad}"
if [ "${1}" = "debug" ] || [ "${1}" = "info" ] || [ "${1}" = "notice" ]; then
color="${color_ok}"
fi
local color_debug="\x1b[35m"
local color_info="\x1b[32m"
local color_notice="\x1b[34m"
local color_warning="\x1b[33m"
local color_error="\x1b[31m"
local color_critical="\x1b[1;31m"
local color_alert="\x1b[1;33;41m"
local color_emergency="\x1b[1;4;5;33;41m"
local colorvar=color_$1
local color="${!colorvar:-$color_error}"
local color_reset="\x1b[0m"
if [[ "${TERM}" != "xterm"* ]] || [ -t 1 ]; then
if [ "${NO_COLOR}" = "true" ] || [[ "${TERM:-}" != "xterm"* ]] || [ -t 1 ]; then
# Don't use colors on pipes or non-recognized terminals
color=""; color_reset=""
fi
@ -89,14 +116,27 @@ trap cleanup_before_exit EXIT
# Translate usage string -> getopts arguments, and set $arg_<flag> defaults
while read line; do
# fetch single character version of option sting
opt="$(echo "${line}" |awk '{print $1}' |sed -e 's#^-##')"
# fetch long version if present
long_opt="$(echo "${line}" |awk '/\-\-/ {print $2}' |sed -e 's#^--##')"
# map long name back to short name
varname="short_opt_${long_opt}"
eval "${varname}=\"${opt}\""
# check if option takes an argument
varname="has_arg_${opt}"
if ! echo "${line}" |egrep '\[.*\]' >/dev/null 2>&1; then
init="0" # it's a flag. init with 0
eval "${varname}=0"
else
opt="${opt}:" # add : if opt has arg
init="" # it has an arg. init with ""
eval "${varname}=1"
fi
opts="${opts}${opt}"
opts="${opts:-}${opt}"
varname="arg_${opt:0:1}"
if ! echo "${line}" |egrep '\. Default=' >/dev/null 2>&1; then
@ -107,20 +147,40 @@ while read line; do
fi
done <<< "${usage}"
# Allow long options like --this
opts="${opts}-:"
# Reset in case getopts has been used previously in the shell.
OPTIND=1
# Overwrite $arg_<flag> defaults with the actual CLI options
while getopts "${opts}" opt; do
line="$(echo "${usage}" |grep "\-${opt}")"
[ "${opt}" = "?" ] && help "Invalid use of script: ${@} "
if [ "${opt}" = "-" ]; then
# OPTARG is long-option-name or long-option=value
if [[ "${OPTARG}" =~ .*=.* ]]; then
# --key=value format
long=${OPTARG/=*/}
# Set opt to the short option corresponding to the long option
eval "opt=\"\${short_opt_${long}}\""
OPTARG=${OPTARG#*=}
else
# --key value format
# Map long name to short version of option
eval "opt=\"\${short_opt_${OPTARG}}\""
# Only assign OPTARG if option takes an argument
eval "OPTARG=\"\${@:OPTIND:\${has_arg_${opt}}}\""
# shift over the argument if argument is expected
((OPTIND+=has_arg_${opt}))
fi
# we have set opt/OPTARG to the short value and the argument as OPTARG if it exists
fi
varname="arg_${opt:0:1}"
default="${!varname}"
value="${OPTARG}"
if [ -z "${OPTARG}" ] && [ "${default}" = "0" ]; then
value="${OPTARG:-}"
if [ -z "${OPTARG:-}" ] && [ "${default}" = "0" ]; then
value="1"
fi
@ -130,10 +190,10 @@ done
shift $((OPTIND-1))
[ "$1" = "--" ] && shift
[ "${1:-}" = "--" ] && shift
### Switches (like -d for debugmdoe, -h for showing helppage)
### Switches (like -d for debugmode, -h for showing helppage)
#####################################################################
# debug mode
@ -142,6 +202,11 @@ if [ "${arg_d}" = "1" ]; then
LOG_LEVEL="7"
fi
# verbose mode
if [ "${arg_v}" = "1" ]; then
set -o verbose
fi
# help mode
if [ "${arg_h}" = "1" ]; then
# Help exists with code 1
@ -152,27 +217,24 @@ fi
### Validation (decide what's required for running your script and error out)
#####################################################################
[ -z "${arg_f}" ] && help "Setting a filename with -f is required"
[ -z "${LOG_LEVEL}" ] && emergency "Cannot continue without LOG_LEVEL. "
[ -z "${arg_f:-}" ] && help "Setting a filename with -f or --file is required"
[ -z "${LOG_LEVEL:-}" ] && emergency "Cannot continue without LOG_LEVEL. "
### Runtime
#####################################################################
# Exit on error. Append ||true if you expect an error.
# set -e is safer than #!/bin/bash -e because that is neutralised if
# someone runs your script like `bash yourscript.sh`
set -o errexit
set -o nounset
info "__file: ${__file}"
info "__dir: ${__dir}"
info "__base: ${__base}"
info "__os: ${__os}"
# Bash will remember & return the highest exitcode in a chain of pipes.
# This way you can catch the error in case mysqldump fails in `mysqldump |gzip`
set -o pipefail
if [[ "${OSTYPE}" == "darwin"* ]]; then
info "You are on OSX"
fi
info "arg_f: ${arg_f}"
info "arg_d: ${arg_d}"
info "arg_v: ${arg_v}"
info "arg_h: ${arg_h}"
# All of these go to STDERR, so you can use STDOUT for piping machine readable information to other software
debug "Info useful to developers for debugging the application, not useful during operations."
info "Normal operational messages - may be harvested for reporting, measuring throughput, etc. - no action required."
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."

View File

@ -1,4 +1,19 @@
{
"name": "bash3boilerplate",
"version": "1.0.3"
"description": "Copypastable templates to write better bash scripts",
"version": "1.2.0",
"scripts": {
"release:major": "env SEMANTIC=major npm run release",
"release:minor": "env SEMANTIC=minor npm run release",
"release:patch": "env SEMANTIC=patch npm run release",
"test": "test/acceptance.sh",
"save:fixtures": "cross-env SAVE_FIXTURES=true npm run test",
"release": "npm version ${SEMANTIC:-patch} -m \"Release %s\" && git push --tags && npm publish"
},
"dependencies": {
"fakefile": "0.0.6"
},
"devDependencies": {
"cross-env": "1.0.7"
}
}

View File

@ -1,10 +1,14 @@
#!/usr/bin/env bash
# Copyright (c) 2014, Transloadit Ltd.
#
# This file
# This file:
# - takes a source (template) & destination (config) filepath argument
# - and then replaces placeholders with variables found in the environment
#
# Run as:
#
# ALLOW_REMAINDERS=1 templater.sh input.cfg output.cfg
#
# Authors:
# - Kevin van Zonneveld <kevin@transloadit.com>
@ -17,6 +21,8 @@ sed=""
[ -n "$(which sed)" ] && sed="$(which sed)"
[ -n "$(which gsed)" ] && sed="$(which gsed)"
ALLOW_REMAINDERS="${ALLOW_REMAINDERS:-0}"
templateSrc="${1}"
templateDst="${2}"
@ -36,7 +42,7 @@ done
# cat "${templateDst}"
if grep '${' ${templateDst}; then
if grep '${' ${templateDst} && [ "${ALLOW_REMAINDERS}" == "0" ]; then
echo "ERROR: Unable to replace the above template vars"
exit 1
fi

166
test/acceptance.sh Executable file
View File

@ -0,0 +1,166 @@
#!/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)"
__file="${__dir}/$(basename "${BASH_SOURCE[0]}")"
__base="$(basename ${__file} .sh)"
__root="$(cd "$(dirname "${__dir}")" && pwd)"
scenarios="${1:-$(ls ${__dir}/scenario/|egrep -v ^prepare$)}"
__sysTmpDir="${TMPDIR:-/tmp}"
__sysTmpDir="${__sysTmpDir%/}" # <-- remove trailing slash on macosx
__b3bpTmpDir="${__sysTmpDir}/b3bp"
mkdir -p "${__b3bpTmpDir}"
if [[ "${OSTYPE}" == "darwin"* ]]; then
cmdSed=gsed
else
cmdSed=sed
fi
if [[ "${OSTYPE}" == "darwin"* ]]; then
cmdTimeout="gtimeout --kill-after=6m 5m"
else
cmdTimeout="timeout --kill-after=6m 5m"
fi
__node="$(which node)"
__os="linux"
if [[ "${OSTYPE}" == "darwin"* ]]; then
__os="darwin"
fi
__arch="amd64"
if ! which "${cmdSed}" > /dev/null; then
echo "Please install ${cmdSed}"
exit 1
fi
# 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.
for scenario in $(echo ${scenarios}); do
echo "==> Scenario: ${scenario}"
pushd "${__dir}/scenario/${scenario}" > /dev/null
# Run scenario
(${cmdTimeout} bash ./run.sh \
> "${__b3bpTmpDir}/${scenario}.stdio" 2>&1; \
echo "${?}" > "${__b3bpTmpDir}/${scenario}.exitcode" \
) || true
# Clear out environmental specifics
for typ in $(echo stdio exitcode); do
curFile="${__b3bpTmpDir}/${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@${__os}@{os}@g" "${curFile}" \
-e "s@${__arch}@{arch}@g" "${curFile}" \
-e "s@OSX@{os}@g" "${curFile}" \
-e "s@Linux@{os}@g" "${curFile}" \
|| false
if [ "$(cat "${curFile}" |grep 'B3BP:STDIO_REPLACE_IPS' |wc -l)" -gt 0 ]; 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 [ "$(cat "${curFile}" |grep 'B3BP:STDIO_REPLACE_UUIDS' |wc -l)" -gt 0 ]; then
"${cmdSed}" -i \
-r 's@[0-9a-f\-]{32,40}@{uuid}@g' \
"${curFile}"
fi
if [ "$(cat "${curFile}" |grep 'B3BP:STDIO_REPLACE_BIGINTS' |wc -l)" -gt 0 ]; then
# Such as: 3811298194
"${cmdSed}" -i \
-r 's@[0-9]{7,64}@{bigint}@g' \
"${curFile}"
fi
if [ "$(cat "${curFile}" |grep 'B3BP:STDIO_REPLACE_DATETIMES' |wc -l)" -gt 0 ]; 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 [ "$(cat "${curFile}" |grep 'B3BP:STDIO_REPLACE_LONGTIMES' |wc -l)" -gt 0 ]; 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 [ "$(cat "${curFile}" |grep 'B3BP:STDIO_REPLACE_DURATIONS' |wc -l)" -gt 0 ]; 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 [ "$(cat "${curFile}" |grep 'B3BP:STDIO_REPLACE_REMOTE_EXEC' |wc -l)" -gt 0 ]; then
egrep -v 'remote-exec\): [ a-zA-Z]' "${curFile}" > "${__sysTmpDir}/b3bp-filtered.txt"
mv "${__sysTmpDir}/b3bp-filtered.txt" "${curFile}"
fi
done
# Save these as new fixtures?
if [ "${SAVE_FIXTURES:-}" = "true" ]; then
for typ in $(echo stdio exitcode); do
curFile="${__b3bpTmpDir}/${scenario}.${typ}"
cp -f \
"${curFile}" \
"${__dir}/fixture/${scenario}.${typ}"
done
fi
# Compare
for typ in $(echo stdio exitcode); do
curFile="${__b3bpTmpDir}/${scenario}.${typ}"
echo -n " comparing ${typ}.. "
if [ "${typ}" = "stdio" ]; then
if [ "$(cat "${curFile}" |grep 'B3BP:STDIO_SKIP_COMPARE' |wc -l)" -gt 0 ]; then
echo "skip"
continue
fi
fi
diff \
--strip-trailing-cr \
"${__dir}/fixture/${scenario}.${typ}" \
"${curFile}" || ( \
echo -e "\n\n==> MISMATCH OF: ${typ}";
echo -e "\n\n==> EXPECTED STDIO: ";
cat "${__dir}/fixture/${scenario}.stdio";
echo -e "\n\n==> ACTUAL STDIO: ";
cat "${__b3bpTmpDir}/${scenario}.stdio";
exit 1; \
)
echo "✓"
done
popd > /dev/null
done

0
test/fixture/.empty Normal file
View File

View File

@ -0,0 +1 @@
1

19
test/fixture/debug.stdio Normal file
View File

@ -0,0 +1,19 @@
B3BP:STDIO_REPLACE_DATETIMES
{datetime} UTC [ debug] cli arg arg_f = () -> {tmpdir}/x
{datetime} UTC [ info] __file: {root}/main.sh
{datetime} UTC [ info] __dir: {root}
{datetime} UTC [ info] __base: main
{datetime} UTC [ info] __os: {os}
{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 [ 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. This is a debug message
{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 @@
1

11
test/fixture/help.stdio Normal file
View File

@ -0,0 +1,11 @@
B3BP: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
{datetime} UTC [ info] Cleaning up. Done

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1,4 @@
B3BP: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 @@
1

View File

@ -0,0 +1,19 @@
B3BP:STDIO_REPLACE_DATETIMES
{datetime} UTC [ debug] cli arg arg_f = () -> {tmpdir}/x
{datetime} UTC [ info] __file: {root}/main.sh
{datetime} UTC [ info] __dir: {root}
{datetime} UTC [ info] __base: main
{datetime} UTC [ info] __os: {os}
{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 [ 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. This is a debug message
{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,15 @@
#!/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)"
__file="${__dir}/$(basename "${BASH_SOURCE[0]}")"
__base="$(basename ${__file} .sh)"
__root="$(cd "$(dirname $(dirname $(dirname "${__dir}")))" && pwd)"
echo "B3BP:STDIO_REPLACE_DATETIMES"
env LOG_LEVEL=8 bash "${__root}/main.sh" -f /tmp/x

15
test/scenario/help/run.sh Executable file
View File

@ -0,0 +1,15 @@
#!/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)"
__file="${__dir}/$(basename "${BASH_SOURCE[0]}")"
__base="$(basename ${__file} .sh)"
__root="$(cd "$(dirname $(dirname $(dirname "${__dir}")))" && pwd)"
echo "B3BP:STDIO_REPLACE_DATETIMES"
bash "${__root}/main.sh" -h

View File

@ -0,0 +1,17 @@
#!/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)"
__file="${__dir}/$(basename "${BASH_SOURCE[0]}")"
__base="$(basename ${__file} .sh)"
__root="$(cd "$(dirname $(dirname $(dirname "${__dir}")))" && pwd)"
echo "B3BP: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,15 @@
#!/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)"
__file="${__dir}/$(basename "${BASH_SOURCE[0]}")"
__base="$(basename ${__file} .sh)"
__root="$(cd "$(dirname $(dirname $(dirname "${__dir}")))" && pwd)"
echo "B3BP:STDIO_REPLACE_DATETIMES"
env LOG_LEVEL=8 NO_COLOR=true bash "${__root}/main.sh" -f /tmp/x