From 8e38078337bdc98132dc04d8f3868cf994f60b00 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Fri, 10 Nov 2023 12:07:40 +0100 Subject: [PATCH] add a script for bumping packages using Git repository sources Signed-off-by: Jo-Philipp Wich --- update_git_source_package.sh | 176 +++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100755 update_git_source_package.sh diff --git a/update_git_source_package.sh b/update_git_source_package.sh new file mode 100755 index 0000000..a2f57f1 --- /dev/null +++ b/update_git_source_package.sh @@ -0,0 +1,176 @@ +#!/usr/bin/env bash +# update_git_source_package.sh: (c) 2023 Jo-Philipp Wich +# Licensed under the terms of the Apache License, Version 2.0 + +MAKEFILE=$1 +COMMIT=${2:-HEAD} +TOPDIR=$3 + +[ -n "$MAKEFILE" ] || { + cat <<-EOT + Usage: $0 [revision] [topdir] + + Update an OpenWrt package Makefile with PKG_SOURCE_PROTO:=git to + the given upstream revision (or 'HEAD' if omitted). + + The script either accepts a package name, like "netifd" or + an absolute or relative path to a Makefile, e.g. + "./package/utils/ucode/Makefile". + + If the revision argument is ommitted, the package is updated + to the current HEAD of the remote Git repository. + + By default, this script tries to infer the buildroot directory + from the package Makefile path but it may be overridden by + passing it as 3rd argument. This is useful in situation where + the Makefile to update does not reside within an OpenWrt buildroot. + + On success, the package Makefile is automatically modified and + the resulting changes are committed in the currently checked + buildroot branch using a standard commit message format. + EOT + + exit 1 +} + +MAKE=$(which gmake) || MAKE=$(which make) +FIND=$(which gfind) || FIND=$(which find) + +[ -x "$MAKE" ] || { + echo "Unable to locate `make` executable" >&2 + exit 1 +} + +[ -x "$FIND" ] || { + echo "Unable to locate `find` executable" >&2 + exit 1 +} + +[ -e "$MAKEFILE" ] || { + MAKEFILE=$("$FIND" "${TOPDIR:-.}/package/" -type f -path "*/$MAKEFILE/Makefile" | head -n1) +} + +[ -f "$MAKEFILE" ] || { + echo "Usage: $0 [target commit] [path/to/buildroot/topdir]" + exit 1 +} + +grep -sq BuildPackage "$MAKEFILE" || { + echo "The file '$MAKEFILE' does not appear to be an OpenWrt package Makefile." >&2 + exit 1 +} + +[ -n "$TOPDIR" ] || { + TOPDIR=$(cd "$(dirname "${MAKEFILE%/*}")"; pwd) + + while [ "$TOPDIR" != "/" ]; do + TOPDIR=$(dirname "$TOPDIR") + [ -f "$TOPDIR/rules.mk" ] && break + done + + [ -f "$TOPDIR/rules.mk" ] || { + echo "Unable to determine buildroot directory." >&2 + exit 1 + } +} + +export TOPDIR + +eval $( + "$MAKE" --no-print-directory -C "$(dirname "$MAKEFILE")" \ + var.PKG_NAME \ + var.PKG_RELEASE \ + var.PKG_SOURCE_PROTO \ + var.PKG_SOURCE_URL \ + var.PKG_SOURCE_DATE \ + var.PKG_SOURCE_VERSION \ + var.PKG_MIRROR_HASH +) + +case "$PKG_SOURCE_PROTO:$PKG_SOURCE_URL" in + git:http://*|git:https://*|git:git://*|git:file:*) + : + ;; + *) + echo "Unsupported combination of source protocol ('$PKG_SOURCE_PROTO') and url ('$PKG_SOURCE_URL')." >&2 + exit 1 + ;; +esac + +TEMP_GIT_DIR= + +for signal in INT TERM EXIT; do + trap ' + [ -d "$TEMP_GIT_DIR" ] && rm -rf "$TEMP_GIT_DIR"; + git -C "$(dirname "$MAKEFILE")" checkout --quiet "$(basename "$MAKEFILE")" + ' $signal +done + +TEMP_GIT_DIR=$(mktemp -d) || { + echo "Unable to create temporary Git directory." >&2 + exit 1 +} + +git clone --bare "$PKG_SOURCE_URL" "$TEMP_GIT_DIR" || { + echo "Unable to clone Git repository '$PKG_SOURCE_URL'." >&2 + exit 1 +} + +GIT_LOG="$(git -C "$TEMP_GIT_DIR" log \ + --reverse --no-merges \ + --format="%h %s" \ + "$PKG_SOURCE_VERSION..$COMMIT" \ +)" || { + echo "Unable to determine changes from commit '$PKG_SOURCE_VERSION' to '$COMMIT'." >&2 + exit 1 +} + +GIT_DATE_COMMIT=$(git -C "$TEMP_GIT_DIR" log \ + -1 --format='%cd %H' \ + --date='format:%Y-%m-%d' \ + "$COMMIT" \ +) || { + echo "Unable to determine target commit ID and date." >&2 + exit 1 +} + +sed -i -r \ + -e "/PKG_SOURCE_VERSION/s#\<$PKG_SOURCE_VERSION\>#${GIT_DATE_COMMIT#* }#" \ + -e "/PKG_SOURCE_DATE/s#\<$PKG_SOURCE_DATE\>#${GIT_DATE_COMMIT% *}#" \ + "$MAKEFILE" + +if [ -n "$PKG_RELEASE" ] && [ "$PKG_RELEASE" != "1" ]; then + sed -i -r \ + -e "/PKG_RELEASE/s#\<$PKG_RELEASE\>#1#" \ + "$MAKEFILE" +fi + +eval $( + "$MAKE" --no-print-directory -C "$(dirname "$MAKEFILE")" \ + var.PKG_SOURCE +) + +"$MAKE" -C "$(dirname "$MAKEFILE")" download || { + echo "Unable to download and pack updated Git sources." >&2 + exit 1 +} + +DL_HASH=$(sha256sum "$TOPDIR/dl/$PKG_SOURCE") || { + echo "Unable to determine archive checksum." >&2 + exit 1 +} + +sed -i -r \ + -e "/PKG_MIRROR_HASH/s#\<$PKG_MIRROR_HASH\>#${DL_HASH%% *}#" \ + "$MAKEFILE" + +git -C "$(dirname "$MAKEFILE")" commit \ + --signoff --no-edit \ + --message "$PKG_NAME: update to Git $COMMIT (${GIT_DATE_COMMIT% *})" \ + --message "$GIT_LOG" \ + "$(basename "$MAKEFILE")" + +"$MAKE" --no-print-directory -C "$(dirname "$MAKEFILE")" check || { + echo "WARNING: Package check failed for updated Makefile!" + exit 1 +} -- 2.30.2