blob: 75254405119937d606068d94467751c6f010783c [file] [log] [blame]
maxwen87a7ed62018-01-14 14:36:53 +01001#!/usr/bin/env bash
2#
3# Pull in linux-stable updates to a kernel tree
4#
5# Copyright (C) 2017 Nathan Chancellor
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>
19
20
21# Get main tree location
22TREE=$( cd $( dirname $( readlink -f "${BASH_SOURCE[0]}" ) )/../../.. && pwd )
23
24
25# Colors for script
26BOLD="\033[1m"
27GRN="\033[01;32m"
28RED="\033[01;31m"
29RST="\033[0m"
30YLW="\033[01;33m"
31
32
33# Alias for echo to handle escape codes like colors
34function echo() {
35 command echo -e "$@"
36}
37
38
39# Prints a formatted header to point out what is being done to the user
40function header() {
41 if [[ -n ${2} ]]; then
42 COLOR=${2}
43 else
44 COLOR=${RED}
45 fi
46 echo ${COLOR}
47 echo "====$(for i in $(seq ${#1}); do echo "=\c"; done)===="
48 echo "== ${1} =="
49 echo "====$(for i in $(seq ${#1}); do echo "=\c"; done)===="
50 echo ${RST}
51}
52
53
54# Prints an error in bold red
55function report_error() {
56 echo
57 echo ${RED}${1}${RST}
58 if [[ ${2} = "-h" ]]; then
59 ${0} -h
60 fi
61 exit 1
62}
63
64
65# Prints a warning in bold yellow
66function report_warning() {
67 echo
68 echo ${YLW}${1}${RST}
69 if [[ -z ${2} ]]; then
70 echo
71 fi
72}
73
74
75# Parse the provided parameters
76function parse_parameters() {
77 while [[ $# -ge 1 ]]; do
78 case ${1} in
79 # Use git cherry-pick
80 "-c"|"--cherry-pick")
81 UPDATE_METHOD=cherry-pick ;;
82
83 # Only update the linux-stable remote
84 "-f"|"--fetch-only")
85 FETCH_REMOTE_ONLY=true ;;
86
87 # Help menu
88 "-h"|"--help")
89 echo
90 echo "${BOLD}Script description:${RST} Merges/cherry-picks Linux upstream into a kernel tree"
91 echo
92 echo "${BOLD}Required parameters:${RST}"
93 echo " -c | --cherry-pick"
94 echo " -m | --merge"
95 echo " Call either git cherry-pick or git merge when updating from upstream"
96 echo
97 echo " -k | --kernel-folder"
98 echo " The device's kernel source's location relative to the \"kernel\" folder in the root of the ROM tree"
99 echo " If unsure, run \"croot; cd kernel; ls --directory */*\" in your terminal (assuming you ran \". build/envsetup.sh\""
100 echo
101 echo "${BOLD}Optional parameters"
102 echo " -f | --fetch-only"
103 echo " Simply fetches the tags from linux-stable then exits"
104 echo
105 echo " -l | --latest"
106 echo " Updates to the latest version available for the current kernel tree"
107 echo
108 echo " -p | --print-latest"
109 echo " Prints the latest version available for the current kernel tree then exits"
110 echo
111 echo " -v | --version"
112 echo " Updates to the specified version (e.g. -v 3.18.78)"
113 echo
114 echo " By default, only ONE version is picked at a time (e.g. 3.18.31 to 3.18.32)"
115 echo
116 exit 1 ;;
117
118 # Kernel source location
119 "-k"|"--kernel-folder")
120 shift
121 if [[ $# -lt 1 ]]; then
122 report_error "Please specify a device directory!"
123 fi
124
125 KERNEL_FOLDER=${TREE}/kernel/${1} ;;
126
127 # Update to the latest version upstream unconditionally
128 "-l"|"--latest")
129 UPDATE_MODE=1 ;;
130
131 # Use git merge
132 "-m"|"--merge")
133 UPDATE_METHOD=merge ;;
134
135 # Print the latest version from kernel.org
136 "-p"|"--latest")
137 PRINT_LATEST=true ;;
138
139 # Update to the specified version
140 "-v"|"--version")
141 shift
142 if [[ $# -lt 1 ]]; then
143 report_error "Please specify a version to update!"
144 fi
145
146 TARGET_VERSION=${1} ;;
147
148 *)
149 report_error "Invalid parameter!" ;;
150 esac
151
152 shift
153 done
154
155 # Sanity checks
156 if [[ ! ${UPDATE_METHOD} ]]; then
157 report_error "Neither cherry-pick nor merge were specified, please supply one!" -h
158 elif [[ ! -d ${KERNEL_FOLDER} ]]; then
159 report_error "Invalid kernel source location specified! Folder does not exist" -h
160 elif [[ ! -f ${KERNEL_FOLDER}/Makefile ]]; then
161 report_error "Invalid kernel source location specified! No Makefile present" -h
162 fi
163
164 # Default update mode is one version at a time
165 if [[ -z ${UPDATE_MODE} ]]; then
166 UPDATE_MODE=0
167 fi
168}
169
170
171# Update the linux-stable remote (and add it if it doesn't exist)
172function update_remote() {
173 header "Updating linux-stable"
174
175 # Add remote if it isn't already present
176 cd ${KERNEL_FOLDER}
177
178 git fetch --tags https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/
179
180 if [[ $? -ne 0 ]]; then
181 report_error "linux-stable update failed!"
182 else
183 echo "linux-stable updated successfully!"
184 fi
185
186 if [[ ${FETCH_REMOTE_ONLY} ]]; then
187 echo
188 exit 0
189 fi
190}
191
192
193# Generate versions
194function generate_versions() {
195 header "Calculating versions"
196
197 # Full kernel version
198 CURRENT_VERSION=$(make kernelversion)
199 # First two numbers (3.4 | 3.10 | 3.18 | 4.4)
200 CURRENT_MAJOR_VERSION=$(echo ${CURRENT_VERSION} | cut -f 1,2 -d .)
201 # Last number
202 CURRENT_SUBLEVEL=$(echo ${CURRENT_VERSION} | cut -d . -f 3)
203
204 # Get latest update from upstream
205 LATEST_VERSION=$(git tag --sort=-taggerdate -l v${CURRENT_MAJOR_VERSION}* | head -n 1 | sed s/v//)
206 LATEST_SUBLEVEL=$(echo ${LATEST_VERSION} | cut -d . -f 3)
207
208 # Print the current/latest version and exit if requested
209 echo "${BOLD}Current kernel version:${RST} ${CURRENT_VERSION}"
210 echo
211 echo "${BOLD}Latest kernel version:${RST} ${LATEST_VERSION}"
212 if [[ ${PRINT_LATEST} ]]; then
213 echo
214 exit 0
215 fi
216
217 # UPDATE_MODES:
218 # 0. Update one version
219 # 1. Update to the latest version
220 case ${UPDATE_MODE} in
221 0)
222 TARGET_SUBLEVEL=$((${CURRENT_SUBLEVEL} + 1))
223 TARGET_VERSION=${CURRENT_MAJOR_VERSION}.${TARGET_SUBLEVEL} ;;
224 1)
225 TARGET_VERSION=${LATEST_VERSION} ;;
226 esac
227
228 # Make sure target version is between current version and latest version
229 TARGET_SUBLEVEL=$(echo ${TARGET_VERSION} | cut -d . -f 3)
230 if [[ ${TARGET_SUBLEVEL} -le ${CURRENT_SUBLEVEL} ]]; then
231 report_error "${TARGET_VERSION} is already present in ${CURRENT_VERSION}!\n"
232 elif [[ ${TARGET_SUBLEVEL} -gt ${LATEST_SUBLEVEL} ]]; then
233 report_error "${CURRENT_VERSION} is the latest!\n"
234 fi
235
236 RANGE=v${CURRENT_VERSION}..v${TARGET_VERSION}
237
238 echo
239 echo "${BOLD}Target kernel version:${RST} ${TARGET_VERSION}"
240 echo
241}
242
243
244function update_to_target_version() {
245 case ${UPDATE_METHOD} in
246 "cherry-pick")
247 git cherry-pick ${RANGE}
248 if [[ $? -ne 0 ]]; then
249 report_error "Cherry-pick needs manual intervention! Resolve conflicts then run:
250
251git add . && git cherry-pick --continue"
252 else
253 header "${TARGET_VERSION} PICKED CLEANLY!" ${GRN}
254 fi ;;
255
256 "merge")
257 GIT_MERGE_VERBOSITY=1 git merge --no-edit v${TARGET_VERSION}
258 if [[ $? -ne 0 ]]; then
259 report_error "Merge needs manual intervention!
260
261Resolve conflicts then run git merge --continue!"
262 else
263 header "${TARGET_VERSION} MERGED CLEANLY!" ${GRN}
264 fi ;;
265 esac
266}
267
268
269parse_parameters $@
270update_remote
271generate_versions
272update_to_target_version