#!/usr/bin/env bash set -euo pipefail repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" # shellcheck source=scripts/apk/package-lib.sh source "${repo_root}/scripts/apk/package-lib.sh" mode="${APK_UPDATE_CHECK_MODE:-warn}" if [[ "${mode}" != "warn" && "${mode}" != "fail" ]]; then printf 'APK_UPDATE_CHECK_MODE must be warn or fail\n' >&2 exit 2 fi github_latest_release() { local repo="$1" local api_url="https://api.github.com/repos/${repo}/releases/latest" local response response="$(curl -fsSL \ -H 'Accept: application/vnd.github+json' \ -H 'X-GitHub-Api-Version: 2022-11-28' \ "${api_url}" 2>/dev/null)" || return 1 printf '%s\n' "${response}" \ | sed -n 's/^[[:space:]]*"tag_name":[[:space:]]*"\([^"]*\)".*/\1/p' \ | head -n 1 } apkbuild_value() { local package_dir="$1" local key="$2" awk -F= -v key="${key}" ' $1 == key { value = $2 gsub(/["'\'']/, "", value) gsub(/^[ \t]+|[ \t]+$/, "", value) print value exit } ' "${package_dir}/APKBUILD" } load_update_metadata() { local package_dir="$1" local metadata="${package_dir}/update-check.conf" provider="" repo="" version_prefix="v" if [[ ! -f "${metadata}" ]]; then return 1 fi # shellcheck source=/dev/null source "${metadata}" if [[ "${provider}" != "github" || -z "${repo}" ]]; then return 1 fi } normalize_version() { local version="$1" local prefix="$2" case "${prefix}" in none|"") printf '%s\n' "${version}" ;; *) printf '%s\n' "${version#"${prefix}"}" ;; esac } version_is_newer() { local latest="$1" local current="$2" local apk_result local sorted if [[ "${latest}" == "${current}" ]]; then return 1 fi if command -v apk >/dev/null 2>&1; then apk_result="$(apk version -t "${latest}-r0" "${current}-r0" 2>/dev/null || true)" [[ "${apk_result}" == ">" ]] return fi if sort -V /dev/null 2>&1; then sorted="$(printf '%s\n%s\n' "${current}" "${latest}" | sort -V | tail -n 1)" [[ "${sorted}" == "${latest}" && "${latest}" != "${current}" ]] return fi return 0 } printf '%-14s %-14s %-14s %-18s %s\n' "PACKAGE" "CURRENT" "LATEST" "STATUS" "UPSTREAM" has_update=0 has_unknown=0 while IFS= read -r package_dir; do apk_validate_package_dir "${package_dir}" package_name="$(apk_package_name "${package_dir}")" current_version="$(apkbuild_value "${package_dir}" "pkgver")" status="unknown" latest_version="-" upstream_url="-" if load_update_metadata "${package_dir}"; then upstream_url="https://github.com/${repo}/releases" if latest_tag="$(github_latest_release "${repo}")" && [[ -n "${latest_tag}" ]]; then latest_version="$(normalize_version "${latest_tag}" "${version_prefix}")" if version_is_newer "${latest_version}" "${current_version}"; then status="update-available" has_update=1 else status="current" fi else has_unknown=1 fi else has_unknown=1 fi printf '%-14s %-14s %-14s %-18s %s\n' \ "${package_name}" \ "${current_version:-"-"}" \ "${latest_version}" \ "${status}" \ "${upstream_url}" done < <(apk_package_dirs "${repo_root}") if [[ "${mode}" == "fail" && ( "${has_update}" -ne 0 || "${has_unknown}" -ne 0 ) ]]; then exit 1 fi