1# Copyright (c) 2019-2024 Cosmin Truta. 2# 3# Use, modification and distribution are subject to the MIT License. 4# Please see the accompanying file LICENSE_MIT.txt 5# 6# SPDX-License-Identifier: MIT 7 8test -f "$BASH_SOURCE" || { 9 echo >&2 "warning: this module requires Bash version 3 or newer" 10} 11test "${#BASH_SOURCE[@]}" -gt 1 || { 12 echo >&2 "warning: this module should be sourced from a Bash script" 13} 14 15# Reset the locale to avoid surprises from locale-dependent commands. 16export LC_ALL=C 17export LANG=C 18export LANGUAGE=C 19 20# Reset CDPATH to avoid surprises from the "cd" command. 21export CDPATH="" 22 23# Initialize the global constants CI_SCRIPT_{NAME,DIR} and CI_TOPLEVEL_DIR. 24CI_SCRIPT_NAME="$(basename -- "$0")" 25CI_SCRIPT_DIR="$(cd "$(dirname -- "$0")" && pwd)" 26CI_TOPLEVEL_DIR="$(cd "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd)" 27 28# Initialize the global constants CI_BUILD_{...} for the host build platform. 29CI_BUILD_ARCH="${CI_BUILD_ARCH:-"$(uname -m | tr 'A-Z/\.-' 'a-z____')"}" 30CI_BUILD_SYSTEM="${CI_BUILD_SYSTEM:-"$(uname -s | tr 'A-Z/\.-' 'a-z____')"}" 31 32# Initialize the global constants CI_TARGET_{...} for the target platform. 33CI_TARGET_ARCH="${CI_TARGET_ARCH:-"$CI_BUILD_ARCH"}" 34CI_TARGET_SYSTEM="${CI_TARGET_SYSTEM:-"$CI_BUILD_SYSTEM"}" 35 36function ci_info { 37 printf >&2 "%s: %s\\n" "$CI_SCRIPT_NAME" "$*" 38} 39 40function ci_warn { 41 printf >&2 "%s: warning: %s\\n" "$CI_SCRIPT_NAME" "$*" 42} 43 44function ci_err { 45 printf >&2 "%s: error: %s\\n" "$CI_SCRIPT_NAME" "$*" 46 exit 2 47} 48 49function ci_err_internal { 50 printf >&2 "%s: internal error: %s\\n" "$CI_SCRIPT_NAME" "$*" 51 printf >&2 "ABORTED\\n" 52 # Exit with the conventional SIGABRT code. 53 exit 134 54} 55 56function ci_expr { 57 if [[ ${*:-0} == [0-9] ]] 58 then 59 # This is the same as in the else-branch below, albeit much faster 60 # for our intended use cases. 61 return $((!$1)) 62 else 63 # The funny-looking compound command "... && return $? || return $?" 64 # allows the execution to continue uninterrupted under "set -e". 65 expr >/dev/null "$@" && return $? || return $? 66 fi 67} 68 69function ci_spawn { 70 printf >&2 "%s: executing:" "$CI_SCRIPT_NAME" 71 printf >&2 " %q" "$@" 72 printf >&2 "\\n" 73 "$@" 74} 75 76# Ensure that the internal initialization is correct. 77[[ $CI_TOPLEVEL_DIR/ci/lib/ci.lib.sh -ef ${BASH_SOURCE[0]} ]] || { 78 ci_err_internal "bad or missing \$CI_TOPLEVEL_DIR" 79} 80[[ $CI_SCRIPT_DIR/$CI_SCRIPT_NAME -ef $0 ]] || { 81 ci_err_internal "bad or missing \$CI_SCRIPT_DIR/\$CI_SCRIPT_NAME" 82} 83[[ $CI_BUILD_ARCH && $CI_BUILD_SYSTEM ]] || { 84 ci_err_internal "missing \$CI_BUILD_ARCH or \$CI_BUILD_SYSTEM" 85} 86[[ $CI_TARGET_ARCH && $CI_TARGET_SYSTEM ]] || { 87 ci_err_internal "missing \$CI_TARGET_ARCH or \$CI_TARGET_SYSTEM" 88} 89 90# Ensure that the user initialization is correct. 91[[ ${CI_FORCE:-0} == [01] ]] || { 92 ci_err "bad boolean option: \$CI_FORCE: '$CI_FORCE'" 93} 94[[ ${CI_NO_TEST:-0} == [01] ]] || { 95 ci_err "bad boolean option: \$CI_NO_TEST: '$CI_NO_TEST'" 96} 97[[ ${CI_NO_INSTALL:-0} == [01] ]] || { 98 ci_err "bad boolean option: \$CI_NO_INSTALL: '$CI_NO_INSTALL'" 99} 100[[ ${CI_NO_CLEAN:-0} == [01] ]] || { 101 ci_err "bad boolean option: \$CI_NO_CLEAN: '$CI_NO_CLEAN'" 102} 103