stm32f1x: use async algorithm in flash programming routine
[openocd.git] / tools / release.sh
1 #!/bin/bash
2 # release.sh: openocd release process automation
3 # Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net>
4 # Release under the GNU GPL v2 (or later versions).
5
6 # FIXME Remove more bash-isms. Fix errors making "ash -e" lose.
7
8 ## set these to control the build process
9 #CONFIG_OPTS=""
10 #MAKE_OPTS=""
11
12 ## specifies the --next release type: major, minor, micro, rc, tag
13 #RELEASE_TYPE=tag
14 ## For tag release type, specifies the name of the tag (e.g. "foo").
15 ## The default is the current user name, as found by the 'id' command.
16 #RELEASE_TAG="$(id -un)"
17
18 . "tools/release/helpers.sh"
19
20 VERSION_SH="tools/release/version.sh"
21
22 usage() {
23 cat << USAGE
24 usage: $0 <command> ...
25 Command Options:
26 --next name The branch's next release type: major, minor, micro, rc, tag.
27 --next-tag name The name for the package version tag.
28 --live Perform the actions in the repository.
29
30 Main Commands:
31 info Show a summary of the next pending release.
32 release Release the current tree as an archive.
33
34 Build Commands:
35 bootstrap Prepare the working copy for configuration and building.
36 configure Configures the package; runs bootstrap, if needed.
37 build Compiles the project; runs configure, if needed.
38
39 Packaging Commands:
40 package Produce new distributable source archives.
41 stage Move archives to staging area for upload.
42
43 Other Commands:
44 clean Forces regeneration of results.
45 clean_all Removes all traces of the release process.
46 help Provides this list of commands.
47
48 For more information about this script, see the Release Processes page
49 in the OpenOCD Developer's Manual (doc/manual/release.txt).
50 USAGE
51 exit 0
52 }
53 do_usage() { usage; }
54 do_help() { usage; }
55
56 do_info() {
57 echo "Current Release Analysis:"
58 package_info_show
59 }
60
61 do_bootstrap() {
62 echo -n "Bootstrapping..."
63 ./bootstrap 2>&1 | perl tools/logger.pl > "release-bootstrap.log"
64 }
65 maybe_bootstrap() { [ -f "configure" ] || do_bootstrap; }
66
67 do_configure() {
68 maybe_bootstrap
69 echo -n "Configuring..."
70 ./configure ${CONFIG_OPTS} 2>&1 | perl tools/logger.pl > "release-config.log"
71 }
72 maybe_configure() { [ -f "Makefile" ] || do_configure; }
73
74 do_build() {
75 maybe_configure
76 echo -n "Compiling OpenOCD ${PACKAGE_VERSION}"
77 make ${MAKE_OPTS} -C doc stamp-vti 2>&1 \
78 | perl tools/logger.pl > "release-version.log"
79 make ${MAKE_OPTS} 2>&1 \
80 | perl tools/logger.pl > "release-make.log"
81 }
82 maybe_build() { [ -f "src/openocd" ] || do_build; }
83 do_build_clean() { [ -f Makefile ] && make maintainer-clean >/dev/null; }
84
85
86 do_package() {
87 maybe_build
88 echo "Building distribution packages..."
89 make ${MAKE_OPTS} distcheck 2>&1 | perl tools/logger.pl > "release-pkg.log"
90 }
91 maybe_package() { [ -f "${PACKAGE_RELEASE}.zip" ] || do_package; }
92 do_package_clean() {
93 for EXT in tar.gz tar.bz2 zip; do
94 rm -v -f *.${EXT}
95 done
96 }
97
98 do_stage() {
99 maybe_package
100 echo "Staging package archives:"
101 mkdir -p archives
102 for EXT in tar.gz tar.bz2 zip; do
103 local FILE="${PACKAGE_RELEASE}.${EXT}"
104 # create archive signatures
105 for HASH in md5 sha1; do
106 echo "sign: ${FILE}.${HASH}"
107 ${HASH}sum "${FILE}" > "archives/${FILE}.${HASH}"
108 done
109 # save archive
110 mv -v "${FILE}" archives/
111 done
112 cp -a NEWS archives/
113 }
114 do_stage_clean() { rm -v -f -r archives; }
115
116 do_clean() {
117 do_build_clean
118 do_package_clean
119 rm -v -f release-*.log
120 }
121 do_clean_all() {
122 do_clean
123 do_stage_clean
124 }
125
126 do_version_commit() {
127 [ "$*" ] || die "usage: $0 commit <message>"
128 git add configure.in || die "error: no version changes to commit"
129 git commit -q -m "$*" configure.in
130 }
131
132 do_version_finalize() {
133 echo "The ${PACKAGE_NAME} ${RELEASE_VERSION} release."
134 echo
135 ${VERSION_SH} tag remove dev
136 [ -z "${RELEASE_FINAL}" ] || ${VERSION_SH} bump final rc
137 }
138 has_dev_tag() {
139 [ "${PACKAGE_VERSION/dev/}" != "${PACKAGE_VERSION}" ]
140 }
141 do_release_step_branch() {
142 git checkout -b "v${RELEASE_VERSION}-release"
143 }
144
145 do_release_step_tag() {
146 do_version_commit "$(do_version_finalize)"
147 package_info_load
148 [ "${PACKAGE_VERSION/dev/}" = "${PACKAGE_VERSION}" ] || \
149 die "'${PACKAGE_NAME}-${PACKAGE_VERSION}' should not be tagged"
150 local MSG="The ${PACKAGE_STRING} release."
151 git tag -m "${MSG}" "v${PACKAGE_VERSION}"
152 }
153
154 do_bump_version() {
155 echo -n "Bump ${RELEASE_TYPE} "
156 [ -z "${RELEASE_TAG}" ] || echo -n "-${RELEASE_TAG} "
157 echo -n "version and add "
158 [ -z "${RELEASE_START_RC}" ] || echo -n "-rc0"
159 echo "-dev tag."
160 echo
161 ${VERSION_SH} bump "${RELEASE_TYPE}" "${RELEASE_TAG}"
162 [ -z "${RELEASE_START_RC}" ] || ${VERSION_SH} bump tag rc
163 ${VERSION_SH} tag add dev
164 }
165 do_release_step_bump() {
166 # bump the version number
167 do_version_commit "$(do_bump_version)"
168 }
169
170 do_release_step_news_msg() {
171 cat <<MSG
172 Archive and recreate NEWS file.
173
174 Archive released NEWS file as NEWS-${RELEASE_VERSION}.
175 Create new NEWS file from release script template.
176 MSG
177 }
178 do_release_step_news() {
179 # only archive the NEWS file for major/minor releases
180 [ "${RELEASE_TYPE}" = "major" -o "${RELEASE_TYPE}" = "minor" ] || \
181 return 0
182 # archive NEWS and create new one from template
183 git mv "NEWS" "NEWS-${RELEASE_VERSION}"
184
185 cat >NEWS <<NEWS
186 This file includes highlights of the changes made in the
187 OpenOCD ${NEXT_RELEASE_VERSION} source archive release. See the
188 repository history for details about what changed, including
189 bugfixes and other issues not mentioned here.
190
191 JTAG Layer:
192 Boundary Scan:
193 Target Layer:
194 Flash Layer:
195 Board, Target, and Interface Configuration Scripts:
196 Documentation:
197 Build and Release:
198
199 For more details about what has changed since the last release,
200 see the git repository history. With gitweb, you can browse that
201 in various levels of detail.
202
203 For older NEWS, see the NEWS files associated with each release
204 (i.e. NEWS-<version>).
205
206 For more information about contributing test reports, bug fixes, or new
207 features and device support, please read the new Developer Manual (or
208 the BUGS and PATCHES.txt files in the source archive).
209 NEWS
210 git add NEWS
211
212 local MSG="$(do_release_step_news_msg)"
213 git commit -q -m "${MSG}" NEWS "NEWS-${RELEASE_VERSION}"
214 }
215
216 do_release_step_package() {
217 [ -z "${RELEASE_FAST}" ] || return 0
218
219 git checkout -q "v${RELEASE_VERSION}"
220 do_stage
221 do_clean
222 }
223
224 do_release_step_rebranch() {
225 # return to the new development head
226 local OLD_BRANCH="v${RELEASE_VERSION}-release"
227 git checkout "${OLD_BRANCH}"
228
229 # create new branch with new version information
230 package_info_load
231 git checkout -b "v${PACKAGE_VERSION}"
232 git branch -d "${OLD_BRANCH}"
233 }
234
235 do_release_setup() {
236 echo "Starting $CMD for ${RELEASE_VERSION}..."
237 [ "${RELEASE_TYPE}" ] || \
238 die "The --next release type must be provided. See --help."
239 }
240
241 do_release_check() {
242 [ -z "${RELEASE_FAST}" ] || return 0
243 echo "Are you sure you want to ${CMD} '${PACKAGE_RELEASE}', "
244 echo -n " to start a new ${RELEASE_TYPE} development cycle? (y/N) "
245 read ANSWER
246 if [ "${ANSWER}" != 'y' ]; then
247 echo "Live release aborted!"
248 exit 0
249 fi
250 do_countdown "Starting live release"
251 }
252 do_countdown() {
253 echo -n "$1 in "
254 for i in $(seq 5 -1 1); do
255 echo -n "$i, "
256 sleep 1
257 done
258 echo "go!"
259 }
260
261 do_branch() {
262 do_release_setup
263 local i=
264 for i in branch bump rebranch; do
265 "do_release_step_${i}"
266 done
267 }
268
269 do_release() {
270 local CMD='release'
271 do_release_setup
272 do_release_check
273 local i=
274 for i in branch tag bump news package rebranch; do
275 "do_release_step_${i}"
276 done
277 }
278 do_all() { do_release "$@"; }
279
280 do_reset() {
281 maybe_bootstrap
282 maybe_configure
283 do_clean_all
284 git checkout configure.in
285 }
286
287 LONGOPTS="fast,final,start-rc,next-tag:,next:,help"
288 OPTIONS=$(getopt -o 'V,n:' --long "${LONGOPTS}" -n $0 -- "$@")
289 if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
290 eval set -- "${OPTIONS}"
291 while true; do
292 case "$1" in
293 --fast)
294 RELEASE_FAST=yes
295 shift
296 ;;
297 --final)
298 RELEASE_FINAL=yes
299 shift
300 ;;
301 --start-rc)
302 RELEASE_START_RC=yes
303 shift
304 ;;
305 -n|--next)
306 export RELEASE_TYPE="$2"
307 shift 2
308 ;;
309 --next-tag)
310 export RELEASE_TAG="$2"
311 shift 2
312 ;;
313 -V)
314 exec $0 info
315 ;;
316 --)
317 shift
318 break
319 ;;
320 --help)
321 usage
322 shift
323 ;;
324 *)
325 echo "Internal error"
326 exit 1
327 ;;
328 esac
329 done
330
331 case "${RELEASE_TYPE}" in
332 major|minor|micro|rc)
333 ;;
334 tag)
335 [ "${RELEASE_TAG}" ] || RELEASE_TAG="$(id -u -n)"
336 ;;
337 '')
338 ;;
339 *)
340 die "Unknown release type '${RELEASE_TYPE}'"
341 ;;
342 esac
343
344 CMD=$1
345 [ "${CMD}" ] || usage
346 shift
347
348 ACTION_CMDS="bootstrap|configure|build|package|stage|clean"
349 MISC_CMDS="all|info|release|branch|reset|help|usage"
350 CLEAN_CMDS="build_clean|package_clean|stage_clean|clean_all"
351 CMDS="|${ACTION_CMDS}|${CLEAN_CMDS}|${MISC_CMDS}|"
352 is_command() { echo "${CMDS}" | grep "|$1|" >/dev/null; }
353
354 package_info_load
355 if is_command "${CMD}"; then
356 "do_${CMD}" "$@"
357 echo "Done with '${CMD}'." >&2
358 else
359 echo "error: unknown command: '${CMD}'"
360 usage
361 fi