diff -Nru breezy-3.1.0/debian/changelog breezy-3.1.0/debian/changelog --- breezy-3.1.0/debian/changelog 2020-11-22 18:35:25.000000000 +0000 +++ breezy-3.1.0/debian/changelog 2020-12-06 15:06:43.000000000 +0000 @@ -1,3 +1,9 @@ +breezy (3.1.0-8) unstable; urgency=medium + + * Add patch 21_extssh: add support for extssh URLs. + + -- Jelmer Vernooij Sun, 06 Dec 2020 15:06:43 +0000 + breezy (3.1.0-7) unstable; urgency=medium * Add patch 19_is_alive: avoid Thread.isAlive, not available in Python diff -Nru breezy-3.1.0/debian/patches/21_cvs breezy-3.1.0/debian/patches/21_cvs --- breezy-3.1.0/debian/patches/21_cvs 1970-01-01 00:00:00.000000000 +0000 +++ breezy-3.1.0/debian/patches/21_cvs 2020-12-06 15:06:43.000000000 +0000 @@ -0,0 +1,118 @@ +=== modified file 'breezy/location.py' +--- old/breezy/location.py 2019-11-17 03:58:40 +0000 ++++ new/breezy/location.py 2020-06-28 23:13:22 +0000 +@@ -45,12 +45,11 @@ + + hooks = LocationHooks() + +- +-def rcp_location_to_url(location, scheme='ssh'): ++def parse_rcp_location(location): + """Convert a rcp-style location to a URL. + + :param location: Location to convert, e.g. "foo:bar" +- :param schenme: URL scheme to return, defaults to "ssh" ++ :param scheme: URL scheme to return, defaults to "ssh" + :return: A URL, e.g. "ssh://foo/bar" + :raises ValueError: if this is not a RCP-style URL + """ +@@ -59,36 +58,57 @@ + raise ValueError("Not a RCP URL") + if m.group('path').startswith('//'): + raise ValueError("Not a RCP URL: already looks like a URL") +- quoted_user = urlutils.quote(m.group('user')[:-1]) if m.group('user') else None ++ return (m.group('host'), ++ m.group('user')[:-1] if m.group('user') else None, ++ m.group('path')) ++ ++ ++def rcp_location_to_url(location, scheme='ssh'): ++ """Convert a rcp-style location to a URL. ++ ++ :param location: Location to convert, e.g. "foo:bar" ++ :param scheme: URL scheme to return, defaults to "ssh" ++ :return: A URL, e.g. "ssh://foo/bar" ++ :raises ValueError: if this is not a RCP-style URL ++ """ ++ (host, user, path) = parse_rcp_location(location) ++ quoted_user = urlutils.quote(user) if user else None + url = urlutils.URL( + scheme=scheme, quoted_user=quoted_user, + port=None, quoted_password=None, +- quoted_host=urlutils.quote(m.group('host')), +- quoted_path=urlutils.quote(m.group('path'))) ++ quoted_host=urlutils.quote(host), ++ quoted_path=urlutils.quote(path)) + return str(url) + + +-def pserver_to_url(location): +- """Convert a CVS pserver location string to a URL. +- +- :param location: pserver URL +- :return: A cvs+pserver URL +- """ ++def parse_cvs_location(location): + parts = location.split(':') +- if parts[0] or parts[1] != 'pserver': ++ if parts[0] or parts[1] not in ('pserver', 'ssh'): + raise ValueError('not a valid pserver location string') + try: + (username, hostname) = parts[2].split('@', 1) + except IndexError: + hostname = parts[2] + username = None ++ scheme = parts[1] ++ path = parts[3] ++ return (scheme, hostname, username, path) ++ ++ ++def cvs_to_url(location): ++ """Convert a CVS pserver location string to a URL. ++ ++ :param location: pserver URL ++ :return: A cvs+pserver URL ++ """ ++ (scheme, host, user, path) = parse_cvs_location(location) + return str(urlutils.URL( +- scheme='cvs+pserver', +- quoted_user=urlutils.quote(username) if username else None, +- quoted_host=urlutils.quote(hostname), ++ scheme='cvs+' + scheme, ++ quoted_user=urlutils.quote(user) if user else None, ++ quoted_host=urlutils.quote(host), + quoted_password=None, + port=None, +- quoted_path=urlutils.quote(parts[3]))) ++ quoted_path=urlutils.quote(path))) + + + def location_to_url(location, purpose=None): +@@ -106,7 +126,7 @@ + raise AssertionError("location not a byte or unicode string") + + if location.startswith(':pserver:'): +- return pserver_to_url(location) ++ return cvs_to_url(location) + + from .directory_service import directories + location = directories.dereference(location, purpose) + +=== modified file 'breezy/tests/test_location.py' +--- old/breezy/tests/test_location.py 2019-11-17 03:58:40 +0000 ++++ new/breezy/tests/test_location.py 2020-06-28 23:13:22 +0000 +@@ -83,6 +83,13 @@ + ':pserver:anonymous@odessa.cvs.sourceforge.net:/cvsroot/odess')) + self.assertRaises(ValueError, location_to_url, ':pserver:blah') + ++ def test_missing_scheme(self): ++ self.skipTest('need clever guessing of scheme') ++ self.assertEqual( ++ 'cvs+pserver://anonymous@savi.cvs.sourceforge.net:/cvsroot/savi', ++ location_to_url( ++ 'anonymous@savi.cvs.sourceforge.net:/cvsroot/savi')) ++ + def test_rcp_url(self): + self.assertEqual( + "ssh://example.com/srv/git/bar", + diff -Nru breezy-3.1.0/debian/patches/21_extssh breezy-3.1.0/debian/patches/21_extssh --- breezy-3.1.0/debian/patches/21_extssh 1970-01-01 00:00:00.000000000 +0000 +++ breezy-3.1.0/debian/patches/21_extssh 2020-12-06 15:06:43.000000000 +0000 @@ -0,0 +1,49 @@ +=== modified file 'breezy/location.py' +--- old/breezy/location.py 2020-06-28 23:13:22 +0000 ++++ new/breezy/location.py 2020-11-22 15:12:57 +0000 +@@ -83,14 +83,16 @@ + + def parse_cvs_location(location): + parts = location.split(':') +- if parts[0] or parts[1] not in ('pserver', 'ssh'): +- raise ValueError('not a valid pserver location string') ++ if parts[0] or parts[1] not in ('pserver', 'ssh', 'extssh'): ++ raise ValueError('not a valid CVS location string') + try: + (username, hostname) = parts[2].split('@', 1) + except IndexError: + hostname = parts[2] + username = None + scheme = parts[1] ++ if scheme == 'extssh': ++ scheme = 'ssh' + path = parts[3] + return (scheme, hostname, username, path) + +@@ -125,7 +127,7 @@ + if not isinstance(location, string_types): + raise AssertionError("location not a byte or unicode string") + +- if location.startswith(':pserver:'): ++ if location.startswith(':pserver:') or location.startswith(':extssh:'): + return cvs_to_url(location) + + from .directory_service import directories + +=== modified file 'breezy/tests/test_location.py' +--- old/breezy/tests/test_location.py 2020-06-28 23:13:22 +0000 ++++ new/breezy/tests/test_location.py 2020-11-22 15:12:57 +0000 +@@ -83,6 +83,12 @@ + ':pserver:anonymous@odessa.cvs.sourceforge.net:/cvsroot/odess')) + self.assertRaises(ValueError, location_to_url, ':pserver:blah') + ++ def test_extssh(self): ++ self.assertEqual( ++ 'cvs+ssh://anonymous@odessa.cvs.sourceforge.net/cvsroot/odess', ++ location_to_url( ++ ':extssh:anonymous@odessa.cvs.sourceforge.net:/cvsroot/odess')) ++ + def test_missing_scheme(self): + self.skipTest('need clever guessing of scheme') + self.assertEqual( + diff -Nru breezy-3.1.0/debian/patches/series breezy-3.1.0/debian/patches/series --- breezy-3.1.0/debian/patches/series 2020-11-22 18:35:25.000000000 +0000 +++ breezy-3.1.0/debian/patches/series 2020-12-06 15:06:43.000000000 +0000 @@ -6,4 +6,6 @@ 18_dulwich_compat 19_is_alive 20_urlescape +21_cvs +21_extssh meliae