#!/usr/bin/env bash # Thu 22 Sep 2016 13:05:54 CEST # Build utilities # Determines the os name we're using osname() { [[ "$(uname -s)" == "Darwin" ]] && echo "macosx" || echo "linux" } # Functions for coloring echo commands log_debug() { echo -e "(`date +%T`) \033[1;32m${@}\033[0m" } log_info() { echo -e "(`date +%T`) \033[1;34m${@}\033[0m" } log_warn() { echo -e "(`date +%T`) \033[1;35mWarning: ${@}\033[0m" >&2 } log_error() { echo -e "(`date +%T`) \033[1;31mError: ${@}\033[0m" >&2 } # Checks a given environment variable is set (non-zero size) check_env() { if [ -z "${1+abc}" ]; then log_error "Variable ${1} is undefined - aborting..."; exit 1 else log_info "${1}=${!1}"; fi } # Exports a given environment variable, verbosely export_env() { if [ -z "${1+abc}" ]; then log_error "Variable ${1} is undefined - aborting..."; exit 1 else export ${1} log_info "export ${1}=${!1}"; fi } # Checks a given environment variable is set (non-zero size) check_pass() { if [ -z "${1+abc}" ]; then log_error "Variable ${1} is undefined - aborting..."; exit 1 else log_info "${1}=********"; fi } # Function for running command and echoing results run_cmd() { log_info "$ ${@}" ${@} local status=$? if [ ${status} != 0 ]; then log_error "Command Failed \"${@}\"" exit ${status} fi } # Prepares ~/.pypirc lock_pypirc() { local lockfile=/var/tmp/pypirc_lock local rc=${HOME}/.pypirc local maxtries=10 local try=0 local sleeptime=30 #seconds while true; do if [[ ${try} -lt ${maxtries} ]]; then ((try++)) if ( set -o noclobber; echo "$$" > "${lockfile}") 2> /dev/null; then log_info "Successfully acquired ${lockfile}" echo $$ > ${lockfile} log_info "trapping on ${lockfile}..." trap 'rm -f "${lockfile}"; exit $?' INT TERM EXIT # start: protected code log_info "Creating ${rc}..." if [ -e ${rc} ]; then run_cmd rm -f ${rc} fi cat <<EOT >> ${rc} [distutils] index-servers = production staging [production] repository: ${PYPISERVER} username: ${PYPIUSER} password: ${PYPIPASS} [staging] repository: ${TESTSERVER} username: ${PYPIUSER} password: ${PYPIPASS} EOT run_cmd chmod 600 ${rc} # end: protected code break else log_warn "${lockfile} exists, owned by process $(cat $lockfile)" log_info "Will retry after a ${sleeptime} seconds sleep (${try}/${maxtries})" run_cmd sleep ${sleeptime} fi else log_error "I already retried deploying ${try} times. Aborting..." log_error "You can retry this step when less packages are building." exit 1 fi done } # Cleans ~/.pypirc, if the lock file belongs to us unlock_pypirc() { local lockfile=/var/tmp/pypirc_lock local rc=${HOME}/.pypirc # untrap if lock belongs to the running process if [[ $(cat ${lockfile}) == $$ ]]; then run_cmd rm -r ${lockfile} run_cmd rm -rf ${rc} log_info "$ trap - INT TERM EXIT" trap - INT TERM EXIT fi } # Runs setup.py in a deployment context. If fails, tries to unlock # the ${HOME}/.pypirc file lock setup_deploy() { log_info "$ ${@}" ${PREFIX}/bin/python setup.py ${@} local status=$? if [ ${status} != 0 ]; then log_error "Command Failed \"${@}\"" unlock_pypirc #just tries exit ${status} fi } # Uploads a file to our intranet location via curl doc_upload() { log_info "curl: ${1} -> ${DOCSERVER}/${2}..." curl --location --silent --show-error --user "${DOCUSER}:${DOCPASS}" --upload-file ${1} ${DOCSERVER}/${2} local status=$? if [ ${status} != 0 ]; then log_error "Curl command finished with an error condition (status=${status})" exit ${status} fi log_info "Successfully uploaded ${1} with curl" } # Activates environment and sets up compilation # $1: root of the conda installation # $2: your current build prefix prepare_build_env() { # Activates conda environment for the build log_info "$ source $1/bin/activate $2" source $1/bin/activate $2 # Configures CCACHE # use_ccache=`which ccache` # if [ -z "${use_ccache}" ]; then # log_warn "Cannot find ccache, compiling from scratch..." # else # local ccache_bin=$2/lib/ccache # if [ ! -d ${ccache_bin} ]; then # run_cmd mkdir -pv ${ccache_bin} # ln -sf ${use_ccache} ${ccache_bin}/gcc # ln -sf ${use_ccache} ${ccache_bin}/g++ # ln -sf ${use_ccache} ${ccache_bin}/cc # ln -sf ${use_ccache} ${ccache_bin}/c++ # fi # use_gcc=`which gcc` # PATH=${ccache_bin}:${PATH} # export_env PATH # log_info "ccache installed at ${use_ccache}, caching compilations..." # log_info "gcc installed at ${use_gcc}..." # fi } # Appends a value to a variable if that is not already set # $1: variable name to append the value # $2: the value to be appended append_if_not_set() { if [ -z "${1+abc}" ]; then eval $1="$2" elif [[ "${!1}" != "*${2}*" ]]; then eval $1="${!1} $2" fi } # Checks if an array contains a value # taken from here: https://stackoverflow.com/questions/3685970/check-if-an-array-contains-a-value # Parameters: <value-to-check> <array-variable> # Usage: "a string" "${array[@]}" contains_element () { local e for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done return 1 } check_env PYTHON_VERSION check_env CI_PROJECT_DIR check_env CI_PROJECT_PATH check_env CI_PROJECT_NAME check_env CI_BUILD_REF check_env CI_BUILD_REF_NAME check_pass PYPIUSER check_pass PYPIPASS check_pass DOCUSER check_pass DOCPASS # Sets up variables OSNAME=`osname` if [ -z "${CONDA_FOLDER}" ]; then CONDA_FOLDER=/opt/conda fi PYVER=py$(echo ${PYTHON_VERSION} | tr -d '.') if [ -z "${CONDA_ENV}" ]; then if [ -d "${CONDA_FOLDER}/envs/bob-devel-${PYVER}-${CI_BUILD_REF_NAME}" ]; then CONDA_ENV=bob-devel-${PYVER}-${CI_BUILD_REF_NAME} else CONDA_ENV=bob-devel-${PYVER} fi fi BOB_PREFIX_PATH=${CONDA_FOLDER}/envs/${CONDA_ENV} if [ -z "${DOCSERVER}" ]; then DOCSERVER=http://www.idiap.ch export_env DOCSERVER fi if [ -z "{PREFIX}" ]; then PREFIX=${CI_PROJECT_DIR}/build-prefix # In case we're setting-up the prefix, erase it if it exists if [ -d "${PREFIX}" ]; then run_cmd rm -rf ${PREFIX} fi fi if [ "${OSNAME}" == "linux" ]; then # Temporary hack to get building done right with gcc-5 compilers if [ -z "${CFLAGS}" ]; then CFLAGS="-D_GLIBCXX_USE_CXX11_ABI=0 -pthread" else CFLAGS="${CFLAGS} -D_GLIBCXX_USE_CXX11_ABI=0 -pthread" fi else CFLAGS="" fi CXXFLAGS=${CFLAGS} if [ -z "${PYPISERVER}" ]; then PYPISERVER="https://pypi.python.org/pypi" fi TESTSERVER=https://testpypi.python.org/pypi check_env OSNAME check_env PYVER check_env PREFIX export_env PREFIX export_env CFLAGS export_env CXXFLAGS export_env BOB_PREFIX_PATH check_env DOCSERVER check_env PYPISERVER check_env TESTSERVER check_env CONDA_FOLDER check_env CONDA_ENV if [ -z "${CI_BUILD_TAG}" ]; then DEFSRV="${DOCSERVER}/software/bob/docs/latest/bob/%s/master/" if [ -z "${BOB_DOCUMENTATION_SERVER}" ]; then BOB_DOCUMENTATION_SERVER="${DEFSRV}" else BOB_DOCUMENTATION_SERVER="${BOB_DOCUMENTATION_SERVER}|${DEFSRV}" fi unset DEFSRV export_env BOB_DOCUMENTATION_SERVER else log_info "Building tag, not setting BOB_DOCUMENTATION_SERVER" fi