# shellcheck shell=bash # Keyman is copyright (C) SIL Global. MIT License. function checkPrerequisites() { # Check the tier if [[ -z "${KEYMAN_TIER:=}" ]]; then echo "TIER.md or \${KEYMAN_TIER} must be set to (alpha, beta, stable) to use this script" exit 1 fi if ! builder_has_option --no-download && ! command -v xmllint > /dev/null; then echo "you must install xmllint (libxml2-utils package) to use this script" exit 1 fi } function downloadSource() { local packageDir packageDir=$1 # shellcheck disable=SC2154 cd "${KEYMAN_ROOT}/linux" || exit ./build.sh clean # Update tier in Debian watch files (replacing any previously set tier) and remove comment sed -e "s/\$tier\|alpha\|beta\|stable/${KEYMAN_TIER}/g" -e "s/^# .*$//" "${KEYMAN_ROOT}/linux/scripts/watch.in" > debian/watch version=$(uscan --report --dehs|xmllint --xpath "//dehs/upstream-version/text()" -) dirversion=$(uscan --report --dehs|xmllint --xpath "//dehs/upstream-url/text()" - | cut -d/ -f6) echo "Keyman version is ${version}" uscan || (echo "ERROR: No new version available for keyman" >&2 && exit 1) cd .. mv "keyman-${version}" "${KEYMAN_ROOT}/linux/${packageDir}" mv "keyman_${version}.orig.tar.xz" "${KEYMAN_ROOT}/linux/${packageDir}" mv "keyman_${version}.pkg.tar.xz" "${KEYMAN_ROOT}/linux/${packageDir}" mv "keyman"*.asc "${KEYMAN_ROOT}/linux/${packageDir}" rm "keyman"*.debian.tar.xz cd "${KEYMAN_ROOT}/linux/${packageDir}" || exit wget -N "https://downloads.keyman.com/linux/${KEYMAN_TIER}/${dirversion}/SHA256SUMS" sha256sum -c --ignore-missing SHA256SUMS | grep "keyman" } function wait_for_apt_deb { # from https://gist.github.com/hrpatel/117419dcc3a75e46f79a9f1dce99ef52 while sudo fuser /var/{lib/{dpkg,apt/lists},cache/apt/archives}/lock &>/dev/null 2>&1; do echo "Waiting for apt/dpkg lock to release, sleeping 10s" sleep 10 done } function checkAndInstallRequirements() { local TOINSTALL="" for p in devscripts equivs python3-dev do if ! dpkg -s "${p}" >/dev/null 2>&1; then TOINSTALL="${TOINSTALL} ${p}" fi done if [[ -n "${TOINSTALL}" ]]; then wait_for_apt_deb && sudo apt-get update # shellcheck disable=SC2086 wait_for_apt_deb && sudo DEBIAN_FRONTEND="noninteractive" \ apt-get -qy install ${TOINSTALL} fi sudo mk-build-deps debian/control wait_for_apt_deb && sudo DEBIAN_FRONTEND="noninteractive" \ apt-get -qy --allow-downgrades install ./keyman-build-deps_*.deb rm -f keyman-build-deps_* } # Generate an array of files and directories to ignore, prefixed with --tar-ignore=keyman/ function generate_tar_ignore_list() { local directory="$1" local includes_var="$2" local excludes_var="$3" local list_var="$4" local prefix="$5" local includes_array="${includes_var}[@]" # shellcheck disable=SC2034 local includes=("${!includes_array}") local excludes_array="${excludes_var}[@]" local excludes=("${!excludes_array}") # Loop through excludes and put all without path in single_excludes local single_excludes=() for item in "${excludes[@]}"; do if [[ ${item} != */* ]]; then single_excludes+=("${item}") fi done local ignore_list=() _process_directory "${directory}" false for item in "${ignore_list[@]}"; do eval "${list_var}+=(\"--tar-ignore=${item}\")" done } function _process_directory() { local directory="$1" local isParentIncluded="$2" local all_items item mapfile -t all_items < <(find "${directory}" -mindepth 1 -maxdepth 1 | sort) for item in "${all_items[@]}"; do debug "Checking item: ${item}" if _is_exact_match "includes" "${item}"; then debug " Including (full match): ${item}" if [[ -d "${item}" ]]; then _process_directory "${item}" true fi elif _starts_with "includes" "${item}"; then debug " Including (partial match): ${item}" if [[ -d "${item}" ]]; then _process_directory "${item}" "${isParentIncluded}" fi elif _is_exact_match "excludes" "${item}"; then debug " Excluding (full match): ${item}" _add_to_list "${item}" elif _ends_with "single_excludes" "${item}" || _is_wildcard_match "single_excludes" "${item}"; then debug " Excluding (single exclude): ${item}" _add_to_list "${item}" elif [[ "${isParentIncluded}" == "false" ]]; then debug " Excluding (not included): ${item}" _add_to_list "${item}" else debug " Including (parent included): ${item}" if [[ -d "${item}" ]]; then _process_directory "${item}" "${isParentIncluded}" fi fi done } function _add_to_list() { local item="$1" ignore_list+=("${prefix}/${item#./}") } # Returns true if one of the values in the $1 array equals ${file} ($2) # Example: will return true for array=(path1/path2) file=./path1/path2 function _is_exact_match() { local array_var="$1" local file="$2" local array_name="${array_var}[@]" local haystack=("${!array_name}") local item for item in "${haystack[@]}"; do if [[ "./${item#./}" == "${file}" ]]; then return 0 fi done return 1 } # Returns true if one of the values in the $1 array starts with ${file} ($2) # Example: will return true for array=(path1/path2) file=./path1 function _starts_with() { local array_var="$1" local file="$2" local array_name="${array_var}[@]" local array_values=("${!array_name}") local array_item for array_item in "${array_values[@]}"; do if [[ "./${array_item#./}" == ${file}* ]]; then return 0 fi done return 1 } # Returns true if ${file} ($2) ends with one of the values in the $1 array # Example: will return true for array=(path2) file=./path1/path2 function _ends_with() { local array_var="$1" local file="$2" local array_name="${array_var}[@]" local array_values=("${!array_name}") local array_item for array_item in "${array_values[@]}"; do if [[ "${file}" == */${array_item#./} ]]; then return 0 fi done return 1 } # Returns true if ${file} ($2) matches one of the values of the $1 array. # These values may contain wildcards. # Example: will return true for array=(*.sh) file=./path1/build.sh function _is_wildcard_match() { local array_var="$1" local file="$2" local array_name="${array_var}[@]" local array_values=("${!array_name}") local array_item for array_item in "${array_values[@]}"; do array_item=${array_item/./\\.} if [[ "${file}" =~ /${array_item/\*/.\*}$ ]]; then return 0 fi done return 1 } function debug() { # echo "$@" return 0 }