Merge lp:~jelmer/loggerhead/no-file-ids into lp:loggerhead
- no-file-ids
- Merge into trunk-rich
Proposed by
Jelmer Vernooij
Status: | Merged |
---|---|
Approved by: | Colin Watson |
Approved revision: | 523 |
Merge reported by: | Otto Co-Pilot |
Merged at revision: | not available |
Proposed branch: | lp:~jelmer/loggerhead/no-file-ids |
Merge into: | lp:loggerhead |
Diff against target: |
705 lines (+102/-175) 15 files modified
loggerhead/controllers/annotate_ui.py (+3/-7) loggerhead/controllers/changelog_ui.py (+5/-10) loggerhead/controllers/download_ui.py (+1/-6) loggerhead/controllers/inventory_ui.py (+7/-15) loggerhead/controllers/revision_ui.py (+5/-5) loggerhead/controllers/view_ui.py (+3/-13) loggerhead/history.py (+51/-73) loggerhead/templates/changelog.pt (+1/-1) loggerhead/templates/inventory.pt (+3/-3) loggerhead/templates/search-box.pt (+1/-2) loggerhead/templates/view.pt (+1/-1) loggerhead/tests/fixtures.py (+2/-3) loggerhead/tests/test_controllers.py (+13/-25) loggerhead/tests/test_simple.py (+3/-6) loggerhead/util.py (+3/-5) |
To merge this branch: | bzr merge lp:~jelmer/loggerhead/no-file-ids |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Colin Watson (community) | Approve | ||
Review via email: mp+426375@code.launchpad.net |
Commit message
Avoid use of file ids - use paths instead.
Description of the change
Avoid use of file ids - use paths instead.
This prepares loggerhead for upcoming Breezy changes, which remove file ids
from the primary API. The goal behind this is to make the implementation
of non-Bazaar filesystems simpler.
To post a comment you must log in.
Revision history for this message
Otto Co-Pilot (otto-copilot) wrote : | # |
A commit message must be set
https:/
Revision history for this message
Otto Co-Pilot (otto-copilot) 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 'loggerhead/controllers/annotate_ui.py' |
2 | --- loggerhead/controllers/annotate_ui.py 2020-07-14 16:41:12 +0000 |
3 | +++ loggerhead/controllers/annotate_ui.py 2022-07-06 12:59:30 +0000 |
4 | @@ -24,14 +24,10 @@ |
5 | |
6 | class AnnotateUI(ViewUI): |
7 | |
8 | - def annotate_file(self, info): |
9 | - file_id = info['file_id'] |
10 | + def annotate_file(self, path, info): |
11 | revid = info['change'].revid |
12 | - if not isinstance(file_id, bytes): |
13 | - raise TypeError(file_id) |
14 | if not isinstance(revid, bytes): |
15 | raise TypeError(revid) |
16 | - path = self._history.get_path(revid, file_id) |
17 | |
18 | tree = self.tree_for(path, revid) |
19 | |
20 | @@ -43,7 +39,7 @@ |
21 | revisions = {} |
22 | |
23 | lineno = 0 |
24 | - for (line_revid, text), lineno in zip(tree.annotate_iter(path, file_id), itertools.count(1)): |
25 | + for (line_revid, text), lineno in zip(tree.annotate_iter(path), itertools.count(1)): |
26 | if line_revid != last_line_revid: |
27 | last_line_revid = line_revid |
28 | |
29 | @@ -84,6 +80,6 @@ |
30 | |
31 | def get_values(self, path, kwargs, headers): |
32 | values = super(AnnotateUI, self).get_values(path, kwargs, headers) |
33 | - values['annotated'] = self.annotate_file(values) |
34 | + values['annotated'] = self.annotate_file(path, values) |
35 | |
36 | return values |
37 | |
38 | === modified file 'loggerhead/controllers/changelog_ui.py' |
39 | --- loggerhead/controllers/changelog_ui.py 2020-07-08 17:14:19 +0000 |
40 | +++ loggerhead/controllers/changelog_ui.py 2022-07-06 12:59:30 +0000 |
41 | @@ -35,21 +35,16 @@ |
42 | def get_values(self, path, kwargs, headers): |
43 | history = self._history |
44 | revid = self.get_revid() |
45 | - filter_file_id = kwargs.get('filter_file_id', None) |
46 | - if filter_file_id is not None: |
47 | - filter_file_id = urlutils.unquote_to_bytes(osutils.safe_utf8(filter_file_id)) |
48 | + filter_path = kwargs.get('filter_path', path) |
49 | query = kwargs.get('q', None) |
50 | start_revid = history.fix_revid(kwargs.get('start_revid', None)) |
51 | orig_start_revid = start_revid |
52 | - pagesize = 20#int(config.get('pagesize', '20')) |
53 | + pagesize = 20 #int(config.get('pagesize', '20')) |
54 | search_failed = False |
55 | |
56 | - if filter_file_id is None and path is not None: |
57 | - filter_file_id = history.get_file_id(revid, path) |
58 | - |
59 | try: |
60 | revid, start_revid, revid_list = history.get_view( |
61 | - revid, start_revid, filter_file_id, query, |
62 | + revid, start_revid, filter_path, query, |
63 | extra_rev_count=pagesize+1) |
64 | util.set_context(kwargs) |
65 | |
66 | @@ -76,7 +71,7 @@ |
67 | |
68 | navigation = util.Container( |
69 | pagesize=pagesize, revid=revid, start_revid=start_revid, |
70 | - revid_list=revid_list, filter_file_id=filter_file_id, |
71 | + revid_list=revid_list, filter_path=filter_path, |
72 | scan_url='/changes', branch=self._branch, feed=True, history=history) |
73 | if query is not None: |
74 | navigation.query = query |
75 | @@ -104,7 +99,7 @@ |
76 | 'history': history, |
77 | 'revid': revid, |
78 | 'navigation': navigation, |
79 | - 'filter_file_id': filter_file_id, |
80 | + 'filter_path': filter_path, |
81 | 'start_revid': start_revid, |
82 | 'viewing_from': (orig_start_revid is not None) and |
83 | (orig_start_revid != history.last_revid), |
84 | |
85 | === modified file 'loggerhead/controllers/download_ui.py' |
86 | --- loggerhead/controllers/download_ui.py 2020-07-08 17:12:21 +0000 |
87 | +++ loggerhead/controllers/download_ui.py 2022-07-06 12:59:30 +0000 |
88 | @@ -61,12 +61,7 @@ |
89 | try: |
90 | path, filename, content = h.get_file(args[1], revid) |
91 | except (NoSuchFile, NoSuchRevision): |
92 | - # Compatibility API for /download/rev_id/file_id/<filename> |
93 | - try: |
94 | - path, filename, content = h.get_file_by_fileid( |
95 | - args[1].encode('UTF-8'), revid) |
96 | - except (NoSuchId, NoSuchRevision): |
97 | - raise httpexceptions.HTTPNotFound() |
98 | + raise httpexceptions.HTTPNotFound() |
99 | mime_type, encoding = mimetypes.guess_type(filename) |
100 | if mime_type is None: |
101 | mime_type = 'application/octet-stream' |
102 | |
103 | === modified file 'loggerhead/controllers/inventory_ui.py' |
104 | --- loggerhead/controllers/inventory_ui.py 2018-11-01 21:48:40 +0000 |
105 | +++ loggerhead/controllers/inventory_ui.py 2022-07-06 12:59:30 +0000 |
106 | @@ -95,7 +95,7 @@ |
107 | file = util.Container( |
108 | filename=entry.name, executable=entry.executable, |
109 | kind=entry.kind, absolutepath=child_path, |
110 | - file_id=entry.file_id, size=size, revid=child_revision, |
111 | + size=size, revid=child_revision, |
112 | change=change_dict[child_revision], contents_changed_rev=contents_changed_rev) |
113 | file_list.append(file) |
114 | |
115 | @@ -125,23 +125,15 @@ |
116 | except errors.NoSuchRevision: |
117 | raise HTTPNotFound() |
118 | |
119 | - file_id = kwargs.get('file_id', None) |
120 | start_revid = kwargs.get('start_revid', None) |
121 | sort_type = kwargs.get('sort', 'filename') |
122 | |
123 | - if path is not None: |
124 | - path = path.rstrip('/') |
125 | - file_id = rev_tree.path2id(path) |
126 | - if file_id is None: |
127 | - raise HTTPNotFound() |
128 | - else: |
129 | - if file_id is None: |
130 | - path = '' |
131 | - else: |
132 | - try: |
133 | - path = rev_tree.id2path(file_id) |
134 | - except errors.NoSuchId: |
135 | - raise HTTPNotFound() |
136 | + if path is None: |
137 | + path = "/" |
138 | + |
139 | + path = path.rstrip('/') |
140 | + if not rev_tree.has_filename(path) and not is_null_rev(revid): |
141 | + raise HTTPNotFound() |
142 | |
143 | # Are we at the top of the tree |
144 | if path in ['/', '']: |
145 | |
146 | === modified file 'loggerhead/controllers/revision_ui.py' |
147 | --- loggerhead/controllers/revision_ui.py 2021-03-29 11:18:58 +0000 |
148 | +++ loggerhead/controllers/revision_ui.py 2022-07-06 12:59:30 +0000 |
149 | @@ -46,7 +46,7 @@ |
150 | h = self._history |
151 | revid = self.get_revid() |
152 | |
153 | - filter_file_id = kwargs.get('filter_file_id', None) |
154 | + filter_path = kwargs.get('filter_path', None) |
155 | start_revid = h.fix_revid(kwargs.get('start_revid', None)) |
156 | query = kwargs.get('q', None) |
157 | compare_revid = h.fix_revid(kwargs.get('compare_revid', None)) |
158 | @@ -56,7 +56,7 @@ |
159 | try: |
160 | revid, start_revid, revid_list = h.get_view(revid, |
161 | start_revid, |
162 | - filter_file_id, |
163 | + filter_path, |
164 | query) |
165 | except BaseException: |
166 | self.log.exception('Exception fetching changes') |
167 | @@ -102,12 +102,12 @@ |
168 | super(RevisionUI, self).add_template_values(values) |
169 | remember = self._history.fix_revid(self.kwargs.get('remember', None)) |
170 | query = self.kwargs.get('q', None) |
171 | - filter_file_id = self.kwargs.get('filter_file_id', None) |
172 | + filter_path = self.kwargs.get('filter_path', None) |
173 | start_revid = self.kwargs['start_revid'] |
174 | navigation = util.Container( |
175 | revid_list=self.revid_list, revid=values['revid'], |
176 | start_revid=start_revid, |
177 | - filter_file_id=filter_file_id, pagesize=1, |
178 | + filter_path=filter_path, pagesize=1, |
179 | scan_url='/revision', branch=self._branch, feed=True, |
180 | history=self._history) |
181 | if query is not None: |
182 | @@ -161,7 +161,7 @@ |
183 | 'navigation': navigation, |
184 | 'remember': remember, |
185 | 'compare_revid': self.compare_revid, |
186 | - 'filter_file_id': filter_file_id, |
187 | + 'filter_path': filter_path, |
188 | 'diff_chunks': diff_chunks, |
189 | 'query': query, |
190 | 'can_export': can_export, |
191 | |
192 | === modified file 'loggerhead/controllers/view_ui.py' |
193 | --- loggerhead/controllers/view_ui.py 2021-11-15 14:40:11 +0000 |
194 | +++ loggerhead/controllers/view_ui.py 2022-07-06 12:59:30 +0000 |
195 | @@ -99,19 +99,10 @@ |
196 | history = self._history |
197 | branch = history._branch |
198 | revid = self.get_revid() |
199 | - file_id = kwargs.get('file_id', None) |
200 | - if file_id is not None: |
201 | - file_id = urlutils.unquote_to_bytes(osutils.safe_utf8(file_id)) |
202 | - if (file_id is None) and (path is None): |
203 | - raise HTTPBadRequest('No file_id or filename ' |
204 | - 'provided to view') |
205 | + if path is None: |
206 | + raise HTTPBadRequest('No filename provided to view') |
207 | |
208 | - try: |
209 | - if file_id is None: |
210 | - file_id = history.get_file_id(revid, path) |
211 | - if path is None: |
212 | - path = history.get_path(revid, file_id) |
213 | - except (NoSuchId, NoSuchRevision): |
214 | + if not history.file_exists(revid, path): |
215 | raise HTTPNotFound() |
216 | |
217 | filename = os.path.basename(path) |
218 | @@ -151,7 +142,6 @@ |
219 | # checking whether we're in "annotated" mode. |
220 | 'annotated': {}, |
221 | 'revno_url': revno_url, |
222 | - 'file_id': file_id, |
223 | 'file_path': path, |
224 | 'filename': filename, |
225 | 'navigation': navigation, |
226 | |
227 | === modified file 'loggerhead/history.py' |
228 | --- loggerhead/history.py 2021-11-15 14:40:11 +0000 |
229 | +++ loggerhead/history.py 2022-07-06 12:59:30 +0000 |
230 | @@ -34,7 +34,6 @@ |
231 | import textwrap |
232 | import threading |
233 | |
234 | -from breezy import version_info as breezy_version |
235 | from breezy import tag |
236 | import breezy.branch |
237 | import breezy.delta |
238 | @@ -127,18 +126,11 @@ |
239 | except breezy.errors.NoSuchFile: |
240 | return breezy.revision.NULL_REVISION |
241 | |
242 | - if breezy_version >= (3, 1): |
243 | - def report(self, paths, versioned, renamed, copied, modified, |
244 | - exe_change, kind): |
245 | - return self._report( |
246 | - paths, versioned, renamed, copied, |
247 | - modified, exe_change, kind) |
248 | - else: |
249 | - def report(self, file_id, paths, versioned, renamed, modified, |
250 | - exe_change, kind): |
251 | - return self._report( |
252 | - paths, versioned, renamed, None, |
253 | - modified, exe_change, kind) |
254 | + def report(self, paths, versioned, renamed, copied, modified, |
255 | + exe_change, kind): |
256 | + return self._report( |
257 | + paths, versioned, renamed, copied, |
258 | + modified, exe_change, kind) |
259 | |
260 | def _report(self, paths, versioned, renamed, copied, modified, |
261 | exe_change, kind): |
262 | @@ -376,6 +368,7 @@ |
263 | def get_short_revision_history_by_fileid(self, file_id): |
264 | # FIXME: would be awesome if we could get, for a folder, the list of |
265 | # revisions where items within that folder changed.i |
266 | + # TODO(jelmer): Avoid versionedfile-specific texts |
267 | possible_keys = [(file_id, revid) for revid in self._rev_indices] |
268 | get_parent_map = self._branch.repository.texts.get_parent_map |
269 | # We chunk the requests as this works better with GraphIndex. |
270 | @@ -478,24 +471,6 @@ |
271 | revid = revid.encode('utf-8') |
272 | return revid |
273 | |
274 | - def get_file_view(self, revid, file_id): |
275 | - """ |
276 | - Given a revid and optional path, return a (revlist, revid) for |
277 | - navigation through the current scope: from the revid (or the latest |
278 | - revision) back to the original revision. |
279 | - |
280 | - If file_id is None, the entire revision history is the list scope. |
281 | - """ |
282 | - if revid is None: |
283 | - revid = self.last_revid |
284 | - if file_id is not None: |
285 | - revlist = list( |
286 | - self.get_short_revision_history_by_fileid(file_id)) |
287 | - revlist = self.get_revids_from(revlist, revid) |
288 | - else: |
289 | - revlist = self.get_revids_from(None, revid) |
290 | - return revlist |
291 | - |
292 | @staticmethod |
293 | def _iterate_sufficiently(iterable, stop_at, extra_rev_count): |
294 | """Return a list of iterable. |
295 | @@ -522,15 +497,33 @@ |
296 | result.append(n) |
297 | return result |
298 | |
299 | - def get_view(self, revid, start_revid, file_id, query=None, |
300 | + def _get_file_view(self, revid, file_id): |
301 | + """ |
302 | + Given a revid and optional path, return a (revlist, revid) for |
303 | + navigation through the current scope: from the revid (or the latest |
304 | + revision) back to the original revision. |
305 | + |
306 | + If file_id is None, the entire revision history is the list scope. |
307 | + """ |
308 | + if revid is None: |
309 | + revid = self.last_revid |
310 | + if file_id is not None: |
311 | + revlist = list( |
312 | + self.get_short_revision_history_by_fileid(file_id)) |
313 | + revlist = self.get_revids_from(revlist, revid) |
314 | + else: |
315 | + revlist = self.get_revids_from(None, revid) |
316 | + return revlist |
317 | + |
318 | + def get_view(self, revid, start_revid, path, query=None, |
319 | extra_rev_count=None): |
320 | """ |
321 | - use the URL parameters (revid, start_revid, file_id, and query) to |
322 | - determine the revision list we're viewing (start_revid, file_id, query) |
323 | + use the URL parameters (revid, start_revid, path, and query) to |
324 | + determine the revision list we're viewing (start_revid, path, query) |
325 | and where we are in it (revid). |
326 | |
327 | - if a query is given, we're viewing query results. |
328 | - - if a file_id is given, we're viewing revisions for a specific |
329 | + - if a path is given, we're viewing revisions for a specific |
330 | file. |
331 | - if a start_revid is given, we're viewing the branch from a |
332 | specific revision up the tree. |
333 | @@ -548,14 +541,19 @@ |
334 | - start_revid: starting revision of this view |
335 | - revid_list: list of revision ids for this view |
336 | |
337 | - file_id and query are never changed so aren't returned, but they may |
338 | + path and query are never changed so aren't returned, but they may |
339 | contain vital context for future url navigation. |
340 | """ |
341 | if start_revid is None: |
342 | start_revid = self.last_revid |
343 | |
344 | if query is None: |
345 | - revid_list = self.get_file_view(start_revid, file_id) |
346 | + repo = self._branch.repository |
347 | + if path is not None: |
348 | + file_id = repo.revision_tree(start_revid).path2id(path) |
349 | + else: |
350 | + file_id = None |
351 | + revid_list = self._get_file_view(start_revid, file_id) |
352 | revid_list = self._iterate_sufficiently(revid_list, revid, |
353 | extra_rev_count) |
354 | if revid is None: |
355 | @@ -563,15 +561,17 @@ |
356 | if revid not in revid_list: |
357 | # if the given revid is not in the revlist, use a revlist that |
358 | # starts at the given revid. |
359 | - revid_list = self.get_file_view(revid, file_id) |
360 | + revid_list = self._get_file_view(revid, file_id) |
361 | revid_list = self._iterate_sufficiently(revid_list, revid, |
362 | extra_rev_count) |
363 | start_revid = revid |
364 | return revid, start_revid, revid_list |
365 | + else: |
366 | + file_id = None |
367 | |
368 | # potentially limit the search |
369 | if file_id is not None: |
370 | - revid_list = self.get_file_view(start_revid, file_id) |
371 | + revid_list = self._get_file_view(start_revid, file_id) |
372 | else: |
373 | revid_list = None |
374 | revid_list = search.search_revisions(self._branch, query) |
375 | @@ -588,18 +588,13 @@ |
376 | def revision_tree(self, revid): |
377 | return self._branch.repository.revision_tree(revid) |
378 | |
379 | - def get_path(self, revid, file_id): |
380 | - if (file_id is None) or (file_id == ''): |
381 | - return '' |
382 | - path = self.revision_tree(revid).id2path(file_id) |
383 | - if (len(path) > 0) and not path.startswith('/'): |
384 | - path = '/' + path |
385 | - return path |
386 | - |
387 | - def get_file_id(self, revid, path): |
388 | - if (len(path) > 0) and not path.startswith('/'): |
389 | - path = '/' + path |
390 | - return self.revision_tree(revid).path2id(path) |
391 | + def file_exists(self, revid, path): |
392 | + if (len(path) > 0) and not path.startswith('/'): |
393 | + path = '/' + path |
394 | + try: |
395 | + return self.revision_tree(revid).has_filename(path) |
396 | + except breezy.errors.NoSuchRevision: |
397 | + return False |
398 | |
399 | def get_merge_point_list(self, revid): |
400 | """ |
401 | @@ -786,32 +781,15 @@ |
402 | return (display_path, breezy.osutils.basename(path), |
403 | rev_tree.get_file_text(path)) |
404 | |
405 | - def get_file_by_fileid(self, fileid, revid): |
406 | - """Returns (path, filename, file contents)""" |
407 | - if not isinstance(fileid, bytes): |
408 | - raise TypeError(fileid) |
409 | - if not isinstance(revid, bytes): |
410 | - raise TypeError(revid) |
411 | - rev_tree = self._branch.repository.revision_tree(revid) |
412 | - path = rev_tree.id2path(fileid) |
413 | - display_path = path |
414 | - if not display_path.startswith('/'): |
415 | - path = '/' + path |
416 | - return (display_path, breezy.osutils.basename(path), |
417 | - rev_tree.get_file_text(path)) |
418 | - |
419 | def file_changes_for_revision_ids(self, old_revid, new_revid): |
420 | """ |
421 | Return a nested data structure containing the changes in a delta:: |
422 | |
423 | - added: list((filename, file_id)), |
424 | - renamed: list((old_filename, new_filename, file_id)), |
425 | - deleted: list((filename, file_id)), |
426 | - modified: list( |
427 | - filename: str, |
428 | - file_id: str, |
429 | - ), |
430 | - text_changes: list((filename, file_id)), |
431 | + added: list((filename)), |
432 | + renamed: list((old_filename, new_filename)), |
433 | + deleted: list((filename)), |
434 | + modified: list((filename)), |
435 | + text_changes: list((filename)), |
436 | """ |
437 | repo = self._branch.repository |
438 | if (breezy.revision.is_null(old_revid) or |
439 | |
440 | === modified file 'loggerhead/templates/changelog.pt' |
441 | --- loggerhead/templates/changelog.pt 2012-02-02 07:42:24 +0000 |
442 | +++ loggerhead/templates/changelog.pt 2022-07-06 12:59:30 +0000 |
443 | @@ -39,7 +39,7 @@ |
444 | </tal:no-link> |
445 | <tal:block condition="changes"> |
446 | » Changes |
447 | - <tal:block condition="filter_file_id">to <span tal:content="python:history.get_path(revid, filter_file_id)" /></tal:block> |
448 | + <tal:block condition="filter_path">to <span tal:content="filter_path" /></tal:block> |
449 | <tal:block condition="start_revid">from revision |
450 | <span tal:content="python:history.get_revno(start_revid)"/> |
451 | </tal:block> |
452 | |
453 | === modified file 'loggerhead/templates/inventory.pt' |
454 | --- loggerhead/templates/inventory.pt 2018-10-20 16:06:44 +0000 |
455 | +++ loggerhead/templates/inventory.pt 2022-07-06 12:59:30 +0000 |
456 | @@ -94,7 +94,7 @@ |
457 | <td class="date" tal:content="python:util.hide_email(file.change.committer)"></td> |
458 | <td class="autcell" tal:content="python:file.change.comment[:50]"></td> |
459 | <td class="timedate2"></td><!-- not showing sizes of folders --> |
460 | - <td class="expcell"><a tal:attributes="href python:url(['/changes'], start_revid=start_revid, filter_file_id=file.file_id); |
461 | + <td class="expcell"><a tal:attributes="href python:url(['/changes'], start_revid=start_revid, filter_path=file.absolutepath); |
462 | title string:Show revision ${file/change/revno}"> |
463 | <img tal:attributes="src python:branch.static_url('/static/images/ico_planilla.gif')" alt="Diff" /> |
464 | </a> |
465 | @@ -119,7 +119,7 @@ |
466 | <td class="date" tal:content="python:util.hide_email(file.change.committer)"></td> |
467 | <td class="autcell" tal:content="python:file.change.comment[:50]"></td> |
468 | <td class="timedate2">.</td> |
469 | - <td class="expcell"><a tal:attributes="href python:url(['/changes'], start_revid=start_revid, filter_file_id=file.file_id); |
470 | + <td class="expcell"><a tal:attributes="href python:url(['/changes'], start_revid=start_revid, filter_path=file.absolutepath); |
471 | title string:Show revision ${file/change/revno}"> |
472 | <img tal:attributes="src python:branch.static_url('/static/images/ico_planilla.gif'); |
473 | title string:Show revision ${file/change/revno}" /> |
474 | @@ -157,7 +157,7 @@ |
475 | </a> |
476 | </td> |
477 | <td class="expcell"> |
478 | - <a tal:attributes="href python:url(['/download', file.revid.decode('utf-8'), file.file_id.decode('utf-8'), file.filename]); |
479 | + <a tal:attributes="href python:url(['/download', file.revid.decode('utf-8'), file.filename]); |
480 | title string:Download ${file/filename} at revision ${file/change/revno}"> |
481 | <img tal:attributes="src python:branch.static_url('/static/images/ico_file_download.gif')" alt="Download File" /> |
482 | </a> |
483 | |
484 | === modified file 'loggerhead/templates/search-box.pt' |
485 | --- loggerhead/templates/search-box.pt 2008-08-13 17:24:10 +0000 |
486 | +++ loggerhead/templates/search-box.pt 2022-07-06 12:59:30 +0000 |
487 | @@ -1,8 +1,7 @@ |
488 | <tal:search-box> |
489 | <form tal:attributes="action python:branch.url('/changes', |
490 | start_revid=getattr(navigation, |
491 | - 'start_revid', None), |
492 | - file_id=getattr(navigation, 'file_id', None))"> |
493 | + 'start_revid', None))"> |
494 | <label>search:</label> |
495 | <input type="search" name="q" id="q" autocomplete="off" onblur="hide_search();" /> |
496 | </form> |
497 | |
498 | === modified file 'loggerhead/templates/view.pt' |
499 | --- loggerhead/templates/view.pt 2020-06-04 19:21:17 +0000 |
500 | +++ loggerhead/templates/view.pt 2022-07-06 12:59:30 +0000 |
501 | @@ -59,7 +59,7 @@ |
502 | <a tal:attributes="href python:url(['/revision', change.revno], clear=1)">view revision</a> |
503 | </li> |
504 | <li> |
505 | - <a tal:attributes="href python:url(['/changes'], clear=1, filter_file_id=file_id)" |
506 | + <a tal:attributes="href python:url(['/changes'], clear=1, filter_path=file_path)" |
507 | >view changes to this file</a> |
508 | </li> |
509 | <li id="last"> |
510 | |
511 | === modified file 'loggerhead/tests/fixtures.py' |
512 | --- loggerhead/tests/fixtures.py 2018-10-20 13:45:31 +0000 |
513 | +++ loggerhead/tests/fixtures.py 2022-07-06 12:59:30 +0000 |
514 | @@ -36,8 +36,7 @@ |
515 | filenames = ['myfilename', 'anotherfile<'] |
516 | self.testcase.build_tree_contents( |
517 | (filename, self.filecontents) for filename in filenames) |
518 | - for filename in filenames: |
519 | - self.tree.add(filename, ('%s-id' % filename).encode('utf-8')) |
520 | - self.fileid = self.tree.path2id('myfilename') |
521 | + self.tree.add(filenames) |
522 | + self.path = 'myfilename' |
523 | self.msg = 'a very exciting commit message <' |
524 | self.revid = self.tree.commit(message=self.msg) |
525 | |
526 | === modified file 'loggerhead/tests/test_controllers.py' |
527 | --- loggerhead/tests/test_controllers.py 2021-03-29 11:18:58 +0000 |
528 | +++ loggerhead/tests/test_controllers.py 2022-07-06 12:59:30 +0000 |
529 | @@ -221,12 +221,12 @@ |
530 | |
531 | class TestAnnotateUI(BasicTests): |
532 | |
533 | - def make_annotate_ui_for_file_history(self, file_id, rev_ids_texts): |
534 | + def make_annotate_ui_for_file_history(self, filename, rev_ids_texts): |
535 | tree = self.make_branch_and_tree('.') |
536 | - self.build_tree_contents([('filename', '')]) |
537 | - tree.add(['filename'], [file_id]) |
538 | + self.build_tree_contents([(filename, '')]) |
539 | + tree.add([filename]) |
540 | for rev_id, text, message in rev_ids_texts: |
541 | - self.build_tree_contents([('filename', text)]) |
542 | + self.build_tree_contents([(filename, text)]) |
543 | tree.commit(rev_id=rev_id, message=message) |
544 | tree.branch.lock_read() |
545 | self.addCleanup(tree.branch.unlock) |
546 | @@ -235,12 +235,11 @@ |
547 | |
548 | def test_annotate_file(self): |
549 | history = [(b'rev1', b'old\nold\n', '.'), (b'rev2', b'new\nold\n', '.')] |
550 | - ann_ui = self.make_annotate_ui_for_file_history(b'file_id', history) |
551 | + ann_ui = self.make_annotate_ui_for_file_history('filename', history) |
552 | # A lot of this state is set up by __call__, but we'll do it directly |
553 | # here. |
554 | ann_ui.args = ['rev2'] |
555 | - annotate_info = ann_ui.get_values(u'filename', |
556 | - kwargs={'file_id': 'file_id'}, headers={}) |
557 | + annotate_info = ann_ui.get_values(u'filename', kwargs={}, headers={}) |
558 | annotated = annotate_info['annotated'] |
559 | self.assertEqual(2, len(annotated)) |
560 | self.assertEqual('2', annotated[1].change.revno) |
561 | @@ -249,32 +248,30 @@ |
562 | def test_annotate_empty_comment(self): |
563 | # Testing empty comment handling without breaking |
564 | history = [(b'rev1', b'old\nold\n', '.'), (b'rev2', b'new\nold\n', '')] |
565 | - ann_ui = self.make_annotate_ui_for_file_history(b'file_id', history) |
566 | + ann_ui = self.make_annotate_ui_for_file_history('filename', history) |
567 | ann_ui.args = ['rev2'] |
568 | - ann_ui.get_values( |
569 | - u'filename', kwargs={'file_id': 'file_id'}, headers={}) |
570 | + ann_ui.get_values(u'filename', kwargs={}, headers={}) |
571 | |
572 | def test_annotate_file_zero_sized(self): |
573 | # Test against a zero-sized file without breaking. No annotation |
574 | # must be present. |
575 | history = [(b'rev1', b'', '.')] |
576 | - ann_ui = self.make_annotate_ui_for_file_history(b'file_id', history) |
577 | + ann_ui = self.make_annotate_ui_for_file_history('filename', history) |
578 | ann_ui.args = ['rev1'] |
579 | - annotate_info = ann_ui.get_values(u'filename', |
580 | - kwargs={'file_id': 'file_id'}, headers={}) |
581 | + annotate_info = ann_ui.get_values(u'filename', kwargs={}, headers={}) |
582 | annotated = annotate_info['annotated'] |
583 | self.assertEqual(0, len(annotated)) |
584 | |
585 | def test_annotate_nonexistent_file(self): |
586 | history = [(b'rev1', b'', '.')] |
587 | - ann_ui = self.make_annotate_ui_for_file_history(b'file_id', history) |
588 | + ann_ui = self.make_annotate_ui_for_file_history('filename', history) |
589 | ann_ui.args = ['rev1'] |
590 | self.assertRaises( |
591 | HTTPNotFound, ann_ui.get_values, u'not-filename', {}, {}) |
592 | |
593 | def test_annotate_nonexistent_rev(self): |
594 | history = [(b'rev1', b'', '.')] |
595 | - ann_ui = self.make_annotate_ui_for_file_history(b'file_id', history) |
596 | + ann_ui = self.make_annotate_ui_for_file_history('filename', history) |
597 | ann_ui.args = ['norev'] |
598 | self.assertRaises( |
599 | HTTPNotFound, ann_ui.get_values, u'not-filename', {}, {}) |
600 | @@ -433,15 +430,6 @@ |
601 | response, |
602 | MatchesDownloadHeaders('myfilename', 'application/octet-stream')) |
603 | |
604 | - def test_download_with_revid(self): |
605 | - app = self.setUpLoggerhead() |
606 | - response = app.get('/download/1/myfilename-id/myfilename') |
607 | - self.assertEqual( |
608 | - b'some\nmultiline\ndata\nwith<htmlspecialchars\n', response.body) |
609 | - self.assertThat( |
610 | - response, |
611 | - MatchesDownloadHeaders('myfilename', 'application/octet-stream')) |
612 | - |
613 | def test_download_bad_revision(self): |
614 | app = self.setUpLoggerhead() |
615 | e = self.assertRaises( |
616 | @@ -449,7 +437,7 @@ |
617 | app.get, '/download/norev/myfilename') |
618 | self.assertContainsRe(str(e), '404 Not Found') |
619 | |
620 | - def test_download_bad_fileid(self): |
621 | + def test_download_bad_filename(self): |
622 | app = self.setUpLoggerhead() |
623 | e = self.assertRaises( |
624 | AppError, |
625 | |
626 | === modified file 'loggerhead/tests/test_simple.py' |
627 | --- loggerhead/tests/test_simple.py 2021-11-15 14:40:11 +0000 |
628 | +++ loggerhead/tests/test_simple.py 2022-07-06 12:59:30 +0000 |
629 | @@ -78,7 +78,7 @@ |
630 | # XXX: This could be cleaned up more... -- mbp 2011-11-25 |
631 | self.useFixture(self.sample_branch_fixture) |
632 | self.tree = self.sample_branch_fixture.tree |
633 | - self.fileid = self.sample_branch_fixture.fileid |
634 | + self.path = self.sample_branch_fixture.path |
635 | self.filecontents = self.sample_branch_fixture.filecontents |
636 | self.msg = self.sample_branch_fixture.msg |
637 | |
638 | @@ -95,7 +95,7 @@ |
639 | |
640 | def test_changes_for_file(self): |
641 | app = self.setUpLoggerhead() |
642 | - res = app.get('/changes?filter_file_id=myfilename-id') |
643 | + res = app.get('/changes?filter_path=%s' % self.path) |
644 | res.mustcontain(escape(self.msg)) |
645 | |
646 | def test_changes_branch_from(self): |
647 | @@ -111,7 +111,7 @@ |
648 | |
649 | def test_annotate(self): |
650 | app = self.setUpLoggerhead() |
651 | - res = app.get('/annotate', params={'file_id': self.fileid}) |
652 | + res = app.get('/annotate/1/%s' % self.path, params={}) |
653 | # If pygments is installed, it inserts <span class="pyg" content into |
654 | # the output, to trigger highlighting. And it specifically highlights |
655 | # the < that we are interested in seeing in the output. |
656 | @@ -137,8 +137,6 @@ |
657 | res.mustcontain('myfilename') |
658 | res = app.get('/files/1/') |
659 | res.mustcontain('myfilename') |
660 | - res = app.get('/files/1/?file_id=' + self.tree.path2id('').decode('utf-8')) |
661 | - res.mustcontain('myfilename') |
662 | |
663 | def test_inventory_bad_rev_404(self): |
664 | app = self.setUpLoggerhead() |
665 | @@ -148,7 +146,6 @@ |
666 | def test_inventory_bad_path_404(self): |
667 | app = self.setUpLoggerhead() |
668 | res = app.get('/files/1/hooha', status=404) |
669 | - res = app.get('/files/1?file_id=dssadsada', status=404) |
670 | |
671 | def test_revision(self): |
672 | app = self.setUpLoggerhead() |
673 | |
674 | === modified file 'loggerhead/util.py' |
675 | --- loggerhead/util.py 2021-11-15 14:40:11 +0000 |
676 | +++ loggerhead/util.py 2022-07-06 12:59:30 +0000 |
677 | @@ -409,7 +409,7 @@ |
678 | navigation.next_page_revid) |
679 | start_revno = navigation.history.get_revno(navigation.start_revid) |
680 | |
681 | - params = {'filter_file_id': navigation.filter_file_id} |
682 | + params = {'filter_path': navigation.filter_path} |
683 | if getattr(navigation, 'query', None) is not None: |
684 | params['q'] = navigation.query |
685 | |
686 | @@ -533,9 +533,7 @@ |
687 | # the current beginning of navigation (navigation continues back to |
688 | # the original revision) -- this defines an 'alternate mainline' |
689 | # when the user navigates into a branch. |
690 | -# - file_id |
691 | -# the file being looked at |
692 | -# - filter_file_id |
693 | +# - filter_path |
694 | # if navigating the revisions that touched a file |
695 | # - q (query) |
696 | # if navigating the revisions that matched a search query |
697 | @@ -553,7 +551,7 @@ |
698 | |
699 | t_context = threading.local() |
700 | _valid = ( |
701 | - 'start_revid', 'filter_file_id', 'q', 'remember', 'compare_revid', 'sort') |
702 | + 'start_revid', 'filter_path', 'q', 'remember', 'compare_revid', 'sort') |
703 | |
704 | |
705 | def set_context(map): |
This does break some old (horrible) URLs, but it seems ultimately necessary, so I'm OK with this. Let's see what the test suite makes of it.