Files
coreboot/util/scripts/update_submodules
Yidi Lin c4eb645a0b update_submodules: Fix submodule path handling
There are two regressions introduced by CB:87823.

1. If the specified repo path has a tailing slash, `submodule` becames a
   empty variable due to `${submodule##*/}`, e.g.,

   `./util/scripts/update_submodules -R 3rdparty/arm-trusted-firmware/`

2. CB:87823 uses `git submodule status | cut -d ' ' -f 3` to retrieve
   all submodule paths. The script gets the wrong path if the format is
   wrong, e.g.,

-26c572974bcf7255930b0e9a51da3144ed0104b5 3rdparty/amd_blobs
 57ac3f74b34a3303f03deee264a1f2247c68008d 3rdparty/arm-trusted-firmware (v2.12.0-908-g57ac3f74b)
+5b7492979fc139efdfdc7f97ae53a2349798f160 3rdparty/cmocka (cmocka-1.1.5-263-g5b74929)

   The script gets the empty path for 3rdparty/amd_blobs and get
   cmocka-1.1.5-263-g5b74929 for 3rdparty/cmocka.

This patch fixes 1 by removing the tailing slash for the input directory
and fixes 2 by the below command.
   `git submodule foreach 'echo ${sm_path}'|grep -v Entering`

Note that `smp_path` is an environment variable[1] set by
`git submodule` when travelling the submodule directory.

[1]: https://git-scm.com/docs/git-submodule

Change-Id: I0016f3a867e2b4594788d71a790ff9a938121da5
Signed-off-by: Yidi Lin <yidilin@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/87972
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
2025-06-06 13:26:30 +00:00

159 lines
3.5 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# SPDX-License-Identifier: GPL-2.0-only
# Description:
# Check all submodules for updates. If there are more than a minimum
# number of changes, create a commit to update the submodule to the
# new version.
set -eu -o pipefail
VERSION="1.01"
PROGRAM=$0
PROGNAME="$(basename "${PROGRAM}")"
export LANG=C
export LC_ALL=C
export TZ=UTC0
min_commits=10
TOP=${PWD}
SUBMODULES_WITH_UPDATES=0
submodule_dirs=()
skip_sync=""
max_commits_to_list=65
show_version() {
echo "${PROGNAME} version ${VERSION}"
echo
}
usage() {
echo "Usage: ${PROGNAME} [options]"
echo
echo "Options:"
echo " -c | --changes <#> Specify the minimum number of changes to update a repo"
echo " -h | --help Print usage and exit"
echo " -R | --repo <dir> Specify a single repo directory to update"
echo " -s | --skipsync Assume that repos are already synced"
echo " -V | --version Print the version and exit"
echo
}
get_args() {
args=$(getopt -l changes:,help,repo:,skipsync,version -o c:hR:sV -- "$@")
getopt_ret=$?
eval set -- "${args}"
if [ ${getopt_ret} != 0 ]; then
usage
exit 1
fi
while true; do
local opt
opt="$1"
shift
case "${opt}" in
-c | --changes)
min_commits="${1}"
shift
;;
-h | --help)
usage
exit 0
;;
-R | --repo)
submodule_dirs="${1%/}"
shift
if [[ ! -d "${submodule_dirs[0]}" ]]; then
echo "Error: ${submodule_dirs[0]} is not valid."
usage
exit 1
fi
;;
-s | --skipsync)
skip_sync=1
;;
-V | --version)
exit 0
;;
*)
break
;;
esac
done
}
main() {
show_version
get_args "$@"
if (( ${#submodule_dirs[@]} == 0 )); then
readarray -t submodule_dirs < <(git submodule foreach 'echo ${sm_path}'|grep -v Entering)
fi
for submodule in "${submodule_dirs[@]}"; do
cd "${TOP}"
echo ""
echo "Checking submodule ${submodule}"
if ! cd "$submodule"; then
echo "Error: could not cd to $submodule"
exit 1
fi
initial_commit_id="$(git log --pretty='%h' -n 1 --abbrev=12)"
initial_commit_description="$(git log --pretty='%ci - (%s)' -n 1)"
if [[ ${skip_sync} != "1" ]]; then
git fetch 2>/dev/null
fi
branch_name="$(git symbolic-ref refs/remotes/origin/HEAD --short)"
updated_commit_id="$(git log --pretty='%h' -n 1 --abbrev=12 "${branch_name}" -- )"
updated_commit_description="$(git log --pretty='%ci - (%s)' -n 1 "${updated_commit_id}")"
if [ "${initial_commit_id}" = "${updated_commit_id}" ]; then
echo "No updates for ${submodule}"
continue
fi
SUBMODULES_WITH_UPDATES+=1
update_log="$(git log --oneline --abbrev=12 "${initial_commit_id}..${updated_commit_id}")"
update_count="$(echo "${update_log}" | wc -l)"
if [[ "${update_count}" -gt "${max_commits_to_list}" ]]; then
update_log=""
new_commit_terminator="."
else
new_commit_terminator=":"
fi
echo "${update_count} new commits for ${submodule}"
if [ "${update_count}" -ge "${min_commits}" ]; then
echo "Creating commit to update ${submodule##*/} submodule"
git checkout "${updated_commit_id}" > /dev/null 2>&1
cd "${TOP}" || exit 1
git add "${submodule}" > /dev/null 2>&1 || exit 1
git commit -s -F- > /dev/null 2>&1 <<-EOF
${submodule}: Update to upstream ${branch_name##*/}
Updating from commit id ${initial_commit_id}:
$initial_commit_description
to commit id ${updated_commit_id}:
${updated_commit_description}
This brings in ${update_count} new commits${new_commit_terminator}
${update_log}
EOF
fi
done
if [ "${SUBMODULES_WITH_UPDATES}" = "0" ]; then
echo "No submodules with any updates."
fi
}
main "$@"