Rev 5480: Merge lp:~vila/bzr/609186-shortcuts fixing NEWS entry in http://bazaar.launchpad.net/~vila/bzr/integration/

Vincent Ladeuil v.ladeuil+lp at free.fr
Mon Oct 11 13:17:13 BST 2010


At http://bazaar.launchpad.net/~vila/bzr/integration/

------------------------------------------------------------
revno: 5480 [merge]
revision-id: v.ladeuil+lp at free.fr-20101011121712-dzbqlqqd83cmxwc5
parent: pqm at pqm.ubuntu.com-20101011110750-blyz6d15y6t61s6i
parent: v.ladeuil+lp at free.fr-20101011074810-r5ksd2g5xctda315
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: trunk
timestamp: Mon 2010-10-11 14:17:12 +0200
message:
  Merge lp:~vila/bzr/609186-shortcuts fixing NEWS entry
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/plugins/launchpad/__init__.py __init__.py-20060315182712-2d5feebd2a1032dc
  bzrlib/plugins/launchpad/lp_directory.py lp_indirect.py-20070126012204-de5rugwlt22c7u7e-1
  bzrlib/plugins/launchpad/test_lp_directory.py test_lp_indirect.py-20070126002743-oyle362tzv9cd8mi-1
  doc/en/tutorials/using_bazaar_with_launchpad.txt using_bazaar_with_lp-20071211073140-7msh8uf9a9h4y9hb-1
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS	2010-10-11 10:27:23 +0000
+++ b/NEWS	2010-10-11 12:17:12 +0000
@@ -16,6 +16,13 @@
 New Features
 ************
 
+* New shortcut url schemes ``ubuntu:`` and ``debianlp:`` access source
+  branches on Launchpad.  E.g. ``bzr branch ubuntu:foo`` gives you the source
+  branch for project ``foo`` in the current distroseries for Ubuntu while
+  ``bzr branch debianlp:lenny/foo`` gives you the source branch (on Launchpad)
+  for project ``foo`` in Debian Lenny.
+  (Barry Warsaw, #609186)
+
 Bug Fixes
 *********
 

=== modified file 'bzrlib/plugins/launchpad/__init__.py'
--- a/bzrlib/plugins/launchpad/__init__.py	2010-10-05 15:52:15 +0000
+++ b/bzrlib/plugins/launchpad/__init__.py	2010-10-11 12:17:12 +0000
@@ -371,6 +371,15 @@
     directories.register_lazy('lp:', 'bzrlib.plugins.launchpad.lp_directory',
                               'LaunchpadDirectory',
                               'Launchpad-based directory service',)
+    directories.register_lazy(
+        'debianlp:', 'bzrlib.plugins.launchpad.lp_directory',
+        'LaunchpadDirectory',
+        'debianlp: shortcut')
+    directories.register_lazy(
+        'ubuntu:', 'bzrlib.plugins.launchpad.lp_directory',
+        'LaunchpadDirectory',
+        'ubuntu: shortcut')
+
 _register_directory()
 
 

=== modified file 'bzrlib/plugins/launchpad/lp_directory.py'
--- a/bzrlib/plugins/launchpad/lp_directory.py	2010-07-26 17:19:33 +0000
+++ b/bzrlib/plugins/launchpad/lp_directory.py	2010-10-07 22:00:43 +0000
@@ -40,6 +40,16 @@
 register_urlparse_netloc_protocol('bzr+ssh')
 register_urlparse_netloc_protocol('lp')
 
+_ubuntu_series_shortcuts = {
+    'n': 'natty',
+    'm': 'maverick',
+    'l': 'lucid',
+    'k': 'karmic',
+    'j': 'jaunty',
+    'h': 'hardy',
+    'd': 'dapper',
+    }
+
 
 class LaunchpadDirectory(object):
 
@@ -62,8 +72,44 @@
                  _request_factory=ResolveLaunchpadPathRequest,
                  _lp_login=None):
         """Resolve the base URL for this transport."""
+        # Do ubuntu: and debianlp: expansions.
+        result = urlsplit(url)
+        if result.scheme in ('ubuntu', 'debianlp'):
+            if result.scheme == 'ubuntu':
+                distro = 'ubuntu'
+                distro_series = _ubuntu_series_shortcuts
+            elif result.scheme == 'debianlp':
+                distro = 'debian'
+                # No shortcuts for Debian distroseries.
+                distro_series = {}
+            else:
+                raise AssertionError('scheme should be ubuntu: or debianlp:')
+            # Split the path.  It's either going to be 'project' or
+            # 'series/project', but recognize that it may be a series we don't
+            # know about.
+            path_parts = result.path.split('/')
+            if len(path_parts) == 1:
+                # It's just a project name.
+                lp_url_template = 'lp:%(distro)s/%(project)s'
+                project = path_parts[0]
+                series = None
+            elif len(path_parts) == 2:
+                # It's a series and project.
+                lp_url_template = 'lp:%(distro)s/%(series)s/%(project)s'
+                series, project = path_parts
+            else:
+                # There are either 0 or > 2 path parts, neither of which is
+                # supported for these schemes.
+                raise errors.InvalidURL('Bad path: %s' % result.path)
+            # Expand any series shortcuts, but keep unknown series.
+            series = distro_series.get(series, series)
+            # Hack the url and let the following do the final resolution.
+            url = lp_url_template % dict(
+                distro=distro,
+                series=series,
+                project=project)
+            result = urlsplit(url)
         service = LaunchpadService.for_url(url)
-        result = urlsplit(url)
         if _lp_login is None:
             _lp_login = get_lp_login()
         path = result[2].strip('/')

=== modified file 'bzrlib/plugins/launchpad/test_lp_directory.py'
--- a/bzrlib/plugins/launchpad/test_lp_directory.py	2010-07-26 17:19:33 +0000
+++ b/bzrlib/plugins/launchpad/test_lp_directory.py	2010-10-11 07:48:10 +0000
@@ -37,10 +37,7 @@
 from bzrlib.plugins.launchpad.lp_directory import (
     LaunchpadDirectory)
 from bzrlib.plugins.launchpad.account import get_lp_login, set_lp_login
-from bzrlib.tests import (
-    http_server,
-    http_utils,
-    )
+from bzrlib.tests import http_server
 
 
 def load_tests(standard_tests, module, loader):
@@ -219,8 +216,8 @@
                     'bzr+ssh://bazaar.launchpad.net/~username/apt/test']))
         self.assertIs(None, get_lp_login())
         directory = LaunchpadDirectory()
-        e = self.assertRaises(errors.InvalidURL,
-            directory._resolve, 'lp:~/apt/test', factory)
+        self.assertRaises(errors.InvalidURL,
+                          directory._resolve, 'lp:~/apt/test', factory)
 
 
 class DirectoryOpenBranchTests(TestCaseWithMemoryTransport):
@@ -237,6 +234,8 @@
                 return '!unexpected look_up value!'
 
         directories.remove('lp:')
+        directories.remove('ubuntu:')
+        directories.remove('debianlp:')
         directories.register('lp:', FooService, 'Map lp URLs to local urls')
         self.addCleanup(_register_directory)
         self.addCleanup(directories.remove, 'lp:')
@@ -259,11 +258,11 @@
     def handle_one_request(self):
         tcs = self.server.test_case_server
         requestline = self.rfile.readline()
-        headers = self.MessageClass(self.rfile, 0)
+        self.MessageClass(self.rfile, 0)
         if requestline.startswith('POST'):
             # The body should be a single line (or we don't know where it ends
             # and we don't want to issue a blocking read)
-            body = self.rfile.readline()
+            self.rfile.readline()
 
         self.wfile.write(tcs.canned_response)
 
@@ -356,3 +355,125 @@
     # FIXME: we need to test with a real proxy, I can't find a way so simulate
     # CONNECT without leaving one server hanging the test :-/ Since that maybe
     # related to the leaking tests problems, I'll punt for now -- vila 20091030
+
+
+class TestDebuntuExpansions(TestCaseInTempDir):
+    """Test expansions for ubuntu: and debianlp: schemes."""
+
+    def setUp(self):
+        tests.TestCase.setUp(self)
+        self.directory = LaunchpadDirectory()
+
+    def _make_factory(self, package='foo', distro='ubuntu', series=None):
+        if series is None:
+            path = '%s/%s' % (distro, package)
+            url_suffix = '~branch/%s/%s' % (distro, package)
+        else:
+            path = '%s/%s/%s' % (distro, series, package)
+            url_suffix = '~branch/%s/%s/%s' % (distro, series, package)
+        return FakeResolveFactory(
+            self, path, dict(urls=[
+                'http://bazaar.launchpad.net/' + url_suffix]))
+
+    def assertURL(self, expected_url, shortcut, package='foo', distro='ubuntu',
+                  series=None):
+        factory = self._make_factory(package=package, distro=distro,
+                                     series=series)
+        self.assertEqual('http://bazaar.launchpad.net/~branch/' + expected_url,
+                         self.directory._resolve(shortcut, factory))
+
+    # Bogus distro.
+
+    def test_bogus_distro(self):
+        self.assertRaises(errors.InvalidURL,
+                          self.directory._resolve, 'gentoo:foo')
+
+    def test_trick_bogus_distro_u(self):
+        self.assertRaises(errors.InvalidURL,
+                          self.directory._resolve, 'utube:foo')
+
+    def test_trick_bogus_distro_d(self):
+        self.assertRaises(errors.InvalidURL,
+                          self.directory._resolve, 'debuntu:foo')
+
+    def test_missing_ubuntu_distroseries_without_project(self):
+        # Launchpad does not hold source packages for Intrepid.  Missing or
+        # bogus distroseries with no project name is treated like a project.
+        self.assertURL('ubuntu/intrepid', 'ubuntu:intrepid', package='intrepid')
+
+    def test_missing_ubuntu_distroseries_with_project(self):
+        # Launchpad does not hold source packages for Intrepid.  Missing or
+        # bogus distroseries with a project name is treated like an unknown
+        # series (i.e. we keep it verbatim).
+        self.assertURL('ubuntu/intrepid/foo',
+                       'ubuntu:intrepid/foo', series='intrepid')
+
+    def test_missing_debian_distroseries(self):
+        # Launchpad does not hold source packages for unstable.  Missing or
+        # bogus distroseries is treated like a project.
+        self.assertURL('debian/sid',
+                       'debianlp:sid', package='sid', distro='debian')
+
+    # Ubuntu Default distro series.
+
+    def test_ubuntu_default_distroseries_expansion(self):
+        self.assertURL('ubuntu/foo', 'ubuntu:foo')
+
+    def test_ubuntu_natty_distroseries_expansion(self):
+        self.assertURL('ubuntu/natty/foo', 'ubuntu:natty/foo', series='natty')
+
+    def test_ubuntu_n_distroseries_expansion(self):
+        self.assertURL('ubuntu/natty/foo', 'ubuntu:n/foo', series='natty')
+
+    def test_ubuntu_maverick_distroseries_expansion(self):
+        self.assertURL('ubuntu/maverick/foo', 'ubuntu:maverick/foo',
+                       series='maverick')
+
+    def test_ubuntu_m_distroseries_expansion(self):
+        self.assertURL('ubuntu/maverick/foo', 'ubuntu:m/foo', series='maverick')
+
+    def test_ubuntu_lucid_distroseries_expansion(self):
+        self.assertURL('ubuntu/lucid/foo', 'ubuntu:lucid/foo', series='lucid')
+
+    def test_ubuntu_l_distroseries_expansion(self):
+        self.assertURL('ubuntu/lucid/foo', 'ubuntu:l/foo', series='lucid')
+
+    def test_ubuntu_karmic_distroseries_expansion(self):
+        self.assertURL('ubuntu/karmic/foo', 'ubuntu:karmic/foo',
+                       series='karmic')
+
+    def test_ubuntu_k_distroseries_expansion(self):
+        self.assertURL('ubuntu/karmic/foo', 'ubuntu:k/foo', series='karmic')
+
+    def test_ubuntu_jaunty_distroseries_expansion(self):
+        self.assertURL('ubuntu/jaunty/foo', 'ubuntu:jaunty/foo',
+                       series='jaunty')
+
+    def test_ubuntu_j_distroseries_expansion(self):
+        self.assertURL('ubuntu/jaunty/foo', 'ubuntu:j/foo', series='jaunty')
+
+    def test_ubuntu_hardy_distroseries_expansion(self):
+        self.assertURL('ubuntu/hardy/foo', 'ubuntu:hardy/foo', series='hardy')
+
+    def test_ubuntu_h_distroseries_expansion(self):
+        self.assertURL('ubuntu/hardy/foo', 'ubuntu:h/foo', series='hardy')
+
+    def test_ubuntu_dapper_distroseries_expansion(self):
+        self.assertURL('ubuntu/dapper/foo', 'ubuntu:dapper/foo',
+                       series='dapper')
+
+    def test_ubuntu_d_distroseries_expansion(self):
+        self.assertURL('ubuntu/dapper/foo', 'ubuntu:d/foo', series='dapper')
+
+    # Debian default distro series.
+
+    def test_debian_default_distroseries_expansion(self):
+        self.assertURL('debian/foo', 'debianlp:foo', distro='debian')
+
+    def test_debian_squeeze_distroseries_expansion(self):
+        self.assertURL('debian/squeeze/foo', 'debianlp:squeeze/foo',
+                       distro='debian', series='squeeze')
+
+    def test_debian_lenny_distroseries_expansion(self):
+        self.assertURL('debian/lenny/foo', 'debianlp:lenny/foo',
+                       distro='debian', series='lenny')

=== modified file 'doc/en/tutorials/using_bazaar_with_launchpad.txt'
--- a/doc/en/tutorials/using_bazaar_with_launchpad.txt	2010-08-13 19:08:57 +0000
+++ b/doc/en/tutorials/using_bazaar_with_launchpad.txt	2010-10-07 21:03:55 +0000
@@ -244,6 +244,41 @@
 quality standards.
 
 
+Package source branches
+-----------------------
+
+When `maintaining packages for Ubuntu using Bazaar`_ you can easily access the
+package's source branch on Launchpad.  The package's source branch in the
+current (default) series can be downloaded like this::
+
+  bzr branch ubuntu:package
+
+where *package* is the name of the Ubuntu package you want to access.  To
+download the package branch for a specific series in Ubuntu (e.g. Maverick or
+Lucid), use this::
+
+  bzr branch ubuntu:maverick/package
+
+Ubuntu distroseries can also be abbreviated to just their first letter.  For
+example, the above could also be written::
+
+  bzr branch ubuntu:m/package
+
+You can also download the package source branch from Launchpad for several
+Debian series.  The default series can be downloaded like this::
+
+  bzr branch debianlp:package
+
+and a specific series can be downloaded like this::
+
+  bzr branch debianlp:lenny/package
+
+Note that the ``debianlp:`` scheme access the Debian source branch for a
+package from Launchpad only.
+
+.. _`maintaining packages for Ubuntu using Bazaar`: https://wiki.ubuntu.com/DistributedDevelopment
+
+
 Linking branches using Launchpad
 ================================
 



More information about the bazaar-commits mailing list