|
| 1 | +#!/usr/bin/env bash |
| 2 | +################################################################ |
| 3 | +# # |
| 4 | +# Local development test runner script for: # |
| 5 | +# # |
| 6 | +# Privex Python Helpers # |
| 7 | +# (C) 2019 Privex Inc. GNU AGPL v3 # |
| 8 | +# # |
| 9 | +# Privex Site: https://www.privex.io/ # |
| 10 | +# # |
| 11 | +# Github Repo: https://github.com/Privex/python-helpers # |
| 12 | +# # |
| 13 | +################################################################ |
| 14 | +# |
| 15 | +# Basic Usage: |
| 16 | +# |
| 17 | +# ./local_tests.sh |
| 18 | +# |
| 19 | +# Run only specific tests (and don't update deps): |
| 20 | +# |
| 21 | +# ./local_deps tests/test_general.py tests/test_collections.py |
| 22 | +# |
| 23 | +################################################################ |
| 24 | +# |
| 25 | +# Runs the unit tests across multiple Python versions locally, similar to Travis-CI. |
| 26 | +# |
| 27 | +# If pyenv is available, will install all python versions listed in PYENV_VERS into pyenv, and |
| 28 | +# create a virtualenv for each version. |
| 29 | +# |
| 30 | +# If pyenv is unavailable, will attempt to use the system python executables listed in PY_VERS |
| 31 | +# (will skip any that aren't available). |
| 32 | +# |
| 33 | +# To force use of system python EXE's, set env var USE_PYENV=0 like so: |
| 34 | +# |
| 35 | +# USE_PYENV=0 ./local_tests.sh |
| 36 | +# |
| 37 | +################################################################ |
| 38 | + |
| 39 | +set -e |
| 40 | + |
| 41 | +# Error handling function for ShellCore |
| 42 | +_sc_fail() { echo >&2 "Failed to load or install Privex ShellCore..." && exit 1; } |
| 43 | +# If `load.sh` isn't found in the user install / global install, then download and run the auto-installer |
| 44 | +# from Privex's CDN. |
| 45 | +[[ -f "${HOME}/.pv-shcore/load.sh" ]] || [[ -f "/usr/local/share/pv-shcore/load.sh" ]] || |
| 46 | + { curl -fsS https://cdn.privex.io/github/shell-core/install.sh | bash >/dev/null; } || _sc_fail |
| 47 | + |
| 48 | +# Attempt to load the local install of ShellCore first, then fallback to global install if it's not found. |
| 49 | +[[ -d "${HOME}/.pv-shcore" ]] && source "${HOME}/.pv-shcore/load.sh" || |
| 50 | + source "/usr/local/share/pv-shcore/load.sh" || _sc_fail |
| 51 | + |
| 52 | +autoupdate_shellcore |
| 53 | + |
| 54 | +sg_load_lib trap |
| 55 | + |
| 56 | +: ${USE_PYENV=1} |
| 57 | + |
| 58 | +if [ -z ${PY_VERS+x} ]; then |
| 59 | + PY_VERS=("python3.6" "python3.7" "python3.8") |
| 60 | +fi |
| 61 | + |
| 62 | +if [ -z ${PYENV_VERS+x} ]; then |
| 63 | + PYENV_VERS=("3.6.7" "3.7.1" "3.8.0") |
| 64 | +fi |
| 65 | + |
| 66 | +### |
| 67 | +# Python Virtualenv shortcuts |
| 68 | +### |
| 69 | + |
| 70 | +activate() { |
| 71 | + local envdir="./venv" |
| 72 | + if [[ "$#" -gt 0 ]]; then envdir="$1"; fi |
| 73 | + source "${envdir}/bin/activate" |
| 74 | + msg bold green "Activated virtualenv in $envdir" |
| 75 | +} |
| 76 | + |
| 77 | +# Usage: mkvenv [python_exe] [env_folder] |
| 78 | +# mkvenv # no args = use system python3 and make in ./venv |
| 79 | +# mkvenv python3.7 # use system python3.7 and make in ./venv |
| 80 | +# mkvenv python3.6 ./env # use system python3.6 and make in ./env |
| 81 | +mkvenv() { |
| 82 | + local pyexe="python3" |
| 83 | + local envdir="./venv" |
| 84 | + if [[ "$#" -gt 0 ]]; then pyexe="$1"; fi |
| 85 | + if [[ "$#" -gt 1 ]]; then envdir="$2"; fi |
| 86 | + local pyver=$(/usr/bin/env "$pyexe" -V) |
| 87 | + /usr/bin/env "$pyexe" -m venv "$envdir" |
| 88 | + msg bold green "Made virtual env using $pyver @ $envdir" |
| 89 | +} |
| 90 | + |
| 91 | +pyenv_install() { |
| 92 | + (($# < 1)) && msg bold red "ERROR: pyenv_install expects at least 1 arg - python version to install" && return 1 |
| 93 | + |
| 94 | + local os_name="$(uname -s)" py_ver="$1" |
| 95 | + if [[ "$os_name" == "Darwin" ]]; then |
| 96 | + export CFLAGS="-I$(brew --prefix readline)/include -I$(brew --prefix openssl)/include" |
| 97 | + export CFLAGS="${CFLAGS} -I$(xcrun --show-sdk-path)/usr/include" |
| 98 | + export LDFLAGS="-L$(brew --prefix readline)/lib -L$(brew --prefix openssl)/lib" |
| 99 | + export PYTHON_CONFIGURE_OPTS="--enable-unicode=ucs2" |
| 100 | + fi |
| 101 | + msg bold green " >>> Installing Python ${py_ver} via pyenv..." |
| 102 | + pyenv install -v "$py_ver" |
| 103 | + msg bold green " >>> Successfully installed Python ${py_ver}" |
| 104 | +} |
| 105 | + |
| 106 | +main_tests() { |
| 107 | + if [[ -d "$VENV_PY_VER" ]]; then |
| 108 | + msg green " >> Virtualenv ${VENV_PY_VER} already exists. Activating it and updating packages." |
| 109 | + activate "${VENV_PY_VER}" |
| 110 | + if (($# > 0)); then |
| 111 | + msg green " >> Installing only main project as extra args were specified" |
| 112 | + ./setup.py install |
| 113 | + else |
| 114 | + msg green " >> Running pip install -U '.[dev]' ..." |
| 115 | + pip install -U '.[dev]' |
| 116 | + fi |
| 117 | + else |
| 118 | + msg green " >> Creating virtualenv at $VENV_PY_VER using python version: ${_CURR_PY_VER[*]}" |
| 119 | + mkvenv "$_PYTHON_EXE" "${VENV_PY_VER}" |
| 120 | + activate "${VENV_PY_VER}" |
| 121 | + msg green " >> [NEW VIRTUALENV] Running pip install -U '.[dev]' ..." |
| 122 | + pip install -U '.[dev]' |
| 123 | + fi |
| 124 | + if (($# > 0)); then |
| 125 | + # msg green " >> Installing only main project as extra args were specified" |
| 126 | + # pip install -U '.' |
| 127 | + msg green " >> Running pytest with args: $* ..." |
| 128 | + python3 -m pytest --cov=./privex -rxXs -v "$@" |
| 129 | + else |
| 130 | + # msg green " >> Running pip install -U '.[dev]' ..." |
| 131 | + # pip install -U '.[dev]' |
| 132 | + msg green " >> Running pytest ..." |
| 133 | + python3 -m pytest --cov=./privex -rxXs -v |
| 134 | + fi |
| 135 | + msg green " >> Deactivating virtualenv ..." |
| 136 | + set +eu |
| 137 | + deactivate |
| 138 | + set -eu |
| 139 | +} |
| 140 | + |
| 141 | +has_command pyenv && HAS_PYENV=1 || HAS_PYENV=0 |
| 142 | + |
| 143 | +if ((HAS_PYENV == 1)) && ((USE_PYENV == 1)); then |
| 144 | + eval "$(pyenv init -)" |
| 145 | + PYENV_AVAIL_VERS=($(pyenv versions --bare)) |
| 146 | + for v in "${PYENV_VERS[@]}"; do |
| 147 | + containsElement "$v" "${PYENV_AVAIL_VERS[@]}" && continue |
| 148 | + pyenv_install "$v" |
| 149 | + done |
| 150 | + for v in "${PYENV_VERS[@]}"; do |
| 151 | + msg green " >> Setting shell python version to $v" |
| 152 | + export PYENV_VERSION="$v" |
| 153 | + _CURR_PY_VER=($(python3 -V)) |
| 154 | + CURR_PY_VER="${_CURR_PY_VER[1]}" |
| 155 | + VENV_PY_VER="venv_pyenv_${CURR_PY_VER}" |
| 156 | + _PYTHON_EXE="python3" |
| 157 | + main_tests "$@" |
| 158 | + done |
| 159 | + msg green " >> Clearing pyenv shell variable ..." |
| 160 | + unset PYENV_VERSION |
| 161 | +else |
| 162 | + for v in "${PY_VERS[@]}"; do |
| 163 | + if ! has_command "$v" || ! "$v" -V; then |
| 164 | + msg red " >> Python version $v is unavailable. Skipping." |
| 165 | + continue |
| 166 | + fi |
| 167 | + _CURR_PY_VER=($("$v" -V)) |
| 168 | + CURR_PY_VER="${_CURR_PY_VER[1]}" |
| 169 | + VENV_PY_VER="venv_py_${CURR_PY_VER}" |
| 170 | + _PYTHON_EXE="$v" |
| 171 | + main_tests "$@" |
| 172 | + # if [[ -d "$VENV_PY_VER" ]]; then |
| 173 | + # msg green " >> Virtualenv ${VENV_PY_VER} already exists. Activating it and updating packages." |
| 174 | + # activate "${VENV_PY_VER}" |
| 175 | + # else |
| 176 | + # msg green " >> Creating virtualenv at $VENV_PY_VER using python version: ${_CURR_PY_VER[*]}" |
| 177 | + # mkvenv "python3" "${VENV_PY_VER}" |
| 178 | + # activate "${VENV_PY_VER}" |
| 179 | + # fi |
| 180 | + # msg green " >> Running pip install -U '.[dev]' ..." |
| 181 | + # pip install -U '.[dev]' |
| 182 | + # msg green " >> Running pytest ..." |
| 183 | + # python3 -m pytest --cov=./privex -rxXs -v |
| 184 | + # msg green " >> Deactivating virtualenv ..." |
| 185 | + # deactivate |
| 186 | + done |
| 187 | +fi |
0 commit comments