• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env bash
2#
3# SPDX-License-Identifier: GPL-2.0-only
4
5# Description:
6# Check all submodules for updates.  If there are more than a minimum
7# number of changes, create a commit to update the submodule to the
8# new version.
9
10set -eu -o pipefail
11
12VERSION="1.01"
13PROGRAM=$0
14PROGNAME="$(basename "${PROGRAM}")"
15
16export LANG=C
17export LC_ALL=C
18export TZ=UTC0
19
20min_commits=10
21TOP=${PWD}
22SUBMODULES_WITH_UPDATES=0
23submodule_dirs=()
24skip_sync=""
25max_commits_to_list=65
26
27show_version() {
28	echo "${PROGNAME} version ${VERSION}"
29	echo
30}
31
32usage() {
33	echo "Usage: ${PROGNAME} [options]"
34	echo
35	echo "Options:"
36	echo " -c | --changes <#>     Specify the minimum number of changes to update a repo"
37	echo " -h | --help            Print usage and exit"
38	echo " -R | --repo <dir>      Specify a single repo directory to update"
39	echo " -s | --skipsync        Assume that repos are already synced"
40	echo " -V | --version         Print the version and exit"
41	echo
42}
43
44get_args() {
45	args=$(getopt -l changes:,help,repo:,skipsync,version -o c:hR:sV -- "$@")
46	getopt_ret=$?
47	eval set -- "${args}"
48
49	if [ ${getopt_ret} != 0 ]; then
50		usage
51		exit 1
52	fi
53
54	while true; do
55		local opt
56		opt="$1"
57		shift
58		case "${opt}" in
59		-c | --changes)
60			min_commits="${1}"
61			shift
62			;;
63		-h | --help)
64			usage
65			exit 0
66			;;
67		-R | --repo)
68			submodule_dirs=("$(readlink -f "${1}")")
69			shift
70			if [[ ! -d "${submodule_dirs[0]}" ]]; then
71				echo "Error: ${submodule_dirs[0]} is not valid."
72				usage
73				exit 1
74			fi
75			;;
76		-s | --skipsync)
77			skip_sync=1
78			;;
79		-V | --version)
80			exit 0
81			;;
82		*)
83			break
84			;;
85		esac
86	done
87}
88
89
90main() {
91	show_version
92	get_args "$@"
93
94	if (( ${#submodule_dirs[@]} == 0 )); then
95		readarray -t submodule_dirs < <(git submodule foreach pwd | grep -v "Entering")
96	fi
97
98	for submodule in "${submodule_dirs[@]}"; do
99		echo "Checking submodule ${submodule}"
100		if ! cd "$submodule"; then
101 			echo "Error: could not cd to $submodule"
102			exit 1
103		fi
104
105		initial_commit_id="$(git log --pretty='%h' -n 1)"
106		initial_commit_description="$(git log --pretty='%ci - (%s)' -n 1)"
107		if [[ ${skip_sync} != "1" ]]; then
108			git fetch 2>/dev/null
109		fi
110
111		declare -a branches=("origin/main" "origin/master" "origin/trunk")
112		for branch in "${branches[@]}"; do
113			if git branch -a | grep "${branch}" > /dev/null; then
114				branch_name="${branch}"
115				break
116			fi
117		done
118
119		updated_commit_id="$(git log --pretty='%h' -n 1 "${branch_name}" -- )"
120		updated_commit_description="$(git log --pretty='%ci - (%s)' -n 1 "${updated_commit_id}")"
121		if [ "${initial_commit_id}" = "${updated_commit_id}" ]; then
122			echo "No updates for ${submodule}"
123			continue
124		fi
125		SUBMODULES_WITH_UPDATES+=1
126		update_log="$(git log --oneline "${initial_commit_id}..${updated_commit_id}")"
127		update_count="$(echo "${update_log}" | wc -l)"
128		if [[ "${update_count}" -gt "${max_commits_to_list}" ]]; then
129			update_log=""
130			new_commit_terminator="."
131		else
132			new_commit_terminator=":"
133		fi
134		echo "${update_count} new commits for ${submodule}"
135		if [ "${update_count}" -ge "${min_commits}" ]; then
136			echo "Creating commit to update ${submodule##*/} submodule"
137			git checkout "${updated_commit_id}" > /dev/null 2>&1
138			cd "${TOP}" || exit 1
139			git add "${submodule}" > /dev/null 2>&1 || exit 1
140			git commit -s -F- > /dev/null 2>&1 <<-EOF
141	Update ${submodule##*/} submodule to upstream ${branch##*/}
142
143	Updating from commit id ${initial_commit_id}:
144	$initial_commit_description
145
146	to commit id ${updated_commit_id}:
147	${updated_commit_description}
148
149	This brings in ${update_count} new commits${new_commit_terminator}
150	${update_log}
151	EOF
152		fi
153	done
154
155	if [ "${SUBMODULES_WITH_UPDATES}" = "0" ]; then
156		echo "No submodules with any updates."
157	fi
158}
159
160main "$@"
161