treewide: Move device_tree to commonlib
[coreboot2.git] / util / scripts / update_submodules
blob9f6c14f5b00067c77683f170e1a272caa80f5829
1 #!/usr/bin/env bash
3 # SPDX-License-Identifier: GPL-2.0-only
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.
10 set -eu -o pipefail
12 VERSION="1.01"
13 PROGRAM=$0
14 PROGNAME="$(basename "${PROGRAM}")"
16 export LANG=C
17 export LC_ALL=C
18 export TZ=UTC0
20 min_commits=10
21 TOP=${PWD}
22 SUBMODULES_WITH_UPDATES=0
23 submodule_dirs=()
24 skip_sync=""
25 max_commits_to_list=65
27 show_version() {
28 echo "${PROGNAME} version ${VERSION}"
29 echo
32 usage() {
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
44 get_args() {
45 args=$(getopt -l changes:,help,repo:,skipsync,version -o c:hR:sV -- "$@")
46 getopt_ret=$?
47 eval set -- "${args}"
49 if [ ${getopt_ret} != 0 ]; then
50 usage
51 exit 1
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
63 -h | --help)
64 usage
65 exit 0
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
76 -s | --skipsync)
77 skip_sync=1
79 -V | --version)
80 exit 0
83 break
85 esac
86 done
90 main() {
91 show_version
92 get_args "$@"
94 if (( ${#submodule_dirs[@]} == 0 )); then
95 readarray -t submodule_dirs < <(git submodule foreach pwd | grep -v "Entering")
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
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
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
117 done
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
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=":"
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##*/}
143 Updating from commit id ${initial_commit_id}:
144 $initial_commit_description
146 to commit id ${updated_commit_id}:
147 ${updated_commit_description}
149 This brings in ${update_count} new commits${new_commit_terminator}
150 ${update_log}
153 done
155 if [ "${SUBMODULES_WITH_UPDATES}" = "0" ]; then
156 echo "No submodules with any updates."
160 main "$@"