daml/dev-env/bin/runpipenv
Digital Asset GmbH 05e691f558 open-sourcing daml
2019-04-04 09:33:38 +01:00

68 lines
2.2 KiB
Bash
Executable File

#!/usr/bin/env bash
set -e
# Helper for starting a Python script with dependencies managed by
# Pipenv. Use it in the shebang line of your Python script:
#
# #!/usr/bin/env runpipenv
#
# When invoked, runpipenv will make sure to call 'pipenv sync' to
# install dependencies from your Pipfile.lock file. Create the
# Pipfile.lock file with 'pipenv lock'.
# Pipenv looks for the Pipfile in the current directory, so we need to
# change to the directory of the script being invoked (passed in $1).
# Using realpath allows $1 to be a symlink to the real Python script.
# The realpath command doesn't exist on OS X, so here is a portable
# replacement.
realpath() {
local path="$1"
if [[ -h "$path" ]]; then
local target=$(readlink "$path")
if [[ $target[0] =~ '^/' ]]; then
echo "$target"
else
echo "$(dirname "$path")/$target"
fi
else
echo "$path"
fi
}
OLD_PWD=$PWD
cd "$(dirname "$(realpath "$1")")"
# Detect if the Pipfile needs Python 2 or Python 3.
PYTHON=python
if grep -q 'python_version\s*=\s*"3' Pipfile; then
PYTHON=python3
fi
# Python 2 outputs version information on stderr, Python 3 uses
# stdout. Furthermore, our dev-env wrapper and Pipenv itself likes to
# chatter on stderr. To work around all that, we combine the two
# channels and use grep to pick out the line we care about.
ACTUAL_VERSION="$(pipenv run python -V 2>&1 | grep '^Python [23]')"
WANTED_VERSION="$($PYTHON -V 2>&1 | grep '^Python [23]')"
if [[ $ACTUAL_VERSION != $WANTED_VERSION ]]; then
cat >&2 <<EOF
[runpipenv] The version of Python in the virtualenv ($ACTUAL_VERSION)
[runpipenv] does not match the version in dev-env ($WANTED_VERSION).
[runpipenv] The virtualenv will be recreated.
EOF
pipenv --rm
fi
# We can now sync the dependencies in the virtualenv Pipenv maintains.
PIPENV_ACTIVE=1 pipenv sync
# We now invoke the script and take care to change back to the
# original working directory first. We pass the target directory and
# any positional arguments as positional arguments to the inner Bash
# process. That way it can take care of passing them through unchanged
# to the Python invocation.
exec pipenv run bash -c 'cd "$0" && python "$@"' "$OLD_PWD" "$@"