Merge lp:~rockstar/launchpad/upgrade-job-2.0-changes into lp:launchpad

Proposed by Paul Hummer
Status: Merged
Approved by: Edwin Grubbs
Approved revision: no longer in the source branch.
Merged at revision: not available
Proposed branch: lp:~rockstar/launchpad/upgrade-job-2.0-changes
Merge into: lp:launchpad
Diff against target: 425 lines (+209/-14)
11 files modified
lib/lp/code/browser/branch.py (+31/-1)
lib/lp/code/browser/configure.zcml (+7/-0)
lib/lp/code/bzr.py (+32/-0)
lib/lp/code/configure.zcml (+1/-0)
lib/lp/code/interfaces/branch.py (+2/-0)
lib/lp/code/model/branch.py (+18/-5)
lib/lp/code/model/branchjob.py (+2/-0)
lib/lp/code/model/tests/test_branch.py (+51/-7)
lib/lp/code/stories/branches/xx-upgrading-branches.txt (+49/-0)
lib/lp/code/templates/branch-messages.pt (+6/-0)
lib/lp/code/templates/branch-metadata.pt (+10/-1)
To merge this branch: bzr merge lp:~rockstar/launchpad/upgrade-job-2.0-changes
Reviewer Review Type Date Requested Status
Edwin Grubbs (community) code Approve
Review via email: mp+17701@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Paul Hummer (rockstar) wrote :

Hi there-

  This branch makes some changes to the branch upgrade structure and the way a
branch determines whether or not it needs to be upgraded. Most of the original
code was pre-2.0, and now that bzr 2.0 has been released, the formats are a
little more stable, and we won't need to be concerned too much about changing
formats anymore.

  Instead of saying X format needs to be upgraded to Y format, we can just
upgrade it and it'll go to the 2.0 format regardless of the original format (as
opposed to the potential downgrade of older bzr).

Cheers,
Paul

Revision history for this message
Paul Hummer (rockstar) wrote :
Download full text (9.6 KiB)

Hrm, this diff seems confused. It has this branch's changes as well as the next branch's changes... Here's the real diff:

=== modified file 'lib/lp/code/bzr.py'
--- lib/lp/code/bzr.py 2009-06-30 16:56:07 +0000
+++ lib/lp/code/bzr.py 2010-01-16 07:38:47 +0000
@@ -8,6 +8,8 @@
     'BranchFormat',
     'BRANCH_FORMAT_UPGRADE_PATH',
     'ControlFormat',
+ 'CURRENT_BRANCH_FORMATS',
+ 'CURRENT_REPOSITORY_FORMATS',
     'RepositoryFormat',
     'REPOSITORY_FORMAT_UPGRADE_PATH',
     ]
@@ -222,6 +224,36 @@
     BZR_METADIR_1 = _format_enum(1, BzrDirMetaFormat1)

+# A tuple of branch formats that should not suggest upgrading.
+CURRENT_BRANCH_FORMATS = (
+ BranchFormat.UNRECOGNIZED,
+ BranchFormat.BRANCH_REFERENCE,
+ BranchFormat.BZR_BRANCH_8,
+ BranchFormat.BZR_LOOM_1,
+ BranchFormat.BZR_LOOM_2,
+ BranchFormat.BZR_LOOM_3,
+)
+
+# A tuple of repository formats that should not suggest upgrading.
+CURRENT_REPOSITORY_FORMATS = (
+ RepositoryFormat.UNRECOGNIZED,
+ RepositoryFormat.BZR_KNITPACK_3,
+ RepositoryFormat.BZR_KNITPACK_5,
+ RepositoryFormat.BZR_KNITPACK_5_RR,
+ RepositoryFormat.BZR_KNITPACK_6,
+ RepositoryFormat.BZR_KNITPACK_6_RR,
+ RepositoryFormat.BZR_PACK_DEV_0,
+ RepositoryFormat.BZR_PACK_DEV_0_SUBTREE,
+ RepositoryFormat.BZR_DEV_1,
+ RepositoryFormat.BZR_DEV_1_SUBTREE,
+ RepositoryFormat.BZR_DEV_2,
+ RepositoryFormat.BZR_DEV_2_SUBTREE,
+ RepositoryFormat.BZR_CHK1,
+ RepositoryFormat.BZR_CHK2,
+ RepositoryFormat.BZR_CHK_2A
+
+)
+
 BRANCH_FORMAT_UPGRADE_PATH = {
     BranchFormat.UNRECOGNIZED: None,
     BranchFormat.BRANCH_REFERENCE: None,

=== modified file 'lib/lp/code/configure.zcml'
--- lib/lp/code/configure.zcml 2010-01-06 14:14:35 +0000
+++ lib/lp/code/configure.zcml 2010-01-18 01:19:38 +0000
@@ -487,6 +487,7 @@
                     pending_writes
                     commitsForDays
                     needs_upgrading
+ upgrade_pending
                     requestUpgrade
                     getUpgradeFormat
                     isBranchMergeable

=== modified file 'lib/lp/code/interfaces/branch.py'
--- lib/lp/code/interfaces/branch.py 2010-01-06 12:15:42 +0000
+++ lib/lp/code/interfaces/branch.py 2010-01-18 01:19:39 +0000
@@ -1057,6 +1057,8 @@
         """

     needs_upgrading = Attribute("Whether the branch needs to be upgraded.")
+ upgrade_pending = Attribute(
+ "Whether a branch has had an upgrade requested.")

     def requestUpgrade():
         """Create an IBranchUpgradeJob to upgrade this branch."""

=== modified file 'lib/lp/code/model/branch.py'
--- lib/lp/code/model/branch.py 2009-12-11 00:56:16 +0000
+++ lib/lp/code/model/branch.py 2010-01-19 21:57:57 +0000
@@ -42,7 +42,8 @@
     IStoreSelector, MAIN_STORE, SLAVE_FLAVOR)

 from lp.code.bzr import (
- BranchFormat, BRANCH_FORMAT_UPGRADE_PATH, ControlFormat, RepositoryFormat,
+ BranchFormat, BRANCH_FORMAT_UPGRADE_PATH, ControlFormat,
+ CURRENT_BRANCH_FORMATS, CURRENT_REPOSITORY_FORMATS, RepositoryFormat,
     REPOSITORY_FORMAT_UPGRADE_PATH)
 from lp.code.enums import (
     BranchLifecycleStatus, BranchMergeControlStatus,
@@ -991,10 +992,22 @@
     @property
  ...

Read more...

Revision history for this message
Edwin Grubbs (edwin-grubbs) wrote :

Hi Paul,

This is a nice improvement. Please change the zcml to require launchpad.Edit for requestUpgrade(). I just have one comment below.

merge-conditional

-Edwin

> === modified file 'lib/lp/code/model/tests/test_branch.py'
> --- lib/lp/code/model/tests/test_branch.py 2010-01-07 06:37:14 +0000
> +++ lib/lp/code/model/tests/test_branch.py 2010-01-19 22:00:02 +0000
> @@ -315,24 +315,33 @@
> SourcePackage(branch.sourcepackagename, branch.distroseries),
> branch.sourcepackage)
>
> + def test_needsUpgrading_already_requested(self):
> + # A branch has a needs_upgrading attribute that returns whether or
> not
> + # a branch needs to be upgraded or not. If the format is
> + # unrecognized, we don't try to upgrade it.
> + branch = self.factory.makePersonalBranch(
> + branch_format=BranchFormat.BZR_BRANCH_6,
> + repository_format=RepositoryFormat.BZR_CHK_2A)
> + branch.requestUpgrade()
> +
> + self.assertFalse(branch.needs_upgrading)
> +
> def test_needsUpgrading_branch_format_unrecognized(self):
> # A branch has a needs_upgrading attribute that returns whether or
> not
> # a branch needs to be upgraded or not. If the format is
> # unrecognized, we don't try to upgrade it.
> branch = self.factory.makePersonalBranch(
> - branch_format=BranchFormat.UNRECOGNIZED)
> + branch_format=BranchFormat.UNRECOGNIZED,
> + repository_format=RepositoryFormat.BZR_CHK_2A)
> self.assertFalse(branch.needs_upgrading)
>
> def test_needsUpgrading_branch_format_upgrade_not_needed(self):
> # A branch has a needs_upgrading attribute that returns whether or
> not
> # a branch needs to be upgraded or not. If a branch is up to date,
> it

s/up to date/up-to-date/

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/code/browser/branch.py'
2--- lib/lp/code/browser/branch.py 2010-01-17 00:59:01 +0000
3+++ lib/lp/code/browser/branch.py 2010-01-20 00:20:29 +0000
4@@ -20,6 +20,7 @@
5 'BranchEditMenu',
6 'BranchInProductView',
7 'BranchSparkView',
8+ 'BranchUpgradeView',
9 'BranchURL',
10 'BranchView',
11 'BranchSubscriptionsView',
12@@ -231,7 +232,7 @@
13 links = [
14 'add_subscriber', 'browse_revisions', 'link_bug',
15 'link_blueprint', 'register_merge', 'source', 'subscription',
16- 'edit_status']
17+ 'edit_status', 'upgrade_branch']
18
19 @enabled_with_permission('launchpad.Edit')
20 def edit_status(self):
21@@ -298,6 +299,14 @@
22 url = self.context.codebrowse_url('files')
23 return Link(url, text, icon='info', enabled=enabled)
24
25+ @enabled_with_permission('launchpad.Edit')
26+ def upgrade_branch(self):
27+ enabled = False
28+ if self.context.needs_upgrading:
29+ enabled = True
30+ return Link(
31+ '+upgrade', 'Upgrade this branch', icon='edit', enabled=enabled)
32+
33
34 class DecoratedBug:
35 """Provide some additional attributes to a normal bug."""
36@@ -877,6 +886,27 @@
37 return canonical_url(self.context)
38
39
40+class BranchUpgradeView(LaunchpadFormView):
41+ """Used to upgrade a branch."""
42+
43+ schema = IBranch
44+ field_names = []
45+
46+ @property
47+ def page_title(self):
48+ return smartquote('Upgrade branch "%s"' % self.context.displayname)
49+
50+ @property
51+ def next_url(self):
52+ return canonical_url(self.context)
53+
54+ cancel_url = next_url
55+
56+ @action('Upgrade', name='upgrade_branch')
57+ def upgrade_branch_action(self, action, data):
58+ self.context.requestUpgrade()
59+
60+
61 class BranchEditView(BranchEditFormView, BranchNameValidationMixin):
62 """The main branch view for editing the branch attributes."""
63
64
65=== modified file 'lib/lp/code/browser/configure.zcml'
66--- lib/lp/code/browser/configure.zcml 2010-01-17 10:15:48 +0000
67+++ lib/lp/code/browser/configure.zcml 2010-01-20 00:20:29 +0000
68@@ -474,6 +474,13 @@
69 permission="launchpad.Edit"
70 template="../../app/templates/generic-edit.pt"/>
71 <browser:page
72+ name="+upgrade"
73+ for="lp.code.interfaces.branch.IBranch"
74+ class="lp.code.browser.branch.BranchUpgradeView"
75+ facet="branches"
76+ permission="launchpad.Edit"
77+ template="../../app/templates/generic-edit.pt"/>
78+ <browser:page
79 name="+reviewer"
80 for="lp.code.interfaces.branch.IBranch"
81 class="lp.code.browser.branch.BranchReviewerEditView"
82
83=== modified file 'lib/lp/code/bzr.py'
84--- lib/lp/code/bzr.py 2009-06-30 16:56:07 +0000
85+++ lib/lp/code/bzr.py 2010-01-20 00:20:29 +0000
86@@ -8,6 +8,8 @@
87 'BranchFormat',
88 'BRANCH_FORMAT_UPGRADE_PATH',
89 'ControlFormat',
90+ 'CURRENT_BRANCH_FORMATS',
91+ 'CURRENT_REPOSITORY_FORMATS',
92 'RepositoryFormat',
93 'REPOSITORY_FORMAT_UPGRADE_PATH',
94 ]
95@@ -222,6 +224,36 @@
96 BZR_METADIR_1 = _format_enum(1, BzrDirMetaFormat1)
97
98
99+# A tuple of branch formats that should not suggest upgrading.
100+CURRENT_BRANCH_FORMATS = (
101+ BranchFormat.UNRECOGNIZED,
102+ BranchFormat.BRANCH_REFERENCE,
103+ BranchFormat.BZR_BRANCH_8,
104+ BranchFormat.BZR_LOOM_1,
105+ BranchFormat.BZR_LOOM_2,
106+ BranchFormat.BZR_LOOM_3,
107+)
108+
109+# A tuple of repository formats that should not suggest upgrading.
110+CURRENT_REPOSITORY_FORMATS = (
111+ RepositoryFormat.UNRECOGNIZED,
112+ RepositoryFormat.BZR_KNITPACK_3,
113+ RepositoryFormat.BZR_KNITPACK_5,
114+ RepositoryFormat.BZR_KNITPACK_5_RR,
115+ RepositoryFormat.BZR_KNITPACK_6,
116+ RepositoryFormat.BZR_KNITPACK_6_RR,
117+ RepositoryFormat.BZR_PACK_DEV_0,
118+ RepositoryFormat.BZR_PACK_DEV_0_SUBTREE,
119+ RepositoryFormat.BZR_DEV_1,
120+ RepositoryFormat.BZR_DEV_1_SUBTREE,
121+ RepositoryFormat.BZR_DEV_2,
122+ RepositoryFormat.BZR_DEV_2_SUBTREE,
123+ RepositoryFormat.BZR_CHK1,
124+ RepositoryFormat.BZR_CHK2,
125+ RepositoryFormat.BZR_CHK_2A
126+
127+)
128+
129 BRANCH_FORMAT_UPGRADE_PATH = {
130 BranchFormat.UNRECOGNIZED: None,
131 BranchFormat.BRANCH_REFERENCE: None,
132
133=== modified file 'lib/lp/code/configure.zcml'
134--- lib/lp/code/configure.zcml 2010-01-16 09:57:33 +0000
135+++ lib/lp/code/configure.zcml 2010-01-20 00:20:29 +0000
136@@ -487,6 +487,7 @@
137 pending_writes
138 commitsForDays
139 needs_upgrading
140+ upgrade_pending
141 requestUpgrade
142 getUpgradeFormat
143 isBranchMergeable
144
145=== modified file 'lib/lp/code/interfaces/branch.py'
146--- lib/lp/code/interfaces/branch.py 2010-01-15 03:22:12 +0000
147+++ lib/lp/code/interfaces/branch.py 2010-01-20 00:20:29 +0000
148@@ -1068,6 +1068,8 @@
149 """
150
151 needs_upgrading = Attribute("Whether the branch needs to be upgraded.")
152+ upgrade_pending = Attribute(
153+ "Whether a branch has had an upgrade requested.")
154
155 def requestUpgrade():
156 """Create an IBranchUpgradeJob to upgrade this branch."""
157
158=== modified file 'lib/lp/code/model/branch.py'
159--- lib/lp/code/model/branch.py 2010-01-15 03:22:12 +0000
160+++ lib/lp/code/model/branch.py 2010-01-20 00:20:29 +0000
161@@ -42,7 +42,8 @@
162 IStoreSelector, MAIN_STORE, SLAVE_FLAVOR)
163
164 from lp.code.bzr import (
165- BranchFormat, BRANCH_FORMAT_UPGRADE_PATH, ControlFormat, RepositoryFormat,
166+ BranchFormat, BRANCH_FORMAT_UPGRADE_PATH, ControlFormat,
167+ CURRENT_BRANCH_FORMATS, CURRENT_REPOSITORY_FORMATS, RepositoryFormat,
168 REPOSITORY_FORMAT_UPGRADE_PATH)
169 from lp.code.enums import (
170 BranchLifecycleStatus, BranchMergeControlStatus,
171@@ -995,10 +996,22 @@
172 @property
173 def needs_upgrading(self):
174 """See `IBranch`."""
175- if (REPOSITORY_FORMAT_UPGRADE_PATH.get(self.repository_format, None)
176- or BRANCH_FORMAT_UPGRADE_PATH.get(self.branch_format, None)):
177- return True
178- return False
179+ if self.upgrade_pending:
180+ return False
181+ return not (
182+ self.branch_format in CURRENT_BRANCH_FORMATS and
183+ self.repository_format in CURRENT_REPOSITORY_FORMATS)
184+
185+ @property
186+ def upgrade_pending(self):
187+ """See `IBranch`."""
188+ from lp.code.model.branchjob import BranchJob, BranchJobType
189+ store = Store.of(self)
190+ jobs = store.find(
191+ BranchJob,
192+ BranchJob.branch == self,
193+ BranchJob.job_type == BranchJobType.UPGRADE_BRANCH)
194+ return jobs.count() > 0
195
196 def requestUpgrade(self):
197 """See `IBranch`."""
198
199=== modified file 'lib/lp/code/model/branchjob.py'
200--- lib/lp/code/model/branchjob.py 2010-01-15 03:32:46 +0000
201+++ lib/lp/code/model/branchjob.py 2010-01-20 00:20:29 +0000
202@@ -264,6 +264,8 @@
203 """See `IBranchUpgradeJobSource`."""
204 if not branch.needs_upgrading:
205 raise AssertionError('Branch does not need upgrading.')
206+ if branch.upgrade_pending:
207+ raise AssertionError('Branch already has upgrade pending.')
208 branch_job = BranchJob(branch, BranchJobType.UPGRADE_BRANCH, {})
209 return cls(branch_job)
210
211
212=== modified file 'lib/lp/code/model/tests/test_branch.py'
213--- lib/lp/code/model/tests/test_branch.py 2010-01-07 06:37:14 +0000
214+++ lib/lp/code/model/tests/test_branch.py 2010-01-20 00:20:29 +0000
215@@ -315,24 +315,33 @@
216 SourcePackage(branch.sourcepackagename, branch.distroseries),
217 branch.sourcepackage)
218
219+ def test_needsUpgrading_already_requested(self):
220+ # A branch has a needs_upgrading attribute that returns whether or not
221+ # a branch needs to be upgraded or not. If the format is
222+ # unrecognized, we don't try to upgrade it.
223+ branch = self.factory.makePersonalBranch(
224+ branch_format=BranchFormat.BZR_BRANCH_6,
225+ repository_format=RepositoryFormat.BZR_CHK_2A)
226+ branch.requestUpgrade()
227+
228+ self.assertFalse(branch.needs_upgrading)
229+
230 def test_needsUpgrading_branch_format_unrecognized(self):
231 # A branch has a needs_upgrading attribute that returns whether or not
232 # a branch needs to be upgraded or not. If the format is
233 # unrecognized, we don't try to upgrade it.
234 branch = self.factory.makePersonalBranch(
235- branch_format=BranchFormat.UNRECOGNIZED)
236+ branch_format=BranchFormat.UNRECOGNIZED,
237+ repository_format=RepositoryFormat.BZR_CHK_2A)
238 self.assertFalse(branch.needs_upgrading)
239
240 def test_needsUpgrading_branch_format_upgrade_not_needed(self):
241 # A branch has a needs_upgrading attribute that returns whether or not
242 # a branch needs to be upgraded or not. If a branch is up to date, it
243 # doesn't need to be upgraded.
244- #
245- # XXX: JonathanLange 2009-06-06: This test needs to be changed every
246- # time Bazaar adds a new branch format. Surely we can think of a
247- # better way of testing this?
248 branch = self.factory.makePersonalBranch(
249- branch_format=BranchFormat.BZR_BRANCH_8)
250+ branch_format=BranchFormat.BZR_BRANCH_8,
251+ repository_format=RepositoryFormat.BZR_CHK_2A)
252 self.assertFalse(branch.needs_upgrading)
253
254 def test_needsUpgrading_branch_format_upgrade_needed(self):
255@@ -340,7 +349,8 @@
256 # a branch needs to be upgraded or not. If a branch doesn't support
257 # stacking, it needs to be upgraded.
258 branch = self.factory.makePersonalBranch(
259- branch_format=BranchFormat.BZR_BRANCH_6)
260+ branch_format=BranchFormat.BZR_BRANCH_6,
261+ repository_format=RepositoryFormat.BZR_CHK_2A)
262 self.assertTrue(branch.needs_upgrading)
263
264 def test_needsUpgrading_repository_format_unrecognized(self):
265@@ -348,6 +358,7 @@
266 # a branch needs to be upgraded or not. In the repo format is
267 # unrecognized, we don't try to upgrade it.
268 branch = self.factory.makePersonalBranch(
269+ branch_format=BranchFormat.BZR_BRANCH_8,
270 repository_format=RepositoryFormat.UNRECOGNIZED)
271 self.assertFalse(branch.needs_upgrading)
272
273@@ -356,6 +367,7 @@
274 # branch needs to be upgraded or not. If the repo format is up to
275 # date, there's no need to upgrade it.
276 branch = self.factory.makePersonalBranch(
277+ branch_format=BranchFormat.BZR_BRANCH_8,
278 repository_format=RepositoryFormat.BZR_KNITPACK_6)
279 self.assertFalse(branch.needs_upgrading)
280
281@@ -364,6 +376,7 @@
282 # branch needs to be upgraded or not. If the format doesn't support
283 # stacking, it needs to be upgraded.
284 branch = self.factory.makePersonalBranch(
285+ branch_format=BranchFormat.BZR_BRANCH_8,
286 repository_format=RepositoryFormat.BZR_REPOSITORY_4)
287 self.assertTrue(branch.needs_upgrading)
288
289@@ -378,6 +391,37 @@
290 jobs,
291 [job,])
292
293+ def test_requestUpgrade_no_upgrade_needed(self):
294+ # If a branch doesn't need to be upgraded, requestUpgrade raises an
295+ # AssertionError.
296+ branch = self.factory.makeAnyBranch(
297+ branch_format=BranchFormat.BZR_BRANCH_8,
298+ repository_format=RepositoryFormat.BZR_CHK_2A)
299+ self.assertRaises(AssertionError, branch.requestUpgrade)
300+
301+ def test_requestUpgrade_upgrade_pending(self):
302+ # If there is a pending upgrade already requested, requestUpgrade
303+ # raises an AssertionError.
304+ branch = self.factory.makeAnyBranch(
305+ branch_format=BranchFormat.BZR_BRANCH_6)
306+ branch.requestUpgrade()
307+
308+ self.assertRaises(AssertionError, branch.requestUpgrade)
309+
310+ def test_upgradePending(self):
311+ # If there is a BranchUpgradeJob pending for the branch, return True.
312+ branch = self.factory.makeAnyBranch(
313+ branch_format=BranchFormat.BZR_BRANCH_6)
314+ branch.requestUpgrade()
315+
316+ self.assertTrue(branch.upgrade_pending)
317+
318+ def test_upgradePending_no_upgrade_requested(self):
319+ # If the branch never had an upgrade requested, return False.
320+ branch = self.factory.makeAnyBranch()
321+
322+ self.assertFalse(branch.upgrade_pending)
323+
324
325 class TestBzrIdentity(TestCaseWithFactory):
326 """Test IBranch.bzr_identity."""
327
328=== added file 'lib/lp/code/stories/branches/xx-upgrading-branches.txt'
329--- lib/lp/code/stories/branches/xx-upgrading-branches.txt 1970-01-01 00:00:00 +0000
330+++ lib/lp/code/stories/branches/xx-upgrading-branches.txt 2010-01-20 00:20:29 +0000
331@@ -0,0 +1,49 @@
332+==================
333+Upgrading Branches
334+==================
335+
336+Launchpad can upgrade branches that were in an older format to a more up to
337+date format.
338+
339+
340+Creating the branch
341+===================
342+
343+Branches are not available to be upgraded if they are in a more up to date
344+format.
345+
346+ >>> from lp.code.bzr import BranchFormat, RepositoryFormat
347+ >>> login('foo.bar@canonical.com')
348+ >>> domino = factory.makePerson(
349+ ... name='domino', email="fats@domino.com", password="test")
350+ >>> twist = factory.makeAnyBranch(
351+ ... branch_format=BranchFormat.BZR_BRANCH_6,
352+ ... repository_format=RepositoryFormat.BZR_CHK_2A,
353+ ... owner=domino)
354+ >>> branch_url = canonical_url(twist)
355+ >>> logout()
356+
357+
358+Requesting an upgrade
359+=====================
360+
361+Only those with edit permissions on a branch can request an upgrade.
362+
363+ >>> nopriv_browser = setupBrowser(
364+ ... auth='Basic nopriv@canonical.com:test')
365+ >>> nopriv_browser.open(branch_url)
366+ >>> link = nopriv_browser.getLink('Upgrade this branch')
367+ Traceback (most recent call last):
368+ LinkNotFoundError
369+
370+ >>> domino_browser = setupBrowser(
371+ ... auth='Basic fats@domino.com:test')
372+ >>> domino_browser.open(branch_url)
373+ >>> domino_browser.getLink("Upgrade this branch").click()
374+ >>> print domino_browser.url
375+ http://code.launchpad.dev/~domino/.../+upgrade
376+ >>> domino_browser.getControl('Upgrade').click()
377+
378+ >>> for msg in get_feedback_messages(domino_browser.contents):
379+ ... print msg
380+ An upgrade of this branch is in progress.
381
382=== modified file 'lib/lp/code/templates/branch-messages.pt'
383--- lib/lp/code/templates/branch-messages.pt 2009-07-17 17:59:07 +0000
384+++ lib/lp/code/templates/branch-messages.pt 2010-01-20 00:20:29 +0000
385@@ -115,6 +115,12 @@
386 tal:condition="branch/mirror_status_message"
387 tal:content="branch/mirror_status_message">
388 </div>
389+ <div id="upgrade-pending"
390+ class="warning message" style="font-weight: normal"
391+ tal:condition="branch/upgrade_pending">
392+ An upgrade of this branch is in progress.
393+ </div>
394+
395 </tal:hosted-branch>
396
397 </div>
398
399=== modified file 'lib/lp/code/templates/branch-metadata.pt'
400--- lib/lp/code/templates/branch-metadata.pt 2009-09-08 21:26:03 +0000
401+++ lib/lp/code/templates/branch-metadata.pt 2010-01-20 00:20:29 +0000
402@@ -1,7 +1,8 @@
403 <div
404 xmlns:tal="http://xml.zope.org/namespaces/tal"
405 xmlns:metal="http://xml.zope.org/namespaces/metal"
406- xmlns:i18n="http://xml.zope.org/namespaces/i18n">
407+ xmlns:i18n="http://xml.zope.org/namespaces/i18n"
408+ tal:define="context_menu context/menu:context">
409
410 <div class="two-column-list">
411 <dl id="branch-format" tal:condition="context/branch_format">
412@@ -18,5 +19,13 @@
413 <dd tal:content="structure context/stacked_on/fmt:bzr-link" />
414 </dl>
415 </div>
416+ <div class="actions">
417+ <div
418+ tal:define="link context_menu/upgrade_branch"
419+ tal:condition="link/enabled"
420+ >
421+ <a tal:replace="structure link/fmt:link" />
422+ </div>
423+ </div>
424
425 </div>