#!/usr/bin/env bash # # Summary: Create a Python virtualenv using the pyenv-virtualenv plugin # # Usage: pyenv virtualenv [-v|--verbose] [VIRTUALENV_OPTIONS] # # -v/--verbose Verbose mode: print compilation status to stdout # PYENV_VIRTUALENV_VERSION="20130218" set -e [ -n "$PYENV_DEBUG" ] && set -x # Provide pyenv completions if [ "$1" = "--complete" ]; then exec pyenv-versions --bare fi if [ -z "$PYENV_ROOT" ]; then PYENV_ROOT="${HOME}/.pyenv" fi # Define library functions parse_options() { OPTIONS=() ARGUMENTS=() local arg option index for arg in "$@"; do if [ "${arg:0:1}" = "-" ]; then if [ "${arg:1:1}" = "-" ]; then OPTIONS[${#OPTIONS[*]}]="${arg:2}" else index=1 while option="${arg:$index:1}"; do [ -n "$option" ] || break OPTIONS[${#OPTIONS[*]}]="$option" index=$(($index+1)) done fi else ARGUMENTS[${#ARGUMENTS[*]}]="$arg" fi done } resolve_link() { $(type -p greadlink readlink | head -1) "$1" } abs_dirname() { local cwd="$(pwd)" local path="$1" while [ -n "$path" ]; do cd "${path%/*}" local name="${path##*/}" path="$(resolve_link "$name" || true)" done pwd cd "$cwd" } version() { echo "pyenv-virtualenv ${PYENV_VIRTUALENV_VERSION}" } usage() { # We can remove the sed fallback once pyenv 0.2.0 is widely available. pyenv-help virtualenv 2>/dev/null || sed -ne '/^#/!q;s/.//;s/.//;1,4d;p' < "$0" [ -z "$1" ] || exit "$1" } unset VERBOSE PYENV_VIRTUALENV_ROOT="$(abs_dirname "$0")/.." VIRTUALENV_OPTIONS=() parse_options "$@" for option in "${OPTIONS[@]}"; do case "$option" in "h" | "help" ) usage 0 ;; "v" | "verbose" ) VERBOSE="-v" ;; "version" ) version exit 0 ;; * ) VIRTUALENV_OPTIONS[${#VIRTUALENV_OPTIONS[*]}]="--$option" ;; esac done VERSION_NAME="${ARGUMENTS[0]}" [ -n "$VERSION_NAME" ] || usage 1 for script in $(pyenv-hooks virtualenv); do source "$script" done PYTHON_BIN=$(PYENV_VERSION="${VERSION_NAME}" pyenv-which python) if [ ! -x "${PYTHON_BIN}" ]; then echo "pyenv-virtualenv: could not obtain python executable: ${PYTHON_BIN}" >&2 exit 1 fi # find canonical name of python executable. # virtualenv will create "bin/python" executable as same name as its bootstraped python. if [ -L "${PYTHON_BIN}" ]; then while [ -L "${PYTHON_BIN}" ]; do # retrieve symlinks PYTHON_BIN="$(dirname "${PYTHON_BIN}")/$(resolve_link "${PYTHON_BIN}")" done else # python 2.6 and older don't have "bin/python" as symlink. # so we must traverse files like "bin/python*" to obtain canonical name. for python in ${PYENV_ROOT}/versions/${VERSION_NAME}/bin/python*; do if ( basename "$python" | grep '^python[0-9][0-9]*\.[0-9][0-9]*$' && cmp "$PYTHON_BIN" "$python" ) >/dev/null; then PYTHON_BIN="${python}" break fi done fi VIRTUALENV_NAME="${ARGUMENTS[1]##*/}" VIRTUALENV_PATH="${PYENV_ROOT}/versions/${VIRTUALENV_NAME}" # create virtualenv VIRTUALENV="${PYENV_VIRTUALENV_ROOT}/libexec/pyenv-virtualenv/virtualenv.py" [ -f "${VIRTUALENV}" ] || VIRTUALENV="${PYENV_VIRTUALENV_ROOT}/python-libexec/virtualenv.py" # backward compatibility before v20130218 [ -f "${VIRTUALENV}" ] || VIRTUALENV="${PYENV_VIRTUALENV_ROOT}/libexec/virtualenv.py" "${PYTHON_BIN}" "${VIRTUALENV}" "${VIRTUALENV_OPTIONS[@]}" "${VIRTUALENV_PATH}" # create symlink of `python' bound for actual executable if [ ! -f "$VIRTUALENV_PYTHON_BIN" ]; then if [ -f "${VIRTUALENV_PATH}/bin/$(basename "${PYTHON_BIN}")" ]; then { cd ${VIRTUALENV_PATH}/bin ln -fs "$(basename "${PYTHON_BIN}")" python } fi fi pyenv-rehash