kernel_bump.sh 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. #!/bin/sh
  2. # SPDX-License-Identifier: GPL-2.0-or-later
  3. #
  4. # Copyright (C) 2024 Olliver Schinagl <[email protected]>
  5. set -eu
  6. if [ -n "${DEBUG_TRACE_SH:-}" ] && \
  7. [ "${DEBUG_TRACE_SH:-}" != "${DEBUG_TRACE_SH#*"$(basename "${0}")"*}" ] || \
  8. [ "${DEBUG_TRACE_SH:-}" = 'all' ]; then
  9. set -x
  10. fi
  11. REQUIRED_COMMANDS='
  12. [
  13. basename
  14. command
  15. echo
  16. exit
  17. git
  18. printf
  19. set
  20. shift
  21. '
  22. _msg()
  23. {
  24. _level="${1:?Missing argument to function}"
  25. shift
  26. if [ "${#}" -le 0 ]; then
  27. echo "${_level}: No content for this message ..."
  28. return
  29. fi
  30. echo "${_level}: ${*}"
  31. }
  32. e_err()
  33. {
  34. _msg 'err' "${*}" >&2
  35. }
  36. e_warn()
  37. {
  38. _msg 'warning' "${*}"
  39. }
  40. e_notice()
  41. {
  42. _msg 'notice' "${*}"
  43. }
  44. usage()
  45. {
  46. echo "Usage: ${0}"
  47. echo 'Helper script to bump the target kernel version, whilst keeping history.'
  48. echo ' -c Migrate config files (e.g. subtargets) only.'
  49. echo " -p Optional Platform name (e.g. 'ath79' [PLATFORM_NAME]"
  50. echo " -s Source version of kernel (e.g. 'v6.1' [SOURCE_VERSION])"
  51. echo " -t Target version of kernel (e.g. 'v6.6' [TARGET_VERSION]')"
  52. echo
  53. echo 'All options can also be passed in environment variables (listed between [BRACKETS]).'
  54. echo 'Note that this script must be run from within the OpenWrt git repository.'
  55. echo 'Example: scripts/kernel_bump.sh -p realtek -s v6.1 -t v6.6'
  56. }
  57. cleanup()
  58. {
  59. trap - EXIT HUP INT QUIT ABRT ALRM TERM
  60. if [ -n "${initial_branch:-}" ] && \
  61. [ "$(git rev-parse --abbrev-ref HEAD)" != "${initial_branch:-}" ]; then
  62. git switch "${initial_branch}"
  63. fi
  64. }
  65. init()
  66. {
  67. src_file="$(readlink -f "${0}")"
  68. src_dir="${src_file%%"${src_file##*'/'}"}"
  69. initial_branch="$(git rev-parse --abbrev-ref HEAD)"
  70. initial_commitish="$(git rev-parse HEAD)"
  71. if [ -n "$(git status --porcelain | grep -v '^?? .*')" ]; then
  72. echo 'Git respository not in a clean state, will not continue.'
  73. exit 1
  74. fi
  75. if [ -n "${src_dir##*'/scripts/'}" ]; then
  76. echo "This script '${src_file}' is not in the scripts subdirectory, this is unexpected, cannot continue."
  77. exit 1
  78. fi
  79. source_version="${source_version#v}"
  80. target_version="${target_version#v}"
  81. trap cleanup EXIT HUP INT QUIT ABRT ALRM TERM
  82. }
  83. bump_kernel()
  84. {
  85. if [ -z "${platform_name}" ] || \
  86. [ -d "${PWD}/image" ]; then
  87. platform_name="${PWD}"
  88. fi
  89. platform_name="${platform_name##*'/'}"
  90. _target_dir="${src_dir}/../target/linux/${platform_name}"
  91. if [ ! -d "${_target_dir}/image" ]; then
  92. e_err "Cannot find target linux directory '${_target_dir:-not defined}'. Not in a platform directory, or -p not set."
  93. exit 1
  94. fi
  95. git switch --force-create '__openwrt_kernel_files_mover'
  96. if [ "${config_only:-false}" != 'true' ]; then
  97. for _path in "${_target_dir}/"*; do
  98. if [ ! -e "${_path}" ] || \
  99. [ "${_path}" = "${_path%%"-${source_version}"}" ]; then
  100. continue
  101. fi
  102. _target_path="${_path%%"-${source_version}"}-${target_version}"
  103. if [ -e "${_target_path}" ]; then
  104. e_err "Target '${_target_path}' already exists!"
  105. exit 1
  106. fi
  107. git mv \
  108. "${_path}" \
  109. "${_target_path}"
  110. done
  111. fi
  112. find "${_target_dir}" -iname "config-${source_version}" | while read -r _config; do
  113. _path="${_config%%"/config-${source_version}"}"
  114. git mv "${_config}" "${_path}/config-${target_version}"
  115. done
  116. git commit \
  117. --signoff \
  118. --message "kernel/${platform_name}: Create kernel files for v${target_version} (from v${source_version})" \
  119. --message 'This is an automatically generated commit.' \
  120. --message 'When doing `git bisect`, consider `git bisect --skip`.'
  121. git checkout 'HEAD~' "${_target_dir}"
  122. git commit \
  123. --signoff \
  124. --message "kernel/${platform_name}: Restore kernel files for v${source_version}" \
  125. --message "$(printf "This is an automatically generated commit which aids following Kernel patch history,\nas git will see the move and copy as a rename thus defeating the purpose.\n\nSee: https://lists.openwrt.org/pipermail/openwrt-devel/2023-October/041673.html\nfor the original discussion.")"
  126. git switch "${initial_branch:?Unable to switch back to original branch. Quitting.}"
  127. GIT_EDITOR=true git merge --no-ff '__openwrt_kernel_files_mover'
  128. git branch --delete '__openwrt_kernel_files_mover'
  129. echo "Original commitish was '${initial_commitish}'."
  130. echo 'Kernel bump complete. Remember to use `git log --follow`.'
  131. }
  132. check_requirements()
  133. {
  134. for _cmd in ${REQUIRED_COMMANDS}; do
  135. if ! _test_result="$(command -V "${_cmd}")"; then
  136. _test_result_fail="${_test_result_fail:-}${_test_result}\n"
  137. else
  138. _test_result_pass="${_test_result_pass:-}${_test_result}\n"
  139. fi
  140. done
  141. echo 'Available commands:'
  142. # As the results contain \n, we expect these to be interpreted.
  143. # shellcheck disable=SC2059
  144. printf "${_test_result_pass:-none\n}"
  145. echo
  146. echo 'Missing commands:'
  147. # shellcheck disable=SC2059
  148. printf "${_test_result_fail:-none\n}"
  149. echo
  150. if [ -n "${_test_result_fail:-}" ]; then
  151. echo 'Command test failed, missing programs.'
  152. test_failed=1
  153. fi
  154. }
  155. main()
  156. {
  157. while getopts 'chp:s:t:' _options; do
  158. case "${_options}" in
  159. 'c')
  160. config_only='true'
  161. ;;
  162. 'h')
  163. usage
  164. exit 0
  165. ;;
  166. 'p')
  167. platform_name="${OPTARG}"
  168. ;;
  169. 's')
  170. source_version="${OPTARG}"
  171. ;;
  172. 't')
  173. target_version="${OPTARG}"
  174. ;;
  175. ':')
  176. e_err "Option -${OPTARG} requires an argument."
  177. exit 1
  178. ;;
  179. *)
  180. e_err "Invalid option: -${OPTARG}"
  181. exit 1
  182. ;;
  183. esac
  184. done
  185. shift "$((OPTIND - 1))"
  186. platform_name="${platform_name:-${PLATFORM_NAME:-}}"
  187. source_version="${source_version:-${SOURCE_VERSION:-}}"
  188. target_version="${target_version:-${TARGET_VERSION:-}}"
  189. if [ -z "${source_version:-}" ] || [ -z "${target_version:-}" ]; then
  190. e_err "Source (${source_version:-missing source version}) and target (${target_version:-missing target version}) versions need to be defined."
  191. echo
  192. usage
  193. exit 1
  194. fi
  195. check_requirements
  196. init
  197. bump_kernel
  198. cleanup
  199. }
  200. main "${@}"
  201. exit 0