@ -86,7 +86,7 @@ set_terminal_colors() {
_Red = '\e[0;31m'
_Green = '\e[0;32m'
_Yellow = '\e[0;33m'
_Blue = '\e[0; 3 4m'
_Blue = '\e[0; 9 4m'
_Violet = '\e[0;35m'
_Cyan = '\e[0;36m'
@ -95,12 +95,12 @@ set_terminal_colors() {
_BRed = '\e[1;31m'
_BGreen = '\e[1;32m'
_BYellow = '\e[1;33m'
_BBlue = '\e[1; 3 4m'
_BBlue = '\e[1; 9 4m'
_BPurple = '\e[1;35m'
_BCyan = '\e[1;36m'
}
if [ ! -p /dev/stdout ] ; then
if [ ! -p /dev/stdout ] && [ ! " $TERM " = 'dumb' ] && [ ! " $TERM " = 'unknown' ] ; then
set_terminal_colors
fi
@ -152,6 +152,12 @@ err_msg() { echo -e "${_BRed}ERROR:${_creset} $*" >&2; }
warn_msg( ) { echo -e " ${ _BBlue } WARN: ${ _creset } $* " >& 2; }
info_msg( ) { echo -e " ${ _BYellow } INFO: ${ _creset } $* " >& 2; }
build_msg( ) {
local tag = " $1 "
shift
echo -e " ${ _Blue } ${ tag : 0 : 10 } ${ _creset } $* "
}
clean_stdin( ) {
if [ [ $( uname -s) != 'Darwin' ] ] ; then
while read -r -n1 -t 0.1; do : ; done
@ -496,6 +502,203 @@ service_is_available() {
return " $exit_val "
}
# python
# ------
PY = " ${ PY : =3 } "
PYTHON = " ${ PYTHON : =python $PY } "
PY_ENV = " ${ PY_ENV : =local/py ${ PY } } "
PY_ENV_BIN = " ${ PY_ENV } /bin "
PY_ENV_REQ = " ${ PY_ENV_REQ : = ${ REPO_ROOT } /requirements*.txt } "
# List of python packages (folders) or modules (files) installed by command:
# pyenv.install
PYOBJECTS = " ${ PYOBJECTS : =. } "
# folder where the python distribution takes place
PYDIST = " ${ PYDIST : =dist } "
# folder where the intermediate build files take place
PYBUILD = " ${ PYBUILD : =build/py ${ PY } } "
# https://www.python.org/dev/peps/pep-0508/#extras
#PY_SETUP_EXTRAS='[develop,test]'
PY_SETUP_EXTRAS = " ${ PY_SETUP_EXTRAS : =[develop,test] } "
PIP_BOILERPLATE = ( pip wheel setuptools )
# shellcheck disable=SC2120
pyenv( ) {
# usage: pyenv [vtenv_opts ...]
#
# vtenv_opts: see 'pip install --help'
#
# Builds virtualenv with 'requirements*.txt' (PY_ENV_REQ) installed. The
# virtualenv will be reused by validating sha256sum of the requirement
# files.
required_commands \
sha256sum " ${ PYTHON } " \
|| exit
local pip_req = ( )
if ! pyenv.OK > /dev/null; then
rm -f " ${ PY_ENV } / ${ PY_ENV_REQ } .sha256 "
pyenv.drop > /dev/null
build_msg PYENV " [virtualenv] installing ${ PY_ENV_REQ } into ${ PY_ENV } "
" ${ PYTHON } " -m venv " $@ " " ${ PY_ENV } "
" ${ PY_ENV_BIN } /python " -m pip install -U " ${ PIP_BOILERPLATE [@] } "
for i in ${ PY_ENV_REQ } ; do
pip_req = ( " ${ pip_req [@] } " "-r" " $i " )
done
(
[ " $VERBOSE " = "1" ] && set -x
# shellcheck disable=SC2086
" ${ PY_ENV_BIN } /python " -m pip install " ${ pip_req [@] } " \
&& sha256sum ${ PY_ENV_REQ } > " ${ PY_ENV } /requirements.sha256 "
)
fi
pyenv.OK
}
_pyenv_OK = ''
pyenv.OK( ) {
# probes if pyenv exists and runs the script from pyenv.check
[ " $_pyenv_OK " = = "OK" ] && return 0
if [ ! -f " ${ PY_ENV_BIN } /python " ] ; then
build_msg PYENV " [virtualenv] missing ${ PY_ENV_BIN } /python "
return 1
fi
if [ ! -f " ${ PY_ENV } /requirements.sha256 " ] \
|| ! sha256sum --check --status <" ${ PY_ENV } /requirements.sha256 " 2>/dev/null; then
build_msg PYENV "[virtualenv] requirements.sha256 failed"
sed 's/^/ [virtualenv] - /' <" ${ PY_ENV } /requirements.sha256 "
return 1
fi
pyenv.check \
| " ${ PY_ENV_BIN } /python " 2>& 1 \
| prefix_stdout " ${ _Blue } PYENV ${ _creset } [check] "
local err = ${ PIPESTATUS [1] }
if [ " $err " -ne "0" ] ; then
build_msg PYENV "[check] python test failed"
return " $err "
fi
build_msg PYENV "OK"
_pyenv_OK = "OK"
return 0
}
pyenv.drop( ) {
build_msg PYENV " [virtualenv] drop ${ PY_ENV } "
rm -rf " ${ PY_ENV } "
_pyenv_OK = ''
}
pyenv.check( ) {
# Prompts a python script with additional checks. Used by pyenv.OK to check
# if virtualenv is ready to install python objects. This function should be
# overwritten by the application script.
local imp = ""
for i in " ${ PIP_BOILERPLATE [@] } " ; do
imp = " $imp , $i "
done
cat <<EOF
import ${ imp #,* }
EOF
}
pyenv.install( ) {
if ! pyenv.OK; then
py.clean > /dev/null
fi
if ! pyenv.install.OK > /dev/null; then
build_msg PYENV " [install] ${ PYOBJECTS } "
if ! pyenv.OK >/dev/null; then
pyenv
fi
for i in ${ PYOBJECTS } ; do
build_msg PYENV " [install] pip install -e ' $i ${ PY_SETUP_EXTRAS } ' "
" ${ PY_ENV_BIN } /python " -m pip install -e " $i ${ PY_SETUP_EXTRAS } "
done
fi
pyenv.install.OK
}
_pyenv_install_OK = ''
pyenv.install.OK( ) {
[ " $_pyenv_install_OK " = = "OK" ] && return 0
local imp = ""
local err = ""
if [ "." = " ${ PYOBJECTS } " ] ; then
imp = " import $( basename " $( pwd ) " ) "
else
# shellcheck disable=SC2086
for i in ${ PYOBJECTS } ; do imp = " $imp , $i " ; done
imp = " import ${ imp #,* } "
fi
(
[ " $VERBOSE " = "1" ] && set -x
" ${ PY_ENV_BIN } /python " -c " import sys; sys.path.pop(0); $imp ; " 2>/dev/null
)
err = $?
if [ " $err " -ne "0" ] ; then
build_msg PYENV "[install] python installation test failed"
return " $err "
fi
build_msg PYENV "[install] OK"
_pyenv_install_OK = "OK"
return 0
}
pyenv.uninstall( ) {
build_msg PYENV " [uninstall] ${ PYOBJECTS } "
if [ "." = " ${ PYOBJECTS } " ] ; then
pyenv.cmd python setup.py develop --uninstall 2>& 1 \
| prefix_stdout " ${ _Blue } PYENV ${ _creset } [pyenv.uninstall] "
else
pyenv.cmd python -m pip uninstall --yes ${ PYOBJECTS } 2>& 1 \
| prefix_stdout " ${ _Blue } PYENV ${ _creset } [pyenv.uninstall] "
fi
}
pyenv.cmd( ) {
pyenv.install
( set -e
# shellcheck source=/dev/null
source " ${ PY_ENV_BIN } /activate "
[ " $VERBOSE " = "1" ] && set -x
" $@ "
)
}
# golang
# ------
@ -1250,7 +1453,7 @@ pkg_install() {
centos)
# shellcheck disable=SC2068
yum install -y $@
; ;
; ;
esac
}
@ -1382,6 +1585,10 @@ LXC_ENV_FOLDER=
if in_container; then
# shellcheck disable=SC2034
LXC_ENV_FOLDER = " lxc-env/ $( hostname) / "
PY_ENV = " ${ LXC_ENV_FOLDER } ${ PY_ENV } "
PY_ENV_BIN = " ${ LXC_ENV_FOLDER } ${ PY_ENV_BIN } "
PYDIST = " ${ LXC_ENV_FOLDER } ${ PYDIST } "
PYBUILD = " ${ LXC_ENV_FOLDER } ${ PYBUILD } "
fi
lxc_init_container_env( ) {