From 6e7945a6260e1348d9cfe6c1737fa1044042169a Mon Sep 17 00:00:00 2001 From: Yamashita Yuu Date: Wed, 19 Jun 2013 23:57:45 +0900 Subject: [PATCH 1/7] prefer `pyvenv` rather than `virtualenv` if `--pyvenv` is given --- bin/pyenv-virtualenv | 41 +++++++++++++++++++++++++++++-------- bin/pyenv-virtualenv-prefix | 8 +++++++- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/bin/pyenv-virtualenv b/bin/pyenv-virtualenv index d40b4ab..efd0397 100755 --- a/bin/pyenv-virtualenv +++ b/bin/pyenv-virtualenv @@ -67,14 +67,14 @@ abs_dirname() { } version() { - local version="$(pyenv-exec virtualenv --version 2>/dev/null || true)" + local version="$(virtualenv --version 2>/dev/null || true)" echo "pyenv-virtualenv ${PYENV_VIRTUALENV_VERSION} (virtualenv ${version:-unknown})" } 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" - pyenv-exec virtualenv --help 2>/dev/null || true + virtualenv --help 2>/dev/null || true [ -z "$1" ] || exit "$1" } @@ -87,6 +87,14 @@ require_executable() { fi } +virtualenv() { + if [ -n "$PYVENV" ]; then + pyenv-exec pyvenv "$@" + else + pyenv-exec virtualenv "$@" + fi +} + PYENV_VIRTUALENV_ROOT="$(abs_dirname "$0")/.." if [ -z "${PYENV_VIRTUALENV_CACHE_PATH}" ]; then PYENV_VIRTUALENV_CACHE_PATH="${PYTHON_BUILD_CACHE_PATH:-${PYENV_ROOT}/cache}" @@ -94,6 +102,7 @@ fi VIRTUALENV_OPTIONS=() unset FORCE +unset PYVENV unset QUIET unset UPGRADE unset VERBOSE @@ -107,6 +116,9 @@ for option in "${OPTIONS[@]}"; do "h" | "help" ) usage 0 ;; + "pyvenv" ) + PYVENV=true + ;; "q" | "quiet" ) QUIET="--quiet" ;; @@ -161,12 +173,23 @@ UPGRADE_LIST="${TMP}/pyenv-virtualenv.${SEED}.txt" VIRTUALENV_PATH="${PYENV_ROOT}/versions/${VIRTUALENV_NAME}" -require_executable "${VERSION_NAME}" "virtualenv" 2>/dev/null || { - require_executable "${VERSION_NAME}" "pip" - VIRTUALENV_VERSION="==${VIRTUALENV_VERSION}" - pyenv-exec pip install $QUIET $VERBOSE "virtualenv${VIRTUALENV_VERSION%==}" - pyenv-rehash -} +if [ -n "$PYVENV" ]; then + require_executable "${VERSION_NAME}" "pyvenv" + # Unset some arguments not supported by pyvenv + unset QUIET + unset VERBOSE + if [ -n "$UPGRADE" ]; then + unset UPGRADE + VIRTUALENV_OPTIONS[${#VIRTUALENV_OPTIONS[*]}]="--upgrade" + fi +else + require_executable "${VERSION_NAME}" "virtualenv" || { + require_executable "${VERSION_NAME}" "pip" + VIRTUALENV_VERSION="==${VIRTUALENV_VERSION}" + pyenv-exec pip install $QUIET $VERBOSE "virtualenv${VIRTUALENV_VERSION%==}" + pyenv-rehash + } +fi # Unset environment variables which starts with `VIRTUALENV_`. # These variables are reserved for virtualenv. @@ -232,7 +255,7 @@ STATUS=0 # change to cache directory to reuse them between invocation. mkdir -p "${PYENV_VIRTUALENV_CACHE_PATH}" cd "${PYENV_VIRTUALENV_CACHE_PATH}" -pyenv-exec virtualenv $QUIET $VERBOSE "${VIRTUALENV_OPTIONS[@]}" "${VIRTUALENV_PATH}" || STATUS="$?" +virtualenv $QUIET $VERBOSE "${VIRTUALENV_OPTIONS[@]}" "${VIRTUALENV_PATH}" || STATUS="$?" # Create symlink of `python' bound for actual executable # TODO: remove this if virtualenv doesn't really need this diff --git a/bin/pyenv-virtualenv-prefix b/bin/pyenv-virtualenv-prefix index aff983d..a7d49ac 100755 --- a/bin/pyenv-virtualenv-prefix +++ b/bin/pyenv-virtualenv-prefix @@ -24,11 +24,17 @@ real_prefix() { # virtualenv PYENV_VERSION="${version}" pyenv-exec python -c 'import sys;print(sys.real_prefix)' 2>/dev/null } +base_prefix() { # pyvenv + # FIXME: non-pyvenv versions also have sys.base_prefix + local version="$1" + PYENV_VERSION="${version}" pyenv-exec python -c 'import sys;print(sys.base_prefix)' 2>/dev/null +} + VIRTUALENV_PREFIX_PATHS=() for version in "${versions[@]}"; do PREFIX="$(pyenv-prefix "${version}")" if [ -f "${PREFIX}/bin/activate" ]; then - VIRTUALENV_PREFIX_PATH="$(real_prefix "${version}" || true)" + VIRTUALENV_PREFIX_PATH="$(real_prefix "${version}" || base_prefix "${version}" || true)" if [ -d "${VIRTUALENV_PREFIX_PATH}" ]; then VIRTUALENV_PREFIX_PATHS=("${VIRTUALENV_PREFIX_PATHS[@]}" "$VIRTUALENV_PREFIX_PATH") fi From 11792cbaf9725296ec692be2900d9f9d6af1bfec Mon Sep 17 00:00:00 2001 From: Yamashita Yuu Date: Thu, 20 Jun 2013 11:57:20 +0900 Subject: [PATCH 2/7] Remove `--pyvenv` option. Use pyvenv only if virtualenv is not installed and there is pyvenv. --- bin/pyenv-virtualenv | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/bin/pyenv-virtualenv b/bin/pyenv-virtualenv index efd0397..f99ff79 100755 --- a/bin/pyenv-virtualenv +++ b/bin/pyenv-virtualenv @@ -6,7 +6,8 @@ # pyenv virtualenv --version # pyenv virtualenv --help # -# -u/--upgrade Upgrade existing virtualenv with migrating installed packages +# -u/--upgrade Upgrade existing virtualenv to use new version of Python, +# assuming Python has been upgraded in-place. # -f/--force Install even if the version appears to be installed already # @@ -78,17 +79,17 @@ usage() { [ -z "$1" ] || exit "$1" } -require_executable() { - local version="$1" - local executable="$2" - if ! PYENV_VERSION="${version}" pyenv-which "${executable}" 1>/dev/null 2>&1; then - echo "pyenv: ${executable} is not installed in ${version}." 1>&2 +virtualenv_is_pyvenv() { + # Use pyvenv only if virtualenv is not installed and there is pyvenv + if pyenv-which "virtualenv" 1>/dev/null 2>&1; then return 1 + else + pyenv-which "pyvenv" 1>/dev/null 2>&1 fi } virtualenv() { - if [ -n "$PYVENV" ]; then + if virtualenv_is_pyvenv; then pyenv-exec pyvenv "$@" else pyenv-exec virtualenv "$@" @@ -102,7 +103,6 @@ fi VIRTUALENV_OPTIONS=() unset FORCE -unset PYVENV unset QUIET unset UPGRADE unset VERBOSE @@ -116,9 +116,6 @@ for option in "${OPTIONS[@]}"; do "h" | "help" ) usage 0 ;; - "pyvenv" ) - PYVENV=true - ;; "q" | "quiet" ) QUIET="--quiet" ;; @@ -173,8 +170,7 @@ UPGRADE_LIST="${TMP}/pyenv-virtualenv.${SEED}.txt" VIRTUALENV_PATH="${PYENV_ROOT}/versions/${VIRTUALENV_NAME}" -if [ -n "$PYVENV" ]; then - require_executable "${VERSION_NAME}" "pyvenv" +if virtualenv_is_pyvenv; then # Unset some arguments not supported by pyvenv unset QUIET unset VERBOSE @@ -183,8 +179,7 @@ if [ -n "$PYVENV" ]; then VIRTUALENV_OPTIONS[${#VIRTUALENV_OPTIONS[*]}]="--upgrade" fi else - require_executable "${VERSION_NAME}" "virtualenv" || { - require_executable "${VERSION_NAME}" "pip" + pyenv-which "virtualenv" 1>/dev/null 2>&1 || { VIRTUALENV_VERSION="==${VIRTUALENV_VERSION}" pyenv-exec pip install $QUIET $VERBOSE "virtualenv${VIRTUALENV_VERSION%==}" pyenv-rehash @@ -233,7 +228,6 @@ if [ -d "${VIRTUALENV_PATH}/bin" ]; then fi if [ -n "$UPGRADE" ]; then - require_executable "${VIRTUALENV_NAME}" "pip" PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-exec pip freeze >"${UPGRADE_LIST}" mv -f "${VIRTUALENV_PATH}" "${UPGRADE_PATH}" fi @@ -269,7 +263,6 @@ fi ## Migrate previously installed packages from requirements.txt if [ -n "$UPGRADE" ]; then UPGRADE_STATUS=0 - require_executable "${VIRTUALENV_NAME}" "pip" || UPGRADE_STATUS=1 PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-exec pip install $QUIET $VERBOSE --requirement "${UPGRADE_LIST}" || UPGRADE_STATUS=$? if [ "$UPGRADE_STATUS" == "0" ]; then rm -f "${UPGRADE_LIST}" From 2e5db090a92cb7e1b9c3ad85a84d8a133d354506 Mon Sep 17 00:00:00 2001 From: Yamashita Yuu Date: Thu, 20 Jun 2013 12:23:46 +0900 Subject: [PATCH 3/7] install setuptools and pip into pyvenv --- bin/pyenv-virtualenv | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/bin/pyenv-virtualenv b/bin/pyenv-virtualenv index f99ff79..2557b3f 100755 --- a/bin/pyenv-virtualenv +++ b/bin/pyenv-virtualenv @@ -67,6 +67,38 @@ abs_dirname() { cd "$cwd" } +http() { + local method="$1" + local url="$2" + local file="$3" + [ -n "$url" ] || return 1 + + if type curl &>/dev/null; then + "http_${method}_curl" "$url" "$file" + elif type wget &>/dev/null; then + "http_${method}_wget" "$url" "$file" + else + echo "error: please install \`curl\` or \`wget\` and try again" >&2 + exit 1 + fi +} + +http_head_curl() { + curl -qsILf "$1" >&4 2>&1 +} + +http_get_curl() { + curl -C - -o "${2:--}" -qsSLf "$1" +} + +http_head_wget() { + wget -q --spider "$1" >&4 2>&1 +} + +http_get_wget() { + wget -nv -c -O "${2:--}" "$1" +} + version() { local version="$(virtualenv --version 2>/dev/null || true)" echo "pyenv-virtualenv ${PYENV_VIRTUALENV_VERSION} (virtualenv ${version:-unknown})" @@ -260,6 +292,16 @@ if [ ! -e "${VIRTUALENV_PATH}/bin/python" ]; then fi fi +if virtualenv_is_pyvenv; then + PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-exec python -c 'import setuptools' 1>/dev/null 2>&1 || { + http get "https://bitbucket.org/pypa/setuptools/raw/0.7.4/ez_setup.py" | PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-exec python + } + + PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-which pip 1>/dev/null 2>&1 || { + http get "https://raw.github.com/pypa/pip/master/contrib/get-pip.py" | PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-exec python + } +fi + ## Migrate previously installed packages from requirements.txt if [ -n "$UPGRADE" ]; then UPGRADE_STATUS=0 From f0ca1b27d02e2fda65a78f1304b1706ed9eb31b1 Mon Sep 17 00:00:00 2001 From: Yamashita Yuu Date: Thu, 20 Jun 2013 13:48:01 +0900 Subject: [PATCH 4/7] add SETUPTOOLS_VERSION and PIP_VERSION --- README.md | 4 ++++ bin/pyenv-virtualenv | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e6707cd..66bbe52 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,8 @@ You can set certain environment variables to control the pyenv-virtualenv. * `VIRTUALENV_VERSION`, if set, forces pyenv-virtualenv to install desired version of virtualenv. If the virtualenv has not been installed, pyenv-virtualenv will try to install the given version of virtualenv. +* `SETUPTOOLS_VERSION` and `PIP_VERSION`, if set and if pyvenv is preferred + than virtualenv, install specified version of setuptools and pip. ## Version History @@ -72,6 +74,8 @@ You can set certain environment variables to control the pyenv-virtualenv. #### 2013XXYY * Removed bundled `virtualenv.py` script. Now pyenv-virtualenv installs `virtualenv` package into source version and then use it. + * On Python 3.3+, use `pyvenv` as virtualenv command if `virtualenv` is not available. + * Install setuptools and pip into environments created by `pyvenv`. #### 20130614 diff --git a/bin/pyenv-virtualenv b/bin/pyenv-virtualenv index 2557b3f..3dd8699 100755 --- a/bin/pyenv-virtualenv +++ b/bin/pyenv-virtualenv @@ -294,11 +294,11 @@ fi if virtualenv_is_pyvenv; then PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-exec python -c 'import setuptools' 1>/dev/null 2>&1 || { - http get "https://bitbucket.org/pypa/setuptools/raw/0.7.4/ez_setup.py" | PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-exec python + http get "https://bitbucket.org/pypa/setuptools/raw/${SETUPTOOLS_VERSION:-0.7.4}/ez_setup.py" | PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-exec python } PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-which pip 1>/dev/null 2>&1 || { - http get "https://raw.github.com/pypa/pip/master/contrib/get-pip.py" | PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-exec python + http get "https://raw.github.com/pypa/pip/${PIP_VERSION:-master}/contrib/get-pip.py" | PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-exec python } fi From 384fab86ef4e9a79bf46aeebbfa24fbc31d73363 Mon Sep 17 00:00:00 2001 From: Yamashita Yuu Date: Thu, 20 Jun 2013 14:50:20 +0900 Subject: [PATCH 5/7] add EZ_SETUP_URL and GET_PIP_URL --- README.md | 4 +++- bin/pyenv-virtualenv | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 66bbe52..ef00f1d 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,9 @@ You can set certain environment variables to control the pyenv-virtualenv. * `VIRTUALENV_VERSION`, if set, forces pyenv-virtualenv to install desired version of virtualenv. If the virtualenv has not been installed, pyenv-virtualenv will try to install the given version of virtualenv. -* `SETUPTOOLS_VERSION` and `PIP_VERSION`, if set and if pyvenv is preferred +* `EZ_SETUP_URL` and `GET_PIP_URL`, if set and pyvenv is preferred + than virtualenv, download `ez_setup.py` and `get_pip.py` from specified URL. +* `SETUPTOOLS_VERSION` and `PIP_VERSION`, if set and pyvenv is preferred than virtualenv, install specified version of setuptools and pip. diff --git a/bin/pyenv-virtualenv b/bin/pyenv-virtualenv index 3dd8699..c1f3d64 100755 --- a/bin/pyenv-virtualenv +++ b/bin/pyenv-virtualenv @@ -293,12 +293,14 @@ if [ ! -e "${VIRTUALENV_PATH}/bin/python" ]; then fi if virtualenv_is_pyvenv; then + [ -n "${EZ_SETUP_URL}" ] || EZ_SETUP_URL="https://bitbucket.org/pypa/setuptools/raw/${SETUPTOOLS_VERSION:-0.7.4}/ez_setup.py" PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-exec python -c 'import setuptools' 1>/dev/null 2>&1 || { - http get "https://bitbucket.org/pypa/setuptools/raw/${SETUPTOOLS_VERSION:-0.7.4}/ez_setup.py" | PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-exec python + http get "${EZ_SETUP_URL}" | PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-exec python } + [ -n "${GET_PIP_URL}" ] || GET_PIP_URL="https://raw.github.com/pypa/pip/${PIP_VERSION:-master}/contrib/get-pip.py" PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-which pip 1>/dev/null 2>&1 || { - http get "https://raw.github.com/pypa/pip/${PIP_VERSION:-master}/contrib/get-pip.py" | PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-exec python + http get "${GET_PIP_URL}" | PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-exec python } fi From f3c5a64281346643b8232aa617d495a677b5ef4c Mon Sep 17 00:00:00 2001 From: Yamashita Yuu Date: Thu, 20 Jun 2013 14:56:24 +0900 Subject: [PATCH 6/7] renamed virtualenv() to venv() --- bin/pyenv-virtualenv | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/pyenv-virtualenv b/bin/pyenv-virtualenv index c1f3d64..e7c49f9 100755 --- a/bin/pyenv-virtualenv +++ b/bin/pyenv-virtualenv @@ -100,14 +100,14 @@ http_get_wget() { } version() { - local version="$(virtualenv --version 2>/dev/null || true)" + local version="$(venv --version 2>/dev/null || true)" echo "pyenv-virtualenv ${PYENV_VIRTUALENV_VERSION} (virtualenv ${version:-unknown})" } 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" - virtualenv --help 2>/dev/null || true + venv --help 2>/dev/null || true [ -z "$1" ] || exit "$1" } @@ -120,7 +120,7 @@ virtualenv_is_pyvenv() { fi } -virtualenv() { +venv() { if virtualenv_is_pyvenv; then pyenv-exec pyvenv "$@" else @@ -281,7 +281,7 @@ STATUS=0 # change to cache directory to reuse them between invocation. mkdir -p "${PYENV_VIRTUALENV_CACHE_PATH}" cd "${PYENV_VIRTUALENV_CACHE_PATH}" -virtualenv $QUIET $VERBOSE "${VIRTUALENV_OPTIONS[@]}" "${VIRTUALENV_PATH}" || STATUS="$?" +venv $QUIET $VERBOSE "${VIRTUALENV_OPTIONS[@]}" "${VIRTUALENV_PATH}" || STATUS="$?" # Create symlink of `python' bound for actual executable # TODO: remove this if virtualenv doesn't really need this From 23a115c12a52f3128d4829d2ea3eba7c10503b55 Mon Sep 17 00:00:00 2001 From: Yamashita Yuu Date: Thu, 20 Jun 2013 16:08:54 +0900 Subject: [PATCH 7/7] set STATUS as non-zero even if the setuptools or pip have failed to install into pyvenv --- bin/pyenv-virtualenv | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/bin/pyenv-virtualenv b/bin/pyenv-virtualenv index e7c49f9..135b1ee 100755 --- a/bin/pyenv-virtualenv +++ b/bin/pyenv-virtualenv @@ -281,7 +281,21 @@ STATUS=0 # change to cache directory to reuse them between invocation. mkdir -p "${PYENV_VIRTUALENV_CACHE_PATH}" cd "${PYENV_VIRTUALENV_CACHE_PATH}" -venv $QUIET $VERBOSE "${VIRTUALENV_OPTIONS[@]}" "${VIRTUALENV_PATH}" || STATUS="$?" +venv $QUIET $VERBOSE "${VIRTUALENV_OPTIONS[@]}" "${VIRTUALENV_PATH}" && { + if virtualenv_is_pyvenv; then + [ -n "${EZ_SETUP_URL}" ] || EZ_SETUP_URL="https://bitbucket.org/pypa/setuptools/raw/${SETUPTOOLS_VERSION:-0.7.4}/ez_setup.py" + PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-exec python -c 'import setuptools' 1>/dev/null 2>&1 || { + echo "Installing setuptools from ${EZ_SETUP_URL}..." 1>&2 + http get "${EZ_SETUP_URL}" | PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-exec python + } + + [ -n "${GET_PIP_URL}" ] || GET_PIP_URL="https://raw.github.com/pypa/pip/${PIP_VERSION:-master}/contrib/get-pip.py" + PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-which pip 1>/dev/null 2>&1 || { + echo "Installing pip from ${GET_PIP_URL}..." 1>&2 + http get "${GET_PIP_URL}" | PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-exec python + } + fi +} || STATUS="$?" # Create symlink of `python' bound for actual executable # TODO: remove this if virtualenv doesn't really need this @@ -292,18 +306,6 @@ if [ ! -e "${VIRTUALENV_PATH}/bin/python" ]; then fi fi -if virtualenv_is_pyvenv; then - [ -n "${EZ_SETUP_URL}" ] || EZ_SETUP_URL="https://bitbucket.org/pypa/setuptools/raw/${SETUPTOOLS_VERSION:-0.7.4}/ez_setup.py" - PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-exec python -c 'import setuptools' 1>/dev/null 2>&1 || { - http get "${EZ_SETUP_URL}" | PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-exec python - } - - [ -n "${GET_PIP_URL}" ] || GET_PIP_URL="https://raw.github.com/pypa/pip/${PIP_VERSION:-master}/contrib/get-pip.py" - PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-which pip 1>/dev/null 2>&1 || { - http get "${GET_PIP_URL}" | PYENV_VERSION="${VIRTUALENV_NAME}" pyenv-exec python - } -fi - ## Migrate previously installed packages from requirements.txt if [ -n "$UPGRADE" ]; then UPGRADE_STATUS=0