Merge lp:~jelmer/brz/location-purpose into lp:brz
- location-purpose
- Merge into trunk
Proposed by
Jelmer Vernooij
Status: | Merged |
---|---|
Approved by: | Jelmer Vernooij |
Approved revision: | no longer in the source branch. |
Merge reported by: | The Breezy Bot |
Merged at revision: | not available |
Proposed branch: | lp:~jelmer/brz/location-purpose |
Merge into: | lp:brz |
Diff against target: |
383 lines (+87/-27) 14 files modified
breezy/builtins.py (+4/-4) breezy/directory_service.py (+26/-6) breezy/git/directory.py (+1/-1) breezy/location.py (+6/-4) breezy/plugins/launchpad/__init__.py (+0/-1) breezy/plugins/launchpad/lp_directory.py (+1/-1) breezy/plugins/launchpad/test_lp_directory.py (+1/-1) breezy/push.py (+1/-1) breezy/tests/blackbox/test_pull.py (+1/-1) breezy/tests/blackbox/test_switch.py (+1/-1) breezy/tests/test_bundle.py (+1/-1) breezy/tests/test_directory_service.py (+36/-1) breezy/tests/test_location.py (+2/-2) breezy/transport/__init__.py (+6/-2) |
To merge this branch: | bzr merge lp:~jelmer/brz/location-purpose |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Martin Packman | Approve | ||
Review via email: mp+362940@code.launchpad.net |
Commit message
Add a purpose argument to location dereference functions.
Description of the change
Add a purpose argument to location dereference functions.
To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) wrote : | # |
Change push => write
Revision history for this message
Jelmer Vernooij (jelmer) wrote : | # |
The idea here is that you can declare whether you're going to read from or write to a branch, allowing callees (such as a directory service) to e.g. give you a https or bzr+ssh URL.
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote : | # |
Running landing tests failed
https:/
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'breezy/builtins.py' | |||
2 | --- breezy/builtins.py 2019-02-04 01:01:24 +0000 | |||
3 | +++ breezy/builtins.py 2019-02-14 22:08:33 +0000 | |||
4 | @@ -1480,7 +1480,7 @@ | |||
5 | 1480 | revision_id = br_from.last_revision() | 1480 | revision_id = br_from.last_revision() |
6 | 1481 | if to_location is None: | 1481 | if to_location is None: |
7 | 1482 | to_location = urlutils.derive_to_location(from_location) | 1482 | to_location = urlutils.derive_to_location(from_location) |
9 | 1483 | to_transport = transport.get_transport(to_location) | 1483 | to_transport = transport.get_transport(to_location, purpose='write') |
10 | 1484 | try: | 1484 | try: |
11 | 1485 | to_transport.mkdir('.') | 1485 | to_transport.mkdir('.') |
12 | 1486 | except errors.FileExists: | 1486 | except errors.FileExists: |
13 | @@ -1574,7 +1574,7 @@ | |||
14 | 1574 | 1574 | ||
15 | 1575 | def run(self, location=".", recursive=False): | 1575 | def run(self, location=".", recursive=False): |
16 | 1576 | if recursive: | 1576 | if recursive: |
18 | 1577 | t = transport.get_transport(location) | 1577 | t = transport.get_transport(location, purpose='read') |
19 | 1578 | if not t.listable(): | 1578 | if not t.listable(): |
20 | 1579 | raise errors.BzrCommandError( | 1579 | raise errors.BzrCommandError( |
21 | 1580 | "Can't scan this type of location.") | 1580 | "Can't scan this type of location.") |
22 | @@ -2058,7 +2058,7 @@ | |||
23 | 2058 | if location is None: | 2058 | if location is None: |
24 | 2059 | location = u'.' | 2059 | location = u'.' |
25 | 2060 | 2060 | ||
27 | 2061 | to_transport = transport.get_transport(location) | 2061 | to_transport = transport.get_transport(location, purpose='write') |
28 | 2062 | 2062 | ||
29 | 2063 | # The path has to exist to initialize a | 2063 | # The path has to exist to initialize a |
30 | 2064 | # branch inside of it. | 2064 | # branch inside of it. |
31 | @@ -2178,7 +2178,7 @@ | |||
32 | 2178 | if location is None: | 2178 | if location is None: |
33 | 2179 | location = '.' | 2179 | location = '.' |
34 | 2180 | 2180 | ||
36 | 2181 | to_transport = transport.get_transport(location) | 2181 | to_transport = transport.get_transport(location, purpose='write') |
37 | 2182 | 2182 | ||
38 | 2183 | if format.fixed_components: | 2183 | if format.fixed_components: |
39 | 2184 | repo_format_name = None | 2184 | repo_format_name = None |
40 | 2185 | 2185 | ||
41 | === modified file 'breezy/directory_service.py' | |||
42 | --- breezy/directory_service.py 2018-11-11 04:08:32 +0000 | |||
43 | +++ breezy/directory_service.py 2019-02-14 22:08:33 +0000 | |||
44 | @@ -67,7 +67,7 @@ | |||
45 | 67 | name and URL, and return a URL. | 67 | name and URL, and return a URL. |
46 | 68 | """ | 68 | """ |
47 | 69 | 69 | ||
49 | 70 | def dereference(self, url): | 70 | def dereference(self, url, purpose=None): |
50 | 71 | """Dereference a supplied URL if possible. | 71 | """Dereference a supplied URL if possible. |
51 | 72 | 72 | ||
52 | 73 | URLs that match a registered directory service prefix are looked up in | 73 | URLs that match a registered directory service prefix are looked up in |
53 | @@ -77,19 +77,39 @@ | |||
54 | 77 | requires further dereferencing. | 77 | requires further dereferencing. |
55 | 78 | 78 | ||
56 | 79 | :param url: The URL to dereference | 79 | :param url: The URL to dereference |
57 | 80 | :param purpose: Purpose of the URL ('read', 'write' or None - if not declared) | ||
58 | 80 | :return: The dereferenced URL if applicable, the input URL otherwise. | 81 | :return: The dereferenced URL if applicable, the input URL otherwise. |
59 | 81 | """ | 82 | """ |
60 | 82 | match = self.get_prefix(url) | 83 | match = self.get_prefix(url) |
61 | 83 | if match is None: | 84 | if match is None: |
62 | 84 | return url | 85 | return url |
63 | 85 | service, name = match | 86 | service, name = match |
65 | 86 | return service().look_up(name, url) | 87 | directory = service() |
66 | 88 | try: | ||
67 | 89 | return directory.look_up(name, url, purpose=purpose) | ||
68 | 90 | except TypeError: | ||
69 | 91 | # Compatibility for plugins written for Breezy < 3.0.0 | ||
70 | 92 | return directory.look_up(name, url) | ||
71 | 87 | 93 | ||
72 | 88 | 94 | ||
73 | 89 | directories = DirectoryServiceRegistry() | 95 | directories = DirectoryServiceRegistry() |
74 | 90 | 96 | ||
75 | 91 | 97 | ||
77 | 92 | class AliasDirectory(object): | 98 | class Directory(object): |
78 | 99 | """Abstract directory lookup class.""" | ||
79 | 100 | |||
80 | 101 | def look_up(self, name, url, purpose=None): | ||
81 | 102 | """Look up an entry in a directory. | ||
82 | 103 | |||
83 | 104 | :param name: Directory name | ||
84 | 105 | :param url: The URL to dereference | ||
85 | 106 | :param purpose: Purpose of the URL ('read', 'write' or None - if not declared) | ||
86 | 107 | :return: The dereferenced URL if applicable, the input URL otherwise. | ||
87 | 108 | """ | ||
88 | 109 | raise NotImplementedError(self.look_up) | ||
89 | 110 | |||
90 | 111 | |||
91 | 112 | class AliasDirectory(Directory): | ||
92 | 93 | """Directory lookup for locations associated with a branch. | 113 | """Directory lookup for locations associated with a branch. |
93 | 94 | 114 | ||
94 | 95 | :parent, :submit, :public, :push, :this, and :bound are currently | 115 | :parent, :submit, :public, :push, :this, and :bound are currently |
95 | @@ -110,7 +130,7 @@ | |||
96 | 110 | branch_aliases.register('this', lambda b: b.base, | 130 | branch_aliases.register('this', lambda b: b.base, |
97 | 111 | help="This branch.") | 131 | help="This branch.") |
98 | 112 | 132 | ||
100 | 113 | def look_up(self, name, url): | 133 | def look_up(self, name, url, purpose=None): |
101 | 114 | branch = _mod_branch.Branch.open_containing('.')[0] | 134 | branch = _mod_branch.Branch.open_containing('.')[0] |
102 | 115 | parts = url.split('/', 1) | 135 | parts = url.split('/', 1) |
103 | 116 | if len(parts) == 2: | 136 | if len(parts) == 2: |
104 | @@ -156,14 +176,14 @@ | |||
105 | 156 | 'Easy access to remembered branch locations') | 176 | 'Easy access to remembered branch locations') |
106 | 157 | 177 | ||
107 | 158 | 178 | ||
109 | 159 | class ColocatedDirectory(object): | 179 | class ColocatedDirectory(Directory): |
110 | 160 | """Directory lookup for colocated branches. | 180 | """Directory lookup for colocated branches. |
111 | 161 | 181 | ||
112 | 162 | co:somename will resolve to the colocated branch with "somename" in | 182 | co:somename will resolve to the colocated branch with "somename" in |
113 | 163 | the current directory. | 183 | the current directory. |
114 | 164 | """ | 184 | """ |
115 | 165 | 185 | ||
117 | 166 | def look_up(self, name, url): | 186 | def look_up(self, name, url, purpose=None): |
118 | 167 | dir = _mod_controldir.ControlDir.open_containing('.')[0] | 187 | dir = _mod_controldir.ControlDir.open_containing('.')[0] |
119 | 168 | return urlutils.join_segment_parameters(dir.user_url, | 188 | return urlutils.join_segment_parameters(dir.user_url, |
120 | 169 | {"branch": urlutils.escape(name)}) | 189 | {"branch": urlutils.escape(name)}) |
121 | 170 | 190 | ||
122 | === modified file 'breezy/git/directory.py' | |||
123 | --- breezy/git/directory.py 2018-11-11 04:08:32 +0000 | |||
124 | +++ breezy/git/directory.py 2019-02-14 22:08:33 +0000 | |||
125 | @@ -26,6 +26,6 @@ | |||
126 | 26 | 26 | ||
127 | 27 | class GitHubDirectory(object): | 27 | class GitHubDirectory(object): |
128 | 28 | 28 | ||
130 | 29 | def look_up(self, name, url): | 29 | def look_up(self, name, url, purpose=None): |
131 | 30 | """See DirectoryService.look_up""" | 30 | """See DirectoryService.look_up""" |
132 | 31 | return "git+ssh://git@github.com/" + name | 31 | return "git+ssh://git@github.com/" + name |
133 | 32 | 32 | ||
134 | === modified file 'breezy/location.py' | |||
135 | --- breezy/location.py 2019-02-09 02:03:11 +0000 | |||
136 | +++ breezy/location.py 2019-02-14 22:08:33 +0000 | |||
137 | @@ -37,26 +37,28 @@ | |||
138 | 37 | Hooks.__init__(self, "breezy.location", "hooks") | 37 | Hooks.__init__(self, "breezy.location", "hooks") |
139 | 38 | self.add_hook( | 38 | self.add_hook( |
140 | 39 | 'rewrite_url', | 39 | 'rewrite_url', |
142 | 40 | "Called with a URL to rewrite.", (3, 0)) | 40 | "Possibly rewrite a URL. Called with a URL to rewrite and the " |
143 | 41 | "purpose of the URL.", (3, 0)) | ||
144 | 41 | 42 | ||
145 | 42 | 43 | ||
146 | 43 | hooks = LocationHooks() | 44 | hooks = LocationHooks() |
147 | 44 | 45 | ||
148 | 45 | 46 | ||
150 | 46 | def location_to_url(location): | 47 | def location_to_url(location, purpose=None): |
151 | 47 | """Determine a fully qualified URL from a location string. | 48 | """Determine a fully qualified URL from a location string. |
152 | 48 | 49 | ||
153 | 49 | This will try to interpret location as both a URL and a directory path. It | 50 | This will try to interpret location as both a URL and a directory path. It |
154 | 50 | will also lookup the location in directories. | 51 | will also lookup the location in directories. |
155 | 51 | 52 | ||
156 | 52 | :param location: Unicode or byte string object with a location | 53 | :param location: Unicode or byte string object with a location |
157 | 54 | :param purpose: Intended method of access (None, 'read' or 'write') | ||
158 | 53 | :raise InvalidURL: If the location is already a URL, but not valid. | 55 | :raise InvalidURL: If the location is already a URL, but not valid. |
159 | 54 | :return: Byte string with resulting URL | 56 | :return: Byte string with resulting URL |
160 | 55 | """ | 57 | """ |
161 | 56 | if not isinstance(location, string_types): | 58 | if not isinstance(location, string_types): |
162 | 57 | raise AssertionError("location not a byte or unicode string") | 59 | raise AssertionError("location not a byte or unicode string") |
163 | 58 | from .directory_service import directories | 60 | from .directory_service import directories |
165 | 59 | location = directories.dereference(location) | 61 | location = directories.dereference(location, purpose) |
166 | 60 | 62 | ||
167 | 61 | # Catch any URLs which are passing Unicode rather than ASCII | 63 | # Catch any URLs which are passing Unicode rather than ASCII |
168 | 62 | try: | 64 | try: |
169 | @@ -77,6 +79,6 @@ | |||
170 | 77 | return urlutils.local_path_to_url(location) | 79 | return urlutils.local_path_to_url(location) |
171 | 78 | 80 | ||
172 | 79 | for hook in hooks['rewrite_url']: | 81 | for hook in hooks['rewrite_url']: |
174 | 80 | location = hook(location) | 82 | location = hook(location, purpose=purpose) |
175 | 81 | 83 | ||
176 | 82 | return location | 84 | return location |
177 | 83 | 85 | ||
178 | === modified file 'breezy/plugins/launchpad/__init__.py' | |||
179 | --- breezy/plugins/launchpad/__init__.py 2019-02-02 22:23:40 +0000 | |||
180 | +++ breezy/plugins/launchpad/__init__.py 2019-02-14 22:08:33 +0000 | |||
181 | @@ -29,7 +29,6 @@ | |||
182 | 29 | 29 | ||
183 | 30 | launchpad-login: Show or set the Launchpad user ID | 30 | launchpad-login: Show or set the Launchpad user ID |
184 | 31 | launchpad-open: Open a Launchpad branch page in your web browser | 31 | launchpad-open: Open a Launchpad branch page in your web browser |
185 | 32 | launchpad-mirror: Ask Launchpad to mirror a branch now | ||
186 | 33 | 32 | ||
187 | 34 | As well as the following deprecated command: | 33 | As well as the following deprecated command: |
188 | 35 | 34 | ||
189 | 36 | 35 | ||
190 | === modified file 'breezy/plugins/launchpad/lp_directory.py' | |||
191 | --- breezy/plugins/launchpad/lp_directory.py 2019-02-02 22:23:40 +0000 | |||
192 | +++ breezy/plugins/launchpad/lp_directory.py 2019-02-14 22:08:33 +0000 | |||
193 | @@ -117,7 +117,7 @@ | |||
194 | 117 | 117 | ||
195 | 118 | class LaunchpadDirectory(object): | 118 | class LaunchpadDirectory(object): |
196 | 119 | 119 | ||
198 | 120 | def look_up(self, name, url): | 120 | def look_up(self, name, url, purpose=None): |
199 | 121 | """See DirectoryService.look_up""" | 121 | """See DirectoryService.look_up""" |
200 | 122 | return self._resolve(url) | 122 | return self._resolve(url) |
201 | 123 | 123 | ||
202 | 124 | 124 | ||
203 | === modified file 'breezy/plugins/launchpad/test_lp_directory.py' | |||
204 | --- breezy/plugins/launchpad/test_lp_directory.py 2019-01-17 01:04:56 +0000 | |||
205 | +++ breezy/plugins/launchpad/test_lp_directory.py 2019-02-14 22:08:33 +0000 | |||
206 | @@ -397,7 +397,7 @@ | |||
207 | 397 | class FooService(object): | 397 | class FooService(object): |
208 | 398 | """A directory service that maps the name to a FILE url""" | 398 | """A directory service that maps the name to a FILE url""" |
209 | 399 | 399 | ||
211 | 400 | def look_up(self, name, url): | 400 | def look_up(self, name, url, purpose=None): |
212 | 401 | if 'lp:///apt' == url: | 401 | if 'lp:///apt' == url: |
213 | 402 | return target_branch.base.rstrip('/') | 402 | return target_branch.base.rstrip('/') |
214 | 403 | return '!unexpected look_up value!' | 403 | return '!unexpected look_up value!' |
215 | 404 | 404 | ||
216 | === modified file 'breezy/push.py' | |||
217 | --- breezy/push.py 2018-11-17 16:53:10 +0000 | |||
218 | +++ breezy/push.py 2019-02-14 22:08:33 +0000 | |||
219 | @@ -81,7 +81,7 @@ | |||
220 | 81 | directory exists without a current control directory in it | 81 | directory exists without a current control directory in it |
221 | 82 | :param lossy: Allow lossy push | 82 | :param lossy: Allow lossy push |
222 | 83 | """ | 83 | """ |
224 | 84 | to_transport = transport.get_transport(location) | 84 | to_transport = transport.get_transport(location, purpose='write') |
225 | 85 | try: | 85 | try: |
226 | 86 | dir_to = controldir.ControlDir.open_from_transport(to_transport) | 86 | dir_to = controldir.ControlDir.open_from_transport(to_transport) |
227 | 87 | except errors.NotBranchError: | 87 | except errors.NotBranchError: |
228 | 88 | 88 | ||
229 | === modified file 'breezy/tests/blackbox/test_pull.py' | |||
230 | --- breezy/tests/blackbox/test_pull.py 2018-11-29 23:42:41 +0000 | |||
231 | +++ breezy/tests/blackbox/test_pull.py 2019-02-14 22:08:33 +0000 | |||
232 | @@ -353,7 +353,7 @@ | |||
233 | 353 | class FooService(object): | 353 | class FooService(object): |
234 | 354 | """A directory service that always returns source""" | 354 | """A directory service that always returns source""" |
235 | 355 | 355 | ||
237 | 356 | def look_up(self, name, url): | 356 | def look_up(self, name, url, purpose=None): |
238 | 357 | return 'source' | 357 | return 'source' |
239 | 358 | directories.register('foo:', FooService, 'Testing directory service') | 358 | directories.register('foo:', FooService, 'Testing directory service') |
240 | 359 | self.addCleanup(directories.remove, 'foo:') | 359 | self.addCleanup(directories.remove, 'foo:') |
241 | 360 | 360 | ||
242 | === modified file 'breezy/tests/blackbox/test_switch.py' | |||
243 | --- breezy/tests/blackbox/test_switch.py 2019-01-04 21:21:12 +0000 | |||
244 | +++ breezy/tests/blackbox/test_switch.py 2019-02-14 22:08:33 +0000 | |||
245 | @@ -347,7 +347,7 @@ | |||
246 | 347 | tree = branch.create_checkout('tree', lightweight=True) | 347 | tree = branch.create_checkout('tree', lightweight=True) |
247 | 348 | 348 | ||
248 | 349 | class FooLookup(object): | 349 | class FooLookup(object): |
250 | 350 | def look_up(self, name, url): | 350 | def look_up(self, name, url, purpose=None): |
251 | 351 | return 'foo-' + name | 351 | return 'foo-' + name |
252 | 352 | directories.register('foo:', FooLookup, 'Create branches named foo-') | 352 | directories.register('foo:', FooLookup, 'Create branches named foo-') |
253 | 353 | self.addCleanup(directories.remove, 'foo:') | 353 | self.addCleanup(directories.remove, 'foo:') |
254 | 354 | 354 | ||
255 | === modified file 'breezy/tests/test_bundle.py' | |||
256 | --- breezy/tests/test_bundle.py 2019-01-01 21:23:40 +0000 | |||
257 | +++ breezy/tests/test_bundle.py 2019-02-14 22:08:33 +0000 | |||
258 | @@ -1848,7 +1848,7 @@ | |||
259 | 1848 | class FooService(object): | 1848 | class FooService(object): |
260 | 1849 | """A directory service that always returns source""" | 1849 | """A directory service that always returns source""" |
261 | 1850 | 1850 | ||
263 | 1851 | def look_up(self, name, url): | 1851 | def look_up(self, name, url, purpose=None): |
264 | 1852 | return 'source' | 1852 | return 'source' |
265 | 1853 | directories.register('foo:', FooService, 'Testing directory service') | 1853 | directories.register('foo:', FooService, 'Testing directory service') |
266 | 1854 | self.addCleanup(directories.remove, 'foo:') | 1854 | self.addCleanup(directories.remove, 'foo:') |
267 | 1855 | 1855 | ||
268 | === modified file 'breezy/tests/test_directory_service.py' | |||
269 | --- breezy/tests/test_directory_service.py 2018-11-11 04:08:32 +0000 | |||
270 | +++ breezy/tests/test_directory_service.py 2019-02-14 22:08:33 +0000 | |||
271 | @@ -36,7 +36,7 @@ | |||
272 | 36 | # eg 'file:///foo' on Unix, or 'file:///C:/foo' on Windows | 36 | # eg 'file:///foo' on Unix, or 'file:///C:/foo' on Windows |
273 | 37 | base = urlutils.local_path_to_url('/foo') | 37 | base = urlutils.local_path_to_url('/foo') |
274 | 38 | 38 | ||
276 | 39 | def look_up(self, name, url): | 39 | def look_up(self, name, url, purpose=None): |
277 | 40 | return self.base + name | 40 | return self.base + name |
278 | 41 | 41 | ||
279 | 42 | 42 | ||
280 | @@ -55,7 +55,12 @@ | |||
281 | 55 | def test_dereference(self): | 55 | def test_dereference(self): |
282 | 56 | self.assertEqual(FooService.base + 'bar', | 56 | self.assertEqual(FooService.base + 'bar', |
283 | 57 | self.registry.dereference('foo:bar')) | 57 | self.registry.dereference('foo:bar')) |
284 | 58 | self.assertEqual(FooService.base + 'bar', | ||
285 | 59 | self.registry.dereference('foo:bar', purpose='write')) | ||
286 | 58 | self.assertEqual('baz:qux', self.registry.dereference('baz:qux')) | 60 | self.assertEqual('baz:qux', self.registry.dereference('baz:qux')) |
287 | 61 | self.assertEqual( | ||
288 | 62 | 'baz:qux', | ||
289 | 63 | self.registry.dereference('baz:qux', purpose='write')) | ||
290 | 59 | 64 | ||
291 | 60 | def test_get_transport(self): | 65 | def test_get_transport(self): |
292 | 61 | directories.register('foo:', FooService, 'Map foo URLs to http urls') | 66 | directories.register('foo:', FooService, 'Map foo URLs to http urls') |
293 | @@ -64,6 +69,36 @@ | |||
294 | 64 | transport.get_transport('foo:bar').base) | 69 | transport.get_transport('foo:bar').base) |
295 | 65 | 70 | ||
296 | 66 | 71 | ||
297 | 72 | class OldService(object): | ||
298 | 73 | """A directory service that maps the name to a FILE url""" | ||
299 | 74 | |||
300 | 75 | # eg 'file:///foo' on Unix, or 'file:///C:/foo' on Windows | ||
301 | 76 | base = urlutils.local_path_to_url('/foo') | ||
302 | 77 | |||
303 | 78 | def look_up(self, name, url): | ||
304 | 79 | return self.base + name | ||
305 | 80 | |||
306 | 81 | |||
307 | 82 | class TestOldDirectoryLookup(TestCase): | ||
308 | 83 | """Test compatibility with older implementations of Directory | ||
309 | 84 | that don't support the purpose argument.""" | ||
310 | 85 | |||
311 | 86 | def setUp(self): | ||
312 | 87 | super(TestOldDirectoryLookup, self).setUp() | ||
313 | 88 | self.registry = DirectoryServiceRegistry() | ||
314 | 89 | self.registry.register('old:', OldService, 'Map foo URLs to http urls') | ||
315 | 90 | |||
316 | 91 | def test_dereference(self): | ||
317 | 92 | self.assertEqual(OldService.base + 'bar', | ||
318 | 93 | self.registry.dereference('old:bar')) | ||
319 | 94 | self.assertEqual(OldService.base + 'bar', | ||
320 | 95 | self.registry.dereference('old:bar', purpose='write')) | ||
321 | 96 | self.assertEqual('baz:qux', self.registry.dereference('baz:qux')) | ||
322 | 97 | self.assertEqual( | ||
323 | 98 | 'baz:qux', | ||
324 | 99 | self.registry.dereference('baz:qux', purpose='write')) | ||
325 | 100 | |||
326 | 101 | |||
327 | 67 | class TestAliasDirectory(TestCaseWithTransport): | 102 | class TestAliasDirectory(TestCaseWithTransport): |
328 | 68 | 103 | ||
329 | 69 | def setUp(self): | 104 | def setUp(self): |
330 | 70 | 105 | ||
331 | === modified file 'breezy/tests/test_location.py' | |||
332 | --- breezy/tests/test_location.py 2019-02-09 02:03:11 +0000 | |||
333 | +++ breezy/tests/test_location.py 2019-02-14 22:08:33 +0000 | |||
334 | @@ -30,7 +30,7 @@ | |||
335 | 30 | 30 | ||
336 | 31 | class SomeDirectory(object): | 31 | class SomeDirectory(object): |
337 | 32 | 32 | ||
339 | 33 | def look_up(self, name, url): | 33 | def look_up(self, name, url, purpose=None): |
340 | 34 | return "http://bar" | 34 | return "http://bar" |
341 | 35 | 35 | ||
342 | 36 | 36 | ||
343 | @@ -78,7 +78,7 @@ | |||
344 | 78 | def test_rewrite_hook(self): | 78 | def test_rewrite_hook(self): |
345 | 79 | self.assertEqual( | 79 | self.assertEqual( |
346 | 80 | 'http://foo.example.com/blah', location_to_url('http://foo.example.com/blah')) | 80 | 'http://foo.example.com/blah', location_to_url('http://foo.example.com/blah')) |
348 | 81 | def rewrite_url(url): | 81 | def rewrite_url(url, purpose=None): |
349 | 82 | return url.replace('foo', 'bar') | 82 | return url.replace('foo', 'bar') |
350 | 83 | self.addCleanup(location_hooks.uninstall_named_hook, 'rewrite_url', 'test') | 83 | self.addCleanup(location_hooks.uninstall_named_hook, 'rewrite_url', 'test') |
351 | 84 | location_hooks.install_named_hook('rewrite_url', rewrite_url, 'test') | 84 | location_hooks.install_named_hook('rewrite_url', rewrite_url, 'test') |
352 | 85 | 85 | ||
353 | === modified file 'breezy/transport/__init__.py' | |||
354 | --- breezy/transport/__init__.py 2018-12-10 05:22:17 +0000 | |||
355 | +++ breezy/transport/__init__.py 2019-02-14 22:08:33 +0000 | |||
356 | @@ -1553,7 +1553,7 @@ | |||
357 | 1553 | raise errors.UnsupportedProtocol(url, last_err) | 1553 | raise errors.UnsupportedProtocol(url, last_err) |
358 | 1554 | 1554 | ||
359 | 1555 | 1555 | ||
361 | 1556 | def get_transport(base, possible_transports=None): | 1556 | def get_transport(base, possible_transports=None, purpose=None): |
362 | 1557 | """Open a transport to access a URL or directory. | 1557 | """Open a transport to access a URL or directory. |
363 | 1558 | 1558 | ||
364 | 1559 | :param base: either a URL or a directory name. | 1559 | :param base: either a URL or a directory name. |
365 | @@ -1561,13 +1561,17 @@ | |||
366 | 1561 | :param transports: optional reusable transports list. If not None, created | 1561 | :param transports: optional reusable transports list. If not None, created |
367 | 1562 | transports will be added to the list. | 1562 | transports will be added to the list. |
368 | 1563 | 1563 | ||
369 | 1564 | :param purpose: Purpose for which the transport will be used | ||
370 | 1565 | (e.g. 'read', 'write' or None) | ||
371 | 1566 | |||
372 | 1564 | :return: A new transport optionally sharing its connection with one of | 1567 | :return: A new transport optionally sharing its connection with one of |
373 | 1565 | possible_transports. | 1568 | possible_transports. |
374 | 1566 | """ | 1569 | """ |
375 | 1567 | if base is None: | 1570 | if base is None: |
376 | 1568 | base = '.' | 1571 | base = '.' |
377 | 1569 | return get_transport_from_url( | 1572 | return get_transport_from_url( |
379 | 1570 | _mod_location.location_to_url(base), possible_transports) | 1573 | _mod_location.location_to_url(base, purpose=purpose), |
380 | 1574 | possible_transports) | ||
381 | 1571 | 1575 | ||
382 | 1572 | 1576 | ||
383 | 1573 | def _try_transport_factories(base, factory_list): | 1577 | def _try_transport_factories(base, factory_list): |
This branch has the hook change in as well. Not quite sure I understand the reasoning here, but seems basically reasonable? Tests use 'push' as a purpose, but the documented values are 'read' 'write' None?