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.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 "WARN: Python $py_ver (python$py_ver) not found."
124 echo -n 'Clearing $PYTHONPATH... '
127 echo -n 'Checking whether we are in a working copy... '
128 if [ -f HISTORY.txt
]; then
131 echo "no (HISTORY.txt doesn't exist)"
133 echo 'Please cd to a working copy before running this script.'
136 echo -n 'Subversion binary to use: '
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|//[^/]\+/[^/]\+||'`"
152 svnurl
="`$svn info . | grep ^URL: | sed 's/URL: //'`"
154 if test -z "$svnurl"; then
155 echo 'Unable to detect Subversion URL. Aborting.'
158 echo "Subversion URL: $svnurl"
159 if ! echo "$svnurl" |
grep -q 'branches\|trunk'; then
160 echo 'Subversion URL contains neither "branches" nor "trunk".'
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.'
170 echo -n 'Detecting current Docutils version... '
171 old_ver
="`python -c 'import docutils; print docutils.__version__'`"
174 # log_prefix is for SVN logs.
175 log_prefix
="Release $new_ver:"
176 echo "New version number (for releasing): $new_ver"
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%:*}"
185 echo "New Subversion version number (after releasing): $svn_ver"
186 echo -n 'Create maintenance branch: '
187 if test "$branch_ver"; then
189 echo "New version number on maintenance branch: $branch_ver"
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
199 echo 'Working copy path contains neither "branches" nor "trunk".'
200 echo 'You need a full checkout in order to branch.'
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.'
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
/
220 confirm
tar xzvf
"../$tarball"
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`"
227 for py_ver in '"$python_versions"'; do
228 echo "Deleting and installing Docutils on Python $py_ver."
231 site_packages="/usr/local/lib/python$py_ver/site-packages"
232 echo "BUG prefers /usr/local too /usr"
233 if test ! -d "$site_packages"; then
234 site_packages="/usr/lib/python$py_ver/site-packages"
236 if test ! -d "$site_packages"; then
237 echo "Error: \"$site_packages\" does not exist."
240 if test -e "$site_packages/docutils-test"; then
241 echo "Error: \"$site_packages/docutils-test\" exists."
242 echo "removing left over from previous release. Ctrl-C to abort."
244 rm -rf $site_packages/docutils-test
246 rm -rfv /usr/{local,}lib/python$py_ver/site-packages/{docutils'"$extras"'}
247 echo "TODO for python3 rm local build, but building takes a long time then "
248 python$py_ver setup.py install
250 echo "Copying the test suite to the site-packages directory of Python $py_ver."
251 echo "TODO for python3 copy test3"
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 "WARNING 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 # BUG user grubert hardcoded
290 # short path "/home/frs/project/docutils/docutils/" also exists
291 scp
-r $new_ver grubert
,docutils@frs.sourceforge.net
:/home
/frs
/project
/d
/do
/docutils
/docutils
/
292 echo 'Upload completed.'
295 function upload_htdocs
()
297 # Assume we have the tarball in the working area.
298 run
cd "$working_area"
299 echo "Upload htdocs for $new_ver"
302 confirm
tar xzvf
"../$tarball"
303 run
cd docutils-
"$new_ver"/tools
/
304 echo "BUG no docutils installation left."
305 echo "DO NOT let call but manually in $(pwd)"
306 confirm .
/buildhtml.py
--local ..
307 confirm .
/buildhtml.py ..
/docs
309 echo '$ find -name test -type d -prune -o -name \*.css -print0 \
310 -o -name \*.html -print0 -o -name \*.txt -print0 \
311 | tar -cjvf docutils-docs.tar.bz2 -T - --null'
312 find -name test -type d
-prune -o -name \
*.css
-print0 \
313 -o -name \
*.html
-print0 -o -name \
*.txt
-print0 \
314 |
tar -cjvf docutils-docs.
tar.bz2
-T - --null
315 echo 'Upload docs to SF.net...'
316 echo 'Press enter (or enter anything to skip).'
318 if [ ! "$REPLY" ]; then
321 tar xjvf ..
/docutils-docs.
tar.bz2
323 chmod -R g
+rw
$new_ver
324 scp
-r -p -C $new_ver web.sourceforge.net
:/home
/groups
/d
/do
/docutils
/htdocs
328 function create_maintenance_branch
()
330 echo 'Creating maintenance branch.'
331 branch_name
="docutils-$new_ver"
332 echo "Branch name: $branch_name"
333 branch_url
="$svnroot/branches/$branch_name"
334 echo "Branch URL: $branch_url"
335 confirm svn
cp "$svnurl" "$branch_url" -m \
336 "$log_prefix created maintenance branch for version $new_ver"
339 cd branches
/"$branch_name"
340 set_ver
"$new_ver" "$branch_ver"
352 echo "Press enter to run stage $1 (or enter anything to skip this stage)."
354 if [ ! "$REPLY" ]; then
356 if [ "$1" == 1 ]; then
358 elif [ "$1" == 2 ]; then
360 elif [ "$1" == 3 ]; then
363 echo 'Invalid stage.'
368 echo "Stage $1 completed."
370 echo "Skipped stage $1."
379 # update __version_details__ string
380 (echo ",s/^__version_details__ = .*\$/__version_details__ = 'release'/";
381 echo wq
) | ed docutils
/__init__.py
2> /dev
/null
382 set_ver
"$old_ver" "$new_ver"
384 history_files
='HISTORY.txt RELEASE-NOTES.txt'
385 echo "Now updating the following files: $history_files"
386 old_string
="Changes Since [0-9.]+"
387 new_string
="Release $new_ver (`date --utc --iso-8601`)"
388 echo 'Press enter to replace "'"$old_string"'" with "'"$new_string"\",
389 echo 'or enter anything to skip.'
391 test "$REPLY" || python
-c "for filename in '$history_files'.split():
393 h = file(filename).read()
394 h = re.sub('$old_string\\n=+', '$new_string\\n' + '=' * len('$new_string'), h, count=1)
395 file(filename, 'w').write(h)"
396 checkin
'closed "Changes Since ..." section' $history_files
401 echo 'Creating working area...'
402 working_area
="`echo ~/tmp/docutils-release.$$`"
403 run mkdir
-p "$working_area"
405 echo 'Getting a fresh export.'
406 echo 'Press enter to proceed (or enter anything to skip)...'
408 if [ ! "$REPLY" ]; then
409 run
cd "$working_area"
410 confirm svn
export "$svnurl"
412 echo 'Building the release tarball.'
414 confirm .
/setup.py sdist
416 echo 'Tarball built.'
417 run
cp docutils
/dist
/"$tarball" .
418 echo 'BETTER run release-test.sh manually for each installed python version.'
420 echo "Testing documentation and uploading htdocs of version $new_ver..."
421 confirm upload_htdocs
422 echo "Tagging current revision..."
423 confirm svn
cp "$svnurl" "$svnroot/tags/docutils-$new_ver/" -m "$log_prefix tagging released revision"
424 echo "Uploading $tarball to SF.net."
425 confirm upload_tarball
426 echo 'Now go to https://sourceforge.net/projects/docutils/files/docutils'
427 echo 'and follow the instructions at'
428 echo 'http://docutils.sf.net/docs/dev/release.html#file-release-system'
430 echo 'Then press enter.'
434 echo 'Downloading the tarball to verify its integrity.'
436 # BUG path is wrong. project admin filemanager shows md5sum
437 confirm wget http
://sourceforge.net
/projects
/docutils
/files
/"$tarball"
438 echo 'Was the download successful?'
439 echo 'If yes, press enter to continue, otherwise enter anything to repeat'
440 echo '(it is possible that the file will show up in a few minutes).'
442 test "$REPLY" ||
break
445 echo 'Registering with PyPI...'
446 echo 'TODO upload to pypi or set download url for this release'
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