4 # Contact: LeWiemann@gmail.com
7 # Copyright: This script has been placed in the public domain.
9 # USAGE see: docutils/docs/dev/release.txt
13 function print_command
()
15 # Print "$@", quoting parameters containing spaces.
18 echo "$param" |
grep -Fq ' ' && echo -n " '$param'" ||
echo -n " $param"
32 # Print, let the user confirm and run "$@".
33 echo 'Press enter to run (or enter anything to skip):'
36 test "$REPLY" && echo Skipped. ||
"$@"
41 if test $svn == svk
; then
42 confirm svk sync
"$depot"
49 # Parameters: log_message, file, file, file ...
52 confirm
$svn diff "$@"
53 confirm
$svn ci
-m "$log_prefix $log_message" "$@"
58 # Parameters: old_version new_version
60 echo Determining list of files to be changed...
61 # BUG ls lists directories but does not descend
62 files
="docutils/__init__.py setup.py `$svn ls test/functional/expected/ | sed 's|^|test/functional/expected/|'`"
63 echo "Now I'll change the version number to $2 in the following files:"
66 echo 'Press enter to proceed (or enter anything to skip)...'
68 if [ ! "$REPLY" ]; then
69 echo 'Modifying files with ed...'
70 old_ver_regex
="`echo "$1" | sed 's/\./\\\\./g'`"
71 # "ed" returns an error code if there has been no substitution, so
72 # we temporarily deactivate exit-on-error.
75 (echo ",s/$old_ver_regex/$2/g"; echo 'wq') | ed
"$F"
80 echo 'CAUTION: please look at the diffs carefully, for wrongly'
81 echo ' replaced embedded numbers.'
82 checkin
"set version number to $2" $files
89 echo ' release.sh new_version svn_version[:branch_version] [stage]'
91 echo 'The following things will be done:'
93 echo '* Change version number to new_version. (stage 1)'
94 echo '* SVN-export, test, and release Docutils version new_version. (stage 2)'
95 echo '* Change version number to svn_version. (stage 3)'
97 echo 'If stage is supplied (1, 2 or 3), only the specified stage will'
98 echo 'be executed. Otherwise, it defaults to executing all stages.'
100 echo 'Before doing dangerous things, you will be asked to press enter.'
102 echo 'A maintenance branch called docutils-new_version will be created'
103 echo 'if branch_version is given. The version number inside the'
104 echo 'maintenance branch will be set to branch_version.'
106 echo 'Access ssh,scp and sftp access to shell/frs.sourceforge.net'
107 echo 'must be configured.'
111 function initialize
()
113 if [ "$#" -lt 2 ]; then
116 echo 'Initializing...'
117 python_versions
='2.3 2.4 2.5 2.6 2.7'
118 for py_ver
in $python_versions; do
119 echo -n "Checking for Python $py_ver (python$py_ver)... "
120 if ! echo 'print "OK"' | python
$py_ver; then
121 echo "Python $py_ver (python$py_ver) not found."
126 echo -n 'Clearing $PYTHONPATH... '
129 echo -n 'Checking whether we are in a working copy... '
130 if [ -f HISTORY.txt
]; then
133 echo "no (HISTORY.txt doesn't exist)"
135 echo 'Please cd to a working copy before running this script.'
138 echo -n 'Subversion binary to use: '
145 working_copy
="`pwd -P`"
146 echo "Working copy: $working_copy"
147 if test $svn = svk
; then
148 depot_path
="`svk info . | grep ^Depot\ Path: | sed 's/Depot Path: //'`"
149 depot
="`echo "$depot_path" | sed 's|\(//[^/]\+/[^/]\+\).*|\1|'`"
150 echo "SVK depot: $depot"
151 mirrored_from
="`svk info . | grep ^Mirrored\ From: | sed 's/Mirrored From: //;s/, Rev\. .*//'`"
152 svnurl
="$mirrored_from`echo "$depot_path" | sed 's|//[^/]\+/[^/]\+||'`"
154 svnurl
="`$svn info . | grep ^URL: | sed 's/URL: //'`"
156 if test -z "$svnurl"; then
157 echo 'Unable to detect Subversion URL. Aborting.'
160 echo "Subversion URL: $svnurl"
161 if ! echo "$svnurl" |
grep -q 'branches\|trunk'; then
162 echo 'Subversion URL contains neither "branches" nor "trunk".'
166 svnroot
="`echo "$svnurl" | sed 's/\/\(branches\|trunk\).*//'`"
167 echo "Subversion root URL: $svnroot"
168 if test "$svnurl" = "$svnroot"; then
169 echo 'Error: Subversion URL and Subversion root URL are the same.'
172 echo -n 'Detecting current Docutils version... '
173 old_ver
="`python -c 'import docutils; print docutils.__version__'`"
176 # log_prefix is for SVN logs.
177 log_prefix
="Release $new_ver:"
178 echo "New version number (for releasing): $new_ver"
180 if echo "$svn_ver" |
grep -q :; then
181 # Split at colon: svn_ver:branch_ver
182 branch_ver
="${svn_ver#*:}"
183 svn_ver
="${svn_ver%:*}"
187 echo "New Subversion version number (after releasing): $svn_ver"
188 echo -n 'Create maintenance branch: '
189 if test "$branch_ver"; then
191 echo "New version number on maintenance branch: $branch_ver"
195 if test "$branch_ver"; then
196 echo -n 'Checking that we have a full checkout... '
197 if echo "$working_copy" |
grep -q 'branches\|trunk'; then
201 echo 'Working copy path contains neither "branches" nor "trunk".'
202 echo 'You need a full checkout in order to branch.'
206 wcroot
="`echo "$working_copy" | sed 's/\/\(branches\|trunk\).*//'`"
207 echo "Working copy root: $wcroot"
209 tarball
=docutils-
"$new_ver".
tar.gz
210 echo "Tarball name: $tarball"
211 echo 'Initialization completed.'
215 function test_tarball
()
217 # Assume we have the tarball in the current directory.
218 # Pass test number as first parameter.
219 echo 'Testing the release tarball.'
220 run mkdir tarball_test
/
222 confirm
tar xzvf
"../$tarball"
224 run
cd docutils-
"$new_ver"
225 echo 'Installing the distribution.'
226 # Extra files, with leading comma.
227 extras
="`cd extras; for extrafile in *.py; do echo -n ",$extrafile{,c
,o
}"; done`"
229 for py_ver in '"$python_versions"'; do
230 echo "Deleting and installing Docutils on Python $py_ver."
233 site_packages="/usr/local/lib/python$py_ver/site-packages"
234 echo "BUG prefers /usr/local too /usr"
235 if test ! -d "$site_packages"; then
236 site_packages="/usr/lib/python$py_ver/site-packages"
238 if test ! -d "$site_packages"; then
239 echo "Error: \"$site_packages\" does not exist."
242 if test -e "$site_packages/docutils-test"; then
243 echo "Error: \"$site_packages/docutils-test\" exists."
244 echo "removing left over from previous releae. Ctrl-C to abort."
246 rm -rf $site_packages/docutils-test
248 rm -rfv /usr/{local,}lib/python$py_ver/site-packages/{docutils'"$extras"'}
249 python$py_ver setup.py install
251 echo "Copying the test suite to the site-packages directory of Python $py_ver."
254 cp -rv test "$site_packages/docutils-test"
257 echo 'Running the test suite as root with all Python versions.'
258 for py_ver
in $python_versions; do
259 site_packages
="/usr/local/lib/python$py_ver/site-packages"
260 if test ! -d "$site_packages"; then
261 site_packages
="/usr/lib/python$py_ver/site-packages"
263 if test ! -d "$site_packages"; then
264 echo "Error: \"$site_packages\" does not exist."
268 echo "shell script exits if any test fails, maybe run in separate shell."
269 confirm su
-c "python$py_ver -u \"$site_packages/docutils-test/alltests.py\""
272 echo "Cleaning up..."
273 confirm su
-c "rm -rf tarball_test"
275 for py_ver in '"$python_versions"'; do
276 rm -rfv /usr{/local,}/lib/python$py_ver/site-packages/docutils{-test,}
281 function upload_tarball
()
283 # Assume we have the tarball in the working area.
284 run
cd "$working_area"
286 cp docutils-
$new_ver.
tar.gz
$new_ver
287 cp docutils
/RELEASE-NOTES.txt
$new_ver
288 # README.txt would be displayed automatically on sf.
289 cp docutils
/RELEASE-NOTES.txt
$new_ver/README.txt
290 # BUG user grubert hardcoded
291 # short path "/home/frs/project/docutils/docutils/" also exists
292 scp
-r $new_ver grubert
,docutils@frs.sourceforge.net
:/home
/frs
/project
/d
/do
/docutils
/docutils
/
293 echo 'Upload completed.'
296 function upload_htdocs
()
298 # Assume we have the tarball in the working area.
299 run
cd "$working_area"
300 echo "Upload htdocs for $new_ver"
303 confirm
tar xzvf
"../$tarball"
304 run
cd docutils-
"$new_ver"/tools
/
305 # BUG no docutils installation left.
306 # BUG and it breaks on test/functional/input/standalone_rst_newlatex.txt:
307 # 1020: (SEVERE/4) Title level inconsistent
308 # because this is an include file.
309 # BUG --local .. still recurses into test
310 confirm .
/buildhtml.py
--local ..
311 confirm .
/buildhtml.py ..
/docs
313 echo '$ find -name test -type d -prune -o -name \*.css -print0 \
314 -o -name \*.html -print0 -o -name \*.txt -print0 \
315 | tar -cjvf docutils-docs.tar.bz2 -T - --null'
316 find -name test -type d
-prune -o -name \
*.css
-print0 \
317 -o -name \
*.html
-print0 -o -name \
*.txt
-print0 \
318 |
tar -cjvf docutils-docs.
tar.bz2
-T - --null
319 echo 'Upload docs to SF.net...'
320 echo 'Press enter (or enter anything to skip).'
322 if [ ! "$REPLY" ]; then
325 tar xjvf ..
/docutils-docs.
tar.bz2
327 chmod -R g
+rw
$new_ver
328 scp
-r -p -C $new_ver web.sourceforge.net
:/home
/groups
/d
/do
/docutils
/htdocs
332 function create_maintenance_branch
()
334 echo 'Creating maintenance branch.'
335 branch_name
="docutils-$new_ver"
336 echo "Branch name: $branch_name"
337 branch_url
="$svnroot/branches/$branch_name"
338 echo "Branch URL: $branch_url"
339 confirm svn
cp "$svnurl" "$branch_url" -m \
340 "$log_prefix created maintenance branch for version $new_ver"
343 cd branches
/"$branch_name"
344 set_ver
"$new_ver" "$branch_ver"
356 echo "Press enter to run stage $1 (or enter anything to skip this stage)."
358 if [ ! "$REPLY" ]; then
360 if [ "$1" == 1 ]; then
362 elif [ "$1" == 2 ]; then
364 elif [ "$1" == 3 ]; then
367 echo 'Invalid stage.'
372 echo "Stage $1 completed."
374 echo "Skipped stage $1."
383 # update __version_details__ string
384 (echo ",s/^__version_details__ = .*\$/__version_details__ = 'release'/";
385 echo wq
) | ed docutils
/__init__.py
2> /dev
/null
386 set_ver
"$old_ver" "$new_ver"
388 history_files
='HISTORY.txt RELEASE-NOTES.txt'
389 echo "Now updating the following files: $history_files"
390 old_string
="Changes Since [0-9.]+"
391 new_string
="Release $new_ver (`date --utc --iso-8601`)"
392 echo 'Press enter to replace "'"$old_string"'" with "'"$new_string"\",
393 echo 'or enter anything to skip.'
395 test "$REPLY" || python
-c "for filename in '$history_files'.split():
397 h = file(filename).read()
398 h = re.sub('$old_string\\n=+', '$new_string\\n' + '=' * len('$new_string'), h, count=1)
399 file(filename, 'w').write(h)"
400 checkin
'closed "Changes Since ..." section' $history_files
405 echo 'Creating working area...'
406 working_area
="`echo ~/tmp/docutils-release.$$`"
407 run mkdir
-p "$working_area"
409 echo 'Getting a fresh export.'
410 echo 'Press enter to proceed (or enter anything to skip)...'
412 if [ ! "$REPLY" ]; then
413 run
cd "$working_area"
414 confirm svn
export "$svnurl"
416 echo 'Building the release tarball.'
418 confirm .
/setup.py sdist
420 echo 'Tarball built.'
421 run
cp docutils
/dist
/"$tarball" .
423 echo "Testing documentation and uploading htdocs of version $new_ver..."
424 confirm upload_htdocs
425 echo "Tagging current revision..."
426 confirm svn
cp "$svnurl" "$svnroot/tags/docutils-$new_ver/" -m "$log_prefix tagging released revision"
427 echo "Uploading $tarball to SF.net."
428 confirm upload_tarball
429 echo 'Now go to https://sourceforge.net/project/admin/explorer.php?group_id=38414'
430 echo 'and follow the instructions at'
431 echo 'http://docutils.sf.net/docs/dev/release.html#file-release-system'
432 echo 'BUG find your way.'
434 echo 'Then press enter.'
438 echo 'Downloading the tarball to verify its integrity.'
440 # BUG path is wrong. project admin filemanager shows md5sum
441 confirm wget http
://osdn.dl.sourceforge.net
/sourceforge
/docutils
/"$tarball"
442 echo 'Was the download successful?'
443 echo 'If yes, press enter to continue, otherwise enter anything to repeat'
444 echo '(it is possible that the file will show up in a few minutes).'
446 test "$REPLY" ||
break
449 echo 'Registering with PyPI...'
450 echo 'Press enter to proceed (or enter anything to skip)...'
452 if [ ! "$REPLY" ]; then
453 echo "Unpacking tarball..."
456 run
tar xzvf
"$tarball"
457 run
cd docutils-
"$new_ver"
458 confirm .
/setup.py register
466 # update __version_details__ string
467 (echo ",s/^__version_details__ = .*\$/__version_details__ = 'repository'/";
468 echo wq
) | ed docutils
/__init__.py
2> /dev
/null
469 checkin
'set __version_details__ to "repository"'
471 history_files
='HISTORY.txt RELEASE-NOTES.txt'
472 echo "Now updating the following files: $history_files"
473 add_string
="Changes Since $new_ver"
475 echo 'Press enter to add "'"$add_string"'" section,'
476 echo 'or enter anything to skip.'
478 test "$REPLY" || python
-c "for filename in '$history_files'.split():
480 h = file(filename).read()
481 h = re.sub('\n$before', '\\n$add_string\\n' + '=' * len('$add_string') +
482 '\\n\\n\\n$before', h, count=1)
483 file(filename, 'w').write(h)"
484 checkin
"added empty \"Changes Since $new_ver\" section" $history_files
486 if test "$branch_ver"; then
487 create_maintenance_branch
490 set_ver
"$new_ver" "$svn_ver"
492 echo 'Please update the web page now (web/index.txt).'
493 echo 'cd into sandbox/infrastructure'
494 echo 'and call docutils-update.local (requires linux, macosx cp misses something)'
495 echo "Press enter when you're done."
503 echo 'Run alltests.py on svn version now.'
506 # indent-tabs-mode: nil