kernel_bump.sh 6.0 KB

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