Merge lp:~cjwatson/launchpad/git-version-info into lp:launchpad
- git-version-info
- Merge into devel
Proposed by
Colin Watson
Status: | Merged |
---|---|
Merged at revision: | 18197 |
Proposed branch: | lp:~cjwatson/launchpad/git-version-info |
Merge into: | lp:launchpad |
Diff against target: |
992 lines (+168/-245) 24 files modified
.bzrignore (+2/-1) Makefile (+7/-7) database/schema/upgrade.py (+33/-20) lib/lp/app/browser/folder.py (+3/-3) lib/lp/app/templates/base-layout-macros.pt (+5/-6) lib/lp/app/templates/base-layout.pt (+4/-3) lib/lp/app/templates/oops.pt (+2/-2) lib/lp/app/tests/test_versioninfo.py (+5/-5) lib/lp/app/versioninfo.py (+20/-12) lib/lp/services/mail/sendmail.py (+2/-2) lib/lp/services/webapp/errorlog.py (+4/-38) lib/lp/services/webapp/errorlog.zcml (+1/-7) lib/lp/services/webapp/interfaces.py (+0/-18) lib/lp/services/webapp/publisher.py (+2/-2) lib/lp/services/webapp/servers.py (+1/-1) lib/lp/services/webapp/tests/test_errorlog.py (+1/-78) lib/lp/services/webapp/tests/test_servers.py (+1/-1) lib/lp/services/webhooks/model.py (+2/-2) lib/lp/services/webhooks/tests/test_job.py (+6/-4) lib/lp/services/webservice/configuration.py (+2/-2) lib/lp/testing/yuixhr.py (+7/-7) lib/lp/translations/utilities/gettext_po_parser.py (+4/-4) scripts/update-version-info.sh (+42/-15) utilities/create-lp-wadl-and-apidoc.py (+12/-5) |
To merge this branch: | bzr merge lp:~cjwatson/launchpad/git-version-info |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
William Grant | code | Approve | |
Review via email: mp+305701@code.launchpad.net |
Commit message
Handle running from a Git working tree.
Description of the change
Handle running from a Git working tree.
To post a comment you must log in.
Revision history for this message
William Grant (wgrant) : | # |
review:
Approve
(code)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file '.bzrignore' |
2 | --- .bzrignore 2013-04-15 02:36:07 +0000 |
3 | +++ .bzrignore 2016-09-19 14:06:13 +0000 |
4 | @@ -1,5 +1,6 @@ |
5 | +*.pyc |
6 | .tags |
7 | -bzr-version-info.py |
8 | +version-info.py |
9 | logs/* |
10 | +* |
11 | sourcecode/* |
12 | |
13 | === added symlink '.gitignore' |
14 | === target is u'.bzrignore' |
15 | === modified file 'Makefile' |
16 | --- Makefile 2015-09-08 02:31:49 +0000 |
17 | +++ Makefile 2016-09-19 14:06:13 +0000 |
18 | @@ -35,7 +35,7 @@ |
19 | |
20 | CONVOY_ROOT?=/srv/launchpad.dev/convoy |
21 | |
22 | -BZR_VERSION_INFO = bzr-version-info.py |
23 | +VERSION_INFO = version-info.py |
24 | |
25 | APIDOC_DIR = lib/canonical/launchpad/apidoc |
26 | APIDOC_TMPDIR = $(APIDOC_DIR).tmp/ |
27 | @@ -73,7 +73,7 @@ |
28 | hosted_branches: $(PY) |
29 | $(PY) ./utilities/make-dummy-hosted-branches |
30 | |
31 | -$(API_INDEX): $(BZR_VERSION_INFO) $(PY) |
32 | +$(API_INDEX): $(VERSION_INFO) $(PY) |
33 | $(RM) -r $(APIDOC_DIR) $(APIDOC_DIR).tmp |
34 | mkdir -p $(APIDOC_DIR).tmp |
35 | LPCONFIG=$(LPCONFIG) $(PY) ./utilities/create-lp-wadl-and-apidoc.py \ |
36 | @@ -238,7 +238,7 @@ |
37 | |
38 | $(subst $(PY),,$(BUILDOUT_BIN)): $(PY) |
39 | |
40 | -compile: $(PY) $(BZR_VERSION_INFO) |
41 | +compile: $(PY) $(VERSION_INFO) |
42 | ${SHHH} $(MAKE) -C sourcecode build PYTHON=${PYTHON} \ |
43 | LPCONFIG=${LPCONFIG} |
44 | ${SHHH} LPCONFIG=${LPCONFIG} ${PY} -t buildmailman.py |
45 | @@ -295,10 +295,10 @@ |
46 | stop_librarian: |
47 | bin/killservice librarian |
48 | |
49 | -$(BZR_VERSION_INFO): |
50 | - scripts/update-bzr-version-info.sh |
51 | +$(VERSION_INFO): |
52 | + scripts/update-version-info.sh |
53 | |
54 | -support_files: $(API_INDEX) $(BZR_VERSION_INFO) |
55 | +support_files: $(API_INDEX) $(VERSION_INFO) |
56 | |
57 | # Intended for use on developer machines |
58 | start: inplace stop support_files initscript-start |
59 | @@ -393,7 +393,7 @@ |
60 | $(RM) -r $(APIDOC_DIR) |
61 | $(RM) -r $(APIDOC_DIR).tmp |
62 | $(RM) -r build |
63 | - $(RM) $(BZR_VERSION_INFO) |
64 | + $(RM) $(VERSION_INFO) |
65 | $(RM) +config-overrides.zcml |
66 | $(RM) -r /var/tmp/builddmaster \ |
67 | /var/tmp/bzrsync \ |
68 | |
69 | === modified file 'database/schema/upgrade.py' |
70 | --- database/schema/upgrade.py 2014-08-29 01:34:04 +0000 |
71 | +++ database/schema/upgrade.py 2016-09-19 14:06:13 +0000 |
72 | @@ -1,6 +1,6 @@ |
73 | #!/usr/bin/python -S |
74 | # |
75 | -# Copyright 2009 Canonical Ltd. This software is licensed under the |
76 | +# Copyright 2009-2016 Canonical Ltd. This software is licensed under the |
77 | # GNU Affero General Public License version 3 (see the file LICENSE). |
78 | |
79 | """ |
80 | @@ -15,6 +15,7 @@ |
81 | from optparse import OptionParser |
82 | import os.path |
83 | import re |
84 | +import subprocess |
85 | from textwrap import dedent |
86 | |
87 | from bzrlib.branch import Branch |
88 | @@ -31,7 +32,7 @@ |
89 | ) |
90 | |
91 | |
92 | -SCHEMA_DIR = os.path.dirname(__file__) |
93 | +SCHEMA_DIR = os.path.dirname(os.path.abspath(__file__)) |
94 | |
95 | |
96 | def main(con=None): |
97 | @@ -161,7 +162,7 @@ |
98 | |
99 | # Repair patch timestamps if necessary. |
100 | cur.execute( |
101 | - FIX_PATCH_TIMES_POST_SQL % sqlvalues(*get_bzr_details())) |
102 | + FIX_PATCH_TIMES_POST_SQL % sqlvalues(*get_vcs_details())) |
103 | |
104 | # Update comments. |
105 | apply_comments(con) |
106 | @@ -245,26 +246,38 @@ |
107 | log.debug("Skipping comments.sql per command line settings") |
108 | |
109 | |
110 | -_bzr_details_cache = None |
111 | - |
112 | - |
113 | -def get_bzr_details(): |
114 | - """Return (branch_nick, revno, revision_id) of this Bazaar branch. |
115 | +_vcs_details_cache = None |
116 | + |
117 | + |
118 | +def get_vcs_details(): |
119 | + """Return (branch_nick, revno, revision_id) of this VCS branch. |
120 | + |
121 | + If this is a Git branch, then revno will be None. |
122 | |
123 | Returns (None, None, None) if the tree this code is running from |
124 | - is not a Bazaar branch. |
125 | + is not a VCS branch. |
126 | """ |
127 | - global _bzr_details_cache |
128 | - if _bzr_details_cache is None: |
129 | - try: |
130 | - branch = Branch.open_containing(SCHEMA_DIR)[0] |
131 | - revno, revision_id = branch.last_revision_info() |
132 | - branch_nick = branch.get_config().get_nickname() |
133 | - except NotBranchError: |
134 | - log.warning("Not a Bazaar branch - branch details unavailable") |
135 | - revision_id, revno, branch_nick = None, None, None |
136 | - _bzr_details_cache = (branch_nick, revno, revision_id) |
137 | - return _bzr_details_cache |
138 | + global _vcs_details_cache |
139 | + if _vcs_details_cache is None: |
140 | + top = os.path.dirname(os.path.dirname(SCHEMA_DIR)) |
141 | + if os.path.exists(os.path.join(top, ".git")): |
142 | + branch_nick = subprocess.check_output( |
143 | + ["git", "rev-parse", "--abbrev-ref", "HEAD"], |
144 | + universal_newlines=True).rstrip("\n") |
145 | + revno = None |
146 | + revision_id = subprocess.check_output( |
147 | + ["git", "rev-parse", "HEAD"], |
148 | + universal_newlines=True).rstrip("\n") |
149 | + else: |
150 | + try: |
151 | + branch = Branch.open_containing(SCHEMA_DIR)[0] |
152 | + revno, revision_id = branch.last_revision_info() |
153 | + branch_nick = branch.get_config().get_nickname() |
154 | + except NotBranchError: |
155 | + log.warning("Not a Bazaar branch - branch details unavailable") |
156 | + revision_id, revno, branch_nick = None, None, None |
157 | + _vcs_details_cache = (branch_nick, revno, revision_id) |
158 | + return _vcs_details_cache |
159 | |
160 | |
161 | if __name__ == '__main__': |
162 | |
163 | === modified symlink 'lib/launchpadversioninfo.py' |
164 | === target changed u'../bzr-version-info.py' => u'../version-info.py' |
165 | === modified file 'lib/lp/app/browser/folder.py' |
166 | --- lib/lp/app/browser/folder.py 2015-10-26 14:54:43 +0000 |
167 | +++ lib/lp/app/browser/folder.py 2016-09-19 14:06:13 +0000 |
168 | @@ -1,4 +1,4 @@ |
169 | -# Copyright 2009 Canonical Ltd. This software is licensed under the |
170 | +# Copyright 2009-2016 Canonical Ltd. This software is licensed under the |
171 | # GNU Affero General Public License version 3 (see the file LICENSE). |
172 | |
173 | __metaclass__ = type |
174 | @@ -43,7 +43,7 @@ |
175 | """View that gives access to the files in a folder. |
176 | |
177 | The URL to the folder can start with an optional path step like |
178 | - /revNNN/ where NNN is one or more digits. This path step will |
179 | + /revNNN/ where NNN is one or more hex digits. This path step will |
180 | be ignored. It is useful for having a different path for |
181 | all resources being served, to ensure that we don't use cached |
182 | files in browsers. |
183 | @@ -52,7 +52,7 @@ |
184 | to True to change this. |
185 | """ |
186 | |
187 | - rev_part_re = re.compile('rev\d+$') |
188 | + rev_part_re = re.compile('rev[0-9a-f]+$') |
189 | |
190 | export_subdirectories = False |
191 | |
192 | |
193 | === modified file 'lib/lp/app/templates/base-layout-macros.pt' |
194 | --- lib/lp/app/templates/base-layout-macros.pt 2016-03-14 00:45:42 +0000 |
195 | +++ lib/lp/app/templates/base-layout-macros.pt 2016-09-19 14:06:13 +0000 |
196 | @@ -35,8 +35,8 @@ |
197 | |
198 | <metal:load-javascript define-macro="load-javascript" |
199 | tal:define=" |
200 | - revno modules/lp.app.versioninfo/revno | string:unknown; |
201 | - icingroot string:/+icing/rev${revno}; |
202 | + revision modules/lp.app.versioninfo/revision | string:unknown; |
203 | + icingroot string:/+icing/rev${revision}; |
204 | combo_url view/combo_url; |
205 | devmode modules/lp.services.config/config/devmode; |
206 | yui_version view/yui_version; |
207 | @@ -109,7 +109,6 @@ |
208 | |
209 | <metal:page-javascript define-macro="page-javascript" |
210 | tal:define=" |
211 | - revno modules/lp.app.versioninfo/revno | string:unknown; |
212 | devmode modules/lp.services.config/config/devmode;"> |
213 | <tal:comment replace="nothing"> |
214 | Load and initialize the common script used by all pages. |
215 | @@ -194,8 +193,8 @@ |
216 | |
217 | <metal:launchpad-stylesheet-3-0 define-macro="launchpad-stylesheet-3-0" |
218 | tal:define=" |
219 | - revno modules/lp.app.versioninfo/revno | string:unknown; |
220 | - icingroot string:/+icing/rev${revno}"> |
221 | + revision modules/lp.app.versioninfo/revision | string:unknown; |
222 | + icingroot string:/+icing/rev${revision}"> |
223 | <tal:comment replace="nothing"> |
224 | This macro loads a single css file containing all our stylesheets. |
225 | If you need to include a new css file here, add it to |
226 | @@ -316,7 +315,7 @@ |
227 | >System status</a> |
228 | <span id="lp-version"> |
229 | • |
230 | - r<tal:revno replace="revno" /> |
231 | + r<tal:display_revision replace="display_revision" /> |
232 | <tal:devmode condition="devmode">devmode</tal:devmode> |
233 | <tal:demo condition="is_demo">demo site</tal:demo> |
234 | (<a href="https://dev.launchpad.net/" |
235 | |
236 | === modified file 'lib/lp/app/templates/base-layout.pt' |
237 | --- lib/lp/app/templates/base-layout.pt 2015-11-21 10:21:42 +0000 |
238 | +++ lib/lp/app/templates/base-layout.pt 2016-09-19 14:06:13 +0000 |
239 | @@ -3,13 +3,14 @@ |
240 | xmlns:tal="http://xml.zope.org/namespaces/tal" |
241 | define-macro="master" |
242 | tal:define=" |
243 | - revno modules/lp.app.versioninfo/revno | string:unknown; |
244 | + revision modules/lp.app.versioninfo/revision | string:unknown; |
245 | + display_revision modules/lp.app.versioninfo/display_revision | string:unknown; |
246 | devmode modules/lp.services.config/config/devmode; |
247 | rooturl modules/lp.services.webapp.vhosts/allvhosts/configs/mainsite/rooturl; |
248 | is_demo modules/lp.services.config/config/launchpad/is_demo; |
249 | is_lpnet modules/lp.services.config/config/launchpad/is_lpnet; |
250 | site_message modules/lp.services.config/config/launchpad/site_message; |
251 | - icingroot string:${rooturl}+icing/rev${revno}; |
252 | + icingroot string:${rooturl}+icing/rev${revision}; |
253 | features request/features; |
254 | feature_scopes request/features/scopes; |
255 | CONTEXTS python:{'template':template, 'context': context, 'view':view}; |
256 | @@ -182,7 +183,7 @@ |
257 | |
258 | Features: ${request/features/usedFlags} |
259 | |
260 | - r${revno} |
261 | + r${display_revision} |
262 | |
263 | -->" /> |
264 | </tal:template> |
265 | |
266 | === modified file 'lib/lp/app/templates/oops.pt' |
267 | --- lib/lp/app/templates/oops.pt 2011-12-24 17:49:30 +0000 |
268 | +++ lib/lp/app/templates/oops.pt 2016-09-19 14:06:13 +0000 |
269 | @@ -6,8 +6,8 @@ |
270 | > |
271 | <head |
272 | tal:define=" |
273 | - revno modules/lp.app.versioninfo/revno | string:unknown; |
274 | - icingroot string:/+icing/rev${revno}" |
275 | + revision modules/lp.app.versioninfo/revision | string:unknown; |
276 | + icingroot string:/+icing/rev${revision}" |
277 | > |
278 | <title>Oops!</title> |
279 | <link |
280 | |
281 | === modified file 'lib/lp/app/tests/test_versioninfo.py' |
282 | --- lib/lp/app/tests/test_versioninfo.py 2012-01-01 02:58:52 +0000 |
283 | +++ lib/lp/app/tests/test_versioninfo.py 2016-09-19 14:06:13 +0000 |
284 | @@ -1,4 +1,4 @@ |
285 | -# Copyright 2010 Canonical Ltd. This software is licensed under the |
286 | +# Copyright 2010-2016 Canonical Ltd. This software is licensed under the |
287 | # GNU Affero General Public License version 3 (see the file LICENSE). |
288 | |
289 | __metaclass__ = type |
290 | @@ -7,7 +7,7 @@ |
291 | import subprocess |
292 | import unittest |
293 | |
294 | -from lp.app.versioninfo import revno |
295 | +from lp.app.versioninfo import revision |
296 | from lp.services.config import TREE_ROOT |
297 | |
298 | |
299 | @@ -17,8 +17,8 @@ |
300 | # Our cronscripts are executed with cwd != LP root. |
301 | # Getting version info should still work in them. |
302 | args = [os.path.join(TREE_ROOT, "bin/py"), "-c", |
303 | - "from lp.app.versioninfo import revno;" |
304 | - "print revno"] |
305 | + "from lp.app.versioninfo import revision;" |
306 | + "print revision"] |
307 | process = subprocess.Popen(args, cwd='/tmp', stdout=subprocess.PIPE) |
308 | (output, errors) = process.communicate(None) |
309 | - self.assertEquals(int(revno), int(output)) |
310 | + self.assertEqual(revision, output.rstrip("\n")) |
311 | |
312 | === modified file 'lib/lp/app/versioninfo.py' |
313 | --- lib/lp/app/versioninfo.py 2011-02-18 16:02:56 +0000 |
314 | +++ lib/lp/app/versioninfo.py 2016-09-19 14:06:13 +0000 |
315 | @@ -1,23 +1,24 @@ |
316 | -# Copyright 2009-2010 Canonical Ltd. This software is licensed under the |
317 | +# Copyright 2009-2016 Canonical Ltd. This software is licensed under the |
318 | # GNU Affero General Public License version 3 (see the file LICENSE). |
319 | |
320 | -"""Give access to bzr and other version info, if available. |
321 | +"""Give access to version info, if available. |
322 | |
323 | -The bzr version info file is expected to be in the Launchpad root in the |
324 | -file bzr-version-info.py. |
325 | +The version info file is expected to be in the Launchpad root in the |
326 | +file version-info.py. |
327 | |
328 | From this module, you can get: |
329 | |
330 | versioninfo: the version_info dict |
331 | - revno: the revision number |
332 | + revision: the commit ID (Git) or revision number (Bazaar) |
333 | + display_revision: `revision` formatted for display |
334 | date: the date of the last revision |
335 | branch_nick: the branch nickname |
336 | |
337 | -If the bzr-version-info.py file does not exist, then revno, date and |
338 | -branch_nick will all be None. |
339 | +If the version-info.py file does not exist, then revision, display_revision, |
340 | +date, and branch_nick will all be None. |
341 | |
342 | -If that file exists, and contains valid Python, revno, date and branch_nick |
343 | -will have appropriate values from version_info. |
344 | +If that file exists, and contains valid Python, revision, display_revision, |
345 | +date, and branch_nick will have appropriate values from version_info. |
346 | |
347 | If that file exists, and contains invalid Python, there will be an error when |
348 | this module is loaded. This module is imported into lp/app/__init__.py so |
349 | @@ -27,7 +28,8 @@ |
350 | __all__ = [ |
351 | 'branch_nick', |
352 | 'date', |
353 | - 'revno', |
354 | + 'display_revision', |
355 | + 'revision', |
356 | 'versioninfo', |
357 | ] |
358 | |
359 | @@ -45,10 +47,16 @@ |
360 | |
361 | |
362 | if versioninfo is None: |
363 | - revno = None |
364 | + revision = None |
365 | + display_revision = None |
366 | date = None |
367 | branch_nick = None |
368 | else: |
369 | - revno = versioninfo.get('revno') |
370 | + if 'revno' in versioninfo: |
371 | + revision = versioninfo.get('revno') |
372 | + display_revision = revision |
373 | + else: |
374 | + revision = versioninfo.get('revision_id') |
375 | + display_revision = revision[:7] |
376 | date = versioninfo.get('date') |
377 | branch_nick = versioninfo.get('branch_nick') |
378 | |
379 | === modified file 'lib/lp/services/mail/sendmail.py' |
380 | --- lib/lp/services/mail/sendmail.py 2015-07-21 09:04:01 +0000 |
381 | +++ lib/lp/services/mail/sendmail.py 2016-09-19 14:06:13 +0000 |
382 | @@ -1,4 +1,4 @@ |
383 | -# Copyright 2009-2011 Canonical Ltd. This software is licensed under the |
384 | +# Copyright 2009-2016 Canonical Ltd. This software is licensed under the |
385 | # GNU Affero General Public License version 3 (see the file LICENSE). |
386 | |
387 | """The One True Way to send mail from the Launchpad application. |
388 | @@ -434,7 +434,7 @@ |
389 | # Add an X-Generated-By header for easy whitelisting |
390 | del message['X-Generated-By'] |
391 | message['X-Generated-By'] = 'Launchpad (canonical.com)' |
392 | - message.set_param('Revision', str(versioninfo.revno), 'X-Generated-By') |
393 | + message.set_param('Revision', str(versioninfo.revision), 'X-Generated-By') |
394 | message.set_param('Instance', config.name, 'X-Generated-By') |
395 | |
396 | # Add a shared secret header for pre-approval with Mailman. This approach |
397 | |
398 | === modified file 'lib/lp/services/webapp/errorlog.py' |
399 | --- lib/lp/services/webapp/errorlog.py 2015-12-07 08:24:41 +0000 |
400 | +++ lib/lp/services/webapp/errorlog.py 2016-09-19 14:06:13 +0000 |
401 | @@ -1,4 +1,4 @@ |
402 | -# Copyright 2009-2011 Canonical Ltd. This software is licensed under the |
403 | +# Copyright 2009-2016 Canonical Ltd. This software is licensed under the |
404 | # GNU Affero General Public License version 3 (see the file LICENSE). |
405 | |
406 | """Error logging facilities.""" |
407 | @@ -18,7 +18,6 @@ |
408 | import oops.createhooks |
409 | import oops_amqp |
410 | from oops_datedir_repo import DateDirRepo |
411 | -import oops_datedir_repo.serializer |
412 | import oops_timeline |
413 | import pytz |
414 | from zope.component.interfaces import ObjectEvent |
415 | @@ -39,7 +38,6 @@ |
416 | soft_timeout_expired, |
417 | ) |
418 | from lp.services.webapp.interfaces import ( |
419 | - IErrorReport, |
420 | IErrorReportEvent, |
421 | IErrorReportRequest, |
422 | IUnloggedException, |
423 | @@ -87,40 +85,6 @@ |
424 | """A new error report has been created.""" |
425 | |
426 | |
427 | -@implementer(IErrorReport) |
428 | -class ErrorReport: |
429 | - |
430 | - def __init__(self, id, type, value, time, tb_text, username, |
431 | - url, duration, req_vars, timeline, informational=None, |
432 | - branch_nick=None, revno=None, topic=None, reporter=None): |
433 | - self.id = id |
434 | - self.type = type |
435 | - self.value = value |
436 | - self.time = time |
437 | - self.topic = topic |
438 | - if reporter is not None: |
439 | - self.reporter = reporter |
440 | - self.tb_text = tb_text |
441 | - self.username = username |
442 | - self.url = url |
443 | - self.duration = duration |
444 | - # informational is ignored - will be going from the oops module |
445 | - # soon too. |
446 | - self.req_vars = req_vars |
447 | - self.timeline = timeline |
448 | - self.branch_nick = branch_nick or versioninfo.branch_nick |
449 | - self.revno = revno or versioninfo.revno |
450 | - |
451 | - def __repr__(self): |
452 | - return '<ErrorReport %s %s: %s>' % (self.id, self.type, self.value) |
453 | - |
454 | - @classmethod |
455 | - def read(cls, fp): |
456 | - # Deprecated: use the oops module directly now, when possible. |
457 | - report = oops_datedir_repo.serializer.read(fp) |
458 | - return cls(**report) |
459 | - |
460 | - |
461 | def notify_publisher(report): |
462 | if not report.get('id'): |
463 | report['id'] = str(id(report)) |
464 | @@ -318,7 +282,9 @@ |
465 | # What do we want in our reports? |
466 | # Constants: |
467 | self._oops_config.template['branch_nick'] = versioninfo.branch_nick |
468 | - self._oops_config.template['revno'] = versioninfo.revno |
469 | + # XXX cjwatson 2016-09-14: This should really be 'revision', but |
470 | + # that requires coordination with python-oops-tools. |
471 | + self._oops_config.template['revno'] = versioninfo.revision |
472 | reporter = config[self._default_config_section].oops_prefix |
473 | if section_name != self._default_config_section: |
474 | reporter = '%s-%s' % (reporter, section_name) |
475 | |
476 | === modified file 'lib/lp/services/webapp/errorlog.zcml' |
477 | --- lib/lp/services/webapp/errorlog.zcml 2013-04-10 09:12:32 +0000 |
478 | +++ lib/lp/services/webapp/errorlog.zcml 2016-09-19 14:06:13 +0000 |
479 | @@ -1,4 +1,4 @@ |
480 | -<!-- Copyright 2009 Canonical Ltd. This software is licensed under the |
481 | +<!-- Copyright 2009-2016 Canonical Ltd. This software is licensed under the |
482 | GNU Affero General Public License version 3 (see the file LICENSE). |
483 | --> |
484 | |
485 | @@ -13,12 +13,6 @@ |
486 | /> |
487 | </class> |
488 | |
489 | - <class class="lp.services.webapp.errorlog.ErrorReport"> |
490 | - <allow |
491 | - interface="lp.services.webapp.interfaces.IErrorReport" |
492 | - /> |
493 | - </class> |
494 | - |
495 | <utility |
496 | provides="zope.error.interfaces.IErrorReportingUtility" |
497 | component="lp.services.webapp.errorlog.globalErrorUtility" |
498 | |
499 | === modified file 'lib/lp/services/webapp/interfaces.py' |
500 | --- lib/lp/services/webapp/interfaces.py 2016-02-28 19:13:17 +0000 |
501 | +++ lib/lp/services/webapp/interfaces.py 2016-09-19 14:06:13 +0000 |
502 | @@ -701,24 +701,6 @@ |
503 | """A new error report has been created.""" |
504 | |
505 | |
506 | -class IErrorReport(Interface): |
507 | - id = TextLine(description=u"The name of this error report.") |
508 | - type = TextLine(description=u"The type of the exception that occurred.") |
509 | - value = TextLine(description=u"The value of the exception that occurred.") |
510 | - time = Datetime(description=u"The time at which the exception occurred.") |
511 | - pageid = TextLine( |
512 | - description=u""" |
513 | - The context class plus the page template where the exception |
514 | - occurred. |
515 | - """) |
516 | - branch_nick = TextLine(description=u"The branch nickname.") |
517 | - revno = TextLine(description=u"The revision number of the branch.") |
518 | - tb_text = Text(description=u"A text version of the traceback.") |
519 | - username = TextLine(description=u"The user associated with the request.") |
520 | - url = TextLine(description=u"The URL for the failed request.") |
521 | - req_vars = Attribute("The request variables.") |
522 | - |
523 | - |
524 | class IErrorReportRequest(Interface): |
525 | oopsid = TextLine( |
526 | description=u"""an identifier for the exception, or None if no |
527 | |
528 | === modified file 'lib/lp/services/webapp/publisher.py' |
529 | --- lib/lp/services/webapp/publisher.py 2016-02-28 19:13:17 +0000 |
530 | +++ lib/lp/services/webapp/publisher.py 2016-09-19 14:06:13 +0000 |
531 | @@ -63,10 +63,10 @@ |
532 | ) |
533 | from zope.traversing.browser.interfaces import IAbsoluteURL |
534 | |
535 | +from lp.app import versioninfo |
536 | from lp.app.errors import NotFoundError |
537 | from lp.app.interfaces.informationtype import IInformationType |
538 | from lp.app.interfaces.launchpad import IPrivacy |
539 | -from lp.app.versioninfo import revno |
540 | from lp.layers import ( |
541 | LaunchpadLayer, |
542 | setFirstLayer, |
543 | @@ -412,7 +412,7 @@ |
544 | from lp.services.config import config |
545 | combo_url = '/+combo' |
546 | if not config.devmode: |
547 | - combo_url += '/rev%s' % revno |
548 | + combo_url += '/rev%s' % versioninfo.revision |
549 | return combo_url |
550 | |
551 | def render(self): |
552 | |
553 | === modified file 'lib/lp/services/webapp/servers.py' |
554 | --- lib/lp/services/webapp/servers.py 2016-06-24 11:31:44 +0000 |
555 | +++ lib/lp/services/webapp/servers.py 2016-09-19 14:06:13 +0000 |
556 | @@ -602,7 +602,7 @@ |
557 | 'Strict-Transport-Security', 'max-age=15552000') |
558 | |
559 | # Publish revision information. |
560 | - self.response.setHeader('X-Launchpad-Revision', versioninfo.revno) |
561 | + self.response.setHeader('X-Launchpad-Revision', versioninfo.revision) |
562 | |
563 | @property |
564 | def stepstogo(self): |
565 | |
566 | === modified file 'lib/lp/services/webapp/tests/test_errorlog.py' |
567 | --- lib/lp/services/webapp/tests/test_errorlog.py 2015-07-08 16:05:11 +0000 |
568 | +++ lib/lp/services/webapp/tests/test_errorlog.py 2016-09-19 14:06:13 +0000 |
569 | @@ -1,13 +1,11 @@ |
570 | -# Copyright 2009-2011 Canonical Ltd. This software is licensed under the |
571 | +# Copyright 2009-2016 Canonical Ltd. This software is licensed under the |
572 | # GNU Affero General Public License version 3 (see the file LICENSE). |
573 | |
574 | """Tests for error logging & OOPS reporting.""" |
575 | |
576 | __metaclass__ = type |
577 | |
578 | -import datetime |
579 | import httplib |
580 | -import StringIO |
581 | import sys |
582 | from textwrap import dedent |
583 | import traceback |
584 | @@ -30,7 +28,6 @@ |
585 | from zope.publisher.interfaces.xmlrpc import IXMLRPCRequest |
586 | from zope.security.interfaces import Unauthorized |
587 | |
588 | -from lp.app import versioninfo |
589 | from lp.app.errors import ( |
590 | GoneError, |
591 | TranslationUnavailable, |
592 | @@ -41,7 +38,6 @@ |
593 | _filter_session_statement, |
594 | _is_sensitive, |
595 | attach_http_request, |
596 | - ErrorReport, |
597 | ErrorReportingUtility, |
598 | notify_publisher, |
599 | ScriptRequest, |
600 | @@ -60,79 +56,6 @@ |
601 | """Used to test handling of exceptions in OOPS reports.""" |
602 | |
603 | |
604 | -class TestErrorReport(testtools.TestCase): |
605 | - |
606 | - def test___init__(self): |
607 | - """Test ErrorReport.__init__()""" |
608 | - entry = ErrorReport('id', 'exc-type', 'exc-value', 'timestamp', |
609 | - 'traceback-text', 'username', 'url', 42, |
610 | - {'name1': 'value1', 'name2': 'value2', |
611 | - 'name3': 'value3'}, |
612 | - [(1, 5, 'store_a', 'SELECT 1'), |
613 | - (5, 10, 'store_b', 'SELECT 2')], |
614 | - topic='pageid', |
615 | - ) |
616 | - self.assertEqual(entry.id, 'id') |
617 | - self.assertEqual(entry.type, 'exc-type') |
618 | - self.assertEqual(entry.value, 'exc-value') |
619 | - self.assertEqual(entry.time, 'timestamp') |
620 | - self.assertEqual(entry.topic, 'pageid') |
621 | - self.assertEqual(entry.branch_nick, versioninfo.branch_nick) |
622 | - self.assertEqual(entry.revno, versioninfo.revno) |
623 | - self.assertEqual(entry.username, 'username') |
624 | - self.assertEqual(entry.url, 'url') |
625 | - self.assertEqual(entry.duration, 42) |
626 | - self.assertEqual({ |
627 | - 'name1': 'value1', |
628 | - 'name2': 'value2', |
629 | - 'name3': 'value3', |
630 | - }, entry.req_vars) |
631 | - self.assertEqual(len(entry.timeline), 2) |
632 | - self.assertEqual(entry.timeline[0], (1, 5, 'store_a', 'SELECT 1')) |
633 | - self.assertEqual(entry.timeline[1], (5, 10, 'store_b', 'SELECT 2')) |
634 | - |
635 | - def test_read(self): |
636 | - """Test ErrorReport.read().""" |
637 | - # Note: this exists to test the compatibility thunk only. |
638 | - fp = StringIO.StringIO(dedent("""\ |
639 | - Oops-Id: OOPS-A0001 |
640 | - Exception-Type: NotFound |
641 | - Exception-Value: error message |
642 | - Date: 2005-04-01T00:00:00+00:00 |
643 | - Page-Id: IFoo:+foo-template |
644 | - User: Sample User |
645 | - URL: http://localhost:9000/foo |
646 | - Duration: 42 |
647 | - |
648 | - HTTP_USER_AGENT=Mozilla/5.0 |
649 | - HTTP_REFERER=http://localhost:9000/ |
650 | - name%3Dfoo=hello%0Aworld |
651 | - |
652 | - 00001-00005@store_a SELECT 1 |
653 | - 00005-00010@store_b SELECT 2 |
654 | - |
655 | - traceback-text""")) |
656 | - entry = ErrorReport.read(fp) |
657 | - self.assertEqual(entry.id, 'OOPS-A0001') |
658 | - self.assertEqual(entry.type, 'NotFound') |
659 | - self.assertEqual(entry.value, 'error message') |
660 | - self.assertEqual( |
661 | - entry.time, datetime.datetime(2005, 4, 1, tzinfo=UTC)) |
662 | - self.assertEqual(entry.topic, 'IFoo:+foo-template') |
663 | - self.assertEqual(entry.tb_text, 'traceback-text') |
664 | - self.assertEqual(entry.username, 'Sample User') |
665 | - self.assertEqual(entry.url, 'http://localhost:9000/foo') |
666 | - self.assertEqual(entry.duration, 42) |
667 | - self.assertEqual({ |
668 | - 'HTTP_USER_AGENT': 'Mozilla/5.0', |
669 | - 'HTTP_REFERER': 'http://localhost:9000/', |
670 | - 'name=foo': 'hello\nworld'}, |
671 | - entry.req_vars) |
672 | - self.assertEqual(len(entry.timeline), 2) |
673 | - self.assertEqual(entry.timeline[0], [1, 5, 'store_a', 'SELECT 1']) |
674 | - self.assertEqual(entry.timeline[1], [5, 10, 'store_b', 'SELECT 2']) |
675 | - |
676 | - |
677 | class TestErrorReportingUtility(testtools.TestCase): |
678 | |
679 | # want rabbit |
680 | |
681 | === modified file 'lib/lp/services/webapp/tests/test_servers.py' |
682 | --- lib/lp/services/webapp/tests/test_servers.py 2016-06-24 11:31:44 +0000 |
683 | +++ lib/lp/services/webapp/tests/test_servers.py 2016-09-19 14:06:13 +0000 |
684 | @@ -386,7 +386,7 @@ |
685 | def test_baserequest_revision_header(self): |
686 | response = LaunchpadBrowserRequest(StringIO.StringIO(''), {}).response |
687 | self.assertEqual( |
688 | - versioninfo.revno, response.getHeader('X-Launchpad-Revision')) |
689 | + versioninfo.revision, response.getHeader('X-Launchpad-Revision')) |
690 | |
691 | def test_baserequest_recovers_from_bad_path_info_encoding(self): |
692 | # The request object recodes PATH_INFO to ensure sane_environment |
693 | |
694 | === modified file 'lib/lp/services/webhooks/model.py' |
695 | --- lib/lp/services/webhooks/model.py 2016-01-19 17:41:11 +0000 |
696 | +++ lib/lp/services/webhooks/model.py 2016-09-19 14:06:13 +0000 |
697 | @@ -43,8 +43,8 @@ |
698 | ) |
699 | from zope.security.proxy import removeSecurityProxy |
700 | |
701 | +from lp.app import versioninfo |
702 | from lp.app.interfaces.security import IAuthorization |
703 | -import lp.app.versioninfo |
704 | from lp.registry.interfaces.role import IPersonRoles |
705 | from lp.registry.model.person import Person |
706 | from lp.services.config import config |
707 | @@ -488,7 +488,7 @@ |
708 | transaction.commit() |
709 | raise WebhookDeliveryFailure(self.error_message) |
710 | user_agent = '%s-Webhooks/r%s' % ( |
711 | - config.vhost.mainsite.hostname, lp.app.versioninfo.revno) |
712 | + config.vhost.mainsite.hostname, versioninfo.revision) |
713 | secret = self.webhook.secret |
714 | result = getUtility(IWebhookClient).deliver( |
715 | self.webhook.delivery_url, config.webhooks.http_proxy, |
716 | |
717 | === modified file 'lib/lp/services/webhooks/tests/test_job.py' |
718 | --- lib/lp/services/webhooks/tests/test_job.py 2015-11-11 18:12:24 +0000 |
719 | +++ lib/lp/services/webhooks/tests/test_job.py 2016-09-19 14:06:13 +0000 |
720 | @@ -1,4 +1,4 @@ |
721 | -# Copyright 2015 Canonical Ltd. This software is licensed under the |
722 | +# Copyright 2015-2016 Canonical Ltd. This software is licensed under the |
723 | # GNU Affero General Public License version 3 (see the file LICENSE). |
724 | |
725 | """Tests for `WebhookJob`s.""" |
726 | @@ -37,7 +37,7 @@ |
727 | from zope.component import getUtility |
728 | from zope.security.proxy import removeSecurityProxy |
729 | |
730 | -from lp.app.versioninfo import revno |
731 | +from lp.app import versioninfo |
732 | from lp.services.features.testing import FeatureFixture |
733 | from lp.services.job.interfaces.job import JobStatus |
734 | from lp.services.job.runner import JobRunner |
735 | @@ -371,7 +371,8 @@ |
736 | self.assertEqual([ |
737 | ('POST', 'http://example.com/ep', |
738 | {'Content-Type': 'application/json', |
739 | - 'User-Agent': 'launchpad.dev-Webhooks/r%s' % revno, |
740 | + 'User-Agent': 'launchpad.dev-Webhooks/r%s' % ( |
741 | + versioninfo.revision), |
742 | 'X-Launchpad-Event-Type': 'test', |
743 | 'X-Launchpad-Delivery': str(job.job_id)}), |
744 | ], reqs) |
745 | @@ -386,7 +387,8 @@ |
746 | self.assertEqual([ |
747 | ('POST', 'http://example.com/ep', |
748 | {'Content-Type': 'application/json', |
749 | - 'User-Agent': 'launchpad.dev-Webhooks/r%s' % revno, |
750 | + 'User-Agent': 'launchpad.dev-Webhooks/r%s' % ( |
751 | + versioninfo.revision), |
752 | 'X-Hub-Signature': |
753 | 'sha1=de75f136c37d89f5eb24834468c1ecd602fa95dd', |
754 | 'X-Launchpad-Event-Type': 'test', |
755 | |
756 | === modified file 'lib/lp/services/webservice/configuration.py' |
757 | --- lib/lp/services/webservice/configuration.py 2012-01-31 01:22:32 +0000 |
758 | +++ lib/lp/services/webservice/configuration.py 2016-09-19 14:06:13 +0000 |
759 | @@ -1,4 +1,4 @@ |
760 | -# Copyright 2009-2011 Canonical Ltd. This software is licensed under the |
761 | +# Copyright 2009-2016 Canonical Ltd. This software is licensed under the |
762 | # GNU Affero General Public License version 3 (see the file LICENSE). |
763 | |
764 | """A configuration class describing the Launchpad web service.""" |
765 | @@ -58,7 +58,7 @@ |
766 | |
767 | @property |
768 | def code_revision(self): |
769 | - return str(versioninfo.revno) |
770 | + return str(versioninfo.revision) |
771 | |
772 | def createRequest(self, body_instream, environ): |
773 | """See `IWebServiceConfiguration`.""" |
774 | |
775 | === modified file 'lib/lp/testing/yuixhr.py' |
776 | --- lib/lp/testing/yuixhr.py 2015-07-08 16:05:11 +0000 |
777 | +++ lib/lp/testing/yuixhr.py 2016-09-19 14:06:13 +0000 |
778 | @@ -1,4 +1,4 @@ |
779 | -# Copyright 2011-2013 Canonical Ltd. This software is licensed under the |
780 | +# Copyright 2011-2016 Canonical Ltd. This software is licensed under the |
781 | # GNU Affero General Public License version 3 (see the file LICENSE). |
782 | |
783 | """Fixture code for YUITest + XHR integration testing.""" |
784 | @@ -33,7 +33,7 @@ |
785 | from zope.security.proxy import removeSecurityProxy |
786 | from zope.session.interfaces import IClientIdManager |
787 | |
788 | -from lp.app.versioninfo import revno |
789 | +from lp.app import versioninfo |
790 | from lp.services.config import config |
791 | from lp.services.webapp.interfaces import ( |
792 | IOpenLaunchBag, |
793 | @@ -207,7 +207,7 @@ |
794 | href="/+yuitest/build/js/yui/console/assets/skins/sam/console.css"/> |
795 | <link rel="stylesheet" |
796 | href="/+yuitest/build/js/yui/test/assets/skins/sam/test.css"/> |
797 | - <link rel="stylesheet" href="/+icing/rev%(revno)s/combo.css"/> |
798 | + <link rel="stylesheet" href="/+icing/rev%(revision)s/combo.css"/> |
799 | <script type="text/javascript" src="%(test_module)s"></script> |
800 | </head> |
801 | <body class="yui3-skin-sam"> |
802 | @@ -234,7 +234,7 @@ |
803 | <title>YUI XHR Tests</title> |
804 | <link rel="stylesheet" |
805 | href="/+icing/yui/assets/skins/sam/skin.css"/> |
806 | - <link rel="stylesheet" href="/+icing/rev%(revno)s/combo.css"/> |
807 | + <link rel="stylesheet" href="/+icing/rev%(revision)s/combo.css"/> |
808 | <style> |
809 | ul { |
810 | text-align: left; |
811 | @@ -358,7 +358,7 @@ |
812 | warning = ' <span class="warning">%s</span>' % warning |
813 | test_lines.append('<li>%s%s</li>' % (link, warning)) |
814 | return self.index_template % { |
815 | - 'revno': revno, |
816 | + 'revision': versioninfo.revision, |
817 | 'tests': '\n'.join(test_lines)} |
818 | |
819 | def renderCOMBOFILE(self): |
820 | @@ -390,7 +390,7 @@ |
821 | return self.page_template % dict( |
822 | test_module='/+yuitest/%s.js' % self.traversed_path, |
823 | test_namespace=self.traversed_path.replace('/', '.'), |
824 | - revno=revno, |
825 | + revision=versioninfo.revision, |
826 | javascript_block=self.renderYUI()) |
827 | |
828 | def renderSETUP(self): |
829 | @@ -445,7 +445,7 @@ |
830 | |
831 | """ |
832 | return self.yui_block_combo % dict( |
833 | - revno=revno, |
834 | + revision=versioninfo.revision, |
835 | combo_url=self.combo_url) |
836 | |
837 | def render(self): |
838 | |
839 | === modified file 'lib/lp/translations/utilities/gettext_po_parser.py' |
840 | --- lib/lp/translations/utilities/gettext_po_parser.py 2015-07-08 16:05:11 +0000 |
841 | +++ lib/lp/translations/utilities/gettext_po_parser.py 2016-09-19 14:06:13 +0000 |
842 | @@ -1,4 +1,4 @@ |
843 | -# Copyright 2009-2014 Canonical Ltd. This software is licensed under the |
844 | +# Copyright 2009-2016 Canonical Ltd. This software is licensed under the |
845 | # GNU Affero General Public License version 3 (see the file LICENSE). |
846 | |
847 | # Originally based on code from msgfmt.py (available from python source |
848 | @@ -23,7 +23,7 @@ |
849 | from zope import datetime as zope_datetime |
850 | from zope.interface import implementer |
851 | |
852 | -from lp.app.versioninfo import revno |
853 | +from lp.app import versioninfo |
854 | from lp.translations.interfaces.translationcommonformat import ( |
855 | ITranslationHeaderData, |
856 | ) |
857 | @@ -352,10 +352,10 @@ |
858 | elif key == 'x-generator': |
859 | # Note the revision number so it would help for debugging |
860 | # problems with bad exports. |
861 | - if revno is None: |
862 | + if versioninfo.revision is None: |
863 | build = 'Unknown' |
864 | else: |
865 | - build = revno |
866 | + build = versioninfo.revision |
867 | raw_content_list.append( |
868 | '%s: Launchpad (build %s)\n' % (value, build)) |
869 | else: |
870 | |
871 | === renamed file 'scripts/update-bzr-version-info.sh' => 'scripts/update-version-info.sh' |
872 | --- scripts/update-bzr-version-info.sh 2009-10-16 01:54:41 +0000 |
873 | +++ scripts/update-version-info.sh 2016-09-19 14:06:13 +0000 |
874 | @@ -1,35 +1,62 @@ |
875 | #!/bin/bash |
876 | # |
877 | -# Copyright 2009 Canonical Ltd. This software is licensed under the |
878 | +# Copyright 2009-2016 Canonical Ltd. This software is licensed under the |
879 | # GNU Affero General Public License version 3 (see the file LICENSE). |
880 | # |
881 | -# Update bzr-version-info.py -- but only if the revision number has |
882 | +# Update version-info.py -- but only if the revision number has |
883 | # changed |
884 | # |
885 | |
886 | -if ! which bzr > /dev/null || ! test -x $(which bzr); then |
887 | - echo "No working 'bzr' executable found" |
888 | +newfile=version-info-${RANDOM}.py |
889 | + |
890 | +if [ -d .git ]; then |
891 | + if ! which git > /dev/null || ! test -x $(which git); then |
892 | + echo "No working 'git' executable found" >&2 |
893 | + exit 1 |
894 | + fi |
895 | + |
896 | + branch_nick="$(git rev-parse --abbrev-ref HEAD | sed "s/'/\\\\'/g")" |
897 | + revision_id="$(git rev-parse HEAD)" |
898 | + cat > $newfile <<EOF |
899 | +#! /usr/bin/env python |
900 | + |
901 | +from __future__ import print_function |
902 | + |
903 | +version_info = { |
904 | + 'branch_nick': u'$branch_nick', |
905 | + 'revision_id': u'$revision_id', |
906 | + } |
907 | + |
908 | +if __name__ == '__main__': |
909 | + print('revision id: %(revision_id)s' % version_info) |
910 | +EOF |
911 | +elif [ -d .bzr ]; then |
912 | + if ! which bzr > /dev/null || ! test -x $(which bzr); then |
913 | + echo "No working 'bzr' executable found" >&2 |
914 | + exit 1 |
915 | + fi |
916 | + |
917 | + bzr version-info --format=python > $newfile 2>/dev/null |
918 | +else |
919 | + echo "Not in a Git or Bazaar working tree" >&2 |
920 | exit 1 |
921 | fi |
922 | |
923 | -newfile=bzr-version-info-${RANDOM}.py |
924 | -bzr version-info --format=python > $newfile 2>/dev/null; |
925 | -# There's a leading space here that I don't care to trim.. |
926 | -revno=$(python $newfile | grep revision: | cut -d: -f2) |
927 | -if ! [ -f bzr-version-info.py ]; then |
928 | - echo "Creating bzr-version-info.py at revno$revno" |
929 | - mv ${newfile} bzr-version-info.py |
930 | +revision_id=$(python $newfile | sed -n 's/^revision id: //p') |
931 | +if ! [ -f version-info.py ]; then |
932 | + echo "Creating version-info.py at revision $revision_id" |
933 | + mv ${newfile} version-info.py |
934 | else |
935 | # Here we compare the actual output instead of the contents of the |
936 | # file because bzr includes a build-date that is actually updated |
937 | # every time you run bzr version-info. |
938 | newcontents=$(python $newfile) |
939 | - oldcontents=$(python bzr-version-info.py) |
940 | + oldcontents=$(python version-info.py) |
941 | if [ "$newcontents" != "$oldcontents" ]; then |
942 | - echo "Updating bzr-version-info.py to revno$revno" |
943 | - mv ${newfile} bzr-version-info.py |
944 | + echo "Updating version-info.py to revision $revision_id" |
945 | + mv ${newfile} version-info.py |
946 | else |
947 | - echo "Skipping bzr-version-info.py update; already at revno$revno" |
948 | + echo "Skipping version-info.py update; already at revision $revision_id" |
949 | rm ${newfile} |
950 | fi |
951 | fi |
952 | |
953 | === modified file 'utilities/create-lp-wadl-and-apidoc.py' |
954 | --- utilities/create-lp-wadl-and-apidoc.py 2013-04-10 09:27:24 +0000 |
955 | +++ utilities/create-lp-wadl-and-apidoc.py 2016-09-19 14:06:13 +0000 |
956 | @@ -1,6 +1,6 @@ |
957 | #! /usr/bin/python -S |
958 | # |
959 | -# Copyright 2010 Canonical Ltd. This software is licensed under the |
960 | +# Copyright 2010-2016 Canonical Ltd. This software is licensed under the |
961 | # GNU Affero General Public License version 3 (see the file LICENSE). |
962 | |
963 | """Create a static WADL file describing the current webservice. |
964 | @@ -15,6 +15,7 @@ |
965 | from multiprocessing import Process |
966 | import optparse |
967 | import os |
968 | +import subprocess |
969 | import sys |
970 | |
971 | import bzrlib |
972 | @@ -137,10 +138,16 @@ |
973 | # Get the time of the last commit. We will use this as the mtime for the |
974 | # generated files so that we can safely use it as part of Apache's etag |
975 | # generation in the face of multiple servers/filesystems. |
976 | - with bzrlib.initialize(): |
977 | - branch = Branch.open(os.path.dirname(os.path.dirname(__file__))) |
978 | - timestamp = branch.repository.get_revision( |
979 | - branch.last_revision()).timestamp |
980 | + top = os.path.dirname(os.path.dirname(__file__)) |
981 | + if os.path.exists(os.path.join(top, ".git")): |
982 | + timestamp = int(subprocess.check_output( |
983 | + ["git", "log", "-1", "--format=%ct", "HEAD"], |
984 | + universal_newlines=True)) |
985 | + else: |
986 | + with bzrlib.initialize(): |
987 | + branch = Branch.open(top) |
988 | + timestamp = branch.repository.get_revision( |
989 | + branch.last_revision()).timestamp |
990 | |
991 | # Start a process to build each set of WADL and HTML files. |
992 | processes = [] |