9 from string
import Template
10 from optparse
import OptionParser
12 last_tag_pattern
= 'EMPATHY_3_9*'
13 upload_server
= 'master.gnome.org'
15 $name $version is now available for download from:
24 You can visit the project web site:
39 f
= open('config.h', 'r')
44 key
['package'] = '#define PACKAGE_NAME "'
45 key
['version'] = '#define PACKAGE_VERSION "'
46 key
['bugreport'] = '#define PACKAGE_BUGREPORT "'
48 for line
in s
.splitlines(1):
49 if line
.startswith(key
['package']):
50 p1
= len(key
['package'])
52 self
.package_name
= line
[p1
:p2
]
53 elif line
.startswith(key
['version']):
54 p1
= len(key
['version'])
56 self
.package_version
= line
[p1
:p2
]
57 elif line
.startswith(key
['bugreport']):
59 p1
= line
.rfind('=') + 1
60 self
.package_module
= line
[p1
:p2
]
62 first
= self
.package_version
.find('.')
63 second
= self
.package_version
.find('.', first
+ 1)
64 if first
== -1 or second
== -1 or first
== second
:
65 version_dir
= self
.package_version
67 version_dir
= self
.package_version
[:second
]
68 self
.package_dl_url
= 'http://download.gnome.org/sources/%s/%s/' % (self
.package_name
.lower(),
70 tags_str
= self
.exec_cmd('git tag -l %s' % (last_tag_pattern
))
71 tags
= tags_str
.splitlines()
72 self
.last_tag
= tags
[len(tags
)-1]
74 def exec_cmd(self
,cmd
):
75 return os
.popen(cmd
).read()
78 f
= open ('NEWS', 'r')
81 start
= s
.find ('NEW in '+ self
.package_version
)
83 start
= s
.find ('\n', start
) + 1
84 start
= s
.find ('\n', start
) + 1
85 end
= s
.find ('NEW in', start
) - 1
86 return s
[start
:end
].strip()
88 def get_md5sums(self
):
91 cmd
= 'md5sum %s-%s.tar.xz' % (self
.package_name
.lower(), self
.package_version
)
92 md5sums
+= self
.exec_cmd(cmd
)
96 def get_bugzilla_info(self
):
97 query
= 'http://bugzilla.gnome.org/browse.cgi?product=%s' % (self
.package_module
)
98 f
= urllib
.urlopen(query
)
106 end
= s
.find(s2
, i
+ 1)
107 description
= s
[start
:end
]
112 i
= s
.rfind(s1
, 0, i
)
115 end
= s
.find(s2
, start
)
116 project_url
= s
[start
:end
]
118 return (description
, project_url
)
120 def get_release_notes(self
):
121 name
= self
.package_name
122 version
= self
.package_version
123 download
= self
.package_dl_url
124 md5sums
= self
.get_md5sums()
125 (about
, website
) = self
.get_bugzilla_info()
126 news
= self
.get_news()
127 footer
= '%s\n%s team' % (datetime
.date
.today().strftime('%d %B %Y'),\
130 t
= Template(template
)
131 return t
.substitute(locals())
133 def get_translations(self
, cmd
, format
):
135 files_str
= self
.exec_cmd(cmd
)
136 files
= files_str
.splitlines()
138 f
= line
[line
.rfind(' '):]
139 lang
= f
[f
.rfind('/')+1:f
.rfind('.')]
140 commit_str
= self
.exec_cmd("git log %s.. %s" % (self
.last_tag
, f
))
145 for line
in commit_str
.splitlines():
146 if line
.startswith('Author:'):
149 author
= line
[p1
:p2
].strip()
151 if authors
.find(author
) != -1:
157 translations
+= format
% (lang
, authors
)
160 def get_bug_author(self
, bug_number
):
161 cmd
= 'git log %s.. | grep -B 20 -E \
162 "(bug %s|#%s)|bugzilla.gnome.org/show_bug.cgi\?id=%s"' \
163 ' | tac | grep ^Author: | head -1' \
164 % (self
.last_tag
, bug_number
, bug_number
, bug_number
)
165 line
= self
.exec_cmd (cmd
)
169 return line
[p1
:p2
].strip()
172 commit_str
= self
.exec_cmd('git show %s' % (self
.last_tag
))
173 for line
in commit_str
.splitlines():
174 if line
.startswith('Date:'):
175 time_str
= line
[5:line
.rfind('+')].strip()
176 t
= time
.strptime(time_str
)
177 last_tag_date
= time
.strftime('%Y-%m-%d', t
)
180 query
= 'http://bugzilla.gnome.org/buglist.cgi?' \
181 'ctype=csv&product=empathy&' \
182 'bug_status=RESOLVED,CLOSED,VERIFIED&resolution=FIXED&' \
183 'chfieldfrom=%s&chfieldto=Now' % (last_tag_date
)
184 f
= urllib
.urlopen(query
)
191 reader
= csv
.reader(s
.splitlines(1))
192 header
= reader
.next()
198 if col
== 'short_short_desc':
204 bug_number
= row
[col_bug_id
]
205 description
= row
[col_description
]
206 author
= self
.get_bug_author(bug_number
)
207 bugs
+= ' - Fixed #%s, %s' % (bug_number
, description
)
209 bugs
+= ' (%s)' % (author
)
213 def generate_news(self
):
214 translations
= self
.get_translations("ls -l po/*.po", \
215 " - Updated %s Translation (%s)\n")
216 help_translations
= self
.get_translations("ls -l help/*/*.po", \
217 " - Updated %s Documentation translation (%s)\n")
218 bugs
= self
.get_bugs()
220 news
= 'NEW in '+ self
.package_version
221 line
= '=' * len(news
)
222 today
= datetime
.date
.today()
223 news
+= ' (%s)\n%s\n' % (today
.strftime('%d/%m/%Y'),line
)
225 news
+= 'Bugs fixed:\n' + bugs
+ '\n'
226 if translations
!= '':
227 news
+= 'Translations:\n' + translations
+ '\n'
228 if help_translations
!= '':
229 news
+= 'Documentation translations:\n' + \
230 help_translations
+ '\n'
234 def write_news(self
):
235 news
= self
.generate_news()
237 f
= open ('/tmp/NEWS', 'w')
241 self
.exec_cmd('cat NEWS >> /tmp/NEWS')
242 self
.exec_cmd('mv /tmp/NEWS .')
245 new_tag
= self
.package_name
.upper() + '_' +\
246 self
.package_version
.replace('.', '_')
247 self
.exec_cmd('git tag -m "Tagged for release %s." %s' % ( self
.package_version
, new_tag
))
249 def _get_username(self
):
250 username
= os
.environ
.get('GNOME_ACCOUNT_NAME')
251 if username
is not None:
257 def upload_tarball(self
):
258 username
= self
._get
_username
()
259 tarball
= '%s-%s.tar.xz' % (self
.package_name
.lower(), self
.package_version
)
261 cmd
= 'scp %s %s@%s:' % (tarball
, username
, upload_server
)
264 cmd
= 'ssh %s@%s install-module -u %s' % (username
, upload_server
, tarball
)
267 def send_email(self
):
268 notes
= self
.get_release_notes()
271 ' --cc telepathy@lists.freedesktop.org' \
272 ' --subject "ANNOUNCE: Empathy %s"' \
274 ' gnome-announce-list@gnome.org' % (self
.package_version
,
275 notes
.replace('"', '\\"'))
280 self
.upload_tarball()
283 if __name__
== '__main__':
285 parser
= OptionParser()
286 parser
.add_option("-n", "--print-news", action
="store_true",\
287 dest
="print_news", help="Generate and print news")
288 parser
.add_option("-p", "--print-notes", action
="store_true",\
289 dest
="print_notes", help="Generate and print the release notes")
290 parser
.add_option("-w", "--write-news", action
="store_true",\
291 dest
="write_news", help="Generate and write news into the NEWS file")
292 parser
.add_option("-r", "--release", action
="store_true",\
293 dest
="release", help="Release the tarball")
294 parser
.add_option("-e", "--email", action
="store_true",\
295 dest
="email", help="Send the release announce email")
297 (options
, args
) = parser
.parse_args ()
298 if (options
.print_news
):
299 print p
.generate_news ()
300 if (options
.print_notes
):
301 print p
.get_release_notes ()
302 if (options
.write_news
):
304 if (options
.release
):