blob: c00062aad835b79330823ad27e64ab2e57c98b03 [file] [log] [blame]
Baptiste Lepilleur1f4847c2010-02-23 07:57:38 +00001"""Tag the sandbox for release, make source and doc tarballs.
2
3Requires Python 2.6
4
5Example of invocation (use to test the script):
6python makerelease.py --force --retag 0.5.0 0.6.0-dev
7
8Example of invocation when doing a release:
9python makerelease.py 0.5.0 0.6.0-dev
10"""
11import os.path
12import subprocess
13import sys
14import doxybuild
15import subprocess
16import xml.etree.ElementTree as ElementTree
Baptiste Lepilleur7c171ee2010-02-23 08:44:52 +000017import shutil
Baptiste Lepilleur1f4847c2010-02-23 07:57:38 +000018
19SVN_ROOT = 'https://jsoncpp.svn.sourceforge.net/svnroot/jsoncpp/'
20SVN_TAG_ROOT = SVN_ROOT + 'tags/jsoncpp'
21
22def set_version( version ):
23 with open('version','wb') as f:
24 f.write( version.strip() )
25
26class SVNError(Exception):
27 pass
28
29def svn_command( command, *args ):
30 cmd = ['svn', '--non-interactive', command] + list(args)
31 print 'Running:', ' '.join( cmd )
32 process = subprocess.Popen( cmd,
33 stdout=subprocess.PIPE,
34 stderr=subprocess.STDOUT )
35 stdout = process.communicate()[0]
36 if process.returncode:
37 error = SVNError( 'SVN command failed:\n' + stdout )
38 error.returncode = process.returncode
39 raise error
40 return stdout
41
42def check_no_pending_commit():
43 """Checks that there is no pending commit in the sandbox."""
44 stdout = svn_command( 'status', '--xml' )
45 etree = ElementTree.fromstring( stdout )
46 msg = []
47 for entry in etree.getiterator( 'entry' ):
48 path = entry.get('path')
49 status = entry.find('wc-status').get('item')
50 if status != 'unversioned':
51 msg.append( 'File "%s" has pending change (status="%s")' % (path, status) )
52 if msg:
53 msg.insert(0, 'Pending change to commit found in sandbox. Commit them first!' )
54 return '\n'.join( msg )
55
56def svn_join_url( base_url, suffix ):
57 if not base_url.endswith('/'):
58 base_url += '/'
59 if suffix.startswith('/'):
60 suffix = suffix[1:]
61 return base_url + suffix
62
63def svn_check_if_tag_exist( tag_url ):
64 """Checks if a tag exist.
65 Returns: True if the tag exist, False otherwise.
66 """
67 try:
68 list_stdout = svn_command( 'list', tag_url )
69 except SVNError, e:
70 if e.returncode != 1 or not str(e).find('tag_url'):
71 raise e
72 # otherwise ignore error, meaning tag does not exist
73 return False
74 return True
75
76def svn_tag_sandbox( tag_url, message ):
77 """Makes a tag based on the sandbox revisions.
78 """
79 svn_command( 'copy', '-m', message, '.', tag_url )
80
81def svn_remove_tag( tag_url, message ):
82 """Removes an existing tag.
83 """
84 svn_command( 'delete', '-m', message, tag_url )
85
Baptiste Lepilleur7c171ee2010-02-23 08:44:52 +000086def svn_export( tag_url, export_dir ):
87 """Exports the tag_url revision to export_dir.
88 Target directory, including its parent is created if it does not exist.
89 If the directory export_dir exist, it is deleted before export proceed.
90 """
91 if os.path.isdir( export_dir ):
92 shutil.rmtree( export_dir )
93 svn_command( 'export', tag_url, export_dir )
94
Baptiste Lepilleur1f4847c2010-02-23 07:57:38 +000095def main():
96 usage = """%prog release_version next_dev_version
97Update 'version' file to release_version and commit.
98Generates the document tarball.
99Tags the sandbox revision with release_version.
100Update 'version' file to next_dev_version and commit.
101
102Performs an svn export of tag release version, and build a source tarball.
103
104Must be started in the project top directory.
105"""
106 from optparse import OptionParser
107 parser = OptionParser(usage=usage)
108 parser.allow_interspersed_args = False
109 parser.add_option('--dot', dest="dot_path", action='store', default=doxybuild.find_program('dot'),
110 help="""Path to GraphViz dot tool. Must be full qualified path. [Default: %default]""")
111 parser.add_option('--doxygen', dest="doxygen_path", action='store', default=doxybuild.find_program('doxygen'),
112 help="""Path to Doxygen tool. [Default: %default]""")
113 parser.add_option('--force', dest="ignore_pending_commit", action='store_true', default=False,
114 help="""Ignore pending commit. [Default: %default]""")
115 parser.add_option('--retag', dest="retag_release", action='store_true', default=False,
116 help="""Overwrite release existing tag if it exist. [Default: %default]""")
117 parser.enable_interspersed_args()
118 options, args = parser.parse_args()
119
120 if len(args) < 1:
121 parser.error( 'release_version missing on command-line.' )
122 release_version = args[0]
123
124 if options.ignore_pending_commit:
125 msg = ''
126 else:
127 msg = check_no_pending_commit()
128 if not msg:
129 print 'Setting version to', release_version
130 set_version( release_version )
131 tag_url = svn_join_url( SVN_TAG_ROOT, release_version )
Baptiste Lepilleur7c171ee2010-02-23 08:44:52 +0000132## if svn_check_if_tag_exist( tag_url ):
133## if options.retag_release:
134## svn_remove_tag( tag_url, 'Overwriting previous tag' )
135## else:
136## print 'Aborting, tag %s already exist. Use --retag to overwrite it!' % tag_url
137## sys.exit( 1 )
138## svn_tag_sandbox( tag_url, 'Release ' + release_version )
139## print 'Generated doxygen document...'
140## doxybuild.build_doc( options, make_release=True )
141 svn_export( tag_url, 'dist/distcheck' )
Baptiste Lepilleur1f4847c2010-02-23 07:57:38 +0000142 #@todo:
Baptiste Lepilleur7c171ee2010-02-23 08:44:52 +0000143 # fix-eol
Baptiste Lepilleur1f4847c2010-02-23 07:57:38 +0000144 # source tarball
145 # decompress source tarball
146 # ?compile & run & check
147 # ?upload documentation
148 else:
149 sys.stderr.write( msg + '\n' )
150
151if __name__ == '__main__':
152 main()