include/herokuish.bash (133 lines of code) (raw):
if [[ "${BASH_VERSINFO[0]}" -lt "4" ]]; then
echo "!! Your system Bash is out of date: $BASH_VERSION"
echo "!! Please upgrade to Bash 4 or greater."
exit 2
fi
readonly app_path="${APP_PATH:-/app}"
readonly env_path="${ENV_PATH:-/tmp/env}"
readonly build_path="${BUILD_PATH:-/tmp/build}"
readonly cache_path="${CACHE_PATH:-/tmp/cache}"
readonly import_path="${IMPORT_PATH:-/tmp/app}"
readonly buildpack_path="${BUILDPACK_PATH:-/tmp/buildpacks}"
declare unprivileged_user="$USER"
declare unprivileged_group="${USER/nobody/nogroup}"
export PS1='\[\033[01;34m\]\w\[\033[00m\] \[\033[01;32m\]$ \[\033[00m\]'
ensure-paths() {
mkdir -p \
"$app_path" \
"$env_path" \
"$build_path" \
"$cache_path" \
"$buildpack_path"
}
paths() {
declare desc="Shows path settings"
printf "%-32s # %s\n" \
"APP_PATH=$app_path" "Application path during runtime" \
"ENV_PATH=$env_path" "Path to files for defining base environment" \
"BUILD_PATH=$build_path" "Working directory during builds" \
"CACHE_PATH=$cache_path" "Buildpack cache location" \
"IMPORT_PATH=$import_path" "Mounted path to copy to app path" \
"BUILDPACK_PATH=$buildpack_path" "Path to installed buildpacks"
}
version() {
declare desc="Show version and supported version info"
echo "herokuish: ${HEROKUISH_VERSION:-dev}"
echo "buildpacks:"
asset-cat include/buildpacks.txt | sed -e 's/.*heroku\///' -e 's/.*dokku\///' | xargs printf " %-26s %s\n"
}
title() {
echo $'\e[1G----->' "$@"
}
indent() {
while read -r line; do
if [[ "$line" == --* ]] || [[ "$line" == ==* ]]; then
# shellcheck disable=SC2086
echo $'\e[1G'$line
else
echo $'\e[1G ' "$line"
fi
done
}
unprivileged() {
setuidgid "$unprivileged_user" "$@"
}
detect-unprivileged() {
unprivileged_user="$(stat -c %U "$app_path")"
unprivileged_group="${unprivileged_user/nobody/nogroup}"
}
randomize-unprivileged() {
local userid="$((RANDOM+1000))"
local username="u${userid}"
addgroup --quiet --gid "$userid" "$username"
adduser \
--shell /bin/bash \
--disabled-password \
--force-badname \
--no-create-home \
--uid "$userid" \
--gid "$userid" \
--gecos '' \
--quiet \
--home "$app_path" \
"$username"
unprivileged_user="$username"
unprivileged_group="$username"
}
herokuish-test() {
declare desc="Test running an app through Herokuish"
declare path="${1:-/}" expected="$2"
export PORT=5678
echo "::: BUILDING APP :::"
buildpack-build
echo "::: STARTING WEB :::"
procfile-start web &
for retry in $(seq 1 30); do
sleep 1
if ! nc -z -w 5 localhost "$PORT"; then
echo "::: RETRYING LISTENER ($retry) :::"
else
echo "::: FOUND LISTENER :::" && break
fi
done
echo "::: CHECKING APP :::"
local output
output="$(curl --fail --retry 10 --retry-delay 2 -v -s "localhost:${PORT}${path}")"
if [[ "$expected" ]]; then
sleep 1
echo "::: APP OUTPUT :::"
echo -e "$output"
if [[ "$output" != "$expected" ]]; then
echo "::: TEST FAILED :::"
exit 2
fi
fi
echo "::: TEST FINISHED :::"
}
main() {
set -eo pipefail; [[ "$TRACE" ]] && set -x
if [[ -d "$import_path" ]] && [[ -n "$(ls -A "$import_path")" ]]; then
rm -rf "$app_path" && cp -r "$import_path" "$app_path"
fi
cmd-export paths
cmd-export version
cmd-export herokuish-test test
cmd-export-ns buildpack "Use and install buildpacks"
cmd-export buildpack-build
cmd-export buildpack-install
cmd-export buildpack-list
cmd-export buildpack-test
cmd-export-ns slug "Manage application slugs"
cmd-export slug-import
cmd-export slug-generate
cmd-export slug-export
cmd-export-ns procfile "Use Procfiles and run app commands"
cmd-export procfile-start
cmd-export procfile-exec
cmd-export procfile-parse
case "$SELF" in
/start) procfile-start "$@";;
/exec) procfile-exec "$@";;
/build) buildpack-build;;
*) cmd-ns "" "$@";
esac
}