Needed files for examples.
[docutils/kirr.git] / sandbox / infrastructure / release.sh
blob668b3073ca4030eb83aa8c79c1508399a4cbc751
1 #!/bin/bash
3 # Author: Lea Wiemann
4 # Contact: LeWiemann@gmail.com
5 # Revision: $Revision$
6 # Date: $Date$
7 # Copyright: This script has been placed in the public domain.
9 set -e
11 function print_command()
13 # Print "$@", quoting parameters containing spaces.
14 echo -n $
15 for param in "$@"; do
16 echo "$param" | grep -Fq ' ' && echo -n " '$param'" || echo -n " $param"
17 done
20 function run()
22 # Print and run "$@".
23 print_command "$@"
24 echo
25 "$@"
28 function confirm()
30 # Print, let the user confirm and run "$@".
31 echo 'Press enter to run (or enter anything to skip):'
32 print_command "$@"
33 read
34 test "$REPLY" && echo Skipped. || "$@"
37 function svn_up()
39 if test $svn == svk; then
40 confirm svk sync "$depot"
42 confirm $svn up
45 function checkin()
47 # Parameters: log_message, file, file, file ...
48 log_message="$1"
49 shift
50 confirm $svn diff "$@"
51 confirm $svn ci -m "$log_prefix $log_message" "$@"
54 function set_ver()
56 # Parameters: old_version new_version
57 shopt -s extglob
58 echo Determining list of files to be changed...
59 # BUG ls lists directories but does not descend
60 files="docutils/__init__.py setup.py `$svn ls test/functional/expected/ | sed 's|^|test/functional/expected/|'`"
61 echo "Now I'll change the version number to $2 in the following files:"
62 echo $files
63 echo
64 echo 'Press enter to proceed (or enter anything to skip)...'
65 read
66 if [ ! "$REPLY" ]; then
67 echo 'Modifying files with ed...'
68 old_ver_regex="`echo "$1" | sed 's/\./\\\\./g'`"
69 # "ed" returns an error code if there has been no substitution, so
70 # we temporarily deactivate exit-on-error.
71 set +e
72 for F in $files; do
73 (echo ",s/$old_ver_regex/$2/g"; echo 'wq') | ed "$F"
74 done
75 set -e
77 echo
78 echo 'CAUTION: please look at the diffs carefully, for wrongly'
79 echo ' replaced embedded numbers.'
80 checkin "set version number to $2" $files
83 function usage()
85 echo 'Usage:'
86 echo
87 echo ' release.sh new_version svn_version[:branch_version] [stage]'
88 echo
89 echo 'The following things will be done:'
90 echo
91 echo '* Change version number to new_version. (stage 1)'
92 echo '* SVN-export, test, and release Docutils version new_version. (stage 2)'
93 echo '* Change version number to svn_version. (stage 3)'
94 echo
95 echo 'If stage is supplied (1, 2 or 3), only the specified stage will'
96 echo 'be executed. Otherwise, it defaults to executing all stages.'
97 echo
98 echo 'Before doing dangerous things, you will be asked to press enter.'
99 echo
100 echo 'A maintenance branch called docutils-new_version will be created'
101 echo 'if branch_version is given. The version number inside the'
102 echo 'maintenance branch will be set to branch_version.'
103 echo
104 echo 'Access ssh,scp and sftp access to shell/frs.sourceforge.net'
105 echo 'must be configured.'
106 exit 1
109 function initialize()
111 if [ "$#" -lt 2 ]; then
112 usage
114 echo 'Initializing...'
115 python_versions='2.3 2.4 2.5 2.6 2.7'
116 for py_ver in $python_versions; do
117 echo -n "Checking for Python $py_ver (python$py_ver)... "
118 if ! echo 'print "OK"' | python$py_ver; then
119 echo "Python $py_ver (python$py_ver) not found."
120 echo Aborting.
121 exit 1
123 done
124 echo -n 'Clearing $PYTHONPATH... '
125 export PYTHONPATH=
126 echo 'done'
127 echo -n 'Checking whether we are in a working copy... '
128 if [ -f HISTORY.txt ]; then
129 echo yes
130 else
131 echo "no (HISTORY.txt doesn't exist)"
132 echo 'Aborting.'
133 echo 'Please cd to a working copy before running this script.'
134 exit 1
136 echo -n 'Subversion binary to use: '
137 if [ -d .svn ]; then
138 svn=svn
139 else
140 svn=svk
142 echo $svn
143 working_copy="`pwd -P`"
144 echo "Working copy: $working_copy"
145 if test $svn = svk; then
146 depot_path="`svk info . | grep ^Depot\ Path: | sed 's/Depot Path: //'`"
147 depot="`echo "$depot_path" | sed 's|\(//[^/]\+/[^/]\+\).*|\1|'`"
148 echo "SVK depot: $depot"
149 mirrored_from="`svk info . | grep ^Mirrored\ From: | sed 's/Mirrored From: //;s/, Rev\. .*//'`"
150 svnurl="$mirrored_from`echo "$depot_path" | sed 's|//[^/]\+/[^/]\+||'`"
151 else
152 svnurl="`$svn info . | grep ^URL: | sed 's/URL: //'`"
154 if test -z "$svnurl"; then
155 echo 'Unable to detect Subversion URL. Aborting.'
156 exit 1
158 echo "Subversion URL: $svnurl"
159 if ! echo "$svnurl" | grep -q 'branches\|trunk'; then
160 echo 'Subversion URL contains neither "branches" nor "trunk".'
161 echo 'Aborting.'
162 exit 1
164 svnroot="`echo "$svnurl" | sed 's/\/\(branches\|trunk\).*//'`"
165 echo "Subversion root URL: $svnroot"
166 if test "$svnurl" = "$svnroot"; then
167 echo 'Error: Subversion URL and Subversion root URL are the same.'
168 exit 1
170 echo -n 'Detecting current Docutils version... '
171 old_ver="`python -c 'import docutils; print docutils.__version__'`"
172 echo "$old_ver"
173 new_ver="$1"
174 # log_prefix is for SVN logs.
175 log_prefix="Release $new_ver:"
176 echo "New version number (for releasing): $new_ver"
177 svn_ver="$2"
178 if echo "$svn_ver" | grep -q :; then
179 # Split at colon: svn_ver:branch_ver
180 branch_ver="${svn_ver#*:}"
181 svn_ver="${svn_ver%:*}"
182 else
183 branch_ver=
185 echo "New Subversion version number (after releasing): $svn_ver"
186 echo -n 'Create maintenance branch: '
187 if test "$branch_ver"; then
188 echo yes
189 echo "New version number on maintenance branch: $branch_ver"
190 else
191 echo no
193 if test "$branch_ver"; then
194 echo -n 'Checking that we have a full checkout... '
195 if echo "$working_copy" | grep -q 'branches\|trunk'; then
196 echo OK
197 else
198 echo 'no'
199 echo 'Working copy path contains neither "branches" nor "trunk".'
200 echo 'You need a full checkout in order to branch.'
201 echo 'Aborting.'
202 exit 1
204 wcroot="`echo "$working_copy" | sed 's/\/\(branches\|trunk\).*//'`"
205 echo "Working copy root: $wcroot"
207 tarball=docutils-"$new_ver".tar.gz
208 echo "Tarball name: $tarball"
209 echo 'Initialization completed.'
210 echo
213 function test_tarball()
215 # Assume we have the tarball in the current directory.
216 # Pass test number as first parameter.
217 echo 'Testing the release tarball.'
218 run mkdir tarball_test/
219 run cd tarball_test/
220 confirm tar xzvf "../$tarball"
221 echo
222 run cd docutils-"$new_ver"
223 echo 'Installing the distribution.'
224 # Extra files, with leading comma.
225 extras="`cd extras; for extrafile in *.py; do echo -n ",$extrafile{,c,o}"; done`"
226 confirm su -c '
227 for py_ver in '"$python_versions"'; do
228 echo "Deleting and installing Docutils on Python $py_ver."
229 echo "Press enter."
230 read
231 site_packages="/usr/local/lib/python$py_ver/site-packages"
232 if test ! -d "$site_packages"; then
233 site_packages="/usr/lib/python$py_ver/site-packages"
235 if test ! -d "$site_packages"; then
236 echo "Error: \"$site_packages\" does not exist."
237 exit 1
239 if test -e "$site_packages/docutils-test"; then
240 echo "Error: \"$site_packages/docutils-test\" exists."
241 exit 1
243 rm -rfv /usr/{local,}lib/python$py_ver/site-packages/{docutils'"$extras"'}
244 python$py_ver setup.py install
245 echo
246 echo "Copying the test suite to the site-packages directory of Python $py_ver."
247 echo "Press enter."
248 read
249 cp -rv test "$site_packages/docutils-test"
250 done'
251 echo
252 echo 'Running the test suite as root with all Python versions.'
253 for py_ver in $python_versions; do
254 site_packages="/usr/local/lib/python$py_ver/site-packages"
255 if test ! -d "$site_packages"; then
256 site_packages="/usr/lib/python$py_ver/site-packages"
258 if test ! -d "$site_packages"; then
259 echo "Error: \"$site_packages\" does not exist."
260 exit 1
262 confirm su -c "python$py_ver -u \"$site_packages/docutils-test/alltests.py\""
263 # BUG shell script exits after alltests.py
264 done
265 run cd ../..
266 echo "Cleaning up..."
267 confirm su -c "run rm -rf tarball_test"
268 confirm su -c '
269 for py_ver in '"$python_versions"'; do
270 rm -rfv /usr{/local,}/lib/python$py_ver/site-packages/docutils{-test,}
271 done'
272 echo
275 function upload_tarball()
277 # Assume we have the tarball in the working area.
278 run cd "$working_area"
279 mkdir $new_ver
280 cp docutils-$new_ver.tar.gz $new_ver
281 cp docutils/RELEASE-NOTES.txt $new_ver
282 # BUG user grubert hardcoded
283 scp -r $new_ver grubert,docutils@frs.sourceforge.net:/home/frs/project/d/do/docutils/docutils/
284 echo 'Upload completed.'
287 function upload_htdocs()
289 # Assume we have the tarball in the working area.
290 run cd "$working_area"
291 echo "Upload htdocs for $new_ver"
292 run mkdir htdocs
293 run cd htdocs
294 confirm tar xzvf "../$tarball"
295 run cd docutils-"$new_ver"/tools/
296 # BUG no docutils installation left.
297 # BUG and it breaks on test/functional/input/standalone_rst_newlatex.txt:
298 # 1020: (SEVERE/4) Title level inconsistent
299 # because this is an include file.
300 # BUG --local .. still recurses into test
301 confirm ./buildhtml.py --local ..
302 confirm ./buildhtml.py ../docs
303 run cd ..
304 echo '$ find -name test -type d -prune -o -name \*.css -print0 \
305 -o -name \*.html -print0 -o -name \*.txt -print0 \
306 | tar -cjvf docutils-docs.tar.bz2 -T - --null'
307 find -name test -type d -prune -o -name \*.css -print0 \
308 -o -name \*.html -print0 -o -name \*.txt -print0 \
309 | tar -cjvf docutils-docs.tar.bz2 -T - --null
310 echo 'Upload docs to SF.net...'
311 echo 'Press enter (or enter anything to skip).'
312 read
313 if [ ! "$REPLY" ]; then
314 mkdir $new_ver
315 cd $new_ver
316 tar xjvf ../docutils-docs.tar.bz2
317 cd ..
318 chmod -R g+rw $new_ver
319 scp -r -p -C $new_ver web.sourceforge.net:/home/groups/d/do/docutils/htdocs
323 function create_maintenance_branch()
325 echo 'Creating maintenance branch.'
326 branch_name="docutils-$new_ver"
327 echo "Branch name: $branch_name"
328 branch_url="$svnroot/branches/$branch_name"
329 echo "Branch URL: $branch_url"
330 confirm svn cp "$svnurl" "$branch_url" -m \
331 "$log_prefix created maintenance branch for version $new_ver"
332 cd "$wcroot"
333 svn_up
334 cd branches/"$branch_name"
335 set_ver "$new_ver" "$branch_ver"
338 function run_stage()
340 if [ ! "$1" ]; then
341 run_stage 1
342 echo
343 run_stage 2
344 echo
345 run_stage 3
346 else
347 echo "Press enter to run stage $1 (or enter anything to skip this stage)."
348 read
349 if [ ! "$REPLY" ]; then
350 cd "$working_copy"
351 if [ "$1" == 1 ]; then
352 stage_1
353 elif [ "$1" == 2 ]; then
354 stage_2
355 elif [ "$1" == 3 ]; then
356 stage_3
357 else
358 echo 'Invalid stage.'
359 echo
360 usage
362 echo
363 echo "Stage $1 completed."
364 else
365 echo "Skipped stage $1."
370 function stage_1()
372 svn_up
373 echo
374 # update __version_details__ string
375 (echo ",s/^__version_details__ = .*\$/__version_details__ = 'release'/";
376 echo wq) | ed docutils/__init__.py 2> /dev/null
377 set_ver "$old_ver" "$new_ver"
378 echo
379 history_files='HISTORY.txt RELEASE-NOTES.txt'
380 echo "Now updating the following files: $history_files"
381 old_string="Changes Since [0-9.]+"
382 new_string="Release $new_ver (`date --utc --iso-8601`)"
383 echo 'Press enter to replace "'"$old_string"'" with "'"$new_string"\",
384 echo 'or enter anything to skip.'
385 read
386 test "$REPLY" || python -c "for filename in '$history_files'.split():
387 import re
388 h = file(filename).read()
389 h = re.sub('$old_string\\n=+', '$new_string\\n' + '=' * len('$new_string'), h, count=1)
390 file(filename, 'w').write(h)"
391 checkin 'closed "Changes Since ..." section' $history_files
394 function stage_2()
396 echo 'Creating working area...'
397 working_area="`echo ~/tmp/docutils-release.$$`"
398 run mkdir -p "$working_area"
399 echo
400 echo 'Getting a fresh export.'
401 echo 'Press enter to proceed (or enter anything to skip)...'
402 read
403 if [ ! "$REPLY" ]; then
404 run cd "$working_area"
405 confirm svn export "$svnurl"
406 echo
407 echo 'Building the release tarball.'
408 run cd docutils
409 confirm ./setup.py sdist
410 run cd ..
411 echo 'Tarball built.'
412 run cp docutils/dist/"$tarball" .
413 confirm test_tarball
414 echo "Testing documentation and uploading htdocs of version $new_ver..."
415 confirm upload_htdocs
416 echo "Tagging current revision..."
417 confirm svn cp "$svnurl" "$svnroot/tags/docutils-$new_ver/" -m "$log_prefix tagging released revision"
418 echo "Uploading $tarball to SF.net."
419 confirm upload_tarball
420 echo 'Now go to https://sourceforge.net/project/admin/explorer.php?group_id=38414'
421 echo 'and follow the instructions at'
422 echo 'http://docutils.sf.net/docs/dev/release.html#file-release-system'
423 echo 'BUG find your way.'
424 echo
425 echo 'Then press enter.'
426 read
428 run cd $working_area
429 echo 'Downloading the tarball to verify its integrity.'
430 while true; do
431 # BUG path is wrong. project admin filemanager shows md5sum
432 confirm wget http://osdn.dl.sourceforge.net/sourceforge/docutils/"$tarball"
433 echo 'Was the download successful?'
434 echo 'If yes, press enter to continue, otherwise enter anything to repeat'
435 echo '(it is possible that the file will show up in a few minutes).'
436 read
437 test "$REPLY" || break
438 done
439 confirm test_tarball
440 echo 'Registering with PyPI...'
441 echo 'Press enter to proceed (or enter anything to skip)...'
442 read
443 if [ ! "$REPLY" ]; then
444 echo "Unpacking tarball..."
445 ls -l
447 run tar xzvf "$tarball"
448 run cd docutils-"$new_ver"
449 confirm ./setup.py register
453 function stage_3()
455 svn_up
456 echo
457 # update __version_details__ string
458 (echo ",s/^__version_details__ = .*\$/__version_details__ = 'repository'/";
459 echo wq) | ed docutils/__init__.py 2> /dev/null
460 checkin 'set __version_details__ to "repository"'
461 echo
462 history_files='HISTORY.txt RELEASE-NOTES.txt'
463 echo "Now updating the following files: $history_files"
464 add_string="Changes Since $new_ver"
465 before="Release "
466 echo 'Press enter to add "'"$add_string"'" section,'
467 echo 'or enter anything to skip.'
468 read
469 test "$REPLY" || python -c "for filename in '$history_files'.split():
470 import re
471 h = file(filename).read()
472 h = re.sub('\n$before', '\\n$add_string\\n' + '=' * len('$add_string') +
473 '\\n\\n\\n$before', h, count=1)
474 file(filename, 'w').write(h)"
475 checkin "added empty \"Changes Since $new_ver\" section" $history_files
476 echo
477 if test "$branch_ver"; then
478 create_maintenance_branch
479 cd "$working_copy"
481 set_ver "$new_ver" "$svn_ver"
482 echo
483 echo 'Please update the web page now (web/index.txt).'
484 echo 'cd into sandbox/infrastructure'
485 echo 'and call docutils-update.local (requires linux, macosx cp misses something)'
486 echo "Press enter when you're done."
487 read
490 initialize "$@"
491 run_stage "$3"
492 echo
493 echo 'Finished.'
494 echo 'Run alltests.py on svn version now.'
496 # Local Variables:
497 # indent-tabs-mode: nil
498 # End: