# This is the .envrc for sentry, for use with direnv.
# It's responsible for enforcing a standard dev environment by checking as much state as possible, and either performing
# initialization (e.g. activating the venv) or giving recommendations on how to reach the desired state.
# It also sets useful environment variables.
# If you'd like to override or set any custom environment variables, this .envrc will read a .env file at the end.

set -e

bold="$(tput bold)"
red="$(tput setaf 1)"
green="$(tput setaf 2)"
reset="$(tput sgr0)"

# XXX: we can't trap bash EXIT, because it'll override direnv's finalizing routines.
#      consequently, using "exit" anywhere will skip this notice from showing.
#      so need to use set -e, and return 1.
trap notice ERR

notice () {
    [ $? -eq 0 ] && return
    cat <<EOF
${red}${bold}direnv wasn't able to complete execution.
You may have been given some recommendations in the error message.
Follow them, and then you'll need to redo direnv by running "direnv allow".${reset}

direnv tooling is in an ALPHA state!
If you're having trouble, or have questions, please ask in #discuss-dev-tooling
and/or reach out to @josh.
EOF
}

require () {
    command -v "$1" 2>&1 > /dev/null
}

info () {
    cat <<EOF
${bold}direnv: ${@}${reset}
EOF
}

die () {
    >&2 cat <<EOF
${red}${bold}direnv FATAL: ${@}
${reset}
EOF
    return 1
}

advice_init_venv () {
    deactivate 2>/dev/null || true
    info "To create a virtualenv, please type: python2.7 -m virtualenv .venv"
    require python2.7 || \
        die "You'll need to install python2.7, or make it available on your PATH.
It's recommended to use pyenv - please refer to https://docs.sentry.io/development/contribute/environment"
    return 1
}

advice_install_sentry () {
    info "To install sentry, please type: make install-sentry-dev"
    return 1
}

advice_install_pre_commit () {
    info "To install pre-commit, please type: make setup-git"
    return 1
}

advice_install_yarn_pkgs () {
    info "To install yarn packages, please type: make install-yarn-pkgs"
    return 1
}

### Environment ###

# don't write *.pyc files; using stale python code occasionally causes subtle problems
export PYTHONDONTWRITEBYTECODE=1

# make sure we don't have any conflicting PYTHONPATH
unset PYTHONPATH

# don't check pypi for a potential new pip version; low-hanging fruit to save a bit of time
export PIP_DISABLE_PIP_VERSION_CHECK=on

# increase node's memory limit, required for our webpacking
export NODE_OPTIONS=--max-old-space-size=4096


### System ###

for pkg in \
    make            \
    docker          \
    chromedriver    \
    pkg-config      \
    openssl         ;
    do
    if ! require "$pkg"; then
        die "You seem to be missing the system dependency: ${pkg}
Please install homebrew, and run brew bundle."
    fi
done


### Git ###

info "Configuring git..."

make setup-git-config


### Python ###

info "Activating virtualenv..."

# we're enforcing that virtualenv be in .venv, since future tooling e.g. venv-update will rely on this.
if [ ! -f ".venv/bin/activate" ]; then
    info "You don't seem to have a virtualenv."
    advice_init_venv
fi

# The user might be cd'ing into sentry with another non-direnv managed
# (in that it would be automatically deactivated) virtualenv active.
deactivate 2>/dev/null || true

source .venv/bin/activate

# XXX: ideally, direnv is able to export PS1 as modified by sourcing venvs
#      but we'd have to patch direnv, and ".venv" isn't descriptive anyways
unset PS1

# We're explicitly disallowing symlinked venvs (python would resolve to the canonical location)
if [ "$(command -v python)" != "${PWD}/.venv/bin/python" ]; then
    info "Failed to activate virtualenv. Your virtualenv's probably symlinked." \
    "We want everyone to be on the same page here, so you'll have to recreate your virtualenv."
    advice_init_venv
fi

python -c "import sys; sys.exit(sys.version_info[:2] != (2, 7))" || \
    die "For some reason, the virtualenv isn't Python 2.7."

if [ "$(command -v sentry)" != "${PWD}/.venv/bin/sentry" ]; then
    info "Your .venv is activated, but sentry doesn't seem to be installed."
    # XXX: if direnv fails, the venv won't be activated outside of direnv execution...
    # So, it is critical that make install-sentry-dev is guarded by scripts/ensure-venv.
    advice_install_sentry
fi


### pre-commit ###

info "Checking pre-commit..."

if ! require pre-commit; then
    info "Looks like you don't have pre-commit installed."
    advice_install_pre_commit
fi


### Node ###

info "Checking node..."

node_version="10.16.3"

# It would be nice to enforce that node is installed via volta (and is therefore a shim that will check against
# the node pin in package.json), but for now, let's just explicitly check the node version.

if ! require node; then
    die "You don't seem to have node installed. We want version ${node_version}.
It's recommended to use volta - please refer to https://docs.sentry.io/development/contribute/environment"
fi

if [ "$(node -v)" != "v${node_version}" ]; then
    die "Your node version doesn't match ${node_version}.
It's recommended to use volta - please refer to https://docs.sentry.io/development/contribute/environment"
fi

if [ ! -x "node_modules/.bin/webpack" ]; then
    info "You don't seem to have yarn packages installed."
    advice_install_yarn_pkgs
fi

PATH_add node_modules/.bin


### Overrides ###

if [ -f '.env' ]; then
    info ".env found. Reading it..."
    dotenv .env
fi

cat <<EOF
${green}${bold}direnv: SUCCESS!
${reset}
EOF

if [ ! -n "${SENTRY_SILENCE_DIRENV_NOTICE:-}" ]; then
    cat <<EOF
direnv tooling is in an ALPHA state!
If you're having trouble, or have questions, please ask in #discuss-dev-tooling
and/or reach out to @josh.

EOF
fi