-
Notifications
You must be signed in to change notification settings - Fork 0
/
pactivate
126 lines (114 loc) · 5.09 KB
/
pactivate
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
# pactivate version 0.4.0 https://github.com/cynic-net/pactivate
[ -n "$BASH_VERSION" ] || { echo 1>&2 "source (.) this with Bash."; exit 9; }
# https://stackoverflow.com/a/28776166/107294
(return 0 2>/dev/null) \
|| { echo 1>&2 "source (.) pactivate with Bash."; exit 9; }
__pa_cleanup() {
unset __pa_cleanup __pa_echo \
__pa_builddir __pa_quiet __pa_python __pa_python_deref __pa_pyver \
__pa_bootdir __pa_basedir __pa_requirements
}
__pa_echo() { [[ -n $__pa_quiet ]] || echo "$@"; }
__pa_basedir=$(cd "$(dirname "$BASH_SOURCE")" && pwd -P)
__pa_builddir=
__pa_quiet=
while [[ $# -gt 0 ]]; do case "$1" in
-b) shift; __pa_builddir="$1"; shift;;
-B) shift; __pa_basedir="$1"; shift;;
-q) shift; __pa_quiet=-q;;
*) echo 1>&2 "pactivate: unknown argument: $1"; __pa_cleanup; return 2;;
esac; done;
if [[ -e $__pa_basedir/.python || -L $__pa_basedir/.python ]]; then
# Even if it's a dangling link (-e fails) we use it so that the
# user sees the error.
__pa_python=$__pa_basedir/.python
else
# We test `py` only in Windows/MINGW because the Unix `py` program
# (from the pythonpy package) is a different thing we never want to use.
for __pa_python in ${MSYSTEM:+py} python3 python PYTHON_NOT_FOUND; do
"$__pa_python" --version >/dev/null 2>&1 && break
done
fi
"$__pa_python" --version >/dev/null 2>&1 || {
[[ -L $__pa_python ]] \
&& echo "$__pa_python -> $(readlink "$__pa_python")"
$__pa_python --version || true # Display the suppressed error message
echo 1>&2 "pactivate: bad python interpreter"
__pa_cleanup; return 3
}
# $__pa_pyver is empty for "modern" versions of Python (i.e., those that
# can use the current get-pip.py, 3.7 and above) and otherwise is the
# major.minor revision number, suitable for use in the URL to download
# an alternate version of get-pip.py.
__pa_pyver=$("$__pa_python" -c '
# Reminder: this script must be compatible with Python 2 syntax.
import sys
M, m = sys.version_info[0], sys.version_info[1] # Major, minor
if (M < 3 or (M == 3 and m < 7)):
print("{}.{}".format(M, m))
')
__pa_requirements="$__pa_basedir/requirements.txt"
[[ -z $__pa_builddir ]] && __pa_builddir=$(cd "$__pa_basedir" && pwd -P)/.build
__pa_bootdir="$__pa_builddir/bootstrap/pactivate${__pa_pyver}"
mkdir -p "$__pa_bootdir" # also ensures that $__pa_builddir exists
[[ -x $__pa_bootdir/bin/pip ]] || {
echo "----- Installing bootstrap pip (ver=${__pa_pyver:-latest})"
# Debian-based systems do not incude distutils in the standard
# python3 package; check that it's available and, if not, print a
# more informative message than the ModuleNotFoundError.
"$__pa_python" -c 'import distutils.cmd' || {
echo 1>&2 \
"Cannot import 'distuils.cmd'; apt-get install python3-distutils?"
return 3
}
# get-pip.py produces spurious upgrade notices on older Python versions
# such as 3.6 or 2.7; --disable-pip-version-check suppresses these.
curl '-#' ${__pa_quiet:+--silent} \
"https://bootstrap.pypa.io/pip/$__pa_pyver/get-pip.py" \
| "$__pa_python" - \
$__pa_quiet -t "$__pa_bootdir" --disable-pip-version-check \
|| return $?
PYTHONPATH="$__pa_bootdir" "$__pa_bootdir/bin/pip" --version
}
[[ -d $__pa_bootdir/virtualenv/ ]] || {
echo '----- Installing bootstrap virtualenv'
# This install produces spurious "bootstrap/.../bin already exists"
# messages; --upgrade suppresses these. However, --upgrade also seems
# to entirely remove the bin/ directory, so we "re-install" pip
# (which will not re-download it) to restore bin/pip as well.
PYTHONPATH="$__pa_bootdir" "$__pa_bootdir/bin/pip" \
$__pa_quiet install --upgrade -t "$__pa_bootdir" pip virtualenv
}
[[ -d $__pa_builddir/virtualenv/ ]] || {
echo '----- Building virtualenv'
echo -n "Using $__pa_python"
if [[ -L $__pa_python ]]; then
# MacOS readlink has no -f option, so we must do this the hard
# way. Fortunately we already know that the binary exists and is
# a Python interpreter.
__pa_python_deref=$(readlink "$__pa_python")
__pa_python_deref=$(cd "$__pa_basedir" \
&& cd $(dirname "$__pa_python_deref") \
&& pwd -P)/$(basename "$__pa_python_deref")
echo " -> $__pa_python_deref"
else
__pa_python_deref="$__pa_python"
echo
fi
echo -n "Version: " && "$__pa_python" --version
PYTHONPATH="$__pa_bootdir" "$__pa_python_deref" -s -m virtualenv \
$__pa_quiet --prompt $(basename "$__pa_basedir") \
"$__pa_builddir/virtualenv/" \
&& [[ -f "$__pa_requirements" ]] \
&& "$__pa_builddir/virtualenv/bin/pip" \
install $__pa_quiet -r "$__pa_requirements"
}
cmp -s $(type -p "$__pa_python") "$__pa_builddir/virtualenv/bin/python" || (
echo 1>&2 "WARNING:" \
virtualenv/bin/python \
"($("$__pa_builddir"/virtualenv/bin/python --version 2>&1))" \
"is not $__pa_python" \
"($("$__pa_python" --version 2>&1))" \
)
. "$__pa_builddir"/virtualenv/*/activate
__pa_cleanup