launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #21595
[Merge] lp:~cjwatson/launchpad/remove-branch-popup-widget into lp:launchpad
Colin Watson has proposed merging lp:~cjwatson/launchpad/remove-branch-popup-widget into lp:launchpad.
Commit message:
Remove BranchPopupWidget, which only exists to create deprecated mirrored branches.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/remove-branch-popup-widget/+merge/324475
--
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad/remove-branch-popup-widget into lp:launchpad.
=== removed file 'lib/lp/code/browser/widgets/branch.py'
--- lib/lp/code/browser/widgets/branch.py 2016-12-22 16:32:38 +0000
+++ lib/lp/code/browser/widgets/branch.py 1970-01-01 00:00:00 +0000
@@ -1,109 +0,0 @@
-# Copyright 2011-2016 Canonical Ltd. This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-__metaclass__ = type
-
-__all__ = [
- 'AlreadyRegisteredError',
- 'BranchPopupWidget',
- 'NoProductError',
- ]
-
-import sys
-
-from lazr.uri import (
- InvalidURIError,
- URI,
- )
-from six import reraise
-from zope.component import getUtility
-from zope.formlib.interfaces import ConversionError
-
-from lp.app.browser.tales import BranchFormatterAPI
-from lp.app.validators import LaunchpadValidationError
-from lp.app.widgets.popup import VocabularyPickerWidget
-from lp.code.enums import BranchType
-from lp.code.interfaces.branch import IBranch
-from lp.code.interfaces.branchlookup import IBranchLookup
-from lp.code.interfaces.branchnamespace import get_branch_namespace
-from lp.services.webapp.escaping import structured
-from lp.services.webapp.interfaces import ILaunchBag
-
-
-class AlreadyRegisteredError(Exception):
- """Raised when we try to register an already-registered branch."""
-
-
-class NoProductError(Exception):
- """Raised when we need a product and can't find one."""
-
-
-class BranchPopupWidget(VocabularyPickerWidget):
- """Custom popup widget for choosing branches."""
-
- displayWidth = '35'
-
- def getBranchNameFromURL(self, url):
- """Return a branch name based on `url`.
-
- The name is based on the last path segment of the URL. If there is
- already another branch of that name on the product, then we'll try to
- find a unique name by appending numbers.
- """
- return URI(url).ensureNoSlash().path.split('/')[-1]
-
- def getPerson(self):
- """Return the person in the context, if any."""
- return getUtility(ILaunchBag).user
-
- def getProduct(self):
- """Return the product in the context, if there is one."""
- return getUtility(ILaunchBag).product
-
- def makeBranchFromURL(self, url):
- """Make a mirrored branch for `url`.
-
- The product and owner of the branch are derived from information in
- the launchbag. The name of the branch is derived from the last segment
- of the URL and is guaranteed to be unique for the product.
-
- :param url: The URL to mirror.
- :return: An `IBranch`.
- """
- # XXX: JonathanLange 2008-12-08 spec=package-branches: This method
- # needs to be rewritten to get the sourcepackage and distroseries out
- # of the launch bag.
- url = unicode(URI(url).ensureNoSlash())
- if getUtility(IBranchLookup).getByUrl(url) is not None:
- raise AlreadyRegisteredError('Already a branch for %r' % url)
- # Make sure the URL is valid.
- IBranch['url'].validate(url)
- product = self.getProduct()
- if product is None:
- raise NoProductError("Could not find product in LaunchBag.")
- owner = self.getPerson()
- name = self.getBranchNameFromURL(url)
- namespace = get_branch_namespace(person=owner, product=product)
- branch = namespace.createBranchWithPrefix(
- BranchType.MIRRORED, name, owner, url=url)
- branch.requestMirror()
- self.request.response.addNotification(
- structured('Registered %s' %
- BranchFormatterAPI(branch).link(None)))
- return branch
-
- def _toFieldValue(self, form_input):
- try:
- return super(BranchPopupWidget, self)._toFieldValue(form_input)
- except ConversionError:
- # Save the initial error so we can re-raise it later.
- exc_class, exc_obj, exc_tb = sys.exc_info()
-
- # Try to register a branch, assuming form_input is a URL.
- try:
- return self.makeBranchFromURL(form_input)
- except (InvalidURIError, NoProductError, AlreadyRegisteredError,
- LaunchpadValidationError):
- # If it's not a URL or we can't figure out a product, then we
- # re-raise the initial error.
- reraise(exc_class, exc_obj, tb=exc_tb)
=== removed file 'lib/lp/code/browser/widgets/tests/test_branchpopupwidget.py'
--- lib/lp/code/browser/widgets/tests/test_branchpopupwidget.py 2015-07-08 16:05:11 +0000
+++ lib/lp/code/browser/widgets/tests/test_branchpopupwidget.py 1970-01-01 00:00:00 +0000
@@ -1,228 +0,0 @@
-# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Unit tests for Launchpad-specific widgets."""
-
-__metaclass__ = type
-
-import unittest
-
-from lazr.uri import URI
-from zope.component import (
- getUtility,
- provideUtility,
- )
-from zope.formlib.interfaces import ConversionError
-from zope.interface import implementer
-from zope.schema import Choice
-
-from lp import _
-from lp.code.browser.widgets.branch import (
- BranchPopupWidget,
- NoProductError,
- )
-from lp.code.enums import BranchType
-from lp.code.interfaces.branchlookup import IBranchLookup
-from lp.code.vocabularies.branch import (
- BranchRestrictedOnProductVocabulary,
- BranchVocabulary,
- )
-from lp.services.webapp.interfaces import ILaunchBag
-from lp.services.webapp.servers import LaunchpadTestRequest
-from lp.testing import (
- ANONYMOUS,
- login,
- logout,
- )
-from lp.testing.factory import LaunchpadObjectFactory
-from lp.testing.layers import LaunchpadFunctionalLayer
-
-
-@implementer(ILaunchBag)
-class DummyLaunchBag:
- """Dummy LaunchBag that we can easily control in our tests."""
-
- def __init__(self, user=None, product=None):
- self.user = user
- self.product = product
-
-
-class TestBranchPopupWidget(unittest.TestCase):
- """Tests for the branch popup widget."""
-
- layer = LaunchpadFunctionalLayer
-
- def assertIs(self, first, second):
- """Assert `first` is `second`."""
- self.assertTrue(first is second, "%r is not %r" % (first, second))
-
- def installLaunchBag(self, user=None, product=None):
- bag = DummyLaunchBag(user, product)
- provideUtility(bag, ILaunchBag)
- return bag
-
- def makeBranchPopup(self, vocabulary=None):
- # Pick a random, semi-appropriate context.
- context = self.factory.makeProduct()
- if vocabulary is None:
- vocabulary = BranchVocabulary(context)
- request = self.makeRequest()
- return BranchPopupWidget(
- self.makeField(context, vocabulary), vocabulary, request)
-
- def makeField(self, context, vocabulary):
- field = Choice(
- title=_('Branch'), vocabulary=vocabulary, required=False,
- description=_("The Bazaar branch."))
- field.context = context
- return field
-
- def makeRequest(self):
- return LaunchpadTestRequest()
-
- def setUp(self):
- login(ANONYMOUS)
- self._original_launch_bag = getUtility(ILaunchBag)
- self.factory = LaunchpadObjectFactory()
- self.launch_bag = self.installLaunchBag(
- user=self.factory.makePerson(),
- product=self.factory.makeProduct())
- self.popup = self.makeBranchPopup()
-
- def tearDown(self):
- provideUtility(self._original_launch_bag, ILaunchBag)
- logout()
-
- def test_getProduct(self):
- """getProduct() returns the product in the LaunchBag."""
- self.assertEqual(self.launch_bag.product, self.popup.getProduct())
-
- def test_getPerson(self):
- """getPerson() returns the logged-in user."""
- self.assertEqual(self.launch_bag.user, self.popup.getPerson())
-
- def test_getBranchNameFromURL(self):
- """getBranchNameFromURL() gets a branch name from a url.
-
- In general, the name is the last path segment of the URL.
- """
- url = self.factory.getUniqueURL()
- name = self.popup.getBranchNameFromURL(url)
- self.assertEqual(URI(url).path.split('/')[-1], name)
-
- def test_makeBranchFromURL(self):
- """makeBranchFromURL(url) creates a mirrored branch at `url`.
-
- The owner and registrant are the currently logged-in user, as given by
- getPerson(), and the product is the product in the LaunchBag.
- """
- url = self.factory.getUniqueURL()
- expected_name = self.popup.getBranchNameFromURL(url)
- branch = self.popup.makeBranchFromURL(url)
- self.assertEqual(BranchType.MIRRORED, branch.branch_type)
- self.assertEqual(url, branch.url)
- self.assertEqual(self.popup.getPerson(), branch.owner)
- self.assertEqual(self.popup.getPerson(), branch.registrant)
- self.assertEqual(self.popup.getProduct(), branch.product)
- self.assertEqual(expected_name, branch.name)
-
- def test_makeBranch_used(self):
- # makeBranch makes up the branch name if the inferred one is already
- # used.
- url = self.factory.getUniqueURL()
- expected_name = self.popup.getBranchNameFromURL(url)
- self.factory.makeProductBranch(
- name=expected_name, product=self.popup.getProduct(),
- owner=self.popup.getPerson())
- branch = self.popup.makeBranchFromURL(url)
- self.assertEqual(expected_name + '-1', branch.name)
-
- def test_makeBranchRequestsMirror(self):
- """makeBranch requests a mirror on the branch it creates."""
- url = self.factory.getUniqueURL()
- branch = self.popup.makeBranchFromURL(url)
- self.assertNotEqual('None', str(branch.next_mirror_time))
-
- def test_makeBranchNoProduct(self):
- """makeBranchFromURL(url) returns None if there's no product.
-
- Not all contexts for branch registration have products. In particular,
- a bug can be on a source package. When we link a branch to that bug,
- there's no clear product to choose, so we don't choose any.
- """
- self.installLaunchBag(product=None, user=self.factory.makePerson())
- url = self.factory.getUniqueURL()
- self.assertRaises(NoProductError, self.popup.makeBranchFromURL, url)
-
- def test_makeBranchTrailingSlash(self):
- """makeBranch creates a mirrored branch even if the URL ends with /.
- """
- uri = URI(self.factory.getUniqueURL())
- expected_name = self.popup.getBranchNameFromURL(
- str(uri.ensureNoSlash()))
- branch = self.popup.makeBranchFromURL(str(uri.ensureSlash()))
- self.assertEqual(str(uri.ensureNoSlash()), branch.url)
- self.assertEqual(expected_name, branch.name)
-
- def test_toFieldValueFallsBackToMakingBranch(self):
- """_toFieldValue falls back to making a branch if it's given a URL."""
- url = self.factory.getUniqueURL()
- # Check that there's no branch with this URL.
- self.assertIs(None, getUtility(IBranchLookup).getByUrl(url))
-
- branch = self.popup._toFieldValue(url)
- self.assertEqual(url, branch.url)
-
- def test_toFieldValueFetchesTheExistingBranch(self):
- """_toFieldValue returns the existing branch that has that URL."""
- expected_branch = self.factory.makeAnyBranch(
- branch_type=BranchType.MIRRORED)
- branch = self.popup._toFieldValue(expected_branch.url)
- self.assertEqual(expected_branch, branch)
-
- def test_toFieldValueNonURL(self):
- """When the input isn't a URL, fall back to the original error."""
- empty_search = 'doesntexist'
- self.assertRaises(
- ConversionError, self.popup._toFieldValue, empty_search)
-
- def test_toFieldValueNoProduct(self):
- """When there's no product, fall back to the original error."""
- self.installLaunchBag(product=None, user=self.factory.makePerson())
- self.assertRaises(
- ConversionError, self.popup._toFieldValue,
- self.factory.getUniqueURL())
-
- def test_toFieldBadURL(self):
- """When the input is a bad URL, fall back to the original error.
-
- There are many valid URLs that are inappropriate for a mirrored
- branch. We don't want to register a mirrored branch when someone
- enters such a URL.
- """
- bad_url = 'svn://svn.example.com/repo/trunk'
- self.assertRaises(ConversionError, self.popup._toFieldValue, bad_url)
-
- def test_branchInRestrictedProduct(self):
- # There are two reasons for a URL not being in the vocabulary. One
- # reason is that it's there's no registered branch with that URL. The
- # other is that the vocabulary on this form is restricted to one
- # product, and there *is* a branch with that URL, but it's registered
- # on a different product.
-
- # Make a popup restricted to a particular product.
- vocab = BranchRestrictedOnProductVocabulary(self.launch_bag.product)
- self.assertEqual(vocab.product, self.launch_bag.product)
- popup = self.makeBranchPopup(vocab)
-
- # Make a branch on a different product.
- branch = self.factory.makeProductBranch(
- branch_type=BranchType.MIRRORED)
- self.assertNotEqual(self.launch_bag.product, branch.product)
-
- # Trying to make a branch with that URL will fail.
- self.assertRaises(ConversionError, popup._toFieldValue, branch.url)
-
- # XXX: JonathanLange 2008-04-17 bug=219019: Not sure how to test what
- # happens when this widget has a good value but other fields have bad
- # values. The correct behaviour is to *not* create the branch.
=== modified file 'lib/lp/code/stories/branches/xx-bug-branch-links.txt'
--- lib/lp/code/stories/branches/xx-bug-branch-links.txt 2017-04-18 22:17:00 +0000
+++ lib/lp/code/stories/branches/xx-bug-branch-links.txt 2017-05-23 13:39:50 +0000
@@ -138,60 +138,6 @@
Undecided New
-Quick branch registration
-=========================
-
-You can also register a branch at the same time as registering a bug-branch
-link. Instead of entering the unique name of a branch, you can enter a URL:
-
- >>> browser.open('http://bugs.launchpad.dev/thunderbird/+bug/15')
- >>> printBugBranchLinks(browser)
- No bug branch links
-
-If we go to register a branch and change our mind, there is a cancel
-link that points back to the bug page:
-
- >>> browser.getLink('Link a related branch').click()
- >>> cancel_link = browser.getLink('Cancel')
- >>> cancel_link.url
- 'http://bugs.launchpad.dev/thunderbird/+bug/15'
-
-But we're here to register a branch:
-
- >>> browser.getControl('Branch').value = (
- ... "http://example.org/branch")
- >>> browser.getControl('Continue').click()
-
-This registers a branch and links it to the bug:
-
- >>> print_notifications(browser)
- Registered lp://dev/~name12/thunderbird/branch
- ...
- >>> printBugBranchLinks(browser)
- lp://dev/~name12/thunderbird/branch
-
-However, if the bug isn't on a project, we don't (can't!) register a branch.
-
- >>> browser.open('http://launchpad.dev/bugs/10')
- >>> printBugBranchLinks(browser)
- No bug branch links
-
-Here we use 'http://example.org/branch2' as the URL. We have to use a
-different URL, since using an already-registered URL will just find that
-branch.
-
- >>> browser.getLink('Link a related branch').click()
- >>> browser.getControl('Branch').value = (
- ... "http://example.org/branch2")
- >>> browser.getControl('Continue').click()
-
-No bug-branch link is registered:
-
- >>> browser.open('http://launchpad.dev/bugs/10')
- >>> printBugBranchLinks(browser)
- No bug branch links
-
-
Deleting bug branch links
=========================
=== modified file 'lib/lp/services/webapp/configure.zcml'
--- lib/lp/services/webapp/configure.zcml 2016-07-21 16:29:52 +0000
+++ lib/lp/services/webapp/configure.zcml 2017-05-23 13:39:50 +0000
@@ -403,16 +403,6 @@
permission="zope.Public"
/>
- <!-- Define the widget used by fields that use BranchVocabulary. -->
- <view
- type="zope.publisher.interfaces.browser.IBrowserRequest"
- for="zope.schema.interfaces.IChoice
- lp.code.vocabularies.branch.BranchVocabulary"
- provides="zope.formlib.interfaces.IInputWidget"
- factory="lp.code.browser.widgets.branch.BranchPopupWidget"
- permission="zope.Public"
- />
-
<!-- Define the widget used by fields that use
DistributionSourcePackageVocabulary. -->
<view
Follow ups