Skip to content

Instantly share code, notes, and snippets.

@estum
Last active February 13, 2024 14:33
Show Gist options
  • Save estum/0b32147f644fbfbd5462a8b6a12b82c5 to your computer and use it in GitHub Desktop.
Save estum/0b32147f644fbfbd5462a8b6a12b82c5 to your computer and use it in GitHub Desktop.
Simple dotenv wrapper on Bash (replace dotenv gem).
#!/usr/bin/env bash
#
#/ Usage: app-env [[-e <DOTENV_FILE>]... ] [[-s <SOURCE_FILE>]... ] [--] <command> [<args>...]
#/ app-env [-h|--help]
#/
#/ Executes a given command with environment variables loaded from dotenv files.
#/ Dotenv files are executed in current shell context, wrapped with `set -e'.
#/ Source files, which are set with the `-s' flag will be included after `set +e'
#/ It is possible to provide several files, just by using flags as many tymes as you need.
#/
#/ Options:
#/ -e <DOTENV_FILE> dotenv files (default ".env.local")
#/ -s <SOURCE_FILE> source files
#/ -v verbose output
#/ -- separator
#/ -h, --help show this text
#/
#/ Note: requires bash version >= 4
if [[ "${BASH_VERSINFO}" -lt 4 ]]; then
echo "!! Required bash >= 4" >> /dev/stderr
exit 1
fi
declare _verbose;
declare -a dotenv_files=()
declare -a source_files=()
declare APP_ENV_PATH
ae__show_help() {
cat < "$0" | grep '^#/' | cut -c4-; exit "${1:-0}"
}
while true; do
case "$1" in
-h|--help) ae__show_help 0; break;;
-v|--verbose) _verbose=1; shift 1;;
-e) dotenv_files+=("$2"); shift 2;;
-s) source_files+=("$2"); shift 2;;
--) shift 1; break;;
*) break;;
esac
done
[[ -z "$1" ]] && show_help 1
_info() {
test -n "${_verbose}" && echo "${1}" >> /dev/stderr
}
_fail() {
echo "${1}" >> /dev/stderr; exit 1
}
if [[ $(uname -s) = "Darwin" ]]; then
ae__q() { echo -n "${1@Q}"; }
else
ae__q() { printf "%q" "$1"; }
fi
ae__quote() {
local -a _args=()
for arg in "$@"; do _args+=($(ae__q "$arg")); done
echo "${_args[*]}"
}
ae__append_default_dotenv() {
local default_dotenv="${PWD}"/.env
[[ -e "${default_dotenv}" ]] && dotenv_files+=("${default_dotenv}")
}
ae__include_dotenv_files() {
_info "$ set -a"; set -a
for source in "${dotenv_files[@]}"; do
if [[ -e "${source}" ]]; then
_info "$ . '${source}'"; source "${source}"
source_real=$(realpath "${source}")
if [[ -e "${APP_ENV_PATH}" ]]; then
APP_ENV_PATH="${source_real}"
else
APP_ENV_PATH="${source_real}:$APP_ENV_PATH"
fi
else
_fail "Can't read ${source}"
fi
done
if [[ -n "${APP_ENV_PATH}" ]]; then
_info "$ export APP_ENV_PATH=${APP_ENV_PATH}"; export APP_ENV_PATH
fi
_info "$ set +a"; set +a
}
declare dotenv_command
ae__include_source_files() {
for source in "${source_files[@]}"; do
if [[ -e "${source}" ]]; then
echo -n "source ${source}; "
else
_fail "Can't read ${source}"
fi
done
echo -n "exec ${dotenv_command}"
}
[[ "${#dotenv_files[@]}" -eq 0 ]] && ae__append_default_dotenv
dotenv_command=$(ae__quote "$@")
[[ "${#dotenv_files[@]}" -gt 0 ]] && ae__include_dotenv_files
dotenv_command=$(ae__include_source_files)
_info "$ ${dotenv_command}"
eval "${dotenv_command}"
mkdir -p bin
\curl https://gist.github.com/estum/0b32147f644fbfbd5462a8b6a12b82c5/raw/app-env > bin/app-env
chmod a+x bin/app-env
@estum
Copy link
Author

estum commented Apr 28, 2016

Quick install executable to bin dir inside your project:

\curl -L https://git.io/vHVxf | bash -s stable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment