mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-05 08:25:32 +00:00
Clarifies the confusing builder.inc.sh / build-utils.sh distinction by giving the scripts more appropriate names. Most build scripts should use builder-full.inc.sh; some helper scripts can use builder-basic.inc.sh. Documented in resources/build/README.md. Renames: * resources/build/builder.inc.sh to resources/build/builder-full.inc.sh * resources/build/build-utils.sh to resources/build/builder-basic.inc.sh Other changes: * Moves Android-specific functions out of builder-basic.inc.sh and into android/build.sh. * Renames functions in builder-basic.inc.sh More functions may be moved from builder-basic.inc.sh into utils.inc.sh or other scripts in the future. Fixes: #14065 Build-bot: build all Test-bot: skip
315 lines
9.9 KiB
Bash
315 lines
9.9 KiB
Bash
#!/usr/bin/env bash
|
|
# shellcheck disable=SC2154 # (variables are set in builder-basic.inc.sh)
|
|
|
|
output_log() {
|
|
echo "$1" >&2
|
|
builder_echo "$1"
|
|
}
|
|
|
|
output_ok() {
|
|
echo ":heavy_check_mark: $1" >&2
|
|
builder_echo green "OK: $1"
|
|
}
|
|
|
|
output_warning() {
|
|
echo ":warning: $1" >&2
|
|
builder_echo warning "WARNING: $1"
|
|
}
|
|
|
|
output_error() {
|
|
echo ":x: $1" >&2
|
|
builder_echo error "ERROR: $1"
|
|
}
|
|
|
|
check_api_not_changed() {
|
|
if [[ -z "${BIN_PKG:-}" ]]; then
|
|
output_warning "Skipping check for API change because binary Debian package not specified"
|
|
return
|
|
fi
|
|
# Checks that the API did not change compared to what's documented in the .symbols file
|
|
tmpDir=$(mktemp -d)
|
|
# shellcheck disable=SC2064
|
|
trap "rm -rf \"${tmpDir}\"" ERR
|
|
dpkg -x "${BIN_PKG}" "${tmpDir}"
|
|
mkdir -p debian/tmp/DEBIAN
|
|
if dpkg-gensymbols -v"${KEYMAN_VERSION}" -p"${PKG_NAME}" -e"${tmpDir}"/usr/lib/x86_64-linux-gnu/"${LIB_NAME}".so* -c4; then
|
|
output_ok "${LIB_NAME} API didn't change"
|
|
else
|
|
output_error "${LIB_NAME} API changed"
|
|
EXIT_CODE=4
|
|
fi
|
|
cd "${REPO_ROOT}/linux"
|
|
rm -rf "${tmpDir}"
|
|
trap ERR
|
|
}
|
|
|
|
#
|
|
# Compare the SHA of the base and head commits for changes to the .symbols file
|
|
#
|
|
is_symbols_file_changed() {
|
|
local CHANGED_REF CHANGED_BASE
|
|
CHANGED_REF=$(git rev-parse "${GIT_SHA}":"linux/debian/${PKG_NAME}.symbols")
|
|
CHANGED_BASE=$(git rev-parse "${GIT_BASE}":"linux/debian/${PKG_NAME}.symbols")
|
|
if [[ "${CHANGED_REF}" == "${CHANGED_BASE}" ]]; then
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
get_changes() {
|
|
local WHAT_CHANGED
|
|
WHAT_CHANGED=$(git diff -I "^${LIB_NAME}.so" "$1".."$2" | diffstat -m -t | grep "${PKG_NAME}.symbols" )
|
|
|
|
IFS=',' read -r -a CHANGES <<< "${WHAT_CHANGED:-0,0,0}"
|
|
}
|
|
|
|
check_updated_version_number() {
|
|
# Checks that the package version number got updated in the .symbols file if it got changed
|
|
# shellcheck disable=SC2310
|
|
if is_symbols_file_changed; then
|
|
# .symbols file changed, now check if the package version got updated as well
|
|
# Note: We don't check that ALL changes in that file have an updated package version -
|
|
# we hope this gets flagged in code review.
|
|
# Note: This version number check may not match the actual released version, if the branch
|
|
# is out of date when it is merged to the release branch (master/beta/stable-x.y). If this
|
|
# is considered important, then make sure the branch is up to date, and wait for test
|
|
# builds to complete, before merging.
|
|
get_changes "${GIT_BASE}" "${GIT_SHA}"
|
|
INSERTED="${CHANGES[0]}"
|
|
DELETED="${CHANGES[1]}"
|
|
MODIFIED="${CHANGES[2]}"
|
|
|
|
if (( DELETED > 0 )) && (( MODIFIED == 0 )) && (( INSERTED == 0)); then
|
|
# If only lines got removed we basically skip this test. A later check will
|
|
# test that the API version got updated.
|
|
output_ok "${PKG_NAME}.symbols file did change but only removed lines"
|
|
else
|
|
local version_base version_head
|
|
version_head=$(get_highest_version_in_symbols_file "${GIT_SHA}")
|
|
version_base=$(get_highest_version_in_symbols_file "${GIT_BASE}")
|
|
if (( $(compare_versions "${version_head}" "${version_base}") > 0 )); then
|
|
output_ok "${PKG_NAME}.symbols file got updated with package version number"
|
|
else
|
|
output_error "${PKG_NAME}.symbols file got changed without changing the package version number of the symbol"
|
|
EXIT_CODE=1
|
|
fi
|
|
fi
|
|
else
|
|
output_ok "${PKG_NAME}.symbols file didn't change"
|
|
fi
|
|
}
|
|
|
|
compare_versions() {
|
|
local first_parts second_parts
|
|
IFS='.' read -r -a first_parts <<< "$1"
|
|
IFS='.' read -r -a second_parts <<< "$2"
|
|
if (( first_parts[0] < second_parts[0] )); then
|
|
echo -1
|
|
elif (( first_parts[0] > second_parts[0] )); then
|
|
echo 1
|
|
elif (( first_parts[1] < second_parts[1] )); then
|
|
echo -1
|
|
elif (( first_parts[1] > second_parts[1] )); then
|
|
echo 1
|
|
elif (( first_parts[2] < second_parts[2] )); then
|
|
echo -1
|
|
elif (( first_parts[2] > second_parts[2] )); then
|
|
echo 1
|
|
else
|
|
echo 0
|
|
fi
|
|
}
|
|
|
|
get_highest_version_in_symbols_file() {
|
|
local sha="$1"
|
|
local symbol_lines line line_version
|
|
local max_version=0
|
|
|
|
tmpfile=$(mktemp)
|
|
if ! git cat-file blob "${sha}:linux/debian/${PKG_NAME}.symbols" > "${tmpfile}" 2>/dev/null; then
|
|
rm "${tmpfile}"
|
|
return 1
|
|
fi
|
|
|
|
# Start with fourth line which is where symbols start
|
|
mapfile -s 3 symbol_lines < "${tmpfile}"
|
|
for line in "${symbol_lines[@]}"; do
|
|
# km_core_actions_dispose@Base 17.0.197
|
|
line_version=${line##* }
|
|
if (( $(compare_versions "${line_version}" "${max_version}") > 0 )); then
|
|
max_version="${line_version}"
|
|
fi
|
|
done
|
|
|
|
echo "${max_version}"
|
|
|
|
rm "${tmpfile}"
|
|
return 0
|
|
}
|
|
|
|
get_api_version_in_symbols_file() {
|
|
# Retrieve symbols file at commit $1 and extract "1" from
|
|
# "libkeymancore.so.1 libkeymancore1 #MINVER#"
|
|
local firstline tmpfile
|
|
local sha="$1"
|
|
|
|
tmpfile=$(mktemp)
|
|
if ! git cat-file blob "${sha}:linux/debian/${PKG_NAME}.symbols" > "${tmpfile}" 2>/dev/null; then
|
|
rm "${tmpfile}"
|
|
echo "-1"
|
|
return
|
|
fi
|
|
|
|
firstline="$(head -1 "${tmpfile}")"
|
|
firstline="${firstline#"${LIB_NAME}".so.}"
|
|
firstline="${firstline%% *}"
|
|
|
|
rm "${tmpfile}"
|
|
echo "${firstline}"
|
|
}
|
|
|
|
get_api_version_from_core() {
|
|
# Retrieve CORE_API_VERSION.md from commit $1 and extract major version
|
|
# number ("1") from "1.0.0"
|
|
local api_version tmpfile
|
|
local sha="$1"
|
|
tmpfile=$(mktemp)
|
|
|
|
if ! git cat-file blob "${sha}:core/CORE_API_VERSION.md" > "${tmpfile}" 2>/dev/null; then
|
|
rm "${tmpfile}"
|
|
echo "-1"
|
|
return
|
|
fi
|
|
|
|
api_version=$(cat "${tmpfile}")
|
|
api_version=${api_version%%.*}
|
|
|
|
rm "${tmpfile}"
|
|
echo "${api_version}"
|
|
}
|
|
|
|
# Check if the API version got updated
|
|
# Returns:
|
|
# 0 - if the API version got updated
|
|
# 1 - the .symbols file got changed but the API version didn't get updated
|
|
# 2 - if we're in the alpha tier and the API version got updated since
|
|
# the last stable version
|
|
# NOTE: it is up to the caller to check if this is a major version
|
|
# change that requires an API version update.
|
|
# Check if the API version got updated
|
|
# Returns:
|
|
# 0 - if the API version got updated
|
|
# 1 - the .symbols file got changed but the API version didn't get updated
|
|
# 2 - if we're in the alpha tier and the API version got updated since
|
|
# the last stable version
|
|
# NOTE: it is up to the caller to check if this is a major version
|
|
# change that requires an API version update.
|
|
is_api_version_updated() {
|
|
local OLD_API_VERSION NEW_API_VERSION KEYMAN_TIER
|
|
OLD_API_VERSION=$(get_api_version_in_symbols_file "${GIT_BASE}")
|
|
NEW_API_VERSION=$(get_api_version_in_symbols_file "${GIT_SHA}")
|
|
if (( NEW_API_VERSION > OLD_API_VERSION )); then
|
|
echo "0"
|
|
return
|
|
fi
|
|
|
|
# API version didn't change. However, that might be ok if we're in alpha
|
|
# and a major change happened previously.
|
|
KEYMAN_TIER=$(cat "${REPO_ROOT}/TIER.md")
|
|
case ${KEYMAN_TIER} in
|
|
alpha)
|
|
local STABLE_VERSION STABLE_API_VERSION STABLE_BRANCH
|
|
STABLE_VERSION=$((${KEYMAN_VERSION%%.*} - 1))
|
|
STABLE_BRANCH="origin/stable-${STABLE_VERSION}.0"
|
|
STABLE_API_VERSION=$(get_api_version_in_symbols_file "${STABLE_BRANCH}")
|
|
if (( STABLE_API_VERSION == -1 )); then
|
|
# .symbols file doesn't exist in stable branch, so let's check CORE_API_VERSION.md. That
|
|
# doesn't exist in 16.0 but appeared in 17.0.
|
|
STABLE_API_VERSION=$(get_api_version_from_core "${STABLE_BRANCH}")
|
|
if (( STABLE_API_VERSION == -1 )); then
|
|
# CORE_API_VERSION.md doesn't exist either
|
|
if (( NEW_API_VERSION > 0 )); then
|
|
# .symbols and CORE_API_VERSION.md file don't exist in stable branch; however, we
|
|
# incremented the version number compared to 16.0, so that's ok
|
|
echo "2"
|
|
return
|
|
fi
|
|
fi
|
|
fi
|
|
if (( NEW_API_VERSION > STABLE_API_VERSION )); then
|
|
echo "2"
|
|
return
|
|
fi ;;
|
|
*)
|
|
;;
|
|
esac
|
|
|
|
echo "1"
|
|
}
|
|
|
|
check_for_major_api_changes() {
|
|
# Checks that API version number gets updated if API changes
|
|
local WHAT_CHANGED CHANGES INSERTED DELETED MODIFIED UPDATED
|
|
|
|
# shellcheck disable=2310
|
|
if ! is_symbols_file_changed; then
|
|
output_ok "No major API change"
|
|
return
|
|
fi
|
|
|
|
get_changes "${GIT_BASE}" "${GIT_SHA}"
|
|
INSERTED="${CHANGES[0]}"
|
|
DELETED="${CHANGES[1]}"
|
|
MODIFIED="${CHANGES[2]}"
|
|
|
|
if (( DELETED > 0 )) || (( MODIFIED > 0 )); then
|
|
builder_echo "Major API change: ${DELETED} lines deleted and ${MODIFIED} lines modified"
|
|
UPDATED=$(is_api_version_updated)
|
|
if [[ ${UPDATED} == 1 ]]; then
|
|
output_error "Major API change without updating API version number in ${PKG_NAME}.symbols file"
|
|
EXIT_CODE=2
|
|
elif [[ ${UPDATED} == 2 ]]; then
|
|
output_ok "API version number got previously updated in ${PKG_NAME}.symbols file after major API change; no change within alpha necessary"
|
|
else
|
|
output_ok "API version number got updated in ${PKG_NAME}.symbols file after major API change"
|
|
fi
|
|
elif (( INSERTED > 0 )); then
|
|
output_ok "Minor API change: ${INSERTED} lines added"
|
|
# We currently don't check version number for minor API changes
|
|
else
|
|
output_ok "No major API change"
|
|
fi
|
|
}
|
|
|
|
check_for_api_version_consistency() {
|
|
# Checks that the (major) API version number in the .symbols file and
|
|
# in CORE_API_VERSION.md are the same
|
|
local symbols_version api_version
|
|
symbols_version=$(get_api_version_in_symbols_file "HEAD")
|
|
api_version=$(get_api_version_from_core "HEAD")
|
|
|
|
if (( symbols_version == api_version )); then
|
|
output_ok "API version in .symbols file and in CORE_API_VERSION.md is the same"
|
|
else
|
|
output_error "API version in .symbols file and in CORE_API_VERSION.md is different"
|
|
EXIT_CODE=3
|
|
fi
|
|
}
|
|
|
|
verify_api_action() {
|
|
local SONAME
|
|
SONAME=$(get_api_version_from_core "HEAD")
|
|
LIB_NAME=libkeymancore
|
|
PKG_NAME="${LIB_NAME}${SONAME}"
|
|
if [[ ! -f debian/${PKG_NAME}.symbols ]]; then
|
|
output_error "Missing ${PKG_NAME}.symbols file"
|
|
exit 0
|
|
fi
|
|
|
|
EXIT_CODE=0
|
|
check_api_not_changed
|
|
check_updated_version_number
|
|
check_for_major_api_changes
|
|
check_for_api_version_consistency
|
|
exit "${EXIT_CODE}"
|
|
}
|