| #!/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=("$(readlink -f "${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 pwd | grep -v "Entering") | |
| fi | |
| for submodule in "${submodule_dirs[@]}"; do | |
| 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)" | |
| initial_commit_description="$(git log --pretty='%ci - (%s)' -n 1)" | |
| if [[ ${skip_sync} != "1" ]]; then | |
| git fetch 2>/dev/null | |
| fi | |
| declare -a branches=("origin/main" "origin/master" "origin/trunk") | |
| for branch in "${branches[@]}"; do | |
| if git branch -a | grep "${branch}" > /dev/null; then | |
| branch_name="${branch}" | |
| break | |
| fi | |
| done | |
| updated_commit_id="$(git log --pretty='%h' -n 1 "${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 "${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 | |
| Update ${submodule##*/} submodule to upstream ${branch##*/} | |
| 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 "$@" |