8 from string
import Template
9 from optparse
import OptionParser
12 upload_server
= 'master.gnome.org'
14 $name $version is now available for download from:
23 You can visit the project web site:
38 f
= open('config.h', 'r')
43 key
['package'] = '#define PACKAGE_NAME "'
44 key
['version'] = '#define PACKAGE_VERSION "'
45 key
['bugreport'] = '#define PACKAGE_BUGREPORT "'
47 for line
in s
.splitlines(1):
48 if line
.startswith(key
['package']):
49 p1
= len(key
['package'])
51 self
.package_name
= line
[p1
:p2
]
52 elif line
.startswith(key
['version']):
53 p1
= len(key
['version'])
55 self
.package_version
= line
[p1
:p2
]
56 elif line
.startswith(key
['bugreport']):
58 p1
= line
.rfind('=') + 1
59 self
.package_module
= line
[p1
:p2
]
61 first
= self
.package_version
.find('.')
62 second
= self
.package_version
.find('.', first
+ 1)
63 if first
== -1 or second
== -1 or first
== second
:
64 version_dir
= self
.package_version
66 version_dir
= self
.package_version
[:second
]
67 self
.package_dl_url
= 'http://download.gnome.org/sources/%s/%s/' % (self
.package_name
.lower(),
69 def exec_cmd(self
,cmd
):
70 return os
.popen(cmd
).read()
73 f
= open ('NEWS', 'r')
76 start
= s
.find ('NEW in '+ self
.package_version
)
78 start
= s
.find ('\n', start
) + 1
79 start
= s
.find ('\n', start
) + 1
80 end
= s
.find ('NEW in', start
) - 1
81 return s
[start
:end
].strip()
83 def get_md5sums(self
):
86 cmd
= 'md5sum %s-%s.tar.gz' % (self
.package_name
.lower(), self
.package_version
)
87 md5sums
+= self
.exec_cmd(cmd
)
89 cmd
= 'md5sum %s-%s.tar.bz2' % (self
.package_name
.lower(), self
.package_version
)
90 md5sums
+= self
.exec_cmd(cmd
).strip()
94 def get_bugzilla_info(self
):
95 query
= 'http://bugzilla.gnome.org/browse.cgi?product=%s' % (self
.package_module
)
96 f
= urllib
.urlopen(query
)
104 end
= s
.find(s2
, i
+ 1)
105 description
= s
[start
:end
]
113 end
= s
.find(s2
, start
)
114 project_url
= s
[start
:end
]
116 return (description
, project_url
)
118 def get_release_notes(self
):
119 name
= self
.package_name
120 version
= self
.package_version
121 download
= self
.package_dl_url
122 md5sums
= self
.get_md5sums()
123 (about
, website
) = self
.get_bugzilla_info()
124 news
= self
.get_news()
125 footer
= '%s\n%s team' % (datetime
.date
.today().strftime('%d %B %Y'),\
128 t
= Template(template
)
129 return t
.substitute(locals())
131 def get_last_tag(self
):
132 tags_str
= self
.exec_cmd('git-tag')
133 tags
= tags_str
.splitlines()
135 return tags
[len(tags
)-1]
137 def parse_commit(self
, ref
, author
, date
, message
):
138 p1
= message
.rfind('(')
139 p2
= message
.rfind (')')
140 if len(message
) - p2
<= 2:
141 author
= message
[p1
+1:p2
]
142 message
= message
[:p1
]
144 msg
= message
.lower()
145 if msg
.find('translation') != -1 and\
146 msg
.find('updated') != -1:
147 self
.translations
+= ' - ' + message
+ ' (' + author
+ ').\n'
148 elif message
.find('#') != -1:
149 p1
= message
.find('#')
152 p2
= message
.find(' ', p1
)
153 bug
.number
= message
[p1
+1:p2
]
155 self
.bug_commits
.append(bug
)
156 p1
= message
.find('#', p2
)
158 self
.commits
+= ' - ' + message
+ ' (' + author
+ ').\n'
160 def query_bug_commits(self
):
162 for bug
in self
.bug_commits
:
163 bugs
+= bug
.number
+ ','
165 # Bugzilla query to use
166 query
= 'http://bugzilla.gnome.org/buglist.cgi?ctype=csv' \
167 '&bug_status=RESOLVED,CLOSED,VERIFIED' \
168 '&resolution=FIXED' \
169 '&bug_id=' + bugs
.replace(',', '%2c')
171 f
= urllib
.urlopen(query
)
178 reader
= csv
.reader(s
.splitlines(1))
179 header
= reader
.next()
185 if col
== 'short_short_desc':
190 bug_number
= row
[col_bug_id
]
191 description
= row
[col_description
]
193 for bug
in self
.bug_commits
:
194 if bug
.number
== bug_number
:
195 self
.bugs
+= ' - Fixed #%s, %s (%s)\n' % (bug
.number
, description
, bug
.author
)
198 def get_commits(self
):
200 self
.translations
= ''
202 self
.bug_commits
= []
203 last_tag
= self
.get_last_tag()
206 changes
= self
.exec_cmd ("git-log " + last_tag
+ "..")
207 for line
in changes
.splitlines(1):
208 if line
.startswith('commit'):
210 self
.parse_commit (ref
, author
, date
, message
)
212 ref
= line
[p1
:].strip()
216 elif line
.startswith('Author:'):
219 author
= line
[p1
:p2
].strip()
220 elif line
.startswith('Date:'):
222 date
= line
[p1
:].strip()
223 elif line
.startswith(' git-svn-id:'):
225 elif line
.startswith('Merge:'):
235 self
.query_bug_commits ()
238 new_tag
= self
.package_name
.upper() + '_' +\
239 self
.package_version
.replace('.', '_')
241 url1
= self
.exec_cmd('git-config svn-remote.svn.url').strip()
242 url2
= url1
[:url1
.rfind('/')] + '/tags/' + new_tag
243 self
.exec_cmd('svn copy %s %s -m "Tagged for release %s."' % (url1
, url2
, self
.package_version
))
245 self
.exec_cmd('git-tag -m "Tagged for release %s." %s' % ( self
.package_version
, new_tag
))
247 def generate_news(self
):
249 news
= 'NEW in '+ self
.package_version
+ '\n==============\n'
250 news
+= self
.commits
+ '\nBugs fixed:\n' + self
.bugs
+ '\nTranslations:\n' + self
.translations
+ '\n'
254 def write_news(self
):
255 news
= self
.generate_news()
257 f
= open ('/tmp/NEWS', 'w')
261 self
.exec_cmd('cat NEWS >> /tmp/NEWS')
262 self
.exec_cmd('mv /tmp/NEWS .')
264 def upload_tarball(self
):
265 tarball
= '%s-%s.tar.gz' % (self
.package_name
.lower(), self
.package_version
)
267 cmd
= 'scp %s %s@%s:' % (tarball
, username
, upload_server
)
270 cmd
= 'ssh %s@%s install-module -u %s' % (username
, upload_server
, tarball
)
273 def send_email(self
):
274 notes
= self
.get_release_notes()
276 ' --cc telepathy@lists.freedesktop.org' \
277 ' --subject "ANNOUNCE: Empathy %s"' \
279 ' gnome-announce-list@gnome.org' % (self
.package_version
,
280 notes
.replace('"', '\\"'))
285 self
.upload_tarball()
288 if __name__
== '__main__':
290 parser
= OptionParser()
291 parser
.add_option("-n", "--print-news", action
="store_true",\
292 dest
="print_news", help="Generate and print news")
293 parser
.add_option("-p", "--print-notes", action
="store_true",\
294 dest
="print_notes", help="Generate and print the release notes")
295 parser
.add_option("-w", "--write-news", action
="store_true",\
296 dest
="write_news", help="Generate and write news into the NEWS file")
297 parser
.add_option("-r", "--release", action
="store_true",\
298 dest
="release", help="Release the tarball")
299 parser
.add_option("-e", "--email", action
="store_true",\
300 dest
="email", help="Send the release announce email")
302 (options
, args
) = parser
.parse_args ()
303 if (options
.print_news
):
304 print p
.generate_news ()
305 if (options
.print_notes
):
306 print p
.get_release_notes ()
307 if (options
.write_news
):
309 if (options
.release
):