Update html-plain writer.
[docutils.git] / sandbox / infrastructure / release.sh
blobda6398f6816a62b551c800808ad1ed3c0ce3811f
1 #!/bin/bash
3 # Author: Lea Wiemann
4 # Contact: grubert@users.sourceforge.net
5 # Revision: $Revision$
6 # Date: $Date$
7 # Copyright: This script has been placed in the public domain.
9 # USAGE see: docutils/docs/dev/release.txt
11 # must be run from docutils trunk/docutils,
12 # because HISTORY and RELEASE_NOTES.txt are modified.
14 set -e
16 function print_command()
18 # Print "$@", quoting parameters containing spaces.
19 echo -n $
20 for param in "$@"; do
21 echo "$param" | grep -Fq ' ' && echo -n " '$param'" || echo -n " $param"
22 done
25 function run()
27 # Print and run "$@".
28 print_command "$@"
29 echo
30 "$@"
33 function confirm()
35 # Print, let the user confirm and run "$@".
36 echo 'Press enter to run (or enter anything to skip):'
37 print_command "$@"
38 read
39 test "$REPLY" && echo Skipped. || "$@"
42 function svn_up()
44 if test $svn == svk; then
45 confirm svk sync "$depot"
47 confirm $svn up
50 function checkin()
52 # Parameters: log_message, file, file, file ...
53 log_message="$1"
54 shift
55 confirm $svn diff "$@"
56 confirm $svn ci -m "$log_prefix $log_message" "$@"
59 function set_ver()
61 # Parameters: old_version new_version
62 shopt -s extglob
63 echo Determining list of files to be changed...
64 # BUG ls lists directories but does not descend
65 files="docutils/__init__.py setup.py `$svn ls test/functional/expected/ | sed 's|^|test/functional/expected/|'`"
66 echo "Now I'll change the version number to $2 in the following files:"
67 echo $files
68 echo
69 echo 'Press enter to proceed (or enter anything to skip)...'
70 read
71 if [ ! "$REPLY" ]; then
72 echo 'Modifying files with ed...'
73 old_ver_regex="`echo "$1" | sed 's/\./\\\\./g'`"
74 # "ed" returns an error code if there has been no substitution, so
75 # we temporarily deactivate exit-on-error.
76 set +e
77 for F in $files; do
78 (echo ",s/$old_ver_regex/$2/g"; echo 'wq') | ed "$F"
79 done
80 set -e
82 echo
83 echo 'CAUTION: please look at the diffs carefully, for wrongly'
84 echo ' replaced embedded numbers.'
85 checkin "set version number to $2" $files
88 function usage()
90 echo 'Usage:'
91 echo
92 echo ' release.sh new_version svn_version[:branch_version] [stage]'
93 echo
94 echo 'The following things will be done:'
95 echo
96 echo '* Change version number to new_version. (stage 1)'
97 echo '* SVN-export, test, and release Docutils version new_version. (stage 2)'
98 echo '* Change version number to svn_version. (stage 3)'
99 echo
100 echo 'If stage is supplied (1, 2 or 3), only the specified stage will'
101 echo 'be executed. Otherwise, it defaults to executing all stages.'
102 echo
103 echo 'Before doing dangerous things, you will be asked to press enter.'
104 echo
105 echo 'A maintenance branch called docutils-new_version will be created'
106 echo 'if branch_version is given. The version number inside the'
107 echo 'maintenance branch will be set to branch_version.'
108 echo
109 echo 'Access ssh,scp and sftp access to shell/frs.sourceforge.net'
110 echo 'must be configured.'
111 exit 1
114 function initialize()
116 if [ "$#" -lt 2 ]; then
117 usage
119 echo 'Initializing...'
120 python_versions='2.4 2.5 2.6 2.7'
121 for py_ver in $python_versions; do
122 echo -n "Checking for Python $py_ver (python$py_ver)... "
123 if ! echo 'print "OK"' | python$py_ver; then
124 echo "WARN: Python $py_ver (python$py_ver) not found."
126 done
127 echo -n 'Clearing $PYTHONPATH... '
128 export PYTHONPATH=
129 echo 'done'
130 echo -n 'Checking whether we are in a working copy... '
131 if [ -f HISTORY.txt ]; then
132 echo yes
133 else
134 echo "no (HISTORY.txt doesn't exist)"
135 echo 'Aborting.'
136 echo 'Please cd to a working copy before running this script.'
137 exit 1
139 echo -n 'Subversion binary to use: '
140 # TODO breaks for newer svn, .svn is in upper. is this for svk
141 svn=svn
142 echo $svn
143 working_copy="`pwd -P`"
144 echo "Working copy: $working_copy"
145 svnurl="`$svn info . | grep ^URL: | sed 's/URL: //'`"
146 if test -z "$svnurl"; then
147 echo 'Unable to detect Subversion URL. Aborting.'
148 exit 1
150 echo "Subversion URL: $svnurl"
151 if ! echo "$svnurl" | grep -q 'branches\|trunk'; then
152 echo 'Subversion URL contains neither "branches" nor "trunk".'
153 echo 'Aborting.'
154 exit 1
156 svnroot="`echo "$svnurl" | sed 's/\/\(branches\|trunk\).*//'`"
157 echo "Subversion root URL: $svnroot"
158 if test "$svnurl" = "$svnroot"; then
159 echo 'Error: Subversion URL and Subversion root URL are the same.'
160 echo ' probably a MacOSX sed problem.'
161 exit 1
163 echo -n 'Detecting current Docutils version... '
164 old_ver="`python -c 'import docutils; print docutils.__version__'`"
165 echo "$old_ver"
166 new_ver="$1"
167 # log_prefix is for SVN logs.
168 log_prefix="Release $new_ver:"
169 echo "New version number (for releasing): $new_ver"
170 svn_ver="$2"
171 if echo "$svn_ver" | grep -q :; then
172 # Split at colon: svn_ver:branch_ver
173 branch_ver="${svn_ver#*:}"
174 svn_ver="${svn_ver%:*}"
175 else
176 branch_ver=
178 echo "New Subversion version number (after releasing): $svn_ver"
179 echo -n 'Create maintenance branch: '
180 if test "$branch_ver"; then
181 echo yes
182 echo "New version number on maintenance branch: $branch_ver"
183 else
184 echo no
186 if test "$branch_ver"; then
187 echo -n 'Checking that we have a full checkout... '
188 if echo "$working_copy" | grep -q 'branches\|trunk'; then
189 echo OK
190 else
191 echo 'no'
192 echo 'Working copy path contains neither "branches" nor "trunk".'
193 echo 'You need a full checkout in order to branch.'
194 echo 'Aborting.'
195 exit 1
197 wcroot="`echo "$working_copy" | sed 's/\/\(branches\|trunk\).*//'`"
198 echo "Working copy root: $wcroot"
200 tarball=docutils-"$new_ver".tar.gz
201 echo "Tarball name: $tarball"
202 echo 'Initialization completed.'
203 echo
206 function test_tarball()
208 # Assume we have the tarball in the current directory.
209 # Pass test number as first parameter.
210 echo 'Testing the release tarball.'
211 run mkdir tarball_test/
212 run cd tarball_test/
213 confirm tar xzvf "../$tarball"
214 echo
215 run cd docutils-"$new_ver"
216 echo 'Deleteing old installations. Installing the distribution.'
217 echo "WARN: might not find installation."
218 for py_ver in '"$python_versions"'; do
219 echo "python$py_ver install/update and test."
220 bash release-test.sh
221 echo "Enter to test next."
222 read
223 done
226 function upload_tarball()
228 # Assume we have the tarball in the working area.
229 run cd "$working_area"
230 mkdir $new_ver
231 cp docutils-$new_ver.tar.gz $new_ver
232 cp docutils/RELEASE-NOTES.txt $new_ver
233 # README.txt would be displayed automatically on sf.
234 # BUG user grubert hardcoded
235 # short path "/home/frs/project/docutils/docutils/" also exists
236 scp -r $new_ver grubert,docutils@frs.sourceforge.net:/home/frs/project/d/do/docutils/docutils/
237 echo 'Upload completed.'
240 function upload_htdocs()
242 # Assume we have the tarball in the working area.
243 run cd "$working_area"
244 echo "Upload htdocs for $new_ver"
245 run mkdir htdocs
246 run cd htdocs
247 confirm tar xzvf "../$tarball"
248 run cd docutils-"$new_ver"/tools/
249 echo "BUG no docutils installation left."
250 echo "DO NOT let call but manually in $(pwd)"
251 confirm ./buildhtml.py --local ..
252 confirm ./buildhtml.py ../docs
253 run cd ..
254 echo '$ find -name test -type d -prune -o -name \*.css -print0 \
255 -o -name \*.html -print0 -o -name \*.txt -print0 \
256 | tar -cjvf docutils-docs.tar.bz2 -T - --null'
257 find -name test -type d -prune -o -name \*.css -print0 \
258 -o -name \*.html -print0 -o -name \*.txt -print0 \
259 | tar -cjvf docutils-docs.tar.bz2 -T - --null
260 echo 'Upload docs to SF.net...'
261 echo 'Press enter (or enter anything to skip).'
262 read
263 if [ ! "$REPLY" ]; then
264 mkdir $new_ver
265 cd $new_ver
266 tar xjvf ../docutils-docs.tar.bz2
267 cd ..
268 chmod -R g+rw $new_ver
269 scp -r -p -C $new_ver web.sourceforge.net:/home/groups/d/do/docutils/htdocs
273 function create_maintenance_branch()
275 echo 'Creating maintenance branch.'
276 branch_name="docutils-$new_ver"
277 echo "Branch name: $branch_name"
278 branch_url="$svnroot/branches/$branch_name"
279 echo "Branch URL: $branch_url"
280 confirm svn cp "$svnurl" "$branch_url" -m \
281 "$log_prefix created maintenance branch for version $new_ver"
282 cd "$wcroot"
283 svn_up
284 cd branches/"$branch_name"
285 set_ver "$new_ver" "$branch_ver"
288 function run_stage()
290 if [ ! "$1" ]; then
291 run_stage 1
292 echo
293 run_stage 2
294 echo
295 run_stage 3
296 else
297 echo "Press enter to run stage $1 (or enter anything to skip this stage)."
298 read
299 if [ ! "$REPLY" ]; then
300 cd "$working_copy"
301 if [ "$1" == 1 ]; then
302 stage_1
303 elif [ "$1" == 2 ]; then
304 stage_2
305 elif [ "$1" == 3 ]; then
306 stage_3
307 else
308 echo 'Invalid stage.'
309 echo
310 usage
312 echo
313 echo "Stage $1 completed."
314 else
315 echo "Skipped stage $1."
320 function stage_1()
322 svn_up
323 echo
324 # update __version_details__ string
325 (echo ",s/^__version_details__ = .*\$/__version_details__ = 'release'/";
326 echo wq) | ed docutils/__init__.py 2> /dev/null
327 set_ver "$old_ver" "$new_ver"
328 echo
329 history_files='HISTORY.txt RELEASE-NOTES.txt'
330 echo "Now updating the following files: $history_files"
331 old_string="Changes Since [0-9.]+"
332 new_string="Release $new_ver (`date --utc --iso-8601`)"
333 echo 'Press enter to replace "'"$old_string"'" with "'"$new_string"\",
334 echo 'or enter anything to skip.'
335 read
336 test "$REPLY" || python -c "for filename in '$history_files'.split():
337 import re
338 h = file(filename).read()
339 h = re.sub('$old_string\\n=+', '$new_string\\n' + '=' * len('$new_string'), h, count=1)
340 file(filename, 'w').write(h)"
341 checkin 'closed "Changes Since ..." section' $history_files
344 function stage_2()
346 echo 'Creating working area...'
347 working_area="`echo ~/tmp/docutils-release.$$`"
348 run mkdir -p "$working_area"
349 echo
350 echo 'Getting a fresh export.'
351 echo 'Press enter to proceed (or enter anything to skip)...'
352 read
353 if [ ! "$REPLY" ]; then
354 run cd "$working_area"
355 confirm svn export "$svnurl"
356 echo
357 echo 'Building the release tarball.'
358 run cd docutils
359 confirm ./setup.py sdist
360 run cd ..
361 echo 'Tarball built.'
362 run cp docutils/dist/"$tarball" .
363 echo 'BETTER run release-test.sh manually for each installed python version.'
364 echo "DO: cd $working_area and call sandbox/infrastructure/release-test.sh py_ver docutils_ver"
365 confirm test_tarball
366 echo "Testing documentation and uploading htdocs of version $new_ver..."
367 confirm upload_htdocs
368 echo "Tagging current revision..."
369 confirm svn cp "$svnurl" "$svnroot/tags/docutils-$new_ver/" -m "$log_prefix tagging released revision"
370 echo "Uploading $tarball to SF.net."
371 confirm upload_tarball
372 echo 'Now go to https://sourceforge.net/projects/docutils/files/docutils'
373 echo 'and follow the instructions at'
374 echo 'http://docutils.sf.net/docs/dev/release.html#file-release-system'
375 echo
376 echo 'Then press enter.'
377 read
379 run cd $working_area
380 echo 'Downloading the tarball to verify its integrity.'
381 while true; do
382 # BUG path is wrong. project admin filemanager shows md5sum
383 confirm wget http://sourceforge.net/projects/docutils/files/"$tarball"
384 echo 'Was the download successful?'
385 echo 'If yes, press enter to continue, otherwise enter anything to repeat'
386 echo '(it is possible that the file will show up in a few minutes).'
387 read
388 test "$REPLY" || break
389 done
390 confirm test_tarball
391 echo 'Registering with PyPI...'
392 echo 'TODO upload to pypi or set download url for this release'
393 echo 'Press enter to proceed (or enter anything to skip)...'
394 read
395 if [ ! "$REPLY" ]; then
396 echo "Unpacking tarball..."
397 ls -l
399 run tar xzvf "$tarball"
400 run cd docutils-"$new_ver"
401 echo 'TODO upload to pypi'
402 confirm ./setup.py register
406 function stage_3()
408 svn_up
409 echo
410 # update __version_details__ string
411 (echo ",s/^__version_details__ = .*\$/__version_details__ = 'repository'/";
412 echo wq) | ed docutils/__init__.py 2> /dev/null
413 checkin 'set __version_details__ to "repository"'
414 echo
415 history_files='HISTORY.txt RELEASE-NOTES.txt'
416 echo "Now updating the following files: $history_files"
417 add_string="Changes Since $new_ver"
418 before="Release "
419 echo 'Press enter to add "'"$add_string"'" section,'
420 echo 'or enter anything to skip.'
421 read
422 test "$REPLY" || python -c "for filename in '$history_files'.split():
423 import re
424 h = file(filename).read()
425 h = re.sub('\n$before', '\\n$add_string\\n' + '=' * len('$add_string') +
426 '\\n\\n\\n$before', h, count=1)
427 file(filename, 'w').write(h)"
428 checkin "added empty \"Changes Since $new_ver\" section" $history_files
429 echo
430 if test "$branch_ver"; then
431 create_maintenance_branch
432 cd "$working_copy"
434 set_ver "$new_ver" "$svn_ver"
435 echo 'Please change version number in README.txt'
436 echo
437 echo 'Please update the web page now (web/index.txt).'
438 echo 'cd into sandbox/infrastructure'
439 echo 'and call docutils-update.local (requires linux, macosx cp misses something)'
440 echo "Press enter when you're done."
441 read
444 initialize "$@"
445 run_stage "$3"
446 echo
447 echo 'Finished.'
448 echo 'Run alltests.py on svn version now.'
450 # Local Variables:
451 # indent-tabs-mode: nil
452 # End: