aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xpython_install.sh114
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}