Merge lp:~thumper/launchpad/new-code-import-owner into lp:launchpad

Proposed by Tim Penhey
Status: Merged
Approved by: Paul Hummer
Approved revision: no longer in the source branch.
Merged at revision: not available
Proposed branch: lp:~thumper/launchpad/new-code-import-owner
Merge into: lp:launchpad
Diff against target: 151 lines (+76/-9)
3 files modified
lib/lp/code/browser/codeimport.py (+31/-9)
lib/lp/code/stories/codeimport/xx-create-codeimport.txt (+42/-0)
lib/lp/code/templates/codeimport-new.pt (+3/-0)
To merge this branch: bzr merge lp:~thumper/launchpad/new-code-import-owner
Reviewer Review Type Date Requested Status
Paul Hummer (community) code Approve
Review via email: mp+23974@code.launchpad.net

Commit message

Allow the user to select the owner for a new code import.

Description of the change

Add the ability for the user to specify the owner for a new import branch.

Admins and bzr-experts can specify any branch owner, other people only get to choose from teams that they are a member of or themselves.

To post a comment you must log in.
Revision history for this message
Paul Hummer (rockstar) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/code/browser/codeimport.py'
--- lib/lp/code/browser/codeimport.py 2010-03-18 17:30:14 +0000
+++ lib/lp/code/browser/codeimport.py 2010-04-23 01:24:23 +0000
@@ -38,7 +38,8 @@
38from lp.code.interfaces.codeimport import (38from lp.code.interfaces.codeimport import (
39 ICodeImport, ICodeImportSet)39 ICodeImport, ICodeImportSet)
40from lp.code.interfaces.codeimportmachine import ICodeImportMachineSet40from lp.code.interfaces.codeimportmachine import ICodeImportMachineSet
41from lp.code.interfaces.branch import BranchExists, IBranch41from lp.code.interfaces.branch import (
42 BranchExists, IBranch, user_has_special_branch_access)
42from lp.code.interfaces.branchtarget import IBranchTarget43from lp.code.interfaces.branchtarget import IBranchTarget
43from lp.registry.interfaces.product import IProduct44from lp.registry.interfaces.product import IProduct
44from canonical.launchpad.webapp import (45from canonical.launchpad.webapp import (
@@ -202,6 +203,7 @@
202class NewCodeImportForm(Interface):203class NewCodeImportForm(Interface):
203 """The fields presented on the form for editing a code import."""204 """The fields presented on the form for editing a code import."""
204205
206 use_template(IBranch, ['owner'])
205 use_template(207 use_template(
206 ICodeImport,208 ICodeImport,
207 ['rcs_type', 'cvs_root', 'cvs_module'])209 ['rcs_type', 'cvs_root', 'cvs_module'])
@@ -266,10 +268,13 @@
266268
267 custom_widget('rcs_type', LaunchpadRadioWidget)269 custom_widget('rcs_type', LaunchpadRadioWidget)
268270
269 initial_values = {271 @property
270 'rcs_type': RevisionControlSystems.BZR_SVN,272 def initial_values(self):
271 'branch_name': 'trunk',273 return {
272 }274 'owner': self.user,
275 'rcs_type': RevisionControlSystems.BZR_SVN,
276 'branch_name': 'trunk',
277 }
273278
274 @property279 @property
275 def context_is_product(self):280 def context_is_product(self):
@@ -292,6 +297,21 @@
292 if self.context_is_product:297 if self.context_is_product:
293 self.form_fields = self.form_fields.omit('product')298 self.form_fields = self.form_fields.omit('product')
294299
300 # If the user can administer branches, then they should be able to
301 # assign the ownership of the branch to any valid person or team.
302 if user_has_special_branch_access(self.user):
303 owner_field = self.schema['owner']
304 any_owner_choice = Choice(
305 __name__='owner', title=owner_field.title,
306 description = _("As an administrator you are able to reassign"
307 " this branch to any person or team."),
308 required=True, vocabulary='ValidPersonOrTeam')
309 any_owner_field = form.Fields(
310 any_owner_choice, render_context=self.render_context)
311 # Replace the normal owner field with a more permissive vocab.
312 self.form_fields = self.form_fields.omit('owner')
313 self.form_fields = any_owner_field + self.form_fields
314
295 def setUpWidgets(self):315 def setUpWidgets(self):
296 CodeImportBaseView.setUpWidgets(self)316 CodeImportBaseView.setUpWidgets(self)
297317
@@ -334,6 +354,7 @@
334 cvs_root, cvs_module, url = self._getImportLocation(data)354 cvs_root, cvs_module, url = self._getImportLocation(data)
335 return getUtility(ICodeImportSet).new(355 return getUtility(ICodeImportSet).new(
336 registrant=self.user,356 registrant=self.user,
357 owner=data['owner'],
337 target=IBranchTarget(product),358 target=IBranchTarget(product),
338 branch_name=data['branch_name'],359 branch_name=data['branch_name'],
339 rcs_type=data['rcs_type'],360 rcs_type=data['rcs_type'],
@@ -410,12 +431,13 @@
410 """See `LaunchpadFormView`."""431 """See `LaunchpadFormView`."""
411 # Make sure that the user is able to create branches for the specified432 # Make sure that the user is able to create branches for the specified
412 # namespace.433 # namespace.
413 celebs = getUtility(ILaunchpadCelebrities)
414 product = self.getProduct(data)434 product = self.getProduct(data)
415 if product is not None:435 # 'owner' in data may be None if it failed validation.
416 namespace = get_branch_namespace(celebs.vcs_imports, product)436 owner = data.get('owner')
437 if product is not None and owner is not None:
438 namespace = get_branch_namespace(owner, product)
417 policy = IBranchNamespacePolicy(namespace)439 policy = IBranchNamespacePolicy(namespace)
418 if not policy.canCreateBranches(celebs.vcs_imports):440 if not policy.canCreateBranches(self.user):
419 self.setFieldError(441 self.setFieldError(
420 'product',442 'product',
421 "You are not allowed to register imports for %s."443 "You are not allowed to register imports for %s."
422444
=== modified file 'lib/lp/code/stories/codeimport/xx-create-codeimport.txt'
--- lib/lp/code/stories/codeimport/xx-create-codeimport.txt 2010-01-20 03:19:44 +0000
+++ lib/lp/code/stories/codeimport/xx-create-codeimport.txt 2010-04-23 01:24:23 +0000
@@ -247,3 +247,45 @@
247 ... print extract_text(message)247 ... print extract_text(message)
248 There is 1 error.248 There is 1 error.
249 Invalid value249 Invalid value
250
251
252Specifying the owner of the branch when it is being created
253===========================================================
254
255When a user is requesting a new code import, they are the owner of the new
256import branch. sometimes the user may wish for the import branch to be owned
257by a team rather than just themselves. There is a drop down choice shown for
258the user for the teams that they are a member of.
259
260 >>> sample_browser = setupBrowser(auth='Basic test@canonical.com:test')
261 >>> sample_browser.open("http://code.launchpad.dev/firefox/+new-import")
262 >>> sample_browser.getControl('Owner').displayValue
263 ['Sample Person (name12)']
264
265Change the owner to be a team that sample person is a member of.
266
267 >>> sample_browser.getControl('Owner').value = ['landscape-developers']
268 >>> sample_browser.getControl('Owner').displayValue
269 ['Landscape Developers (landscape-developers)']
270 >>> sample_browser.getControl('Branch URL').value = (
271 ... "http://svn.example.com/firefox-beta/trunk")
272 >>> sample_browser.getControl('Request Import').click()
273
274 >>> print_tag_with_id(sample_browser.contents, 'registration')
275 Created by Sample Person ...
276 >>> print_tag_with_id(sample_browser.contents, 'owner')
277 Owner: Landscape Developers
278
279Admins can specify any owner for a new code import.
280
281 >>> admin_browser = setupBrowser(auth='Basic admin@canonical.com:test')
282 >>> admin_browser.open("http://code.launchpad.dev/firefox/+new-import")
283 >>> admin_browser.getControl('Owner').value = 'mark'
284 >>> admin_browser.getControl('Branch URL').value = (
285 ... "http://svn.example.com/firefox-theta/trunk")
286 >>> admin_browser.getControl('Request Import').click()
287
288 >>> print_tag_with_id(admin_browser.contents, 'registration')
289 Created by Foo Bar ...
290 >>> print_tag_with_id(admin_browser.contents, 'owner')
291 Owner: Mark Shuttleworth
250292
=== modified file 'lib/lp/code/templates/codeimport-new.pt'
--- lib/lp/code/templates/codeimport-new.pt 2010-01-20 03:19:44 +0000
+++ lib/lp/code/templates/codeimport-new.pt 2010-04-23 01:24:23 +0000
@@ -30,6 +30,9 @@
3030
31 <table class="form">31 <table class="form">
3232
33 <tal:widget define="widget nocall:view/widgets/owner">
34 <metal:block use-macro="context/@@launchpad_form/widget_row" />
35 </tal:widget>
33 <tal:show-product condition="not: view/context_is_product">36 <tal:show-product condition="not: view/context_is_product">
34 <tal:widget define="widget nocall:view/widgets/product">37 <tal:widget define="widget nocall:view/widgets/product">
35 <metal:block use-macro="context/@@launchpad_form/widget_row" />38 <metal:block use-macro="context/@@launchpad_form/widget_row" />