2020 February 29 Breaking Changes Update (#8064)
[jackhill/qmk/firmware.git] / util / chibios-upgrader.sh
1 #!/bin/bash
2
3 set -eEuo pipefail
4 umask 022
5
6 sinfo() { echo "$@" >&2 ; }
7 shead() { sinfo "" ; sinfo "---------------------------------" ; sinfo "-- $@" ; sinfo "---------------------------------" ; }
8 havecmd() { command command type "${1}" >/dev/null 2>&1 || return 1 ; }
9
10 this_script="$(realpath "${BASH_SOURCE[0]}")"
11 script_dir="$(realpath "$(dirname "$this_script")")"
12 qmk_firmware_dir="$(realpath "$script_dir/../")"
13
14 declare -A file_hashes
15
16 export PATH="$PATH:$script_dir/fmpp/bin"
17
18 build_fmpp() {
19 [ -f "$script_dir/fmpp.tar.gz" ] \
20 || wget -O"$script_dir/fmpp.tar.gz" https://github.com/freemarker/fmpp/archive/v0.9.16.tar.gz
21 [ -d "$script_dir/fmpp" ] \
22 || { mkdir "$script_dir/fmpp" && tar xf "$script_dir/fmpp.tar.gz" -C "$script_dir/fmpp" --strip-components=1 ; }
23 pushd "$script_dir/fmpp" >/dev/null 2>&1
24 sed -e "s#bootclasspath.path=.*#bootclasspath.path=$(find /usr/lib/jvm -name 'rt.jar' | sort | tail -n1)#g" \
25 -e "s#ant.jar.path=.*#ant.jar.path=$(find /usr/share/java -name 'ant-1*.jar' | sort | tail -n1)#g" \
26 build.properties.sample > build.properties
27 sed -e 's#source="1.5"#source="1.8"#g' \
28 -e 's#target="1.5"#target="1.8"#g' \
29 build.xml > build.xml.new
30 mv build.xml.new build.xml
31 ant clean
32 ant
33 chmod +x "$script_dir/fmpp/bin/fmpp"
34 popd >/dev/null 2>&1
35 }
36
37 find_chibi_files() {
38 local search_path="$1"
39 shift
40 local conditions=( "$@" )
41 find "$search_path" -not -path '*/lib/chibios*' -and -not -path '*/lib/ugfx*' -and -not -path '*/util/*' -and \( "${conditions[@]}" \) | sort
42 }
43
44 revert_chibi_files() {
45 local search_path="$1"
46 shead "Reverting ChibiOS config/board files..."
47 for file in $(find_chibi_files "$search_path" -name chconf.h -or -name halconf.h -or -name mcuconf.h -or -name board.c -or -name board.h -or -name board.mk -or -name board.chcfg) ; do
48 pushd "$search_path" >/dev/null 2>&1
49 local relpath=$(realpath --relative-to="$search_path" "$file")
50 git checkout upstream/master -- "$relpath" || git checkout origin/master -- "$relpath" || true
51 popd >/dev/null 2>&1
52 done
53 }
54
55 populate_file_hashes() {
56 local search_path="$1"
57 shead "Determining duplicate config/board files..."
58 for file in $(find_chibi_files "$search_path" -name chconf.h -or -name halconf.h -or -name mcuconf.h -or -name board.c -or -name board.h) ; do
59 local key="file_$(clang-format "$file" | sha1sum | cut -d' ' -f1)"
60 local relpath=$(realpath --relative-to="$search_path" "$file")
61 file_hashes[$key]="${file_hashes[$key]:-} $relpath"
62 done
63 for file in $(find_chibi_files "$search_path" -name board.mk -or -name board.chcfg) ; do
64 local key="file_$(cat "$file" | sha1sum | cut -d' ' -f1)"
65 local relpath=$(realpath --relative-to="$search_path" "$file")
66 file_hashes[$key]="${file_hashes[$key]:-} $relpath"
67 done
68 }
69
70 determine_equivalent_files() {
71 local search_file="$1"
72 for K in "${!file_hashes[@]}"; do
73 for V in ${file_hashes[$K]}; do
74 if [[ "$V" == "$search_file" ]] ; then
75 for V in ${file_hashes[$K]}; do
76 echo "$V"
77 done
78 return 0
79 fi
80 done
81 done
82 return 1
83 }
84
85 deploy_staged_files() {
86 shead "Deploying staged files..."
87 for file in $(find "$qmk_firmware_dir/util/chibios-upgrade-staging" -type f) ; do
88 local relpath=$(realpath --relative-to="$qmk_firmware_dir/util/chibios-upgrade-staging" "$file")
89 sinfo "Deploying staged file: $relpath"
90 for other in $(determine_equivalent_files "$relpath") ; do
91 sinfo " => $other"
92 cp "$qmk_firmware_dir/util/chibios-upgrade-staging/$relpath" "$qmk_firmware_dir/$other"
93 done
94 done
95 }
96
97 swap_mcuconf_f3xx_f303() {
98 shead "Swapping STM32F3xx_MCUCONF -> STM32F303_MCUCONF..."
99 for file in $(find_chibi_files "$qmk_firmware_dir" -name mcuconf.h) ; do
100 sed -i 's#STM32F3xx_MCUCONF#STM32F303_MCUCONF#g' "$file"
101 dos2unix "$file" >/dev/null 2>&1
102 done
103 }
104
105 upgrade_conf_files_generic() {
106 local search_filename="$1"
107 local update_script="$2"
108 shead "Updating $search_filename files ($update_script)..."
109 pushd "$qmk_firmware_dir/lib/chibios/tools/updater" >/dev/null 2>&1
110 for file in $(find_chibi_files "$qmk_firmware_dir" -name "$search_filename") ; do
111 cp -f "$file" "$file.orig"
112 clang-format --style='{IndentPPDirectives: None}' -i "$file"
113 cp -f "$file" "$file.formatted"
114 bash "$update_script" "$file"
115 if ! diff "$file" "$file.formatted" >/dev/null 2>&1 ; then
116 dos2unix "$file" >/dev/null 2>&1
117 else
118 cp -f "$file.orig" "$file"
119 fi
120 rm -f "$file.orig" "$file.formatted"
121 done
122 popd >/dev/null 2>&1
123 }
124
125 upgrade_chconf_files() {
126 upgrade_conf_files_generic chconf.h update_chconf_rt.sh
127 }
128
129 upgrade_halconf_files() {
130 upgrade_conf_files_generic halconf.h update_halconf.sh
131 }
132
133 upgrade_mcuconf_files() {
134 pushd "$qmk_firmware_dir/lib/chibios/tools/updater" >/dev/null 2>&1
135 for f in $(find . -name 'update_mcuconf*') ; do
136 upgrade_conf_files_generic mcuconf.h $f
137 done
138 popd >/dev/null 2>&1
139 }
140
141 update_staged_files() {
142 shead "Updating staged files with ChibiOS upgraded versions..."
143 for file in $(find "$qmk_firmware_dir/util/chibios-upgrade-staging" -type f) ; do
144 local relpath=$(realpath --relative-to="$qmk_firmware_dir/util/chibios-upgrade-staging" "$file")
145 sinfo "Updating staged file: $relpath"
146 cp "$qmk_firmware_dir/$relpath" "$qmk_firmware_dir/util/chibios-upgrade-staging/$relpath"
147 done
148 }
149
150 havecmd fmpp || build_fmpp
151 revert_chibi_files "$qmk_firmware_dir"
152 populate_file_hashes "$qmk_firmware_dir"
153
154 shead "Showing duplicate ChibiOS files..."
155 for K in "${!file_hashes[@]}"; do
156 sinfo ${K#file_}:
157 for V in ${file_hashes[$K]}; do
158 sinfo " $V"
159 done
160 done
161
162 if [ "${1:-}" == "-r" ] ; then
163 exit 0
164 fi
165
166 swap_mcuconf_f3xx_f303
167
168 deploy_staged_files
169 upgrade_mcuconf_files
170 upgrade_chconf_files
171 upgrade_halconf_files
172 update_staged_files