kernel_bump.sh 6.6 KB

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