diff options
| -rwxr-xr-x | python_install.sh | 114 |
1 files changed, 101 insertions, 13 deletions
diff --git a/python_install.sh b/python_install.sh index c92e7c5..4e8010a 100755 --- a/python_install.sh +++ b/python_install.sh @@ -11,39 +11,122 @@ readonly PROGNAME="$(basename "${0}")"; readonly PROGDIR="$(readlink -f "$(dirname "${0}")")"; readonly ARGS="${@}"; -install_virtualenv() +readonly PYTHON_VERSION_PATH="$(mktemp)"; +readonly PIP_INSTALL_SCRIPT="$(mktemp)"; + +cleanup() +{ + local rc=$?; # Keep original return code + + rm -f "${PYTHON_VERSION_PATH}" + rm -f "${PIP_INSTALL_SCRIPT}" + exit ${rc} +} + +get_python_version() +{ + local python="${1}"; shift; + local version_path="${1}"; shift; + + # Redirecting stderr to stdout is necessary because older versions + # of Python printed to stderr + "${python}" --version 2>&1 \ + | cut -d\ -f2 \ + > "${version_path}" +} + +venv_install_method() { local python="${1}"; shift; local env_dir="${1}"; shift; - local install_script_path="$(mktemp)"; - wget 'https://bootstrap.pypa.io/get-pip.py' -O "${install_script_path}" + "${python}" -m venv "${env_dir}" +} - mkdir -p "${env_dir}" +pip_install_method() +{ + local python="${1}"; shift; + local env_dir="${1}"; shift; + local num="${1}"; shift; + local opts=''; + wget 'https://bootstrap.pypa.io/get-pip.py' \ + -O "${PIP_INSTALL_SCRIPT}" PYTHONUSERBASE="${env_dir}" \ - "${python}" "${install_script_path}" --user --ignore-installed --no-cache - rm -f "${install_script_path}" + "${python}" "${PIP_INSTALL_SCRIPT}" --isolated \ + --user \ + --ignore-installed \ + --no-cache + + # WARNING: for some reason it is not possible to force + # the script to build from source (with --no-binary setuptools,pip) + # due to an unsupported --no-user option in the install procedure. + # So it is better to check that the installed binary is compatible + # with the local system (notably the SSL library which may cause + # issues when downloading packages from HTTPS). +} +install_environment() +{ + + get_python_version "${python}" "${PYTHON_VERSION_PATH}" + local major="$(cat "${PYTHON_VERSION_PATH}" | cut -d. -f1)"; + local minor="$(cat "${PYTHON_VERSION_PATH}" | cut -d. -f2)"; + local num=$((${minor} + 10 * ${major})); + + if [ ${num} -gt 33 ]; + then + set +o errexit + "${python}" -m ensurepip --help 2>1 >/dev/null + local rc=$? + set -o errexit + + if [ 0 -eq ${rc} ]; + then + venv_install_method "${python}" "${env_dir}" + else + pip_install_method "${python}" "${env_dir}" "${num}" + install_virtualenv "${python}" "${env_dir}" + fi + elif [ ${num} -eq 27 ]; + then + pip_install_method "${python}" "${env_dir}" "${num}" + install_virtualenv "${python}" "${env_dir}" + else + >&2 echo "Unsupported Python version" + exit 1 + fi + +} + +install_virtualenv() +{ + local python="${1}"; shift; + local env_dir="${1}"; shift; + + # Install virtualenv PYTHONUSERBASE="${env_dir}" \ - "${env_dir}/bin/pip" install --user --ignore-installed --no-cache virtualenv + "${env_dir}/bin/pip" install --user \ + --ignore-installed \ + --no-cache \ + --no-binary virtualenv \ + virtualenv - local virtualenv_path="$(find "${env_dir}/lib" -name 'virtualenv.py')"; - local python_pkg_dir="$(readlink -f "$(dirname "${virtualenv_path}")")"; + local _pkg_dir="$(find "${env_dir}/lib" -name "virtualenv.py" \ + -exec dirname {} \;)"; + local pkg_dir="$(readlink -f "${_pkg_dir}")"; mkdir -p "${env_dir}/cache" PIP_CACHE_DIR="${env_dir}/cache" \ PIP_IGNORE_INSTALLED=true \ - PYTHONPATH="${python_pkg_dir}" \ + PYTHONPATH="${pkg_dir}" \ "${python}" -m virtualenv "${env_dir}" cat > "${env_dir}/pip.conf" << EOF [global] cache-dir=${env_dir}/cache EOF - - echo 'Environment ready' } main() @@ -53,7 +136,12 @@ main() local install_dir="$(readlink -f "${_install_dir}")"; local env_dir="${install_dir}/env"; - install_virtualenv "${python}" "${env_dir}" + trap 'cleanup' INT TERM EXIT + + install_environment "${python}" "${env_dir}" + + trap - INT TERM EXIT + echo 'Environment ready' } main ${ARGS} |
