This repository has been archived by the owner on Mar 28, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathsetup-pyenv.sh
178 lines (159 loc) · 5.82 KB
/
setup-pyenv.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#!/usr/bin/env bash
# NOTE: This script needs to be sourced so it can modify the environment.
#
# Environment variables that can be set:
# - PYENV_VERSION
# Python to install [required]
# - PYENV_VERSION_STRING
# String to `grep -F` against the output of `python --version` to validate
# that the correct Python was installed (recommended) [default: none]
# - PYENV_ROOT
# Directory in which to install pyenv [default: ~/.travis-pyenv]
# - PYENV_RELEASE
# Release tag of pyenv to download [default: clone from master]
# - PYENV_CACHE_PATH
# Directory where full Python builds are cached (i.e., for Travis)
# - VIRTUALENV_EXTRA_ARGS
# Extra arguments to be used when creating the virtualenv
# PYENV_ROOT is exported because pyenv uses it
export PYENV_ROOT="${PYENV_ROOT:-$HOME/.travis-pyenv}"
PYENV_CACHE_PATH="${PYENV_CACHE_PATH:-$HOME/.pyenv_cache}"
version_cache_path="$PYENV_CACHE_PATH/$PYENV_VERSION"
version_pyenv_path="$PYENV_ROOT/versions/$PYENV_VERSION"
# Functions
#
# verify_python -- attempts to call the Python command or binary
# supplied in the first argument with the --version flag. If
# PYENV_VERSION_STRING is set, then it validates the returned version string
# as well (using grep -F). Returns whatever status code the command returns.
verify_python() {
local python_bin="$1"; shift
if [[ -n "$PYENV_VERSION_STRING" ]]; then
"$python_bin" --version 2>&1 | grep -F "$PYENV_VERSION_STRING" &>/dev/null
else
"$python_bin" --version &>/dev/null
fi
}
# use_existing_python -- checks if there's already an installed
# PYENV_VERSION Python (i.e. if it's in the Travis base image) and verifying
# that works. Returns 0 if it finds one and it verifies, otherwise returns 1.
use_existing_python() {
if [[ -d "$version_pyenv_path" ]]; then
printf "Python %s already installed. Verifying..." "$PYENV_VERSION"
if verify_python "$version_pyenv_path/bin/python"; then
printf "success!\n"
return 0
else
printf "FAILED.\nClearing installed version..."
rm -f "$version_pyenv_path"
printf "done.\n"
return 1
fi
else
echo "No existing python found"
return 1
fi
}
# use_cached_python -- Tries symlinking to the cached PYENV_VERSION and
# verifying that it's a working build. Returns 0 if it's found and it
# verifies, otherwise returns 1.
use_cached_python() {
if [[ -d "$version_cache_path" ]]; then
printf "Cached python found, %s. Verifying..." "$PYENV_VERSION"
ln -s "$version_cache_path" "$version_pyenv_path"
if verify_python "$version_pyenv_path/bin/python"; then
printf "success!\n"
return 0
else
printf "FAILED.\nClearing cached version..."
rm -f "$version_pyenv_path"
rm -rf "$version_cache_path"
printf "done.\n"
return 1
fi
else
echo "No cached python found."
return 1
fi
}
# output_debugging_info -- Outputs useful debugging information
output_debugging_info() {
echo "**** Debugging information"
printf "PYENV_VERSION\n%s\n" "$PYENV_VERSION"
printf "PYENV_VERSION_STRING\n%s\n" "$PYENV_VERSION_STRING"
printf "PYENV_CACHE_PATH\n%s\n" "$PYENV_CACHE_PATH"
set -x
python --version
"$version_cache_path/bin/python" --version
which python
pyenv which python
set +x
}
# Main script begins.
if [[ -z "$PYENV_VERSION" ]]; then
echo "PYENV_VERSION is not set. Not installing a pyenv."
return 0
fi
# Get out of the virtualenv we're in (if we're in one).
[[ -z "$VIRTUAL_ENV" ]] || deactivate
# Install pyenv
echo "**** Installing pyenv."
if [[ -n "$PYENV_RELEASE" ]]; then
# Fetch the release archive from Github (slightly faster than cloning)
mkdir "$PYENV_ROOT"
curl -fsSL "https://github.com/pyenv/pyenv/archive/$PYENV_RELEASE.tar.gz" \
| tar -xz -C "$PYENV_ROOT" --strip-components 1
else
# Don't have a release to fetch, so just clone directly
git clone --depth 1 https://github.com/pyenv/pyenv.git "$PYENV_ROOT"
fi
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
# Make sure the cache directory exists
mkdir -p "$PYENV_CACHE_PATH"
# Try using an already cached/installed PYENV_VERSION. If it fails or is not found,
# then install from scratch.
echo "**** Trying to find and use cached python $PYENV_VERSION."
if ! use_existing_python && ! use_cached_python; then
echo "**** Installing python $PYENV_VERSION with pyenv now."
if pyenv install "$PYENV_VERSION"; then
if mv "$version_pyenv_path" "$PYENV_CACHE_PATH"; then
echo "Python was successfully built and moved to cache."
echo "**** Trying to find and use cached python $PYENV_VERSION."
if ! use_cached_python; then
echo "Python version $PYENV_VERSION was apparently successfully built"
echo "with pyenv, but, once cached, it could not be verified."
output_debugging_info
return 1
fi
else
echo "**** Warning: Python was succesfully built, but moving to cache"
echo "failed. Proceeding anyway without caching."
fi
else
echo "Python version $PYENV_VERSION build FAILED."
return 1
fi
fi
# Now we have to reinitialize pyenv, as we need the shims etc to be created so
# the pyenv activates correctly.
echo "**** Activating python $PYENV_VERSION and generating new virtualenv."
eval "$(pyenv init -)"
pyenv global "$PYENV_VERSION"
# Make sure virtualenv is installed and up-to-date...
pip install -U virtualenv
# Then make and source a new virtualenv
VIRTUAL_ENV="$HOME/ve-pyenv-$PYENV_VERSION"
# shellcheck disable=SC2086
# We deliberately want to not quote "VIRTUALENV_EXTRA_ARGS" because it's extra arguments which should be split
virtualenv -p "$(which python)" ${VIRTUALENV_EXTRA_ARGS:-} "$VIRTUAL_ENV"
# shellcheck source=/dev/null
source "$VIRTUAL_ENV/bin/activate"
printf "One final verification that the virtualenv is working..."
if verify_python "python"; then
printf "success!\n"
else
printf "FAILED!\n"
output_debugging_info
return 1
fi