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 release. 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 echo "TODO for python3 rm local build, but building takes a long time then "
250 python$py_ver setup.py install
252 echo "Copying the test suite to the site-packages directory of Python $py_ver."
253 echo "TODO for python3 copy test3"
256 cp -rv test "$site_packages/docutils-test"
259 echo 'Running the test suite as root with all Python versions.'
260 for py_ver
in $python_versions; do
261 site_packages
="/usr/local/lib/python$py_ver/site-packages"
262 if test ! -d "$site_packages"; then
263 site_packages
="/usr/lib/python$py_ver/site-packages"
265 if test ! -d "$site_packages"; then
266 echo "Error: \"$site_packages\" does not exist."
270 echo "WARNING shell script exits if any test fails, maybe run in separate shell."
271 confirm su
-c "python$py_ver -u \"$site_packages/docutils-test/alltests.py\""
274 echo "Cleaning up..."
275 confirm su
-c "rm -rf tarball_test"
277 for py_ver in '"$python_versions"'; do
278 rm -rfv /usr{/local,}/lib/python$py_ver/site-packages/docutils{-test,}
283 function upload_tarball
()
285 # Assume we have the tarball in the working area.
286 run
cd "$working_area"
288 cp docutils-
$new_ver.
tar.gz
$new_ver
289 cp docutils
/RELEASE-NOTES.txt
$new_ver
290 # README.txt would be displayed automatically on sf.
291 # BUG user grubert hardcoded
292 # short path "/home/frs/project/docutils/docutils/" also exists
293 scp
-r $new_ver grubert
,docutils@frs.sourceforge.net
:/home
/frs
/project
/d
/do
/docutils
/docutils
/
294 echo 'Upload completed.'
297 function upload_htdocs
()
299 # Assume we have the tarball in the working area.
300 run
cd "$working_area"
301 echo "Upload htdocs for $new_ver"
304 confirm
tar xzvf
"../$tarball"
305 run
cd docutils-
"$new_ver"/tools
/
306 echo "BUG no docutils installation left."
307 echo "DO NOT let call but manually in $(pwd)"
308 confirm .
/buildhtml.py
--local ..
309 confirm .
/buildhtml.py ..
/docs
311 echo '$ find -name test -type d -prune -o -name \*.css -print0 \
312 -o -name \*.html -print0 -o -name \*.txt -print0 \
313 | tar -cjvf docutils-docs.tar.bz2 -T - --null'
314 find -name test -type d
-prune -o -name \
*.css
-print0 \
315 -o -name \
*.html
-print0 -o -name \
*.txt
-print0 \
316 |
tar -cjvf docutils-docs.
tar.bz2
-T - --null
317 echo 'Upload docs to SF.net...'
318 echo 'Press enter (or enter anything to skip).'
320 if [ ! "$REPLY" ]; then
323 tar xjvf ..
/docutils-docs.
tar.bz2
325 chmod -R g
+rw
$new_ver
326 scp
-r -p -C $new_ver web.sourceforge.net
:/home
/groups
/d
/do
/docutils
/htdocs
330 function create_maintenance_branch
()
332 echo 'Creating maintenance branch.'
333 branch_name
="docutils-$new_ver"
334 echo "Branch name: $branch_name"
335 branch_url
="$svnroot/branches/$branch_name"
336 echo "Branch URL: $branch_url"
337 confirm svn
cp "$svnurl" "$branch_url" -m \
338 "$log_prefix created maintenance branch for version $new_ver"
341 cd branches
/"$branch_name"
342 set_ver
"$new_ver" "$branch_ver"
354 echo "Press enter to run stage $1 (or enter anything to skip this stage)."
356 if [ ! "$REPLY" ]; then
358 if [ "$1" == 1 ]; then
360 elif [ "$1" == 2 ]; then
362 elif [ "$1" == 3 ]; then
365 echo 'Invalid stage.'
370 echo "Stage $1 completed."
372 echo "Skipped stage $1."
381 # update __version_details__ string
382 (echo ",s/^__version_details__ = .*\$/__version_details__ = 'release'/";
383 echo wq
) | ed docutils
/__init__.py
2> /dev
/null
384 set_ver
"$old_ver" "$new_ver"
386 history_files
='HISTORY.txt RELEASE-NOTES.txt'
387 echo "Now updating the following files: $history_files"
388 old_string
="Changes Since [0-9.]+"
389 new_string
="Release $new_ver (`date --utc --iso-8601`)"
390 echo 'Press enter to replace "'"$old_string"'" with "'"$new_string"\",
391 echo 'or enter anything to skip.'
393 test "$REPLY" || python
-c "for filename in '$history_files'.split():
395 h = file(filename).read()
396 h = re.sub('$old_string\\n=+', '$new_string\\n' + '=' * len('$new_string'), h, count=1)
397 file(filename, 'w').write(h)"
398 checkin
'closed "Changes Since ..." section' $history_files
403 echo 'Creating working area...'
404 working_area
="`echo ~/tmp/docutils-release.$$`"
405 run mkdir
-p "$working_area"
407 echo 'Getting a fresh export.'
408 echo 'Press enter to proceed (or enter anything to skip)...'
410 if [ ! "$REPLY" ]; then
411 run
cd "$working_area"
412 confirm svn
export "$svnurl"
414 echo 'Building the release tarball.'
416 confirm .
/setup.py sdist
418 echo 'Tarball built.'
419 run
cp docutils
/dist
/"$tarball" .
421 echo "Testing documentation and uploading htdocs of version $new_ver..."
422 confirm upload_htdocs
423 echo "Tagging current revision..."
424 confirm svn
cp "$svnurl" "$svnroot/tags/docutils-$new_ver/" -m "$log_prefix tagging released revision"
425 echo "Uploading $tarball to SF.net."
426 confirm upload_tarball
427 echo 'Now go to https://sourceforge.net/projects/docutils/files/docutils'
428 echo 'and follow the instructions at'
429 echo 'http://docutils.sf.net/docs/dev/release.html#file-release-system'
431 echo 'Then press enter.'
435 echo 'Downloading the tarball to verify its integrity.'
437 # BUG path is wrong. project admin filemanager shows md5sum
438 confirm wget http
://sourceforge.net
/projects
/docutils
/files
/"$tarball"
439 echo 'Was the download successful?'
440 echo 'If yes, press enter to continue, otherwise enter anything to repeat'
441 echo '(it is possible that the file will show up in a few minutes).'
443 test "$REPLY" ||
break
446 echo 'Registering with PyPI...'
447 echo 'Press enter to proceed (or enter anything to skip)...'
449 if [ ! "$REPLY" ]; then
450 echo "Unpacking tarball..."
453 run
tar xzvf
"$tarball"
454 run
cd docutils-
"$new_ver"
455 confirm .
/setup.py register
463 # update __version_details__ string
464 (echo ",s/^__version_details__ = .*\$/__version_details__ = 'repository'/";
465 echo wq
) | ed docutils
/__init__.py
2> /dev
/null
466 checkin
'set __version_details__ to "repository"'
468 history_files
='HISTORY.txt RELEASE-NOTES.txt'
469 echo "Now updating the following files: $history_files"
470 add_string
="Changes Since $new_ver"
472 echo 'Press enter to add "'"$add_string"'" section,'
473 echo 'or enter anything to skip.'
475 test "$REPLY" || python
-c "for filename in '$history_files'.split():
477 h = file(filename).read()
478 h = re.sub('\n$before', '\\n$add_string\\n' + '=' * len('$add_string') +
479 '\\n\\n\\n$before', h, count=1)
480 file(filename, 'w').write(h)"
481 checkin
"added empty \"Changes Since $new_ver\" section" $history_files
483 if test "$branch_ver"; then
484 create_maintenance_branch
487 set_ver
"$new_ver" "$svn_ver"
489 echo 'Please update the web page now (web/index.txt).'
490 echo 'cd into sandbox/infrastructure'
491 echo 'and call docutils-update.local (requires linux, macosx cp misses something)'
492 echo "Press enter when you're done."
500 echo 'Run alltests.py on svn version now.'
503 # indent-tabs-mode: nil