Merge lp:~michael.nelson/launchpad/470181-ppa-inline-style into lp:launchpad/db-devel
- 470181-ppa-inline-style
- Merge into db-devel
Proposed by
Michael Nelson
Status: | Merged |
---|---|
Approved by: | Michael Nelson |
Approved revision: | not available |
Merged at revision: | not available |
Proposed branch: | lp:~michael.nelson/launchpad/470181-ppa-inline-style |
Merge into: | lp:launchpad/db-devel |
Diff against target: |
607 lines (+268/-38) 11 files modified
Makefile (+3/-1) lib/canonical/launchpad/webapp/publisher.py (+0/-16) lib/devscripts/ec2test/instance.py (+19/-4) lib/devscripts/ec2test/tests/test_ec2instance.py (+185/-0) lib/lp/code/model/directbranchcommit.py (+17/-3) lib/lp/code/tests/test_directbranchcommit.py (+1/-1) lib/lp/soyuz/templates/archive-index.pt (+1/-1) lib/lp/translations/doc/translations-export-to-branch.txt (+11/-3) lib/lp/translations/scripts/translations_to_branch.py (+13/-6) lib/lp/translations/utilities/gettext_po_exporter.py (+15/-2) utilities/rocketfuel-setup (+3/-1) |
To merge this branch: | bzr merge lp:~michael.nelson/launchpad/470181-ppa-inline-style |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Abel Deuring (community) | Approve | ||
Review via email: mp+15325@code.launchpad.net |
Commit message
Fixes bug 470181 by adding a missing class required for correct styling of the inline text area editor.
Description of the change
To post a comment you must log in.
Revision history for this message
Michael Nelson (michael.nelson) wrote : | # |
Revision history for this message
Abel Deuring (adeuring) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'Makefile' | |||
2 | --- Makefile 2009-11-17 20:43:28 +0000 | |||
3 | +++ Makefile 2009-11-27 16:21:25 +0000 | |||
4 | @@ -335,6 +335,8 @@ | |||
5 | 335 | launchpad.pot: | 335 | launchpad.pot: |
6 | 336 | bin/i18nextract.py | 336 | bin/i18nextract.py |
7 | 337 | 337 | ||
8 | 338 | # Called by the rocketfuel-setup script. You probably don't want to run this | ||
9 | 339 | # on its own. | ||
10 | 338 | install: reload-apache | 340 | install: reload-apache |
11 | 339 | 341 | ||
12 | 340 | copy-certificates: | 342 | copy-certificates: |
13 | @@ -353,7 +355,7 @@ | |||
14 | 353 | a2ensite local-launchpad | 355 | a2ensite local-launchpad |
15 | 354 | 356 | ||
16 | 355 | reload-apache: enable-apache-launchpad | 357 | reload-apache: enable-apache-launchpad |
18 | 356 | /etc/init.d/apache2 reload | 358 | /etc/init.d/apache2 restart |
19 | 357 | 359 | ||
20 | 358 | static: | 360 | static: |
21 | 359 | $(PY) scripts/make-static.py | 361 | $(PY) scripts/make-static.py |
22 | 360 | 362 | ||
23 | === modified file 'lib/canonical/launchpad/webapp/publisher.py' | |||
24 | --- lib/canonical/launchpad/webapp/publisher.py 2009-11-14 22:44:07 +0000 | |||
25 | +++ lib/canonical/launchpad/webapp/publisher.py 2009-11-27 16:21:25 +0000 | |||
26 | @@ -38,8 +38,6 @@ | |||
27 | 38 | from zope.security.checker import ProxyFactory, NamesChecker | 38 | from zope.security.checker import ProxyFactory, NamesChecker |
28 | 39 | from zope.traversing.browser.interfaces import IAbsoluteURL | 39 | from zope.traversing.browser.interfaces import IAbsoluteURL |
29 | 40 | 40 | ||
30 | 41 | from canonical.cachedproperty import cachedproperty | ||
31 | 42 | from canonical.config import config | ||
32 | 43 | from canonical.launchpad.layers import setFirstLayer, WebServiceLayer | 41 | from canonical.launchpad.layers import setFirstLayer, WebServiceLayer |
33 | 44 | from canonical.launchpad.webapp.vhosts import allvhosts | 42 | from canonical.launchpad.webapp.vhosts import allvhosts |
34 | 45 | from canonical.launchpad.webapp.interfaces import ( | 43 | from canonical.launchpad.webapp.interfaces import ( |
35 | @@ -232,7 +230,6 @@ | |||
36 | 232 | many templates not set via zcml, or you want to do | 230 | many templates not set via zcml, or you want to do |
37 | 233 | rendering from Python. | 231 | rendering from Python. |
38 | 234 | - isBetaUser <-- whether the logged-in user is a beta tester | 232 | - isBetaUser <-- whether the logged-in user is a beta tester |
39 | 235 | - striped_class<-- a tr class for an alternating row background | ||
40 | 236 | """ | 233 | """ |
41 | 237 | 234 | ||
42 | 238 | def __init__(self, context, request): | 235 | def __init__(self, context, request): |
43 | @@ -285,19 +282,6 @@ | |||
44 | 285 | else: | 282 | else: |
45 | 286 | return self.render() | 283 | return self.render() |
46 | 287 | 284 | ||
47 | 288 | @cachedproperty | ||
48 | 289 | def striped_class(self): | ||
49 | 290 | """Return a generator which yields alternating CSS classes. | ||
50 | 291 | |||
51 | 292 | This is to be used for HTML tables in which the row colors should be | ||
52 | 293 | alternated. | ||
53 | 294 | """ | ||
54 | 295 | def bg_stripe_generator(): | ||
55 | 296 | while True: | ||
56 | 297 | yield 'white' | ||
57 | 298 | yield 'shaded' | ||
58 | 299 | return bg_stripe_generator() | ||
59 | 300 | |||
60 | 301 | def _getErrorMessage(self): | 285 | def _getErrorMessage(self): |
61 | 302 | """Property getter for `error_message`.""" | 286 | """Property getter for `error_message`.""" |
62 | 303 | return self._error_message | 287 | return self._error_message |
63 | 304 | 288 | ||
64 | === modified file 'lib/devscripts/ec2test/instance.py' | |||
65 | --- lib/devscripts/ec2test/instance.py 2009-11-23 02:36:18 +0000 | |||
66 | +++ lib/devscripts/ec2test/instance.py 2009-11-27 16:21:25 +0000 | |||
67 | @@ -19,11 +19,9 @@ | |||
68 | 19 | import traceback | 19 | import traceback |
69 | 20 | 20 | ||
70 | 21 | from bzrlib.errors import BzrCommandError | 21 | from bzrlib.errors import BzrCommandError |
71 | 22 | from bzrlib.plugins.launchpad.account import get_lp_login | ||
72 | 23 | 22 | ||
73 | 24 | import paramiko | 23 | import paramiko |
74 | 25 | 24 | ||
75 | 26 | from devscripts.ec2test.credentials import EC2Credentials | ||
76 | 27 | from devscripts.ec2test.session import EC2SessionName | 25 | from devscripts.ec2test.session import EC2SessionName |
77 | 28 | 26 | ||
78 | 29 | 27 | ||
79 | @@ -194,6 +192,17 @@ | |||
80 | 194 | to allow access to the instance. | 192 | to allow access to the instance. |
81 | 195 | :param credentials: An `EC2Credentials` object. | 193 | :param credentials: An `EC2Credentials` object. |
82 | 196 | """ | 194 | """ |
83 | 195 | # This import breaks in the test environment. Do it here so | ||
84 | 196 | # that unit tests (which don't use this factory) can still | ||
85 | 197 | # import EC2Instance. | ||
86 | 198 | from bzrlib.plugins.launchpad.account import get_lp_login | ||
87 | 199 | |||
88 | 200 | # XXX JeroenVermeulen 2009-11-27 bug=489073: EC2Credentials | ||
89 | 201 | # imports boto, which isn't necessarily installed in our test | ||
90 | 202 | # environment. Doing the import here so that unit tests (which | ||
91 | 203 | # don't use this factory) can still import EC2Instance. | ||
92 | 204 | from devscripts.ec2test.credentials import EC2Credentials | ||
93 | 205 | |||
94 | 197 | assert isinstance(name, EC2SessionName) | 206 | assert isinstance(name, EC2SessionName) |
95 | 198 | if instance_type not in AVAILABLE_INSTANCE_TYPES: | 207 | if instance_type not in AVAILABLE_INSTANCE_TYPES: |
96 | 199 | raise ValueError('unknown instance_type %s' % (instance_type,)) | 208 | raise ValueError('unknown instance_type %s' % (instance_type,)) |
97 | @@ -388,6 +397,10 @@ | |||
98 | 388 | self._ensure_ec2test_user_has_keys() | 397 | self._ensure_ec2test_user_has_keys() |
99 | 389 | return self._connect('ec2test') | 398 | return self._connect('ec2test') |
100 | 390 | 399 | ||
101 | 400 | def _report_traceback(self): | ||
102 | 401 | """Print traceback.""" | ||
103 | 402 | traceback.print_exc() | ||
104 | 403 | |||
105 | 391 | def set_up_and_run(self, postmortem, shutdown, func, *args, **kw): | 404 | def set_up_and_run(self, postmortem, shutdown, func, *args, **kw): |
106 | 392 | """Start, run `func` and then maybe shut down. | 405 | """Start, run `func` and then maybe shut down. |
107 | 393 | 406 | ||
108 | @@ -405,16 +418,17 @@ | |||
109 | 405 | # We ignore the value of the 'shutdown' argument and always shut down | 418 | # We ignore the value of the 'shutdown' argument and always shut down |
110 | 406 | # unless `func` returns normally. | 419 | # unless `func` returns normally. |
111 | 407 | really_shutdown = True | 420 | really_shutdown = True |
112 | 421 | retval = None | ||
113 | 408 | try: | 422 | try: |
114 | 409 | self.start() | 423 | self.start() |
115 | 410 | try: | 424 | try: |
117 | 411 | return func(*args, **kw) | 425 | retval = func(*args, **kw) |
118 | 412 | except Exception: | 426 | except Exception: |
119 | 413 | # When running in postmortem mode, it is really helpful to see | 427 | # When running in postmortem mode, it is really helpful to see |
120 | 414 | # if there are any exceptions before it waits in the console | 428 | # if there are any exceptions before it waits in the console |
121 | 415 | # (in the finally block), and you can't figure out why it's | 429 | # (in the finally block), and you can't figure out why it's |
122 | 416 | # broken. | 430 | # broken. |
124 | 417 | traceback.print_exc() | 431 | self._report_traceback() |
125 | 418 | else: | 432 | else: |
126 | 419 | really_shutdown = shutdown | 433 | really_shutdown = shutdown |
127 | 420 | finally: | 434 | finally: |
128 | @@ -427,6 +441,7 @@ | |||
129 | 427 | finally: | 441 | finally: |
130 | 428 | if really_shutdown: | 442 | if really_shutdown: |
131 | 429 | self.shutdown() | 443 | self.shutdown() |
132 | 444 | return retval | ||
133 | 430 | 445 | ||
134 | 431 | def _copy_single_file(self, sftp, local_path, remote_dir): | 446 | def _copy_single_file(self, sftp, local_path, remote_dir): |
135 | 432 | """Copy `local_path` to `remote_dir` on this instance. | 447 | """Copy `local_path` to `remote_dir` on this instance. |
136 | 433 | 448 | ||
137 | === added file 'lib/devscripts/ec2test/tests/test_ec2instance.py' | |||
138 | --- lib/devscripts/ec2test/tests/test_ec2instance.py 1970-01-01 00:00:00 +0000 | |||
139 | +++ lib/devscripts/ec2test/tests/test_ec2instance.py 2009-11-27 16:21:25 +0000 | |||
140 | @@ -0,0 +1,185 @@ | |||
141 | 1 | # Copyright 2009 Canonical Ltd. This software is licensed under the | ||
142 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | ||
143 | 3 | # pylint: disable-msg=E0702 | ||
144 | 4 | |||
145 | 5 | """Test handling of EC2 machine images.""" | ||
146 | 6 | |||
147 | 7 | __metaclass__ = type | ||
148 | 8 | |||
149 | 9 | from unittest import TestCase, TestLoader | ||
150 | 10 | |||
151 | 11 | from devscripts.ec2test.instance import EC2Instance | ||
152 | 12 | |||
153 | 13 | |||
154 | 14 | class Stub: | ||
155 | 15 | """Generic recipient of invocations. | ||
156 | 16 | |||
157 | 17 | Use this to: | ||
158 | 18 | - Stub methods that should do nothing. | ||
159 | 19 | - Inject failures into methods. | ||
160 | 20 | - Record whether a method is being called. | ||
161 | 21 | """ | ||
162 | 22 | # XXX JeroenVermeulen 2009-11-26: This probably exists somewhere | ||
163 | 23 | # already. Or if not, maybe it should. But with a name that won't | ||
164 | 24 | # turn Stuart Bishop's IRC client into a disco simulator. | ||
165 | 25 | |||
166 | 26 | call_count = 0 | ||
167 | 27 | |||
168 | 28 | def __init__(self, return_value=None, simulated_failure=None): | ||
169 | 29 | """Define what to do when this stub gets invoked. | ||
170 | 30 | |||
171 | 31 | :param return_value: Something to return from the invocation. | ||
172 | 32 | :parma simulated_failure: Something to raise in the invocation. | ||
173 | 33 | """ | ||
174 | 34 | assert return_value is None or simulated_failure is None, ( | ||
175 | 35 | "Stub can raise an exception or return a value, but not both.") | ||
176 | 36 | self.return_value = return_value | ||
177 | 37 | self.simulated_failure = simulated_failure | ||
178 | 38 | |||
179 | 39 | def __call__(self, *args, **kwargs): | ||
180 | 40 | """Catch a call. | ||
181 | 41 | |||
182 | 42 | Records the fact that an invocation was made in | ||
183 | 43 | `call_count`. | ||
184 | 44 | |||
185 | 45 | If you passed a `simulated_failure` to the constructor, that | ||
186 | 46 | object is raised. | ||
187 | 47 | |||
188 | 48 | :return: The `return_value` you passed to the constructor. | ||
189 | 49 | """ | ||
190 | 50 | self.call_count += 1 | ||
191 | 51 | |||
192 | 52 | if self.simulated_failure is not None: | ||
193 | 53 | raise self.simulated_failure | ||
194 | 54 | |||
195 | 55 | return self.return_value | ||
196 | 56 | |||
197 | 57 | |||
198 | 58 | class FakeAccount: | ||
199 | 59 | """Helper for setting up an `EC2Instance` without EC2.""" | ||
200 | 60 | acquire_private_key = Stub() | ||
201 | 61 | acquire_security_group = Stub() | ||
202 | 62 | |||
203 | 63 | |||
204 | 64 | class FakeOutput: | ||
205 | 65 | """Pretend stdout/stderr output from EC2 instance.""" | ||
206 | 66 | output = "Fake output." | ||
207 | 67 | |||
208 | 68 | |||
209 | 69 | class FakeBotoInstance: | ||
210 | 70 | """Helper for setting up an `EC2Instance` without EC2.""" | ||
211 | 71 | id = 0 | ||
212 | 72 | state = 'running' | ||
213 | 73 | public_dns_name = 'fake-instance' | ||
214 | 74 | |||
215 | 75 | update = Stub() | ||
216 | 76 | stop = Stub() | ||
217 | 77 | get_console_output = FakeOutput | ||
218 | 78 | |||
219 | 79 | |||
220 | 80 | class FakeReservation: | ||
221 | 81 | """Helper for setting up an `EC2Instance` without EC2.""" | ||
222 | 82 | def __init__(self): | ||
223 | 83 | self.instances = [FakeBotoInstance()] | ||
224 | 84 | |||
225 | 85 | |||
226 | 86 | class FakeImage: | ||
227 | 87 | """Helper for setting up an `EC2Instance` without EC2.""" | ||
228 | 88 | run = Stub(return_value=FakeReservation()) | ||
229 | 89 | |||
230 | 90 | |||
231 | 91 | class FakeFailure(Exception): | ||
232 | 92 | """A pretend failure from the test runner.""" | ||
233 | 93 | |||
234 | 94 | |||
235 | 95 | class TestEC2Instance(TestCase): | ||
236 | 96 | """Test running of an `EC2Instance` without EC2.""" | ||
237 | 97 | |||
238 | 98 | def _makeInstance(self): | ||
239 | 99 | """Set up an `EC2Instance`, with stubbing where needed. | ||
240 | 100 | |||
241 | 101 | `EC2Instance.shutdown` is replaced with a `Stub`, so check its | ||
242 | 102 | call_count to see whether it's been invoked. | ||
243 | 103 | """ | ||
244 | 104 | session_name = None | ||
245 | 105 | image = FakeImage() | ||
246 | 106 | instance_type = 'c1.xlarge' | ||
247 | 107 | demo_networks = None | ||
248 | 108 | account = FakeAccount() | ||
249 | 109 | from_scratch = None | ||
250 | 110 | user_key = None | ||
251 | 111 | login = None | ||
252 | 112 | |||
253 | 113 | instance = EC2Instance( | ||
254 | 114 | session_name, image, instance_type, demo_networks, account, | ||
255 | 115 | from_scratch, user_key, login) | ||
256 | 116 | |||
257 | 117 | instance.shutdown = Stub() | ||
258 | 118 | instance._report_traceback = Stub() | ||
259 | 119 | instance.log = Stub() | ||
260 | 120 | |||
261 | 121 | return instance | ||
262 | 122 | |||
263 | 123 | def _runInstance(self, instance, runnee=None, headless=False): | ||
264 | 124 | """Set up and run an `EC2Instance` (but without EC2).""" | ||
265 | 125 | if runnee is None: | ||
266 | 126 | runnee = Stub() | ||
267 | 127 | |||
268 | 128 | instance.set_up_and_run(False, not headless, runnee) | ||
269 | 129 | |||
270 | 130 | def test_EC2Instance_test_baseline(self): | ||
271 | 131 | # The EC2 instances we set up have neither started nor been shut | ||
272 | 132 | # down. After running, they have started. | ||
273 | 133 | # Not a very useful test, except it establishes the basic | ||
274 | 134 | # assumptions for the other tests. | ||
275 | 135 | instance = self._makeInstance() | ||
276 | 136 | runnee = Stub() | ||
277 | 137 | |||
278 | 138 | self.assertEqual(0, runnee.call_count) | ||
279 | 139 | self.assertEqual(0, instance.shutdown.call_count) | ||
280 | 140 | |||
281 | 141 | self._runInstance(instance, runnee=runnee) | ||
282 | 142 | |||
283 | 143 | self.assertEqual(1, runnee.call_count) | ||
284 | 144 | |||
285 | 145 | def test_set_up_and_run_headful(self): | ||
286 | 146 | # A non-headless run executes all tests in the instance, then | ||
287 | 147 | # shuts down. | ||
288 | 148 | instance = self._makeInstance() | ||
289 | 149 | |||
290 | 150 | self._runInstance(instance, headless=False) | ||
291 | 151 | |||
292 | 152 | self.assertEqual(1, instance.shutdown.call_count) | ||
293 | 153 | |||
294 | 154 | def test_set_up_and_run_headless(self): | ||
295 | 155 | # An asynchronous, headless run kicks off the tests on the | ||
296 | 156 | # instance but does not shut it down. | ||
297 | 157 | instance = self._makeInstance() | ||
298 | 158 | |||
299 | 159 | self._runInstance(instance, headless=True) | ||
300 | 160 | |||
301 | 161 | self.assertEqual(0, instance.shutdown.call_count) | ||
302 | 162 | |||
303 | 163 | def test_set_up_and_run_headful_failure(self): | ||
304 | 164 | # If the test runner barfs, the instance swallows the exception | ||
305 | 165 | # and shuts down. | ||
306 | 166 | instance = self._makeInstance() | ||
307 | 167 | runnee = Stub(simulated_failure=FakeFailure("Headful barfage.")) | ||
308 | 168 | |||
309 | 169 | self._runInstance(instance, runnee=runnee, headless=False) | ||
310 | 170 | |||
311 | 171 | self.assertEqual(1, instance.shutdown.call_count) | ||
312 | 172 | |||
313 | 173 | def test_set_up_and_run_headless_failure(self): | ||
314 | 174 | # If the instance's test runner fails to set up for a headless | ||
315 | 175 | # run, the instance swallows the exception and shuts down. | ||
316 | 176 | instance = self._makeInstance() | ||
317 | 177 | runnee = Stub(simulated_failure=FakeFailure("Headless boom.")) | ||
318 | 178 | |||
319 | 179 | self._runInstance(instance, runnee=runnee, headless=True) | ||
320 | 180 | |||
321 | 181 | self.assertEqual(1, instance.shutdown.call_count) | ||
322 | 182 | |||
323 | 183 | |||
324 | 184 | def test_suite(): | ||
325 | 185 | return TestLoader().loadTestsFromName(__name__) | ||
326 | 0 | 186 | ||
327 | === modified file 'lib/lp/code/model/directbranchcommit.py' | |||
328 | --- lib/lp/code/model/directbranchcommit.py 2009-09-09 20:03:19 +0000 | |||
329 | +++ lib/lp/code/model/directbranchcommit.py 2009-11-27 16:21:25 +0000 | |||
330 | @@ -74,6 +74,8 @@ | |||
331 | 74 | self.db_branch = db_branch | 74 | self.db_branch = db_branch |
332 | 75 | self.to_mirror = to_mirror | 75 | self.to_mirror = to_mirror |
333 | 76 | 76 | ||
334 | 77 | self.last_scanned_id = self.db_branch.last_scanned_id | ||
335 | 78 | |||
336 | 77 | if committer is None: | 79 | if committer is None: |
337 | 78 | committer = db_branch.owner | 80 | committer = db_branch.owner |
338 | 79 | self.committer = committer | 81 | self.committer = committer |
339 | @@ -172,12 +174,18 @@ | |||
340 | 172 | assert self.is_locked, "Getting revision on un-locked branch." | 174 | assert self.is_locked, "Getting revision on un-locked branch." |
341 | 173 | last_revision = None | 175 | last_revision = None |
342 | 174 | last_revision = self.bzrbranch.last_revision() | 176 | last_revision = self.bzrbranch.last_revision() |
344 | 175 | if last_revision != self.db_branch.last_scanned_id: | 177 | if last_revision != self.last_scanned_id: |
345 | 176 | raise ConcurrentUpdateError( | 178 | raise ConcurrentUpdateError( |
346 | 177 | "Branch has been changed. Not committing.") | 179 | "Branch has been changed. Not committing.") |
347 | 178 | 180 | ||
350 | 179 | def commit(self, commit_message): | 181 | def commit(self, commit_message, txn=None): |
351 | 180 | """Commit to branch.""" | 182 | """Commit to branch. |
352 | 183 | |||
353 | 184 | :param commit_message: Message for branch's commit log. | ||
354 | 185 | :param txn: Transaction to commit. Can be helpful in avoiding | ||
355 | 186 | long idle times in database transactions. May be committed | ||
356 | 187 | more than once. | ||
357 | 188 | """ | ||
358 | 181 | assert self.is_open, "Committing closed DirectBranchCommit." | 189 | assert self.is_open, "Committing closed DirectBranchCommit." |
359 | 182 | assert self.is_locked, "Not locked at commit time." | 190 | assert self.is_locked, "Not locked at commit time." |
360 | 183 | 191 | ||
361 | @@ -185,6 +193,9 @@ | |||
362 | 185 | try: | 193 | try: |
363 | 186 | self._checkForRace() | 194 | self._checkForRace() |
364 | 187 | 195 | ||
365 | 196 | if txn: | ||
366 | 197 | txn.commit() | ||
367 | 198 | |||
368 | 188 | rev_id = self.revision_tree.get_revision_id() | 199 | rev_id = self.revision_tree.get_revision_id() |
369 | 189 | if rev_id == NULL_REVISION: | 200 | if rev_id == NULL_REVISION: |
370 | 190 | if list(self.transform_preview.iter_changes()) == []: | 201 | if list(self.transform_preview.iter_changes()) == []: |
371 | @@ -193,6 +204,9 @@ | |||
372 | 193 | self.bzrbranch, commit_message) | 204 | self.bzrbranch, commit_message) |
373 | 194 | IMasterObject(self.db_branch).requestMirror() | 205 | IMasterObject(self.db_branch).requestMirror() |
374 | 195 | 206 | ||
375 | 207 | if txn: | ||
376 | 208 | txn.commit() | ||
377 | 209 | |||
378 | 196 | finally: | 210 | finally: |
379 | 197 | self.unlock() | 211 | self.unlock() |
380 | 198 | self.is_open = False | 212 | self.is_open = False |
381 | 199 | 213 | ||
382 | === modified file 'lib/lp/code/tests/test_directbranchcommit.py' | |||
383 | --- lib/lp/code/tests/test_directbranchcommit.py 2009-10-02 09:48:30 +0000 | |||
384 | +++ lib/lp/code/tests/test_directbranchcommit.py 2009-11-27 16:21:25 +0000 | |||
385 | @@ -37,7 +37,7 @@ | |||
386 | 37 | 37 | ||
387 | 38 | self.committer = DirectBranchCommit(self.db_branch) | 38 | self.committer = DirectBranchCommit(self.db_branch) |
388 | 39 | if update_last_scanned_id: | 39 | if update_last_scanned_id: |
390 | 40 | self.db_branch.last_scanned_id = ( | 40 | self.committer.last_scanned_id = ( |
391 | 41 | self.committer.bzrbranch.last_revision()) | 41 | self.committer.bzrbranch.last_revision()) |
392 | 42 | 42 | ||
393 | 43 | def _tearDownCommitter(self): | 43 | def _tearDownCommitter(self): |
394 | 44 | 44 | ||
395 | === modified file 'lib/lp/soyuz/templates/archive-index.pt' | |||
396 | --- lib/lp/soyuz/templates/archive-index.pt 2009-11-04 13:56:17 +0000 | |||
397 | +++ lib/lp/soyuz/templates/archive-index.pt 2009-11-27 16:21:25 +0000 | |||
398 | @@ -30,7 +30,7 @@ | |||
399 | 30 | This archive has been disabled. | 30 | This archive has been disabled. |
400 | 31 | </p> | 31 | </p> |
401 | 32 | 32 | ||
403 | 33 | <div id="edit-description" | 33 | <div id="edit-description" class="lazr-multiline-edit" |
404 | 34 | tal:content="structure view/archive_description_html" | 34 | tal:content="structure view/archive_description_html" |
405 | 35 | /> | 35 | /> |
406 | 36 | </div> | 36 | </div> |
407 | 37 | 37 | ||
408 | === modified file 'lib/lp/translations/doc/translations-export-to-branch.txt' | |||
409 | --- lib/lp/translations/doc/translations-export-to-branch.txt 2009-10-20 06:03:46 +0000 | |||
410 | +++ lib/lp/translations/doc/translations-export-to-branch.txt 2009-11-27 16:21:25 +0000 | |||
411 | @@ -45,7 +45,7 @@ | |||
412 | 45 | ... if self.simulate_race: | 45 | ... if self.simulate_race: |
413 | 46 | ... raise ConcurrentUpdateError("Simulated race condition.") | 46 | ... raise ConcurrentUpdateError("Simulated race condition.") |
414 | 47 | ... | 47 | ... |
416 | 48 | ... def commit(self, message=None): | 48 | ... def commit(self, message=None, txn=None): |
417 | 49 | ... self._checkForRace() | 49 | ... self._checkForRace() |
418 | 50 | ... self.logger.info("Committed %d file(s)." % self.written_files) | 50 | ... self.logger.info("Committed %d file(s)." % self.written_files) |
419 | 51 | ... | 51 | ... |
420 | @@ -129,11 +129,11 @@ | |||
421 | 129 | 129 | ||
422 | 130 | >>> transaction.commit() | 130 | >>> transaction.commit() |
423 | 131 | >>> script = MockExportTranslationsToBranch( | 131 | >>> script = MockExportTranslationsToBranch( |
425 | 132 | ... 'export-to-branch', test_args=['-vv']) | 132 | ... 'export-to-branch', test_args=[]) |
426 | 133 | >>> script.main() | 133 | >>> script.main() |
427 | 134 | INFO Exporting to translations branches. | 134 | INFO Exporting to translations branches. |
428 | 135 | INFO Exporting Gazblachko trunk series. | 135 | INFO Exporting Gazblachko trunk series. |
430 | 136 | DEBUG No previous translations commit found. | 136 | DEBUG ... |
431 | 137 | INFO Writing file 'po/main/nl.po': | 137 | INFO Writing file 'po/main/nl.po': |
432 | 138 | INFO # ... | 138 | INFO # ... |
433 | 139 | msgid "" | 139 | msgid "" |
434 | @@ -143,6 +143,7 @@ | |||
435 | 143 | msgid "maingazpot msgid" | 143 | msgid "maingazpot msgid" |
436 | 144 | msgstr "maingazpot msgstr" | 144 | msgstr "maingazpot msgstr" |
437 | 145 | <BLANKLINE> | 145 | <BLANKLINE> |
438 | 146 | DEBUG ... | ||
439 | 146 | INFO Writing file 'po/module/nl.po': | 147 | INFO Writing file 'po/module/nl.po': |
440 | 147 | INFO # ... | 148 | INFO # ... |
441 | 148 | msgid "" | 149 | msgid "" |
442 | @@ -152,6 +153,8 @@ | |||
443 | 152 | <BLANKLINE> | 153 | <BLANKLINE> |
444 | 153 | msgid "gazmod msgid" | 154 | msgid "gazmod msgid" |
445 | 154 | msgstr "gazmod msgstr" | 155 | msgstr "gazmod msgstr" |
446 | 156 | <BLANKLINE> | ||
447 | 157 | DEBUG ... | ||
448 | 155 | INFO Committed 2 file(s). | 158 | INFO Committed 2 file(s). |
449 | 156 | INFO Unlock. | 159 | INFO Unlock. |
450 | 157 | INFO Processed 1 item(s); 0 failure(s). | 160 | INFO Processed 1 item(s); 0 failure(s). |
451 | @@ -186,6 +189,7 @@ | |||
452 | 186 | >>> script.main() | 189 | >>> script.main() |
453 | 187 | INFO Exporting to translations branches. | 190 | INFO Exporting to translations branches. |
454 | 188 | INFO Exporting Gazblachko trunk series. | 191 | INFO Exporting Gazblachko trunk series. |
455 | 192 | DEBUG .... | ||
456 | 189 | DEBUG Last commit was at .... | 193 | DEBUG Last commit was at .... |
457 | 190 | INFO Unlock. | 194 | INFO Unlock. |
458 | 191 | INFO Processed 1 item(s); 0 failure(s). | 195 | INFO Processed 1 item(s); 0 failure(s). |
459 | @@ -197,6 +201,7 @@ | |||
460 | 197 | >>> script.main() | 201 | >>> script.main() |
461 | 198 | INFO Exporting to translations branches. | 202 | INFO Exporting to translations branches. |
462 | 199 | INFO Exporting Gazblachko trunk series. | 203 | INFO Exporting Gazblachko trunk series. |
463 | 204 | DEBUG .... | ||
464 | 200 | DEBUG Last commit was at ... | 205 | DEBUG Last commit was at ... |
465 | 201 | INFO Writing file 'po/main/nl.po': | 206 | INFO Writing file 'po/main/nl.po': |
466 | 202 | INFO ... | 207 | INFO ... |
467 | @@ -228,11 +233,14 @@ | |||
468 | 228 | >>> script.main() | 233 | >>> script.main() |
469 | 229 | INFO Exporting to translations branches. | 234 | INFO Exporting to translations branches. |
470 | 230 | INFO Exporting Gazblachko trunk series. | 235 | INFO Exporting Gazblachko trunk series. |
471 | 236 | DEBUG .... | ||
472 | 231 | DEBUG No previous translations commit found. | 237 | DEBUG No previous translations commit found. |
473 | 238 | DEBUG .... | ||
474 | 232 | INFO Writing file 'po/main/nl.po': | 239 | INFO Writing file 'po/main/nl.po': |
475 | 233 | ... | 240 | ... |
476 | 234 | msgstr "gazmod msgstr" | 241 | msgstr "gazmod msgstr" |
477 | 235 | <BLANKLINE> | 242 | <BLANKLINE> |
478 | 243 | DEBUG ... | ||
479 | 236 | INFO Unlock. | 244 | INFO Unlock. |
480 | 237 | ERROR Failure: Simulated race condition. | 245 | ERROR Failure: Simulated race condition. |
481 | 238 | INFO Processed 1 item(s); 1 failure(s). | 246 | INFO Processed 1 item(s); 1 failure(s). |
482 | 239 | 247 | ||
483 | === modified file 'lib/lp/translations/scripts/translations_to_branch.py' | |||
484 | --- lib/lp/translations/scripts/translations_to_branch.py 2009-10-20 06:03:46 +0000 | |||
485 | +++ lib/lp/translations/scripts/translations_to_branch.py 2009-11-27 16:21:25 +0000 | |||
486 | @@ -119,7 +119,7 @@ | |||
487 | 119 | def _commit(self, source, committer): | 119 | def _commit(self, source, committer): |
488 | 120 | """Commit changes to branch. Check for race conditions.""" | 120 | """Commit changes to branch. Check for race conditions.""" |
489 | 121 | self._checkForObjections(source) | 121 | self._checkForObjections(source) |
491 | 122 | committer.commit(self.commit_message) | 122 | committer.commit(self.commit_message, txn=self.txn) |
492 | 123 | 123 | ||
493 | 124 | def _isTranslationsCommit(self, revision): | 124 | def _isTranslationsCommit(self, revision): |
494 | 125 | """Is `revision` an automatic translations commit?""" | 125 | """Is `revision` an automatic translations commit?""" |
495 | @@ -159,6 +159,9 @@ | |||
496 | 159 | self._checkForObjections(source) | 159 | self._checkForObjections(source) |
497 | 160 | 160 | ||
498 | 161 | committer = self._prepareBranchCommit(source.translations_branch) | 161 | committer = self._prepareBranchCommit(source.translations_branch) |
499 | 162 | self.logger.debug("Created DirectBranchCommit.") | ||
500 | 163 | if self.txn: | ||
501 | 164 | self.txn.commit() | ||
502 | 162 | 165 | ||
503 | 163 | bzr_branch = committer.bzrbranch | 166 | bzr_branch = committer.bzrbranch |
504 | 164 | 167 | ||
505 | @@ -185,15 +188,17 @@ | |||
506 | 185 | base_path = os.path.dirname(template.path) | 188 | base_path = os.path.dirname(template.path) |
507 | 186 | 189 | ||
508 | 187 | for pofile in template.pofiles: | 190 | for pofile in template.pofiles: |
509 | 188 | |||
510 | 189 | has_changed = ( | 191 | has_changed = ( |
511 | 190 | changed_since is None or | 192 | changed_since is None or |
512 | 191 | pofile.date_changed > changed_since) | 193 | pofile.date_changed > changed_since) |
513 | 192 | if not has_changed: | 194 | if not has_changed: |
514 | 193 | continue | 195 | continue |
515 | 194 | 196 | ||
516 | 197 | language_code = pofile.getFullLanguageCode() | ||
517 | 198 | self.logger.debug("Exporting %s." % language_code) | ||
518 | 199 | |||
519 | 195 | pofile_path = os.path.join( | 200 | pofile_path = os.path.join( |
521 | 196 | base_path, pofile.getFullLanguageCode() + '.po') | 201 | base_path, language_code + '.po') |
522 | 197 | pofile_contents = pofile.export() | 202 | pofile_contents = pofile.export() |
523 | 198 | 203 | ||
524 | 199 | committer.writeFile(pofile_path, pofile_contents) | 204 | committer.writeFile(pofile_path, pofile_contents) |
525 | @@ -210,6 +215,7 @@ | |||
526 | 210 | template.clearPOFileCache() | 215 | template.clearPOFileCache() |
527 | 211 | 216 | ||
528 | 212 | if change_count > 0: | 217 | if change_count > 0: |
529 | 218 | self.logger.debug("Writing to branch.") | ||
530 | 213 | self._commit(source, committer) | 219 | self._commit(source, committer) |
531 | 214 | finally: | 220 | finally: |
532 | 215 | committer.unlock() | 221 | committer.unlock() |
533 | @@ -231,13 +237,14 @@ | |||
534 | 231 | raise | 237 | raise |
535 | 232 | except Exception, e: | 238 | except Exception, e: |
536 | 233 | items_failed += 1 | 239 | items_failed += 1 |
538 | 234 | self.logger.error("Failure: %s" % e) | 240 | message = unicode(e) |
539 | 241 | if message == u'': | ||
540 | 242 | message = e.__class__.__name__ | ||
541 | 243 | self.logger.error("Failure: %s" % message) | ||
542 | 235 | if self.txn: | 244 | if self.txn: |
543 | 236 | self.txn.abort() | 245 | self.txn.abort() |
544 | 237 | 246 | ||
545 | 238 | items_done += 1 | 247 | items_done += 1 |
546 | 239 | if self.txn: | ||
547 | 240 | self.txn.begin() | ||
548 | 241 | 248 | ||
549 | 242 | self.logger.info("Processed %d item(s); %d failure(s)." % ( | 249 | self.logger.info("Processed %d item(s); %d failure(s)." % ( |
550 | 243 | items_done, items_failed)) | 250 | items_done, items_failed)) |
551 | 244 | 251 | ||
552 | === modified file 'lib/lp/translations/utilities/gettext_po_exporter.py' | |||
553 | --- lib/lp/translations/utilities/gettext_po_exporter.py 2009-11-02 00:10:05 +0000 | |||
554 | +++ lib/lp/translations/utilities/gettext_po_exporter.py 2009-11-27 16:21:25 +0000 | |||
555 | @@ -14,6 +14,7 @@ | |||
556 | 14 | 'GettextPOExporter', | 14 | 'GettextPOExporter', |
557 | 15 | ] | 15 | ] |
558 | 16 | 16 | ||
559 | 17 | import logging | ||
560 | 17 | import os | 18 | import os |
561 | 18 | 19 | ||
562 | 19 | from zope.interface import implements | 20 | from zope.interface import implements |
563 | @@ -344,8 +345,20 @@ | |||
564 | 344 | raise UnicodeEncodeError( | 345 | raise UnicodeEncodeError( |
565 | 345 | '%s:\n%s' % (file_path, str(error))) | 346 | '%s:\n%s' % (file_path, str(error))) |
566 | 346 | 347 | ||
569 | 347 | # This message cannot be represented in current encoding, | 348 | # This message cannot be represented in the current |
570 | 348 | # change to UTF-8 and try again. | 349 | # encoding. |
571 | 350 | if translation_file.path: | ||
572 | 351 | file_description = translation_file.path | ||
573 | 352 | elif translation_file.language_code: | ||
574 | 353 | file_description = ( | ||
575 | 354 | "%s translation" % translation_file.language_code) | ||
576 | 355 | else: | ||
577 | 356 | file_description = "template" | ||
578 | 357 | logging.info( | ||
579 | 358 | "Can't represent %s as %s; using UTF-8 instead." % ( | ||
580 | 359 | file_description, | ||
581 | 360 | translation_file.header.charset.upper())) | ||
582 | 361 | |||
583 | 349 | old_charset = translation_file.header.charset | 362 | old_charset = translation_file.header.charset |
584 | 350 | translation_file.header.charset = 'UTF-8' | 363 | translation_file.header.charset = 'UTF-8' |
585 | 351 | # We need to update the header too. | 364 | # We need to update the header too. |
586 | 352 | 365 | ||
587 | === modified file 'utilities/rocketfuel-setup' | |||
588 | --- utilities/rocketfuel-setup 2009-11-12 06:57:28 +0000 | |||
589 | +++ utilities/rocketfuel-setup 2009-11-27 16:21:25 +0000 | |||
590 | @@ -7,7 +7,7 @@ | |||
591 | 7 | # workstation, from scratch. The script lives in the LP codebase itself, | 7 | # workstation, from scratch. The script lives in the LP codebase itself, |
592 | 8 | # as utilities/rocketfuel-setup | 8 | # as utilities/rocketfuel-setup |
593 | 9 | 9 | ||
595 | 10 | # We require Bazaar 1.16.1 or higher. | 10 | # We require Bazaar 1.16.1 or higher. |
596 | 11 | # So first, grab the output of 'bzr --version' and transform the | 11 | # So first, grab the output of 'bzr --version' and transform the |
597 | 12 | # version line, like "Bazaar (bzr) 1.16.1", into "1 16 1": | 12 | # version line, like "Bazaar (bzr) 1.16.1", into "1 16 1": |
598 | 13 | VER_RAW=`bzr --version | head -1 | sed -e 's/Bazaar (bzr) //g'` | 13 | VER_RAW=`bzr --version | head -1 | sed -e 's/Bazaar (bzr) //g'` |
599 | @@ -315,6 +315,8 @@ | |||
600 | 315 | fi | 315 | fi |
601 | 316 | fi | 316 | fi |
602 | 317 | 317 | ||
603 | 318 | # Call the newly minted Launchpad branch's 'make install' target to do some | ||
604 | 319 | # more apache setup. | ||
605 | 318 | sudo make install > /dev/null | 320 | sudo make install > /dev/null |
606 | 319 | if [ $? -ne 0 ]; then | 321 | if [ $? -ne 0 ]; then |
607 | 320 | echo "ERROR: Unable to install apache config appropriately" | 322 | echo "ERROR: Unable to install apache config appropriately" |
= Summary =
This is a fix for bug 470181.
I'm not 100%, but it seems as though since we integrated the multiline editor on the PPA index page, a subsequent requirement has been added (via lazr-js) of a lazr-multiline-edit class.
This branch simply adds that class to fix the bug.
== Demo and Q/A ==
View https:/ /launchpad. dev/~cprov/ +archive/ ppa before merging this branch to see the issue (or view a ppa on edge).
Then reload the same page after merging to see it fixed.
= Launchpad lint =
Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.
Linting changed files: soyuz/templates /archive- index.pt
lib/lp/