Merge lp:~brz/loggerhead/breezy into lp:loggerhead
- breezy
- Merge into trunk-rich
Status: | Merged |
---|---|
Merged at revision: | 494 |
Proposed branch: | lp:~brz/loggerhead/breezy |
Merge into: | lp:loggerhead |
Diff against target: |
4166 lines (+984/-812) 66 files modified
.bzrignore (+2/-0) .testr.conf (+4/-0) .travis.yml (+28/-0) MANIFEST.in (+1/-1) Makefile (+1/-1) NEWS (+7/-1) README.rst (+6/-5) __init__.py (+79/-85) byov.conf (+23/-0) docs/index.rst (+22/-21) docs/loggerhead-serve.rst (+5/-5) info.py (+0/-15) loggerhead-serve.1 (+3/-3) loggerhead.wsgi (+12/-7) loggerhead/__init__.py (+2/-11) loggerhead/apps/__init__.py (+1/-1) loggerhead/apps/branch.py (+48/-40) loggerhead/apps/error.py (+1/-1) loggerhead/apps/transport.py (+11/-20) loggerhead/changecache.py (+15/-4) loggerhead/config.py (+2/-2) loggerhead/controllers/__init__.py (+21/-11) loggerhead/controllers/annotate_ui.py (+12/-7) loggerhead/controllers/atom_ui.py (+2/-2) loggerhead/controllers/changelog_ui.py (+8/-6) loggerhead/controllers/diff_ui.py (+5/-5) loggerhead/controllers/directory_ui.py (+14/-12) loggerhead/controllers/download_ui.py (+9/-8) loggerhead/controllers/error_ui.py (+4/-4) loggerhead/controllers/filediff_ui.py (+32/-27) loggerhead/controllers/inventory_ui.py (+43/-30) loggerhead/controllers/revision_ui.py (+8/-7) loggerhead/controllers/revlog_ui.py (+5/-3) loggerhead/controllers/search_ui.py (+3/-3) loggerhead/controllers/view_ui.py (+40/-32) loggerhead/daemon.py (+2/-2) loggerhead/exporter.py (+0/-60) loggerhead/highlight.py (+3/-3) loggerhead/history.py (+70/-56) loggerhead/load_test.py (+11/-7) loggerhead/lsprof.py (+5/-2) loggerhead/main.py (+24/-18) loggerhead/middleware/profile.py (+1/-1) loggerhead/search.py (+3/-3) loggerhead/static/css/global.css (+2/-2) loggerhead/static/css/view.css (+1/-2) loggerhead/templatefunctions.py (+20/-17) loggerhead/templates/directory.pt (+23/-13) loggerhead/templates/inventory.pt (+26/-13) loggerhead/templates/macros.pt (+1/-1) loggerhead/tests/__init__.py (+8/-4) loggerhead/tests/fixtures.py (+1/-1) loggerhead/tests/test_controllers.py (+98/-57) loggerhead/tests/test_corners.py (+7/-5) loggerhead/tests/test_history.py (+70/-69) loggerhead/tests/test_http_head.py (+14/-14) loggerhead/tests/test_load_test.py (+10/-7) loggerhead/tests/test_revision_ui.py (+3/-2) loggerhead/tests/test_simple.py (+27/-23) loggerhead/tests/test_templating.py (+1/-1) loggerhead/tests/test_util.py (+2/-2) loggerhead/util.py (+43/-26) loggerhead/wholehistory.py (+9/-5) loggerhead/zptsupport.py (+9/-6) loggerheadd (+3/-3) setup.py (+8/-7) |
To merge this branch: | bzr merge lp:~brz/loggerhead/breezy |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Colin Watson (community) | Approve | ||
Review via email:
|
Commit message
Switch loggerhead over to using the Breezy rather than Bazaar APIs.
Description of the change
Switch loggerhead over to using the Breezy rather than Bazaar APIs.
- 506. By Jelmer Vernooij
-
Add travis config.
- 507. By Jelmer Vernooij
-
Install simpletal from homepage.
- 508. By Jelmer Vernooij
-
s/Bazaar/Breezy.
- 509. By Jelmer Vernooij
-
s/Bazaar/Breezy/.
- 510. By Jelmer Vernooij
-
s/bazaar.
conf/breezy. conf. - 511. By Jelmer Vernooij
-
Fix local path serving in serve-branches.
- 512. By Jelmer Vernooij
-
Use bool_from_string.
- 513. By Jelmer Vernooij
-
Serving .bzr/ on remote branches (or readonly+ branches) works fine.
- 514. By Jelmer Vernooij
-
Determine public URL for branching from request URL.
- 515. By Jelmer Vernooij
-
Some fixes for working with git trees.
- 516. By Jelmer Vernooij
-
Fix remaining tests.
- 517. By Jelmer Vernooij
-
Use more standard breezy infrastructure.
- 518. By Jelmer Vernooij
-
Merge support for more columns.
- 519. By Jelmer Vernooij
-
Remove python path hackery.
- 520. By Jelmer Vernooij
-
Use setuptools.
- 521. By Jelmer Vernooij
-
Some python3 porting work.
- 522. By Jelmer Vernooij
-
Avoid using cStringIO.
- 523. By Jelmer Vernooij
-
Fix some more import errors.
- 524. By Jelmer Vernooij
-
Use bleach rather than simpleTAL's HTMLStructureCl
eaner. - 525. By Jelmer Vernooij
-
More python3 porting work.
- 526. By Jelmer Vernooij
-
Set install_requires. I can't find an entry in pip for SimpleTAL. :(
- 527. By Jelmer Vernooij
-
Fix relative import.
- 528. By Jelmer Vernooij
-
More python3 porting work.
- 529. By Jelmer Vernooij
-
More python 3 work; down to 16 failing tests.
- 530. By Jelmer Vernooij
-
More python3 porting.
- 531. By Jelmer Vernooij
-
Fix some more tests on Python 3.
- 532. By Jelmer Vernooij
-
More python 3 fixes.
- 533. By Jelmer Vernooij
-
Finish python 3 port.
- 534. By Jelmer Vernooij
-
Run tests on python 3.
- 535. By Jelmer Vernooij
-
Add NEWS, drop info.py.
- 536. By Jelmer Vernooij
-
Rename serve-branches to loggerhead-serve.
- 537. By Jelmer Vernooij
-
Add dependency on bleach.
- 538. By Jelmer Vernooij
-
Fix loading when loggerhead is installed separately.
- 539. By Jelmer Vernooij
-
Don't unnecessarily encode paths.
- 540. By Jelmer Vernooij
-
Fix use of urllib.unquote.
- 541. By Jelmer Vernooij
-
Avoid use of file_ids.
- 542. By Jelmer Vernooij
-
Merge trunk.
- 543. By Jelmer Vernooij
-
Drop python 3.4 support on travis.
- 544. By Jelmer Vernooij
-
Don't install loggerhead.wsgi - it's not an executable.
- 545. By Jelmer Vernooij
-
Try local loggerhead first, then fall back to system one.
- 546. By Jelmer Vernooij
-
Add byov.conf.
- 547. By Vincent Ladeuil
-
Don't depend on python3-simpletal, which is not available in Ubuntu yet.
- 548. By Jelmer Vernooij
-
Install simpletal from the webz.
- 549. By Jelmer Vernooij
-
Add missing dependency on six in byov.conf.
- 550. By Jelmer Vernooij
-
Add dependency on fixtures.
- 551. By Jelmer Vernooij
-
Fix compatibility with newer versions of breezy.
- 552. By Jelmer Vernooij
-
Merge breezy changes.
- 553. By Jelmer Vernooij
-
Review comments.

Jelmer Vernooij (jelmer) wrote : | # |
Can you please land? I don't have access to lp:loggerhead

Colin Watson (cjwatson) wrote : | # |
Landed. Thanks!
Preview Diff
1 | === modified file '.bzrignore' |
2 | --- .bzrignore 2011-07-10 22:53:59 +0000 |
3 | +++ .bzrignore 2019-09-18 16:50:15 +0000 |
4 | @@ -10,3 +10,5 @@ |
5 | tags |
6 | .project |
7 | .pydevproject |
8 | +.testrepository |
9 | +MANIFEST |
10 | |
11 | === added file '.testr.conf' |
12 | --- .testr.conf 1970-01-01 00:00:00 +0000 |
13 | +++ .testr.conf 2019-09-18 16:50:15 +0000 |
14 | @@ -0,0 +1,4 @@ |
15 | +[DEFAULT] |
16 | +test_command=BRZ_PLUGINS_AT=loggerhead@`pwd` BRZ_PLUGIN_PATH=-site:-user ${BRZ:-brz} selftest -s bp.loggerhead. --subunit2 $IDOPTION $LISTOPT |
17 | +test_id_option=--load-list $IDFILE |
18 | +test_list_option=--list |
19 | |
20 | === added file '.travis.yml' |
21 | --- .travis.yml 1970-01-01 00:00:00 +0000 |
22 | +++ .travis.yml 2019-09-18 16:50:15 +0000 |
23 | @@ -0,0 +1,28 @@ |
24 | +language: python |
25 | +addons: |
26 | + apt: |
27 | + update: true |
28 | +sudo: false |
29 | +cache: pip |
30 | +git: |
31 | + depth: false |
32 | + |
33 | +matrix: |
34 | + include: |
35 | + - python: 2.7 |
36 | + env: TAL_VERSION=4.3 |
37 | + - python: 3.5 |
38 | + env: TAL_VERSION=5.2 |
39 | + - python: 3.6 |
40 | + env: TAL_VERSION=5.2 |
41 | + |
42 | +script: |
43 | + - python -m coverage run -p -m unittest loggerhead.tests.test_suite |
44 | + |
45 | +install: |
46 | + - sudo apt install python-all subunit python-testtools adduser libjs-yui3-min |
47 | + - travis_retry pip install -U setuptools |
48 | + - travis_retry pip install -U pip coverage codecov flake8 testtools configobj cython testscenarios six docutils python-subunit dulwich bzr+lp:brz pygments simplejson paste http://www.owlfish.com/software/simpleTAL/downloads/SimpleTAL-$TAL_VERSION.tar.gz bleach |
49 | + |
50 | +after_success: |
51 | + - codecov |
52 | |
53 | === renamed file 'HACKING' => 'HACKING.rst' |
54 | === modified file 'MANIFEST.in' |
55 | --- MANIFEST.in 2012-02-08 00:25:23 +0000 |
56 | +++ MANIFEST.in 2019-09-18 16:50:15 +0000 |
57 | @@ -3,7 +3,7 @@ |
58 | include NEWS |
59 | include README.txt |
60 | include apache-loggerhead.conf |
61 | -include bazaar.conf |
62 | +include breezy.conf |
63 | include loggerhead.conf.example |
64 | include loggerheadd |
65 | include Makefile |
66 | |
67 | === modified file 'Makefile' |
68 | --- Makefile 2011-03-14 08:47:03 +0000 |
69 | +++ Makefile 2019-09-18 16:50:15 +0000 |
70 | @@ -8,4 +8,4 @@ |
71 | rm -rf dist/ |
72 | |
73 | check: |
74 | - BZR_PLUGINS_AT=loggerhead@$$(pwd) bzr selftest -s bp.loggerhead |
75 | + BRZ_PLUGINS_AT=loggerhead@$$(pwd) brz selftest -s bp.loggerhead |
76 | |
77 | === modified file 'NEWS' |
78 | --- NEWS 2019-06-20 16:18:17 +0000 |
79 | +++ NEWS 2019-09-18 16:50:15 +0000 |
80 | @@ -1,9 +1,15 @@ |
81 | What's changed in loggerhead? |
82 | ============================= |
83 | |
84 | -NEXT |
85 | +1.20.0 |
86 | ---- |
87 | |
88 | + - Port to Breezy (https://www.breezy-vcs.org/). (Jelmer Vernooij) |
89 | + |
90 | + - Port to Python 3. (Jelmer Vernooij) |
91 | + |
92 | + - Serve-branches has been renamed to 'loggerhead-serve'. (Jelmer Vernooij) |
93 | + |
94 | - Fixed weird icon in file lists (e.g. revision summaries) when a file or |
95 | directory with a blank name was listed. (Cruz Bishop, #387337). |
96 | |
97 | |
98 | === renamed file 'README' => 'README.rst' |
99 | --- README 2010-04-23 01:30:29 +0000 |
100 | +++ README.rst 2019-09-18 16:50:15 +0000 |
101 | @@ -4,8 +4,7 @@ |
102 | Overview |
103 | -------- |
104 | |
105 | -Loggerhead is a web viewer for Bazaar branches. Its lets users do |
106 | -stuff like: |
107 | +Loggerhead is a web viewer for Breezy. Its lets users do stuff like: |
108 | |
109 | * navigate through branch history |
110 | * view the files in a given revision |
111 | @@ -23,6 +22,8 @@ |
112 | Licensing |
113 | --------- |
114 | |
115 | -This software is (C) Copyright Canonical Limited 2006-10 under the |
116 | -GPL Version 2 or later. Please see the file COPYING.txt for the |
117 | -licence details. |
118 | +This software is licensed under the GPL Version 2 or later. |
119 | +Please see the file COPYING.txt for the licence details. |
120 | + |
121 | + (C) Copyright Canonical Limited 2006-10 |
122 | + (C) Copyright Breezy Developers 2018 |
123 | |
124 | === modified file '__init__.py' |
125 | --- __init__.py 2012-02-08 01:50:02 +0000 |
126 | +++ __init__.py 2019-09-18 16:50:15 +0000 |
127 | @@ -18,8 +18,8 @@ |
128 | # This file allows loggerhead to be treated as a plugin for bzr. |
129 | # |
130 | # XXX: Because loggerhead already contains a loggerhead directory, much of the |
131 | -# code is going to appear loaded at bzrlib.plugins.loggerhead.loggerhead. |
132 | -# This seems like the easiest thing, because bzrlib wants the top-level plugin |
133 | +# code is going to appear loaded at breezy.plugins.loggerhead.loggerhead. |
134 | +# This seems like the easiest thing, because breezy wants the top-level plugin |
135 | # directory to be the module, but when it's used as a library people expect |
136 | # the source directory to contain a directory called loggerhead. -- mbp |
137 | # 20090123 |
138 | @@ -32,91 +32,85 @@ |
139 | |
140 | import sys |
141 | |
142 | -from info import ( |
143 | - bzr_plugin_version as version_info, |
144 | - bzr_compatible_versions, |
145 | - ) |
146 | - |
147 | -if __name__ == 'bzrlib.plugins.loggerhead': |
148 | - import bzrlib |
149 | - from bzrlib.api import require_any_api |
150 | - from bzrlib import commands |
151 | - |
152 | - require_any_api(bzrlib, bzr_compatible_versions) |
153 | - |
154 | - from bzrlib.transport import transport_server_registry |
155 | - |
156 | - DEFAULT_HOST = '0.0.0.0' |
157 | - DEFAULT_PORT = 8080 |
158 | - HELP = ('Loggerhead, a web-based code viewer and server. (default port: %d)' % |
159 | - (DEFAULT_PORT,)) |
160 | - |
161 | - def _ensure_loggerhead_path(): |
162 | - """Ensure that you can 'import loggerhead' and get the root.""" |
163 | - # loggerhead internal code will try to 'import loggerhead', so |
164 | - # let's put it on the path if we can't find it in the existing path |
165 | - try: |
166 | - import loggerhead.apps.transport |
167 | - except ImportError: |
168 | - import os.path, sys |
169 | - sys.path.append(os.path.dirname(__file__)) |
170 | - |
171 | - def serve_http(transport, host=None, port=None, inet=None): |
172 | - # TODO: if we supported inet to pass requests in and respond to them, |
173 | - # then it would be easier to test the full stack, but it probably |
174 | - # means routing around paste.httpserver.serve which probably |
175 | - # isn't testing the full stack |
176 | - from paste.httpexceptions import HTTPExceptionHandler |
177 | - from paste.httpserver import serve |
178 | - |
179 | - _ensure_loggerhead_path() |
180 | - |
181 | +version_info = (1, 20, 0) # Keep in sync with loggerhead/__init__.py |
182 | + |
183 | +import breezy |
184 | +from breezy import commands |
185 | + |
186 | +from breezy.transport import transport_server_registry |
187 | + |
188 | +DEFAULT_HOST = '0.0.0.0' |
189 | +DEFAULT_PORT = 8080 |
190 | +HELP = ('Loggerhead, a web-based code viewer and server. (default port: %d)' % |
191 | + (DEFAULT_PORT,)) |
192 | + |
193 | + |
194 | +def serve_http(transport, host=None, port=None, inet=None, client_timeout=None): |
195 | + # TODO: if we supported inet to pass requests in and respond to them, |
196 | + # then it would be easier to test the full stack, but it probably |
197 | + # means routing around paste.httpserver.serve which probably |
198 | + # isn't testing the full stack |
199 | + from paste.httpexceptions import HTTPExceptionHandler |
200 | + from paste.httpserver import serve |
201 | + |
202 | + try: |
203 | + from .loggerhead.apps.http_head import HeadMiddleware |
204 | + from .loggerhead.apps.transport import BranchesFromTransportRoot |
205 | + from .loggerhead.config import LoggerheadConfig |
206 | + from .loggerhead.main import setup_logging |
207 | + except ImportError: |
208 | from loggerhead.apps.http_head import HeadMiddleware |
209 | from loggerhead.apps.transport import BranchesFromTransportRoot |
210 | from loggerhead.config import LoggerheadConfig |
211 | from loggerhead.main import setup_logging |
212 | |
213 | - if host is None: |
214 | - host = DEFAULT_HOST |
215 | - if port is None: |
216 | - port = DEFAULT_PORT |
217 | - argv = ['--host', host, '--port', str(port), '--', transport.base] |
218 | - if not transport.is_readonly(): |
219 | - argv.insert(0, '--allow-writes') |
220 | - config = LoggerheadConfig(argv) |
221 | - setup_logging(config, init_logging=False, log_file=sys.stderr) |
222 | - app = BranchesFromTransportRoot(transport.base, config) |
223 | - # Bug #758618, HeadMiddleware seems to break HTTPExceptionHandler from |
224 | - # actually sending appropriate return codes to the client. Since nobody |
225 | - # desperately needs HeadMiddleware right now, just ignoring it. |
226 | - # app = HeadMiddleware(app) |
227 | - app = HTTPExceptionHandler(app) |
228 | - serve(app, host=host, port=port) |
229 | - |
230 | - transport_server_registry.register('http', serve_http, help=HELP) |
231 | - |
232 | - class cmd_load_test_loggerhead(commands.Command): |
233 | - """Run a load test against a live loggerhead instance. |
234 | - |
235 | - Pass in the name of a script file to run. See loggerhead/load_test.py |
236 | - for a description of the file format. |
237 | - """ |
238 | - |
239 | - takes_args = ["filename"] |
240 | - |
241 | - def run(self, filename): |
242 | - from bzrlib.plugins.loggerhead.loggerhead import load_test |
243 | - script = load_test.run_script(filename) |
244 | - for thread_id in sorted(script._threads): |
245 | - worker = script._threads[thread_id][0] |
246 | - for url, success, time in worker.stats: |
247 | - self.outf.write(' %5.3fs %s %s\n' |
248 | - % (time, str(success)[0], url)) |
249 | - |
250 | - commands.register_command(cmd_load_test_loggerhead) |
251 | - |
252 | - def load_tests(standard_tests, module, loader): |
253 | - _ensure_loggerhead_path() |
254 | - standard_tests.addTests(loader.loadTestsFromModuleNames( |
255 | - ['bzrlib.plugins.loggerhead.loggerhead.tests'])) |
256 | - return standard_tests |
257 | + if host is None: |
258 | + host = DEFAULT_HOST |
259 | + if port is None: |
260 | + port = DEFAULT_PORT |
261 | + argv = ['--host', host, '--port', str(port), '--', transport.base] |
262 | + if not transport.is_readonly(): |
263 | + argv.insert(0, '--allow-writes') |
264 | + config = LoggerheadConfig(argv) |
265 | + setup_logging(config, init_logging=False, log_file=sys.stderr) |
266 | + app = BranchesFromTransportRoot(transport.base, config) |
267 | + # Bug #758618, HeadMiddleware seems to break HTTPExceptionHandler from |
268 | + # actually sending appropriate return codes to the client. Since nobody |
269 | + # desperately needs HeadMiddleware right now, just ignoring it. |
270 | + # app = HeadMiddleware(app) |
271 | + app = HTTPExceptionHandler(app) |
272 | + serve(app, host=host, port=port) |
273 | + |
274 | +transport_server_registry.register('http', serve_http, help=HELP) |
275 | + |
276 | +class cmd_load_test_loggerhead(commands.Command): |
277 | + """Run a load test against a live loggerhead instance. |
278 | + |
279 | + Pass in the name of a script file to run. See loggerhead/load_test.py |
280 | + for a description of the file format. |
281 | + """ |
282 | + |
283 | + hidden = True |
284 | + takes_args = ["filename"] |
285 | + |
286 | + def run(self, filename): |
287 | + try: |
288 | + from .loggerhead.loggerhead import load_test |
289 | + except ImportError: |
290 | + from loggerhead.loggerhead import load_test |
291 | + script = load_test.run_script(filename) |
292 | + for thread_id in sorted(script._threads): |
293 | + worker = script._threads[thread_id][0] |
294 | + for url, success, time in worker.stats: |
295 | + self.outf.write(' %5.3fs %s %s\n' |
296 | + % (time, str(success)[0], url)) |
297 | + |
298 | +commands.register_command(cmd_load_test_loggerhead) |
299 | + |
300 | +def load_tests(loader, basic_tests, pattern): |
301 | + try: |
302 | + from .loggerhead.tests import test_suite |
303 | + except ImportError: |
304 | + from loggerhead.tests import test_suite |
305 | + basic_tests.addTest(test_suite()) |
306 | + return basic_tests |
307 | |
308 | === renamed file 'bazaar.conf' => 'breezy.conf' |
309 | === added file 'byov.conf' |
310 | --- byov.conf 1970-01-01 00:00:00 +0000 |
311 | +++ byov.conf 2019-09-18 16:50:15 +0000 |
312 | @@ -0,0 +1,23 @@ |
313 | +# Use lxd containers by default |
314 | +vm.class = lxd |
315 | +# Start with an up to date system by default |
316 | +vm.update = True |
317 | +# External sources dependencies, packages are not recent enough |
318 | +dulwich.clone = (git clone git://jelmer.uk/dulwich ../dulwich.git) |
319 | +dulwich.install = (cd ../dulwich.git && ./setup.py install --user) |
320 | +dulwich3.install = (cd ../dulwich.git && python3 ./setup.py install --user) |
321 | +simpletal3.install = pip3 install http://www.owlfish.com/software/simpleTAL/downloads/SimpleTAL-5.2.tar.gz |
322 | + |
323 | +[loggerhead] |
324 | +vm.release = xenial |
325 | +brz.build_deps = gcc, debhelper, python, python-all-dev, python3-all-dev, python-configobj, python3-configobj, python-docutils, python3-docutils, python-paramiko, python3-paramiko, python-subunit, python3-subunit, python-testtools, python3-testtools, subunit, cython, cython3, python-fastimport, python-dulwich, python-six, python3-six |
326 | +loggerhead.build_deps = python-setuptools, python3-setuptools, libjs-yui3-min, python-docutils, python3-docutils, python-pygments, python3-pygments, python-simplejson, python3-simplejson, python-paste, python3-paste, python-pastedeploy, python3-pastedeploy, python-simpletal, python-bleach, python3-bleach |
327 | +loggerhead.test_deps = python3-fixtures, python-fixtures |
328 | +vm.packages = {brz.build_deps}, {loggerhead.build_deps}, {loggerhead.test_deps}, bzr, python-junitxml, python3-pip |
329 | +brz.branch = (bzr branch lp:brz ../brz-trunk) |
330 | +brz.make = (cd ../brz-trunk && make) |
331 | +byoci.setup.command = ({dulwich.clone} && {dulwich.install} && {brz.branch} && {brz.make}) |
332 | +byoci.tests.command = bash -o pipefail -c "bzr log -l2 && (BRZ_PLUGINS_AT=loggerhead@`pwd` BRZ_PLUGIN_PATH=-site:-user python2 ../brz-trunk/brz selftest -v --parallel=fork --subunit2 | subunit2junitxml -o ../results.xml -f | subunit2pyunit)" |
333 | +[loggerhead-py3] |
334 | +byoci.setup.command = ({dulwich.clone} && {dulwich3.install} && {brz.branch} && {brz.make} && {simpletal3.install}) |
335 | +byoci.tests.command = bash -o pipefail -c "bzr log -l2 && (BRZ_PLUGINS_AT=loggerhead@`pwd` BRZ_PLUGIN_PATH=-site:-user python3 ../brz-trunk/brz selftest -v --parallel=fork --subunit2 | subunit2junitxml -o ../results.xml -f | subunit2pyunit)" |
336 | |
337 | === modified file 'docs/index.rst' |
338 | --- docs/index.rst 2012-02-02 04:58:46 +0000 |
339 | +++ docs/index.rst 2019-09-18 16:50:15 +0000 |
340 | @@ -1,7 +1,7 @@ |
341 | Loggerhead: A web viewer for ``bzr`` branches |
342 | ============================================== |
343 | |
344 | -Loggerhead is a web viewer for projects in Bazaar. It can be used to navigate |
345 | +Loggerhead is a web viewer for projects in Breezy. It can be used to navigate |
346 | a branch history, annotate files, view patches, perform searches, etc. |
347 | Loggerhead is heavily based on `bazaar-webserve |
348 | <https://launchpad.net/bzr-webserve>`_, which was, in turn, loosely |
349 | @@ -53,12 +53,12 @@ |
350 | ---------------------------------------- |
351 | |
352 | After installing all the dependencies, you should be able to run |
353 | -:command:`serve-branches` with the branch you want to serve on the |
354 | +:command:`loggerhead-serve` with the branch you want to serve on the |
355 | command line: |
356 | |
357 | .. code-block:: sh |
358 | |
359 | - ./serve-branches ~/path/to/branch |
360 | + ./loggerhead-serve ~/path/to/branch |
361 | |
362 | By default, the script listens on port 8080, so head to |
363 | http://localhost:8080/ in your browser to see the branch. |
364 | @@ -70,7 +70,7 @@ |
365 | Loggerhead will notice and refresh, and Bazaar uses its own branch |
366 | locking to prevent corruption. |
367 | |
368 | -See :doc:`serve-branches` for all command line options. |
369 | +See :doc:`loggerhead-serve` for all command line options. |
370 | |
371 | Running Loggerhead as a Daemon |
372 | ------------------------------ |
373 | @@ -84,7 +84,7 @@ |
374 | $ sudo cp ./loggerheadd /etc/init.d |
375 | |
376 | 2) Edit the file to configure where your Loggerhead is installed, and which |
377 | - serve-branches options you would like. |
378 | + loggerhead-serve options you would like. |
379 | |
380 | .. code-block:: sh |
381 | |
382 | @@ -101,16 +101,16 @@ |
383 | $ sudo chkconfig --add loggerheadd |
384 | |
385 | |
386 | -Using Loggerhead as a Bazaar Plugin |
387 | ------------------------------------- |
388 | +Using Loggerhead as a Breezy Plugin |
389 | +----------------------------------- |
390 | |
391 | -This branch contains experimental support for using Loggerhead as a Bazaar |
392 | +This branch contains experimental support for using Loggerhead as a Breezy |
393 | plugin. To use it, place the top-level Loggerhead directory (the one |
394 | -containing COPYING.txt) at ``~/.bazaar/plugins/loggerhead``. E.g.: |
395 | +containing COPYING.txt) at ``~/.config/breezy/plugins/loggerhead``. E.g.: |
396 | |
397 | .. code-block:: sh |
398 | |
399 | - $ bzr branch lp:loggerhead ~/.bazaar/plugins/loggerhead |
400 | + $ bzr branch lp:loggerhead ~/.config/breezy/plugins/loggerhead |
401 | $ cd ~/myproject |
402 | $ bzr serve --http |
403 | |
404 | @@ -118,7 +118,7 @@ |
405 | Using a Config File |
406 | ------------------- |
407 | |
408 | -To hide branches from being displayed, add to ``~/.bazaar/locations.conf``, |
409 | +To hide branches from being displayed, add to ``~/.config/breezy/locations.conf``, |
410 | under the branch's section: |
411 | |
412 | .. code-block:: ini |
413 | @@ -132,7 +132,7 @@ |
414 | Serving Loggerhead behind Apache |
415 | -------------------------------- |
416 | |
417 | -If you want to view Bazaar branches from your existing Apache |
418 | +If you want to view Breezy branches from your existing Apache |
419 | installation, you'll need to configure Apache to proxy certain |
420 | requests to Loggerhead. Adding lines like this to your Apache |
421 | configuration is one way to do this: |
422 | @@ -144,7 +144,7 @@ |
423 | ProxyPassReverse http://127.0.0.1:8080/branches/ |
424 | </Location> |
425 | |
426 | -If Paste Deploy is installed, the :command:`serve-branches` script can be |
427 | +If Paste Deploy is installed, the :command:`loggerhead-serve` script can be |
428 | run behind a proxy at the root of a site, but if you're running it at |
429 | some path into the site, you'll need to specify it using |
430 | ``--prefix=/some_path``. |
431 | @@ -154,8 +154,8 @@ |
432 | |
433 | A second method for using Loggerhead with apache is to have apache itself |
434 | execute Loggerhead via mod_wsgi. You need to add configuration for apache and |
435 | -for bazaar to make this work. Example config files are in the Loggerhead doc |
436 | -directory as apache-loggerhead.conf and bazaar.conf. You can copy them into |
437 | +for breezy to make this work. Example config files are in the Loggerhead doc |
438 | +directory as apache-loggerhead.conf and breezy.conf. You can copy them into |
439 | place and use them as a starting point following these directions: |
440 | |
441 | 1) Install mod_wsgi. On Ubuntu and other Debian derived distros:: |
442 | @@ -166,19 +166,20 @@ |
443 | |
444 | su -c yum install mod_wsgi |
445 | |
446 | -2) Copy the bazaar.conf file where apache will find it (May be done for you if |
447 | +2) Copy the breezy.conf file where apache will find it (May be done for you if |
448 | you installed Loggerhead from a distribution package):: |
449 | |
450 | # install -d -o apache -g apache -m 0755 /etc/loggerhead |
451 | - # cp -p /usr/share/doc/loggerhead*/bazaar.conf /etc/loggerhead/ |
452 | - # ln -s /etc/loggerhead /var/www/.bazaar |
453 | + # cp -p /usr/share/doc/loggerhead*/breezy.conf /etc/loggerhead/ |
454 | + # mkdir -p /var/www/.config |
455 | + # ln -s /etc/loggerhead /var/www/.config/breezy |
456 | |
457 | 3) Create the cache directory (May be done for you if you installed Loggerhead |
458 | from a distribution package):: |
459 | |
460 | # install -d -o apache -g apache -m 0700 /var/cache/loggerhead/ |
461 | |
462 | -4) Edit /etc/loggerhead/bazaar.conf. You need to set http_root_dir to the filesystem |
463 | +4) Edit /etc/loggerhead/breezy.conf. You need to set http_root_dir to the filesystem |
464 | path that you will find your bzr branches under. Note that normal |
465 | directories under that path will also be visible in Loggerhead. |
466 | |
467 | @@ -188,7 +189,7 @@ |
468 | |
469 | 6) Edit /etc/httpd/conf.d/loggerhead.conf to point to the url you desire to |
470 | serve Loggerhead on. This should match with the setting for |
471 | - http_user_prefix in bazaar.conf |
472 | + http_user_prefix in breezy.conf |
473 | |
474 | 7) Restart apache and you should be able to start browsing |
475 | |
476 | @@ -220,7 +221,7 @@ |
477 | .. toctree:: |
478 | :maxdepth: 2 |
479 | |
480 | - serve-branches |
481 | + loggerhead-serve |
482 | |
483 | |
484 | Support |
485 | |
486 | === renamed file 'docs/serve-branches.rst' => 'docs/loggerhead-serve.rst' |
487 | --- docs/serve-branches.rst 2010-03-25 10:32:47 +0000 |
488 | +++ docs/loggerhead-serve.rst 2019-09-18 16:50:15 +0000 |
489 | @@ -1,17 +1,17 @@ |
490 | -:command:`serve-branches` |
491 | +:command:`loggerhead-serve` |
492 | ========================= |
493 | |
494 | -The :command:`serve-branches` script runs a standalone Loggerhead server in |
495 | +The :command:`loggerhead-serve` script runs a standalone Loggerhead server in |
496 | the foreground. |
497 | |
498 | -.. program:: serve-branches |
499 | +.. program:: loggerhead-serve |
500 | |
501 | Usage |
502 | ----- |
503 | |
504 | .. code-block:: sh |
505 | |
506 | - serve-branches [OPTIONS] <target directory> |
507 | + loggerhead-serve [OPTIONS] <target directory> |
508 | |
509 | Options |
510 | ------- |
511 | @@ -76,7 +76,7 @@ |
512 | |
513 | .. cmdoption:: --allow-writes |
514 | |
515 | - Allow writing to the Bazaar server. |
516 | + Allow writing to the Breezy server. |
517 | |
518 | Setting this option keeps Loggerhead from adding a 'readonly+' prefix |
519 | to the base URL of the branch. The only effect of suppressing this prefix |
520 | |
521 | === removed file 'info.py' |
522 | --- info.py 2011-11-23 08:33:12 +0000 |
523 | +++ info.py 1970-01-01 00:00:00 +0000 |
524 | @@ -1,15 +0,0 @@ |
525 | -#!/usr/bin/env python |
526 | -# API Info for loggerhead |
527 | - |
528 | -bzr_plugin_name = "loggerhead" |
529 | - |
530 | -bzr_plugin_version = (1, 18, 1) # Keep in sync with loggerhead/__init__.py |
531 | - |
532 | -bzr_compatible_versions = [ |
533 | - (1, 17, 0), (1, 18, 0), (2, 0, 0), (2, 1, 0), (2, 2, 0), (2, 3, 0), |
534 | - (2, 4, 0), (2, 5, 0), |
535 | - ] |
536 | - |
537 | -bzr_minimum_version = bzr_compatible_versions[0] |
538 | - |
539 | -bzr_maximum_version = bzr_compatible_versions[-1] |
540 | |
541 | === renamed file 'serve-branches' => 'loggerhead-serve' |
542 | === renamed file 'serve-branches.1' => 'loggerhead-serve.1' |
543 | --- serve-branches.1 2008-09-10 23:12:59 +0000 |
544 | +++ loggerhead-serve.1 2019-09-18 16:50:15 +0000 |
545 | @@ -2,14 +2,14 @@ |
546 | .SH NAME |
547 | loggerhead \- run a loggerhead server |
548 | .SH SYNOPSIS |
549 | -.B serve-branches |
550 | +.B loggerhead-serve |
551 | [\fIoptions\fR] \fI<path>\fR |
552 | .SH DESCRIPTION |
553 | -Loggerhead is a web viewer for projects in bazaar. It can be used to navigate |
554 | +Loggerhead is a web viewer for projects in Breezy. It can be used to navigate |
555 | a branch history, annotate files, view patches, perform searches, etc. It's |
556 | heavily based on bazaar-webserve, which is itself based on hgweb for Mercurial. |
557 | .PP |
558 | -The serve-branches command runs a standalone loggerhead server in the foreground. |
559 | +The loggerhead-serve command runs a standalone loggerhead server in the foreground. |
560 | .SH OPTIONS |
561 | .TP |
562 | \fB\-h\fR, \fB\-\-help\fR |
563 | |
564 | === modified file 'loggerhead.wsgi' |
565 | --- loggerhead.wsgi 2012-02-08 01:50:02 +0000 |
566 | +++ loggerhead.wsgi 2019-09-18 16:50:15 +0000 |
567 | @@ -23,9 +23,10 @@ |
568 | from loggerhead.apps.transport import BranchesFromTransportRoot |
569 | from loggerhead.apps.error import ErrorHandlerApp |
570 | from loggerhead.config import LoggerheadConfig |
571 | -from bzrlib import config as bzrconfig |
572 | +from breezy import config as bzrconfig |
573 | +from breezy.sixish import PY3 |
574 | from paste.deploy.config import PrefixMiddleware |
575 | -from bzrlib.plugin import load_plugins |
576 | +from breezy.plugin import load_plugins |
577 | |
578 | class NotConfiguredError(Exception): |
579 | pass |
580 | @@ -36,14 +37,18 @@ |
581 | prefix = config.get_option('user_prefix') or '' |
582 | # Note we could use LoggerheadConfig here if it didn't fail when a |
583 | # config option is not also a commandline option |
584 | -root_dir = bzrconfig.GlobalConfig().get_user_option('http_root_dir') |
585 | -if not root_dir: |
586 | - raise NotConfiguredError('You must have a ~/.bazaar/bazaar.conf file for' |
587 | +root_dir = os.getenv('LOGGERHEAD_ROOT_DIR') |
588 | +if not root_dir: |
589 | + root_dir = bzrconfig.GlobalConfig().get_user_option('http_root_dir') |
590 | +if not root_dir: |
591 | + raise NotConfiguredError('You must set LOGGERHEAD_ROOT_DIR or have ' |
592 | + 'a ~/.config/breezy/breezy.conf file for' |
593 | ' %(user)s with http_root_dir set to the base directory you want' |
594 | ' to serve bazaar repositories from' % |
595 | {'user': pwd.getpwuid(os.geteuid()).pw_name}) |
596 | -prefix = prefix.encode('utf-8', 'ignore') |
597 | -root_dir = root_dir.encode('utf-8', 'ignore') |
598 | +if not PY3: |
599 | + prefix = prefix.encode('utf-8', 'ignore') |
600 | + root_dir = root_dir.encode('utf-8', 'ignore') |
601 | app = BranchesFromTransportRoot(root_dir, config) |
602 | app = PrefixMiddleware(app, prefix=prefix) |
603 | app = HTTPExceptionHandler(app) |
604 | |
605 | === modified file 'loggerhead/__init__.py' |
606 | --- loggerhead/__init__.py 2012-09-11 20:49:32 +0000 |
607 | +++ loggerhead/__init__.py 2019-09-18 16:50:15 +0000 |
608 | @@ -22,9 +22,9 @@ |
609 | |
610 | import pkg_resources |
611 | |
612 | -__version__ = '1.18.2' # Keep in sync with ../info.py. |
613 | +__version__ = '1.20.0' # Keep in sync with ../__init__.py. |
614 | __revision__ = None |
615 | -required_bzrlib = (1, 17) |
616 | +required_breezy = (3, 0) |
617 | |
618 | pkg_resources.get_distribution('Paste>=1.6') |
619 | try: |
620 | @@ -32,12 +32,3 @@ |
621 | except pkg_resources.DistributionNotFound: |
622 | # No paste.deploy is OK, but an old paste.deploy is bad. |
623 | pass |
624 | - |
625 | -try: |
626 | - from bzrlib.branch import Branch |
627 | - branch = Branch.open('./'); |
628 | - |
629 | - __revision__ = branch.revno() |
630 | - |
631 | -except: |
632 | - pass |
633 | |
634 | === modified file 'loggerhead/apps/__init__.py' |
635 | --- loggerhead/apps/__init__.py 2010-04-30 21:30:18 +0000 |
636 | +++ loggerhead/apps/__init__.py 2019-09-18 16:50:15 +0000 |
637 | @@ -4,7 +4,7 @@ |
638 | |
639 | from paste import urlparser, fileapp |
640 | |
641 | -from loggerhead.util import convert_file_errors |
642 | +from ..util import convert_file_errors |
643 | |
644 | static = os.path.join( |
645 | os.path.dirname(os.path.dirname(__file__)), 'static') |
646 | |
647 | === modified file 'loggerhead/apps/branch.py' |
648 | --- loggerhead/apps/branch.py 2012-02-08 01:50:02 +0000 |
649 | +++ loggerhead/apps/branch.py 2019-09-18 16:50:15 +0000 |
650 | @@ -17,31 +17,33 @@ |
651 | """The WSGI application for serving a Bazaar branch.""" |
652 | |
653 | import logging |
654 | -import urllib |
655 | import sys |
656 | +import wsgiref.util |
657 | |
658 | -import bzrlib.branch |
659 | -import bzrlib.errors |
660 | -from bzrlib.hooks import Hooks |
661 | -import bzrlib.lru_cache |
662 | +import breezy.branch |
663 | +import breezy.errors |
664 | +from breezy.hooks import Hooks |
665 | +import breezy.lru_cache |
666 | +from breezy.sixish import viewitems |
667 | +from breezy import urlutils |
668 | |
669 | from paste import request |
670 | from paste import httpexceptions |
671 | |
672 | -from loggerhead.apps import static_app |
673 | -from loggerhead.controllers.annotate_ui import AnnotateUI |
674 | -from loggerhead.controllers.view_ui import ViewUI |
675 | -from loggerhead.controllers.atom_ui import AtomUI |
676 | -from loggerhead.controllers.changelog_ui import ChangeLogUI |
677 | -from loggerhead.controllers.diff_ui import DiffUI |
678 | -from loggerhead.controllers.download_ui import DownloadUI, DownloadTarballUI |
679 | -from loggerhead.controllers.filediff_ui import FileDiffUI |
680 | -from loggerhead.controllers.inventory_ui import InventoryUI |
681 | -from loggerhead.controllers.revision_ui import RevisionUI |
682 | -from loggerhead.controllers.revlog_ui import RevLogUI |
683 | -from loggerhead.controllers.search_ui import SearchUI |
684 | -from loggerhead.history import History |
685 | -from loggerhead import util |
686 | +from ..apps import static_app |
687 | +from ..controllers.annotate_ui import AnnotateUI |
688 | +from ..controllers.view_ui import ViewUI |
689 | +from ..controllers.atom_ui import AtomUI |
690 | +from ..controllers.changelog_ui import ChangeLogUI |
691 | +from ..controllers.diff_ui import DiffUI |
692 | +from ..controllers.download_ui import DownloadUI, DownloadTarballUI |
693 | +from ..controllers.filediff_ui import FileDiffUI |
694 | +from ..controllers.inventory_ui import InventoryUI |
695 | +from ..controllers.revision_ui import RevisionUI |
696 | +from ..controllers.revlog_ui import RevLogUI |
697 | +from ..controllers.search_ui import SearchUI |
698 | +from ..history import History |
699 | +from .. import util |
700 | |
701 | |
702 | _DEFAULT = object() |
703 | @@ -63,7 +65,7 @@ |
704 | self.branch_link = branch_link # Currently only used in Launchpad |
705 | self.log = logging.getLogger('loggerhead.%s' % (friendly_name,)) |
706 | if graph_cache is None: |
707 | - graph_cache = bzrlib.lru_cache.LRUCache(10) |
708 | + graph_cache = breezy.lru_cache.LRUCache(10) |
709 | self.graph_cache = graph_cache |
710 | self.is_root = is_root |
711 | self.served_url = served_url |
712 | @@ -84,7 +86,7 @@ |
713 | # Only import the cache if we're going to use it. |
714 | # This makes sqlite optional |
715 | try: |
716 | - from loggerhead.changecache import RevInfoDiskCache |
717 | + from ..changecache import RevInfoDiskCache |
718 | except ImportError: |
719 | self.log.debug("Couldn't load python-sqlite," |
720 | " continuing without using a cache") |
721 | @@ -92,18 +94,32 @@ |
722 | revinfo_disk_cache = RevInfoDiskCache(cache_path) |
723 | return History( |
724 | self.branch, self.graph_cache, |
725 | - revinfo_disk_cache=revinfo_disk_cache, cache_key=self.friendly_name) |
726 | + revinfo_disk_cache=revinfo_disk_cache, |
727 | + cache_key=(self.friendly_name.encode('utf-8') if self.friendly_name else None)) |
728 | + |
729 | + # Before the addition of this method, clicking to sort by date from |
730 | + # within a branch caused a jump up to the top of that branch. |
731 | + def sort_url(self, *args, **kw): |
732 | + if isinstance(args[0], list): |
733 | + args = args[0] |
734 | + qs = [] |
735 | + for k, v in viewitems(kw): |
736 | + if v is not None: |
737 | + qs.append('%s=%s' % (k, urlutils.quote(v))) |
738 | + qs = '&'.join(qs) |
739 | + path_info = self._path_info.strip('/').split('?')[0] |
740 | + path_info += '?' + qs |
741 | + return self._url_base + '/' + path_info |
742 | |
743 | def url(self, *args, **kw): |
744 | if isinstance(args[0], list): |
745 | args = args[0] |
746 | qs = [] |
747 | - for k, v in kw.iteritems(): |
748 | + for k, v in viewitems(kw): |
749 | if v is not None: |
750 | - qs.append('%s=%s' % (k, urllib.quote(v))) |
751 | + qs.append('%s=%s' % (k, urlutils.quote(v))) |
752 | qs = '&'.join(qs) |
753 | - path_info = urllib.quote( |
754 | - unicode('/'.join(args)).encode('utf-8'), safe='/~:') |
755 | + path_info = urlutils.quote('/'.join(args), safe='/~:') |
756 | if qs: |
757 | path_info += '?' + qs |
758 | return self._url_base + path_info |
759 | @@ -147,14 +163,15 @@ |
760 | return change.date |
761 | |
762 | def public_branch_url(self): |
763 | - return self.branch.get_config().get_user_option('public_branch') |
764 | + return self.branch.get_public_branch() |
765 | |
766 | def lookup_app(self, environ): |
767 | # Check again if the branch is blocked from being served, this is |
768 | # mostly for tests. It's already checked in apps/transport.py |
769 | - if self.branch.get_config().get_user_option('http_serve') == 'False': |
770 | + if not self.branch.get_config().get_user_option_as_bool('http_serve', default=True): |
771 | raise httpexceptions.HTTPNotFound() |
772 | self._url_base = environ['SCRIPT_NAME'] |
773 | + self._path_info = environ['PATH_INFO'] |
774 | self._static_url_base = environ.get('loggerhead.static.url') |
775 | if self._static_url_base is None: |
776 | self._static_url_base = self._url_base |
777 | @@ -164,13 +181,7 @@ |
778 | if public_branch is not None: |
779 | self.served_url = public_branch |
780 | else: |
781 | - # Loggerhead only supports serving .bzr/ on local branches, so |
782 | - # we shouldn't suggest something that won't work. |
783 | - try: |
784 | - util.local_path_from_url(self.branch.base) |
785 | - self.served_url = self.url([]) |
786 | - except bzrlib.errors.InvalidURL: |
787 | - self.served_url = None |
788 | + self.served_url = wsgiref.util.application_uri(environ) |
789 | for hook in self.hooks['controller']: |
790 | controller = hook(self, environ) |
791 | if controller is not None: |
792 | @@ -190,8 +201,7 @@ |
793 | raise httpexceptions.HTTPNotFound() |
794 | |
795 | def app(self, environ, start_response): |
796 | - self.branch.lock_read() |
797 | - try: |
798 | + with self.branch.lock_read(): |
799 | try: |
800 | c = self.lookup_app(environ) |
801 | return c(environ, start_response) |
802 | @@ -199,8 +209,6 @@ |
803 | environ['exc_info'] = sys.exc_info() |
804 | environ['branch'] = self |
805 | raise |
806 | - finally: |
807 | - self.branch.unlock() |
808 | |
809 | |
810 | class BranchWSGIAppHooks(Hooks): |
811 | @@ -210,7 +218,7 @@ |
812 | def __init__(self): |
813 | """Create the default hooks. |
814 | """ |
815 | - Hooks.__init__(self, "bzrlib.plugins.loggerhead.apps.branch", |
816 | + Hooks.__init__(self, "breezy.plugins.loggerhead.apps.branch", |
817 | "BranchWSGIApp.hooks") |
818 | self.add_hook('controller', |
819 | "Invoked when looking for the controller to use for a " |
820 | |
821 | === modified file 'loggerhead/apps/error.py' |
822 | --- loggerhead/apps/error.py 2012-02-08 01:50:02 +0000 |
823 | +++ loggerhead/apps/error.py 2019-09-18 16:50:15 +0000 |
824 | @@ -15,7 +15,7 @@ |
825 | # Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
826 | # |
827 | |
828 | -from loggerhead.controllers.error_ui import ErrorUI |
829 | +from ..controllers.error_ui import ErrorUI |
830 | |
831 | |
832 | class ErrorHandlerApp(object): |
833 | |
834 | === modified file 'loggerhead/apps/transport.py' |
835 | --- loggerhead/apps/transport.py 2012-02-08 01:50:02 +0000 |
836 | +++ loggerhead/apps/transport.py 2019-09-18 16:50:15 +0000 |
837 | @@ -18,28 +18,22 @@ |
838 | |
839 | import threading |
840 | |
841 | -from bzrlib import branch, errors, lru_cache, urlutils |
842 | -from bzrlib.config import LocationConfig |
843 | -from bzrlib.smart import request |
844 | -from bzrlib.transport import get_transport |
845 | -from bzrlib.transport.http import wsgi |
846 | +from breezy import branch, errors, lru_cache, urlutils |
847 | +from breezy.config import LocationConfig |
848 | +from breezy.bzr.smart import request |
849 | +import breezy.ui |
850 | +from breezy.transport import get_transport |
851 | +from breezy.transport.http import wsgi |
852 | |
853 | from paste.request import path_info_pop |
854 | from paste import httpexceptions |
855 | from paste import urlparser |
856 | |
857 | -from loggerhead import util |
858 | -from loggerhead.apps.branch import BranchWSGIApp |
859 | -from loggerhead.apps import favicon_app, robots_app, static_app |
860 | -from loggerhead.controllers.directory_ui import DirectoryUI |
861 | +from .. import util |
862 | +from ..apps.branch import BranchWSGIApp |
863 | +from ..apps import favicon_app, robots_app, static_app |
864 | +from ..controllers.directory_ui import DirectoryUI |
865 | |
866 | -# TODO: Use bzrlib.ui.bool_from_string(), added in bzr 1.18 |
867 | -_bools = { |
868 | - 'yes': True, 'no': False, |
869 | - 'on': True, 'off': False, |
870 | - '1': True, '0': False, |
871 | - 'true': True, 'false': False, |
872 | - } |
873 | |
874 | class BranchesFromTransportServer(object): |
875 | |
876 | @@ -103,10 +97,7 @@ |
877 | return urlparser.make_static(None, path) |
878 | |
879 | def check_serveable(self, config): |
880 | - value = config.get_user_option('http_serve') |
881 | - if value is None: |
882 | - return |
883 | - elif not _bools.get(value.lower(), True): |
884 | + if not config.get_user_option_as_bool('http_serve', default=True): |
885 | raise httpexceptions.HTTPNotFound() |
886 | |
887 | def __call__(self, environ, start_response): |
888 | |
889 | === modified file 'loggerhead/changecache.py' |
890 | --- loggerhead/changecache.py 2012-02-08 01:50:02 +0000 |
891 | +++ loggerhead/changecache.py 2019-09-18 16:50:15 +0000 |
892 | @@ -26,7 +26,10 @@ |
893 | cached a change, it's good forever. |
894 | """ |
895 | |
896 | -import cPickle |
897 | +try: |
898 | + import cPickle as pickle |
899 | +except ImportError: # Python >= 3 |
900 | + import pickle |
901 | import marshal |
902 | import os |
903 | import tempfile |
904 | @@ -73,10 +76,10 @@ |
905 | con.close() |
906 | |
907 | def _serialize(self, obj): |
908 | - return dbapi2.Binary(cPickle.dumps(obj, protocol=2)) |
909 | + return dbapi2.Binary(pickle.dumps(obj, protocol=2)) |
910 | |
911 | def _unserialize(self, data): |
912 | - return cPickle.loads(str(data)) |
913 | + return pickle.loads(str(data)) |
914 | |
915 | def get(self, revid): |
916 | self.cursor.execute( |
917 | @@ -115,6 +118,10 @@ |
918 | self.cursor = self.connection.cursor() |
919 | |
920 | def get(self, key, revid): |
921 | + if not isinstance(key, bytes): |
922 | + raise TypeError(key) |
923 | + if not isinstance(revid, bytes): |
924 | + raise TypeError(revid) |
925 | self.cursor.execute( |
926 | "select revid, data from data where key = ?", (dbapi2.Binary(key),)) |
927 | row = self.cursor.fetchone() |
928 | @@ -126,13 +133,17 @@ |
929 | return marshal.loads(zlib.decompress(row[1])) |
930 | |
931 | def set(self, key, revid, data): |
932 | + if not isinstance(key, bytes): |
933 | + raise TypeError(key) |
934 | + if not isinstance(revid, bytes): |
935 | + raise TypeError(revid) |
936 | try: |
937 | self.cursor.execute( |
938 | 'delete from data where key = ?', (dbapi2.Binary(key), )) |
939 | blob = zlib.compress(marshal.dumps(data)) |
940 | self.cursor.execute( |
941 | "insert into data (key, revid, data) values (?, ?, ?)", |
942 | - map(dbapi2.Binary, [key, revid, blob])) |
943 | + list(map(dbapi2.Binary, [key, revid, blob]))) |
944 | self.connection.commit() |
945 | except dbapi2.IntegrityError: |
946 | # If another thread or process attempted to set the same key, we |
947 | |
948 | === modified file 'loggerhead/config.py' |
949 | --- loggerhead/config.py 2011-07-07 19:09:11 +0000 |
950 | +++ loggerhead/config.py 2019-09-18 16:50:15 +0000 |
951 | @@ -17,7 +17,7 @@ |
952 | import sys |
953 | import tempfile |
954 | |
955 | -from bzrlib import config |
956 | +from breezy import config |
957 | |
958 | _temporary_sql_dir = None |
959 | |
960 | @@ -120,7 +120,7 @@ |
961 | |
962 | def get_option(self, option): |
963 | """Get the value for the config option, either |
964 | - from ~/.bazaar/bazaar.conf or from the command line. |
965 | + from ~/.config/breezy/breezy.conf or from the command line. |
966 | All loggerhead-specific settings start with 'http_' |
967 | """ |
968 | global_config = config.GlobalConfig().get_user_option('http_'+option) |
969 | |
970 | === modified file 'loggerhead/controllers/__init__.py' |
971 | --- loggerhead/controllers/__init__.py 2012-02-08 01:50:02 +0000 |
972 | +++ loggerhead/controllers/__init__.py 2019-09-18 16:50:15 +0000 |
973 | @@ -17,16 +17,19 @@ |
974 | # along with this program; if not, write to the Free Software |
975 | # Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
976 | |
977 | -import bzrlib.errors |
978 | +import breezy.errors |
979 | import simplejson |
980 | import time |
981 | |
982 | +from breezy import osutils |
983 | + |
984 | from paste.httpexceptions import HTTPNotFound, HTTPSeeOther |
985 | from paste.request import path_info_pop, parse_querystring |
986 | |
987 | -from loggerhead import util |
988 | -from loggerhead.templatefunctions import templatefunctions |
989 | -from loggerhead.zptsupport import load_template |
990 | +from .. import templates |
991 | +from .. import util |
992 | +from ..templatefunctions import templatefunctions |
993 | +from ..zptsupport import load_template |
994 | |
995 | |
996 | class BufferingWriter(object): |
997 | @@ -39,7 +42,7 @@ |
998 | self.buf_limit = buf_limit |
999 | |
1000 | def flush(self): |
1001 | - self.writefunc(''.join(self.buf)) |
1002 | + self.writefunc(b''.join(self.buf)) |
1003 | self.buf = [] |
1004 | self.buflen = 0 |
1005 | |
1006 | @@ -53,7 +56,7 @@ |
1007 | |
1008 | class TemplatedBranchView(object): |
1009 | |
1010 | - template_path = None |
1011 | + template_name = None |
1012 | supports_json = False |
1013 | |
1014 | def __init__(self, branch, history_callable): |
1015 | @@ -81,7 +84,10 @@ |
1016 | |
1017 | path = None |
1018 | if len(args) > 1: |
1019 | - path = unicode('/'.join(args[1:]), 'utf-8') |
1020 | + path = '/'.join(args[1:]) |
1021 | + if isinstance(path, bytes): |
1022 | + # Python 2 |
1023 | + path = path.decode('utf-8') |
1024 | self.args = args |
1025 | self.kwargs = kwargs |
1026 | return path |
1027 | @@ -109,7 +115,7 @@ |
1028 | headers['Content-Type'] = 'application/json' |
1029 | elif 'Content-Type' not in headers: |
1030 | headers['Content-Type'] = 'text/html' |
1031 | - writer = start_response("200 OK", headers.items()) |
1032 | + writer = start_response("200 OK", list(headers.items())) |
1033 | if environ.get('REQUEST_METHOD') == 'HEAD': |
1034 | # No content for a HEAD request |
1035 | return [] |
1036 | @@ -117,10 +123,11 @@ |
1037 | w = BufferingWriter(writer, 8192) |
1038 | if environ.get('loggerhead.as_json'): |
1039 | w.write(simplejson.dumps(values, |
1040 | - default=util.convert_to_json_ready)) |
1041 | + default=util.convert_to_json_ready).encode('utf-8')) |
1042 | else: |
1043 | self.add_template_values(values) |
1044 | - template = load_template(self.template_path) |
1045 | + template = load_template( |
1046 | + '%s.%s' % (templates.__name__, self.template_name)) |
1047 | template.expand_into(w, **values) |
1048 | w.flush() |
1049 | self.log.info( |
1050 | @@ -135,8 +142,11 @@ |
1051 | if len(self.args) > 0 and self.args != ['']: |
1052 | try: |
1053 | revid = h.fix_revid(self.args[0]) |
1054 | - except bzrlib.errors.NoSuchRevision: |
1055 | + except breezy.errors.NoSuchRevision: |
1056 | raise HTTPNotFound; |
1057 | + assert isinstance(revid, bytes) |
1058 | else: |
1059 | revid = h.last_revid |
1060 | + if revid is not None and not isinstance(revid, bytes): |
1061 | + raise TypeError(revid) |
1062 | return revid |
1063 | |
1064 | === modified file 'loggerhead/controllers/annotate_ui.py' |
1065 | --- loggerhead/controllers/annotate_ui.py 2012-02-08 01:50:02 +0000 |
1066 | +++ loggerhead/controllers/annotate_ui.py 2019-09-18 16:50:15 +0000 |
1067 | @@ -18,17 +18,22 @@ |
1068 | |
1069 | import itertools |
1070 | |
1071 | -from loggerhead.controllers.view_ui import ViewUI |
1072 | -from loggerhead import util |
1073 | +from ..controllers.view_ui import ViewUI |
1074 | +from .. import util |
1075 | |
1076 | class AnnotateUI(ViewUI): |
1077 | |
1078 | def annotate_file(self, info): |
1079 | file_id = info['file_id'] |
1080 | revid = info['change'].revid |
1081 | - |
1082 | + if not isinstance(file_id, bytes): |
1083 | + raise TypeError(file_id) |
1084 | + if not isinstance(revid, bytes): |
1085 | + raise TypeError(revid) |
1086 | + path = self._history.get_path(revid, file_id) |
1087 | + |
1088 | tree = self.tree_for(file_id, revid) |
1089 | - |
1090 | + |
1091 | change_cache = {} |
1092 | last_line_revid = None |
1093 | last_lineno = None |
1094 | @@ -37,7 +42,7 @@ |
1095 | revisions = {} |
1096 | |
1097 | lineno = 0 |
1098 | - for (line_revid, text), lineno in zip(tree.annotate_iter(file_id), itertools.count(1)): |
1099 | + for (line_revid, text), lineno in zip(tree.annotate_iter(path, file_id), itertools.count(1)): |
1100 | if line_revid != last_line_revid: |
1101 | last_line_revid = line_revid |
1102 | |
1103 | @@ -70,9 +75,9 @@ |
1104 | revisions[last_lineno].revspan = lineno - last_lineno + 1 |
1105 | |
1106 | return revisions |
1107 | - |
1108 | + |
1109 | def get_values(self, path, kwargs, headers): |
1110 | values = super(AnnotateUI, self).get_values(path, kwargs, headers) |
1111 | values['annotated'] = self.annotate_file(values) |
1112 | - |
1113 | + |
1114 | return values |
1115 | |
1116 | === modified file 'loggerhead/controllers/atom_ui.py' |
1117 | --- loggerhead/controllers/atom_ui.py 2012-02-08 01:50:02 +0000 |
1118 | +++ loggerhead/controllers/atom_ui.py 2019-09-18 16:50:15 +0000 |
1119 | @@ -17,12 +17,12 @@ |
1120 | # Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
1121 | # |
1122 | |
1123 | -from loggerhead.controllers import TemplatedBranchView |
1124 | +from ..controllers import TemplatedBranchView |
1125 | |
1126 | |
1127 | class AtomUI (TemplatedBranchView): |
1128 | |
1129 | - template_path = 'loggerhead.templates.atom' |
1130 | + template_name = 'atom' |
1131 | |
1132 | def get_values(self, path, kwargs, headers): |
1133 | history = self._history |
1134 | |
1135 | === modified file 'loggerhead/controllers/changelog_ui.py' |
1136 | --- loggerhead/controllers/changelog_ui.py 2012-02-08 01:50:02 +0000 |
1137 | +++ loggerhead/controllers/changelog_ui.py 2019-09-18 16:50:15 +0000 |
1138 | @@ -18,24 +18,26 @@ |
1139 | # Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
1140 | # |
1141 | |
1142 | -import urllib |
1143 | - |
1144 | import simplejson |
1145 | |
1146 | from paste.httpexceptions import HTTPServerError |
1147 | |
1148 | -from loggerhead import util |
1149 | -from loggerhead.controllers import TemplatedBranchView |
1150 | +from breezy import osutils, urlutils |
1151 | + |
1152 | +from .. import util |
1153 | +from ..controllers import TemplatedBranchView |
1154 | |
1155 | |
1156 | class ChangeLogUI(TemplatedBranchView): |
1157 | |
1158 | - template_path = 'loggerhead.templates.changelog' |
1159 | + template_name = 'changelog' |
1160 | |
1161 | def get_values(self, path, kwargs, headers): |
1162 | history = self._history |
1163 | revid = self.get_revid() |
1164 | filter_file_id = kwargs.get('filter_file_id', None) |
1165 | + if filter_file_id is not None: |
1166 | + filter_file_id = urlutils.unquote_to_bytes(osutils.safe_utf8(filter_file_id)) |
1167 | query = kwargs.get('q', None) |
1168 | start_revid = history.fix_revid(kwargs.get('start_revid', None)) |
1169 | orig_start_revid = start_revid |
1170 | @@ -67,7 +69,7 @@ |
1171 | data = {} |
1172 | for i, c in enumerate(changes): |
1173 | c.index = i |
1174 | - data[str(i)] = urllib.quote(urllib.quote(c.revid, safe='')) |
1175 | + data[str(i)] = urlutils.quote(urlutils.quote_from_bytes(c.revid, safe='')) |
1176 | except: |
1177 | self.log.exception('Exception fetching changes') |
1178 | raise HTTPServerError('Could not fetch changes') |
1179 | |
1180 | === modified file 'loggerhead/controllers/diff_ui.py' |
1181 | --- loggerhead/controllers/diff_ui.py 2012-07-31 20:25:42 +0000 |
1182 | +++ loggerhead/controllers/diff_ui.py 2019-09-18 16:50:15 +0000 |
1183 | @@ -16,15 +16,15 @@ |
1184 | # Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
1185 | # |
1186 | |
1187 | -from cStringIO import StringIO |
1188 | +from io import BytesIO |
1189 | import time |
1190 | |
1191 | from paste.request import path_info_pop, parse_querystring |
1192 | |
1193 | -from bzrlib.diff import show_diff_trees |
1194 | -from bzrlib.revision import NULL_REVISION |
1195 | +from breezy.diff import show_diff_trees |
1196 | +from breezy.revision import NULL_REVISION |
1197 | |
1198 | -from loggerhead.controllers import TemplatedBranchView |
1199 | +from ..controllers import TemplatedBranchView |
1200 | |
1201 | |
1202 | class DiffUI(TemplatedBranchView): |
1203 | @@ -71,7 +71,7 @@ |
1204 | revtree1 = repo.revision_tree(revid_to) |
1205 | revtree2 = repo.revision_tree(revid_from) |
1206 | |
1207 | - diff_content_stream = StringIO() |
1208 | + diff_content_stream = BytesIO() |
1209 | show_diff_trees(revtree1, revtree2, diff_content_stream, |
1210 | old_label='', new_label='', context=numlines) |
1211 | |
1212 | |
1213 | === modified file 'loggerhead/controllers/directory_ui.py' |
1214 | --- loggerhead/controllers/directory_ui.py 2012-02-08 01:50:02 +0000 |
1215 | +++ loggerhead/controllers/directory_ui.py 2019-09-18 16:50:15 +0000 |
1216 | @@ -20,33 +20,33 @@ |
1217 | import logging |
1218 | import stat |
1219 | |
1220 | -from bzrlib import branch, errors |
1221 | +from breezy import branch, errors, urlutils |
1222 | |
1223 | -from loggerhead import util |
1224 | -from loggerhead.controllers import TemplatedBranchView |
1225 | +from .. import util |
1226 | +from ..controllers import TemplatedBranchView |
1227 | |
1228 | |
1229 | class DirEntry(object): |
1230 | |
1231 | def __init__(self, dirname, parity, branch): |
1232 | - self.dirname = dirname |
1233 | + self.dirname = urlutils.unquote(dirname) |
1234 | self.parity = parity |
1235 | self.branch = branch |
1236 | if branch is not None: |
1237 | # If a branch is empty, bzr raises an exception when trying this |
1238 | try: |
1239 | - self.last_change = datetime.datetime.utcfromtimestamp( |
1240 | - branch.repository.get_revision( |
1241 | - branch.last_revision()).timestamp) |
1242 | - except: |
1243 | - self.last_change = None |
1244 | + self.last_revision = branch.repository.get_revision(branch.last_revision()) |
1245 | + self.last_change_time = datetime.datetime.utcfromtimestamp(self.last_revision.timestamp) |
1246 | + except errors.NoSuchRevision: |
1247 | + self.last_revision = None |
1248 | + self.last_change_time = None |
1249 | |
1250 | |
1251 | class DirectoryUI(TemplatedBranchView): |
1252 | """ |
1253 | """ |
1254 | |
1255 | - template_path = 'loggerhead.templates.directory' |
1256 | + template_name = 'directory' |
1257 | |
1258 | def __init__(self, static_url_base, transport, name): |
1259 | |
1260 | @@ -72,15 +72,17 @@ |
1261 | for d in listing: |
1262 | try: |
1263 | b = branch.Branch.open_from_transport(self.transport.clone(d)) |
1264 | - if b.get_config().get_user_option('http_serve') == 'False': |
1265 | - continue |
1266 | except: |
1267 | + # TODO(jelmer): don't catch all exceptions here |
1268 | try: |
1269 | if not stat.S_ISDIR(self.transport.stat(d).st_mode): |
1270 | continue |
1271 | except errors.NoSuchFile: |
1272 | continue |
1273 | b = None |
1274 | + else: |
1275 | + if not b.get_config().get_user_option_as_bool('http_serve', default=True): |
1276 | + continue |
1277 | dirs.append(DirEntry(d, parity, b)) |
1278 | parity = 1 - parity |
1279 | # Create breadcrumb trail |
1280 | |
1281 | === modified file 'loggerhead/controllers/download_ui.py' |
1282 | --- loggerhead/controllers/download_ui.py 2012-03-22 14:09:52 +0000 |
1283 | +++ loggerhead/controllers/download_ui.py 2019-09-18 16:50:15 +0000 |
1284 | @@ -21,15 +21,15 @@ |
1285 | import mimetypes |
1286 | import urllib |
1287 | |
1288 | -from bzrlib.errors import ( |
1289 | +from breezy.errors import ( |
1290 | NoSuchId, |
1291 | NoSuchRevision, |
1292 | ) |
1293 | +from breezy import osutils, urlutils |
1294 | from paste import httpexceptions |
1295 | from paste.request import path_info_pop |
1296 | |
1297 | -from loggerhead.controllers import TemplatedBranchView |
1298 | -from loggerhead.exporter import export_archive |
1299 | +from ..controllers import TemplatedBranchView |
1300 | |
1301 | log = logging.getLogger("loggerhead.controllers") |
1302 | |
1303 | @@ -38,7 +38,7 @@ |
1304 | |
1305 | def encode_filename(self, filename): |
1306 | |
1307 | - return urllib.quote(filename.encode('utf-8')) |
1308 | + return urlutils.escape(filename) |
1309 | |
1310 | def get_args(self, environ): |
1311 | args = [] |
1312 | @@ -57,7 +57,7 @@ |
1313 | raise httpexceptions.HTTPMovedPermanently( |
1314 | self._branch.absolute_url('/changes')) |
1315 | revid = h.fix_revid(args[0]) |
1316 | - file_id = args[1] |
1317 | + file_id = urlutils.unquote_to_bytes(osutils.safe_utf8(args[1])) |
1318 | try: |
1319 | path, filename, content = h.get_file(file_id, revid) |
1320 | except (NoSuchId, NoSuchRevision): |
1321 | @@ -102,12 +102,13 @@ |
1322 | # TODO: Perhaps set the tarball suggested mtime to the revision |
1323 | # mtime. |
1324 | root = self._branch.friendly_name or 'branch' |
1325 | - encoded_filename = self.encode_filename( |
1326 | - root + version_part + '.' + archive_format) |
1327 | + filename = root + version_part + '.' + archive_format |
1328 | + encoded_filename = self.encode_filename(filename) |
1329 | headers = [ |
1330 | ('Content-Type', 'application/octet-stream'), |
1331 | ('Content-Disposition', |
1332 | "attachment; filename*=utf-8''%s" % (encoded_filename,)), |
1333 | ] |
1334 | start_response('200 OK', headers) |
1335 | - return export_archive(history, root, revid, archive_format) |
1336 | + tree = history._branch.repository.revision_tree(revid) |
1337 | + return tree.archive(root=root, format=archive_format, name=filename) |
1338 | |
1339 | === modified file 'loggerhead/controllers/error_ui.py' |
1340 | --- loggerhead/controllers/error_ui.py 2012-02-08 01:50:02 +0000 |
1341 | +++ loggerhead/controllers/error_ui.py 2019-09-18 16:50:15 +0000 |
1342 | @@ -16,16 +16,16 @@ |
1343 | # Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
1344 | # |
1345 | |
1346 | -from StringIO import StringIO |
1347 | +from io import StringIO |
1348 | import traceback |
1349 | |
1350 | -from loggerhead.controllers import TemplatedBranchView |
1351 | -from loggerhead import util |
1352 | +from ..controllers import TemplatedBranchView |
1353 | +from .. import util |
1354 | |
1355 | |
1356 | class ErrorUI(TemplatedBranchView): |
1357 | |
1358 | - template_path = 'loggerhead.templates.error' |
1359 | + template_name = 'error' |
1360 | |
1361 | def __init__(self, branch, exc_info): |
1362 | super(ErrorUI, self).__init__(branch, lambda: None) |
1363 | |
1364 | === modified file 'loggerhead/controllers/filediff_ui.py' |
1365 | --- loggerhead/controllers/filediff_ui.py 2015-03-19 14:48:47 +0000 |
1366 | +++ loggerhead/controllers/filediff_ui.py 2019-09-18 16:50:15 +0000 |
1367 | @@ -1,47 +1,52 @@ |
1368 | -from StringIO import StringIO |
1369 | -import urllib |
1370 | - |
1371 | -from bzrlib import diff |
1372 | -from bzrlib import errors |
1373 | -from bzrlib import osutils |
1374 | - |
1375 | -from loggerhead import util |
1376 | -from loggerhead.controllers import TemplatedBranchView |
1377 | +from io import BytesIO |
1378 | + |
1379 | +from breezy import ( |
1380 | + diff, |
1381 | + errors, |
1382 | + osutils, |
1383 | + urlutils, |
1384 | + ) |
1385 | + |
1386 | +from .. import util |
1387 | +from ..controllers import TemplatedBranchView |
1388 | + |
1389 | |
1390 | def _process_diff(difftext): |
1391 | chunks = [] |
1392 | chunk = None |
1393 | + def decode_line(line): |
1394 | + return line.decode('utf-8', 'replace') |
1395 | for line in difftext.splitlines(): |
1396 | if len(line) == 0: |
1397 | continue |
1398 | - if line.startswith('+++ ') or line.startswith('--- '): |
1399 | + if line.startswith(b'+++ ') or line.startswith(b'--- '): |
1400 | continue |
1401 | - if line.startswith('@@ '): |
1402 | + if line.startswith(b'@@ '): |
1403 | # new chunk |
1404 | if chunk is not None: |
1405 | chunks.append(chunk) |
1406 | chunk = util.Container() |
1407 | chunk.diff = [] |
1408 | - split_lines = line.split(' ')[1:3] |
1409 | - lines = [int(x.split(',')[0][1:]) for x in split_lines] |
1410 | + split_lines = line.split(b' ')[1:3] |
1411 | + lines = [int(x.split(b',')[0][1:]) for x in split_lines] |
1412 | old_lineno = lines[0] |
1413 | new_lineno = lines[1] |
1414 | - elif line.startswith(' '): |
1415 | + elif line.startswith(b' '): |
1416 | chunk.diff.append(util.Container(old_lineno=old_lineno, |
1417 | new_lineno=new_lineno, |
1418 | type='context', |
1419 | - line=line[1:])) |
1420 | + line=decode_line(line[1:]))) |
1421 | old_lineno += 1 |
1422 | new_lineno += 1 |
1423 | - elif line.startswith('+'): |
1424 | + elif line.startswith(b'+'): |
1425 | chunk.diff.append(util.Container(old_lineno=None, |
1426 | new_lineno=new_lineno, |
1427 | - type='insert', line=line[1:])) |
1428 | + type='insert', line=decode_line(line[1:]))) |
1429 | new_lineno += 1 |
1430 | - elif line.startswith('-'): |
1431 | + elif line.startswith(b'-'): |
1432 | chunk.diff.append(util.Container(old_lineno=old_lineno, |
1433 | new_lineno=None, |
1434 | - type='delete', line=line[1:])) |
1435 | + type='delete', line=decode_line(line[1:]))) |
1436 | old_lineno += 1 |
1437 | else: |
1438 | chunk.diff.append(util.Container(old_lineno=None, |
1439 | @@ -60,17 +65,17 @@ |
1440 | lines = {} |
1441 | args = [] |
1442 | for r in (compare_revid, revid): |
1443 | - if r == 'null:': |
1444 | + if r == b'null:': |
1445 | lines[r] = [] |
1446 | else: |
1447 | args.append((file_id, r, r)) |
1448 | for r, bytes_iter in repository.iter_files_bytes(args): |
1449 | - lines[r] = osutils.split_lines(''.join(bytes_iter)) |
1450 | - buffer = StringIO() |
1451 | + lines[r] = osutils.split_lines(b''.join(bytes_iter)) |
1452 | + buffer = BytesIO() |
1453 | try: |
1454 | diff.internal_diff('', lines[compare_revid], '', lines[revid], buffer, context_lines=context_lines) |
1455 | except errors.BinaryFile: |
1456 | - difftext = '' |
1457 | + difftext = b'' |
1458 | else: |
1459 | difftext = buffer.getvalue() |
1460 | |
1461 | @@ -79,13 +84,13 @@ |
1462 | |
1463 | class FileDiffUI(TemplatedBranchView): |
1464 | |
1465 | - template_path = 'loggerhead.templates.filediff' |
1466 | + template_name = 'filediff' |
1467 | supports_json = True |
1468 | |
1469 | def get_values(self, path, kwargs, headers): |
1470 | - revid = urllib.unquote(self.args[0]) |
1471 | - compare_revid = urllib.unquote(self.args[1]) |
1472 | - file_id = urllib.unquote(self.args[2]) |
1473 | + revid = urlutils.unquote_to_bytes(self.args[0]) |
1474 | + compare_revid = urlutils.unquote_to_bytes(self.args[1]) |
1475 | + file_id = urlutils.unquote_to_bytes(self.args[2]) |
1476 | |
1477 | try: |
1478 | context_lines = int(kwargs['context']) |
1479 | |
1480 | === modified file 'loggerhead/controllers/inventory_ui.py' |
1481 | --- loggerhead/controllers/inventory_ui.py 2013-03-27 05:29:14 +0000 |
1482 | +++ loggerhead/controllers/inventory_ui.py 2019-09-18 16:50:15 +0000 |
1483 | @@ -24,60 +24,68 @@ |
1484 | |
1485 | from paste.httpexceptions import HTTPNotFound, HTTPMovedPermanently |
1486 | |
1487 | -from bzrlib import errors |
1488 | -from bzrlib.revision import is_null as is_null_rev |
1489 | +from breezy import ( |
1490 | + errors, |
1491 | + osutils, |
1492 | + urlutils, |
1493 | + ) |
1494 | +from breezy.revision import is_null as is_null_rev |
1495 | |
1496 | -from loggerhead import util |
1497 | -from loggerhead.controllers import TemplatedBranchView |
1498 | +from .. import util |
1499 | +from ..controllers import TemplatedBranchView |
1500 | |
1501 | |
1502 | |
1503 | def dirname(path): |
1504 | if path is not None: |
1505 | path = path.rstrip('/') |
1506 | - path = urllib.quote(posixpath.dirname(path).encode('utf-8')) |
1507 | + path = urlutils.escape(posixpath.dirname(path)) |
1508 | return path |
1509 | |
1510 | |
1511 | class InventoryUI(TemplatedBranchView): |
1512 | |
1513 | - template_path = 'loggerhead.templates.inventory' |
1514 | + template_name = 'inventory' |
1515 | supports_json = True |
1516 | |
1517 | - def get_filelist(self, inv, path, sort_type, revno_url): |
1518 | + def get_filelist(self, tree, path, sort_type, revno_url): |
1519 | """ |
1520 | return the list of all files (and their attributes) within a given |
1521 | path subtree. |
1522 | |
1523 | - @param inv: The inventory. |
1524 | - @param path: The path of a directory within the inventory. |
1525 | + @param tree: The tree |
1526 | + @param path: The path of a directory within the tree. |
1527 | @param sort_type: How to sort the results... XXX. |
1528 | """ |
1529 | - file_id = inv.path2id(path) |
1530 | - dir_ie = inv[file_id] |
1531 | file_list = [] |
1532 | |
1533 | - if dir_ie.kind != 'directory': |
1534 | + if tree.kind(path) != 'directory': |
1535 | raise HTTPMovedPermanently(self._branch.context_url(['/view', revno_url, path])) |
1536 | |
1537 | revid_set = set() |
1538 | |
1539 | - for filename, entry in dir_ie.children.iteritems(): |
1540 | - revid_set.add(entry.revision) |
1541 | + child_entries = [] |
1542 | + |
1543 | + for entry in tree.iter_child_entries(path): |
1544 | + child_path = osutils.pathjoin(path, entry.name) |
1545 | + child_revision = tree.get_file_revision(child_path) |
1546 | + revid_set.add(child_revision) |
1547 | + child_entries.append((child_path, entry, child_revision)) |
1548 | |
1549 | change_dict = {} |
1550 | for change in self._history.get_changes(list(revid_set)): |
1551 | change_dict[change.revid] = change |
1552 | |
1553 | - for filename, entry in dir_ie.children.iteritems(): |
1554 | - pathname = filename |
1555 | + for child_path, entry, child_revision in child_entries: |
1556 | + pathname = entry.name |
1557 | + contents_changed_rev = None |
1558 | if entry.kind == 'directory': |
1559 | pathname += '/' |
1560 | - if path == '': |
1561 | - absolutepath = pathname |
1562 | + size = None |
1563 | else: |
1564 | - absolutepath = path + '/' + pathname |
1565 | - revid = entry.revision |
1566 | + size = entry.text_size |
1567 | + |
1568 | + file_timestamp = change_dict[child_revision].timestamp |
1569 | |
1570 | # TODO: For the JSON rendering, this inlines the "change" aka |
1571 | # revision information attached to each file. Consider either |
1572 | @@ -85,21 +93,26 @@ |
1573 | # including the revision id and having a separate request to get |
1574 | # back the revision info. |
1575 | file = util.Container( |
1576 | - filename=filename, executable=entry.executable, |
1577 | - kind=entry.kind, absolutepath=absolutepath, |
1578 | - file_id=entry.file_id, size=entry.text_size, revid=revid, |
1579 | - change=change_dict[revid]) |
1580 | + filename=entry.name, executable=entry.executable, |
1581 | + kind=entry.kind, absolutepath=child_path, |
1582 | + file_id=entry.file_id, size=size, revid=child_revision, |
1583 | + change=change_dict[child_revision], contents_changed_rev=contents_changed_rev) |
1584 | file_list.append(file) |
1585 | |
1586 | if sort_type == 'filename': |
1587 | file_list.sort(key=lambda x: x.filename.lower()) # case-insensitive |
1588 | elif sort_type == 'size': |
1589 | - file_list.sort(key=lambda x: x.size) |
1590 | + def size_key(x): |
1591 | + if x.size is None: |
1592 | + return -1 |
1593 | + return x.size |
1594 | + file_list.sort(key=size_key) |
1595 | elif sort_type == 'date': |
1596 | - file_list.sort(key=lambda x: x.change.date) |
1597 | + file_list.sort(key=lambda x: x.change.date, reverse=True) |
1598 | |
1599 | - # Always sort directories first. |
1600 | - file_list.sort(key=lambda x: x.kind != 'directory') |
1601 | + if sort_type != 'date': |
1602 | + # Don't always sort directories first. |
1603 | + file_list.sort(key=lambda x: x.kind != 'directory') |
1604 | |
1605 | return file_list |
1606 | |
1607 | @@ -137,14 +150,14 @@ |
1608 | updir = dirname(path) |
1609 | |
1610 | if not is_null_rev(revid): |
1611 | - change = history.get_changes([ revid ])[0] |
1612 | + change = history.get_changes([revid])[0] |
1613 | # If we're looking at the tip, use head: in the URL instead |
1614 | if revid == branch.last_revision(): |
1615 | revno_url = 'head:' |
1616 | else: |
1617 | revno_url = history.get_revno(revid) |
1618 | history.add_branch_nicks(change) |
1619 | - filelist = self.get_filelist(rev_tree.inventory, path, sort_type, revno_url) |
1620 | + filelist = self.get_filelist(rev_tree, path, sort_type, revno_url) |
1621 | |
1622 | else: |
1623 | start_revid = None |
1624 | |
1625 | === modified file 'loggerhead/controllers/revision_ui.py' |
1626 | --- loggerhead/controllers/revision_ui.py 2015-03-19 14:48:47 +0000 |
1627 | +++ loggerhead/controllers/revision_ui.py 2019-09-18 16:50:15 +0000 |
1628 | @@ -18,24 +18,25 @@ |
1629 | # |
1630 | |
1631 | import simplejson |
1632 | -import urllib |
1633 | |
1634 | from paste.httpexceptions import HTTPServerError |
1635 | |
1636 | -from loggerhead import util |
1637 | -from loggerhead.controllers import TemplatedBranchView |
1638 | -from loggerhead.controllers.filediff_ui import diff_chunks_for_file |
1639 | +from breezy import urlutils |
1640 | + |
1641 | +from .. import util |
1642 | +from ..controllers import TemplatedBranchView |
1643 | +from ..controllers.filediff_ui import diff_chunks_for_file |
1644 | |
1645 | |
1646 | DEFAULT_LINE_COUNT_LIMIT = 3000 |
1647 | |
1648 | def dq(p): |
1649 | - return urllib.quote(urllib.quote(p, safe='')) |
1650 | + return urlutils.quote(urlutils.quote(p, safe='')) |
1651 | |
1652 | |
1653 | class RevisionUI(TemplatedBranchView): |
1654 | |
1655 | - template_path = 'loggerhead.templates.revision' |
1656 | + template_name = 'revision' |
1657 | supports_json = True |
1658 | |
1659 | def get_values(self, path, kwargs, headers): |
1660 | @@ -88,7 +89,7 @@ |
1661 | merged_in = None |
1662 | |
1663 | return { |
1664 | - 'revid': revid, |
1665 | + 'revid': revid.decode('utf-8'), |
1666 | 'change': change, |
1667 | 'file_changes': file_changes, |
1668 | 'merged_in': merged_in, |
1669 | |
1670 | === modified file 'loggerhead/controllers/revlog_ui.py' |
1671 | --- loggerhead/controllers/revlog_ui.py 2011-06-27 15:05:06 +0000 |
1672 | +++ loggerhead/controllers/revlog_ui.py 2019-09-18 16:50:15 +0000 |
1673 | @@ -1,17 +1,19 @@ |
1674 | import urllib |
1675 | |
1676 | -from loggerhead.controllers import TemplatedBranchView |
1677 | +from breezy import osutils, urlutils |
1678 | + |
1679 | +from ..controllers import TemplatedBranchView |
1680 | |
1681 | |
1682 | class RevLogUI(TemplatedBranchView): |
1683 | |
1684 | - template_path = 'loggerhead.templates.revlog' |
1685 | + template_name = 'revlog' |
1686 | supports_json = True |
1687 | |
1688 | def get_values(self, path, kwargs, headers): |
1689 | history = self._history |
1690 | |
1691 | - revid = urllib.unquote(self.args[0]) |
1692 | + revid = urlutils.unquote_to_bytes(osutils.safe_utf8(self.args[0])) |
1693 | |
1694 | change = history.get_changes([revid])[0] |
1695 | file_changes = history.get_file_changes(change) |
1696 | |
1697 | === modified file 'loggerhead/controllers/search_ui.py' |
1698 | --- loggerhead/controllers/search_ui.py 2012-02-08 01:50:02 +0000 |
1699 | +++ loggerhead/controllers/search_ui.py 2019-09-18 16:50:15 +0000 |
1700 | @@ -16,8 +16,8 @@ |
1701 | # Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
1702 | # |
1703 | |
1704 | -from loggerhead.controllers import TemplatedBranchView |
1705 | -from loggerhead import search |
1706 | +from ..controllers import TemplatedBranchView |
1707 | +from .. import search |
1708 | |
1709 | |
1710 | class SearchUI(TemplatedBranchView): |
1711 | @@ -26,7 +26,7 @@ |
1712 | Class to output progressive search result terms. |
1713 | """ |
1714 | |
1715 | - template_path = 'loggerhead.templates.search' |
1716 | + template_name = 'search' |
1717 | |
1718 | def get_values(self, path, kwargs, response): |
1719 | """ |
1720 | |
1721 | === modified file 'loggerhead/controllers/view_ui.py' |
1722 | --- loggerhead/controllers/view_ui.py 2012-03-22 14:09:52 +0000 |
1723 | +++ loggerhead/controllers/view_ui.py 2019-09-18 16:50:15 +0000 |
1724 | @@ -19,13 +19,16 @@ |
1725 | |
1726 | import os |
1727 | |
1728 | -from bzrlib.errors import ( |
1729 | +from breezy.errors import ( |
1730 | BinaryFile, |
1731 | NoSuchId, |
1732 | NoSuchRevision, |
1733 | ) |
1734 | -import bzrlib.textfile |
1735 | -import bzrlib.osutils |
1736 | +from breezy import ( |
1737 | + osutils, |
1738 | + urlutils, |
1739 | + ) |
1740 | +import breezy.textfile |
1741 | |
1742 | from paste.httpexceptions import ( |
1743 | HTTPBadRequest, |
1744 | @@ -34,38 +37,47 @@ |
1745 | HTTPServerError, |
1746 | ) |
1747 | |
1748 | -from loggerhead.controllers import TemplatedBranchView |
1749 | +from ..controllers import TemplatedBranchView |
1750 | try: |
1751 | - from loggerhead.highlight import highlight |
1752 | + from ..highlight import highlight |
1753 | except ImportError: |
1754 | highlight = None |
1755 | -from loggerhead import util |
1756 | +from .. import util |
1757 | |
1758 | |
1759 | class ViewUI(TemplatedBranchView): |
1760 | |
1761 | - template_path = 'loggerhead.templates.view' |
1762 | - |
1763 | + template_name = 'view' |
1764 | + |
1765 | def tree_for(self, file_id, revid): |
1766 | - file_revid = self._history.get_inventory(revid)[file_id].revision |
1767 | + if not isinstance(file_id, bytes): |
1768 | + raise TypeError(file_id) |
1769 | + if not isinstance(revid, bytes): |
1770 | + raise TypeError(revid) |
1771 | + rev_tree = self._history.revision_tree(revid) |
1772 | + file_revid = rev_tree.get_file_revision(rev_tree.id2path(file_id)) |
1773 | return self._history._branch.repository.revision_tree(file_revid) |
1774 | |
1775 | def text_lines(self, file_id, revid): |
1776 | - file_name = os.path.basename(self._history.get_path(revid, file_id)) |
1777 | - |
1778 | + path = self._history.get_path(revid, file_id) |
1779 | + file_name = os.path.basename(path) |
1780 | + |
1781 | tree = self.tree_for(file_id, revid) |
1782 | - file_text = tree.get_file_text(file_id) |
1783 | + file_text = tree.get_file_text(path) |
1784 | + |
1785 | encoding = 'utf-8' |
1786 | try: |
1787 | - file_text = file_text.decode(encoding) |
1788 | + file_text.decode(encoding) |
1789 | except UnicodeDecodeError: |
1790 | encoding = 'iso-8859-15' |
1791 | - file_text = file_text.decode(encoding) |
1792 | - |
1793 | - file_lines = bzrlib.osutils.split_lines(file_text) |
1794 | - # This can throw bzrlib.errors.BinaryFile (which our caller catches). |
1795 | - bzrlib.textfile.check_text_lines(file_lines) |
1796 | - |
1797 | + file_text.decode(encoding) |
1798 | + |
1799 | + file_lines = osutils.split_lines(file_text) |
1800 | + # This can throw breezy.errors.BinaryFile (which our caller catches). |
1801 | + breezy.textfile.check_text_lines(file_lines) |
1802 | + |
1803 | + file_text = file_text.decode(encoding) |
1804 | + |
1805 | if highlight is not None: |
1806 | hl_lines = highlight(file_name, file_text, encoding) |
1807 | # highlight strips off extra newlines at the end of the file. |
1808 | @@ -73,8 +85,8 @@ |
1809 | hl_lines.extend([u''] * extra_lines) |
1810 | else: |
1811 | hl_lines = map(util.html_escape, file_lines) |
1812 | - |
1813 | - return hl_lines; |
1814 | + |
1815 | + return hl_lines |
1816 | |
1817 | def file_contents(self, file_id, revid): |
1818 | try: |
1819 | @@ -89,8 +101,9 @@ |
1820 | history = self._history |
1821 | branch = history._branch |
1822 | revid = self.get_revid() |
1823 | - revid = history.fix_revid(revid) |
1824 | file_id = kwargs.get('file_id', None) |
1825 | + if file_id is not None: |
1826 | + file_id = urlutils.unquote_to_bytes(osutils.safe_utf8(file_id)) |
1827 | if (file_id is None) and (path is None): |
1828 | raise HTTPBadRequest('No file_id or filename ' |
1829 | 'provided to view') |
1830 | @@ -119,20 +132,15 @@ |
1831 | self._branch.is_root, |
1832 | 'files')) |
1833 | |
1834 | + tree = history.revision_tree(revid) |
1835 | + |
1836 | # Create breadcrumb trail for the path within the branch |
1837 | - try: |
1838 | - inv = history.get_inventory(revid) |
1839 | - except: |
1840 | - self.log.exception('Exception fetching changes') |
1841 | - raise HTTPServerError('Could not fetch changes') |
1842 | - branch_breadcrumbs = util.branch_breadcrumbs(path, inv, 'files') |
1843 | + branch_breadcrumbs = util.branch_breadcrumbs(path, tree, 'files') |
1844 | |
1845 | - try: |
1846 | - file = inv[file_id] |
1847 | - except NoSuchId: |
1848 | + if not tree.has_id(file_id): |
1849 | raise HTTPNotFound() |
1850 | |
1851 | - if file.kind == "directory": |
1852 | + if tree.kind(path) == "directory": |
1853 | raise HTTPMovedPermanently(self._branch.context_url(['/files', revno_url, path])) |
1854 | |
1855 | # no navbar for revisions |
1856 | |
1857 | === modified file 'loggerhead/daemon.py' |
1858 | --- loggerhead/daemon.py 2009-05-13 14:03:48 +0000 |
1859 | +++ loggerhead/daemon.py 2019-09-18 16:50:15 +0000 |
1860 | @@ -16,7 +16,7 @@ |
1861 | |
1862 | try: |
1863 | pid = os.fork() |
1864 | - except OSError, e: |
1865 | + except OSError as e: |
1866 | raise Exception("%s [%d]" % (e.strerror, e.errno)) |
1867 | |
1868 | if pid == 0: # The first child. |
1869 | @@ -24,7 +24,7 @@ |
1870 | |
1871 | try: |
1872 | pid = os.fork() # Fork a second child. |
1873 | - except OSError, e: |
1874 | + except OSError as e: |
1875 | raise Exception("%s [%d]" % (e.strerror, e.errno)) |
1876 | |
1877 | if pid == 0: # The second child. |
1878 | |
1879 | === removed file 'loggerhead/exporter.py' |
1880 | --- loggerhead/exporter.py 2011-11-24 07:46:41 +0000 |
1881 | +++ loggerhead/exporter.py 1970-01-01 00:00:00 +0000 |
1882 | @@ -1,60 +0,0 @@ |
1883 | -# Copyright (C) 2011 Canonical Ltd |
1884 | -# |
1885 | -# This program is free software; you can redistribute it and/or modify |
1886 | -# it under the terms of the GNU General Public License as published by |
1887 | -# the Free Software Foundation; either version 2 of the License, or |
1888 | -# (at your option) any later version. |
1889 | -# |
1890 | -# This program is distributed in the hope that it will be useful, |
1891 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1892 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1893 | -# GNU General Public License for more details. |
1894 | -# |
1895 | -"""Exports an archive from a bazaar branch""" |
1896 | - |
1897 | -from bzrlib.export import get_export_generator |
1898 | - |
1899 | - |
1900 | -class ExporterFileObject(object): |
1901 | - """Shim that accumulates temporarily written out data. |
1902 | - |
1903 | - There are python tarfile classes that want to write to a file like object. |
1904 | - We want to stream data. But wsgi assumes it can pull data from the |
1905 | - handler, rather than having bytes pushed. |
1906 | - |
1907 | - So this class holds the data temporarily, until it is pulled. It |
1908 | - should never buffer everything because as soon as a chunk is produced, |
1909 | - wsgi will be given the chance to take it. |
1910 | - """ |
1911 | - |
1912 | - def __init__(self): |
1913 | - self._buffer = [] |
1914 | - |
1915 | - def write(self, s): |
1916 | - self._buffer.append(s) |
1917 | - |
1918 | - def get_buffer(self): |
1919 | - try: |
1920 | - return ''.join(self._buffer) |
1921 | - finally: |
1922 | - self._buffer = [] |
1923 | - |
1924 | - def close(self): |
1925 | - pass |
1926 | - |
1927 | - |
1928 | -def export_archive(history, root, revid, archive_format): |
1929 | - """Export tree contents to an archive |
1930 | - |
1931 | - :param history: Instance of history to export |
1932 | - :param root: Root location inside the archive. |
1933 | - :param revid: Revision to export |
1934 | - :param archive_format: Format of the archive, eg 'tar.gz'. |
1935 | - """ |
1936 | - fileobj = ExporterFileObject() |
1937 | - tree = history._branch.repository.revision_tree(revid) |
1938 | - for _ in get_export_generator(tree=tree, root=root, fileobj=fileobj, |
1939 | - format=archive_format): |
1940 | - yield fileobj.get_buffer() |
1941 | - # Might have additonal contents written |
1942 | - yield fileobj.get_buffer() |
1943 | |
1944 | === modified file 'loggerhead/highlight.py' |
1945 | --- loggerhead/highlight.py 2012-02-08 01:50:02 +0000 |
1946 | +++ loggerhead/highlight.py 2019-09-18 16:50:15 +0000 |
1947 | @@ -16,7 +16,7 @@ |
1948 | # Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
1949 | # |
1950 | |
1951 | -import bzrlib.osutils |
1952 | +import breezy.osutils |
1953 | import cgi |
1954 | |
1955 | from pygments import highlight as _highlight_func |
1956 | @@ -37,7 +37,7 @@ |
1957 | """ |
1958 | |
1959 | if len(text) > MAX_HIGHLIGHT_SIZE: |
1960 | - return map(cgi.escape, bzrlib.osutils.split_lines(text)) |
1961 | + return map(cgi.escape, breezy.osutils.split_lines(text)) |
1962 | |
1963 | formatter = HtmlFormatter(style=style, nowrap=True, classprefix='pyg-') |
1964 | |
1965 | @@ -50,6 +50,6 @@ |
1966 | lexer = TextLexer(encoding=encoding) |
1967 | |
1968 | hl_lines = _highlight_func(text, lexer, formatter) |
1969 | - hl_lines = bzrlib.osutils.split_lines(hl_lines) |
1970 | + hl_lines = breezy.osutils.split_lines(hl_lines) |
1971 | |
1972 | return hl_lines |
1973 | |
1974 | === modified file 'loggerhead/history.py' |
1975 | --- loggerhead/history.py 2016-03-30 06:18:39 +0000 |
1976 | +++ loggerhead/history.py 2019-09-18 16:50:15 +0000 |
1977 | @@ -35,23 +35,28 @@ |
1978 | import threading |
1979 | import tarfile |
1980 | |
1981 | -from bzrlib import tag |
1982 | -import bzrlib.branch |
1983 | -import bzrlib.delta |
1984 | -import bzrlib.errors |
1985 | -import bzrlib.foreign |
1986 | -import bzrlib.revision |
1987 | +from breezy import tag |
1988 | +import breezy.branch |
1989 | +import breezy.delta |
1990 | +import breezy.errors |
1991 | +import breezy.foreign |
1992 | +import breezy.osutils |
1993 | +import breezy.revision |
1994 | +from breezy.sixish import ( |
1995 | + text_type, |
1996 | + viewvalues, |
1997 | + ) |
1998 | |
1999 | -from loggerhead import search |
2000 | -from loggerhead import util |
2001 | -from loggerhead.wholehistory import compute_whole_history_data |
2002 | +from . import search |
2003 | +from . import util |
2004 | +from .wholehistory import compute_whole_history_data |
2005 | |
2006 | |
2007 | def is_branch(folder): |
2008 | try: |
2009 | - bzrlib.branch.Branch.open(folder) |
2010 | + breezy.branch.Branch.open(folder) |
2011 | return True |
2012 | - except: |
2013 | + except breezy.errors.NotBranchError: |
2014 | return False |
2015 | |
2016 | |
2017 | @@ -108,20 +113,22 @@ |
2018 | |
2019 | class FileChangeReporter(object): |
2020 | |
2021 | - def __init__(self, old_inv, new_inv): |
2022 | + def __init__(self, old_tree, new_tree): |
2023 | self.added = [] |
2024 | self.modified = [] |
2025 | self.renamed = [] |
2026 | self.removed = [] |
2027 | self.text_changes = [] |
2028 | - self.old_inv = old_inv |
2029 | - self.new_inv = new_inv |
2030 | + self.old_tree = old_tree |
2031 | + self.new_tree = new_tree |
2032 | |
2033 | - def revid(self, inv, file_id): |
2034 | + def revid(self, tree, file_id): |
2035 | try: |
2036 | - return inv[file_id].revision |
2037 | - except bzrlib.errors.NoSuchId: |
2038 | - return 'null:' |
2039 | + path = tree.id2path(file_id) |
2040 | + except breezy.errors.NoSuchId: |
2041 | + return b'null:' |
2042 | + else: |
2043 | + return tree.get_file_revision(path) |
2044 | |
2045 | def report(self, file_id, paths, versioned, renamed, modified, |
2046 | exe_change, kind): |
2047 | @@ -132,8 +139,8 @@ |
2048 | filename = rich_filename(paths[1], kind[1]) |
2049 | self.text_changes.append(util.Container( |
2050 | filename=filename, file_id=file_id, |
2051 | - old_revision=self.revid(self.old_inv, file_id), |
2052 | - new_revision=self.revid(self.new_inv, file_id))) |
2053 | + old_revision=self.revid(self.old_tree, file_id), |
2054 | + new_revision=self.revid(self.new_tree, file_id))) |
2055 | if versioned == 'added': |
2056 | self.added.append(util.Container( |
2057 | filename=rich_filename(paths[1], kind), kind=kind[1])) |
2058 | @@ -299,7 +306,7 @@ |
2059 | |
2060 | @property |
2061 | def has_revisions(self): |
2062 | - return not bzrlib.revision.is_null(self.last_revid) |
2063 | + return not breezy.revision.is_null(self.last_revid) |
2064 | |
2065 | def get_config(self): |
2066 | return self._branch.get_config() |
2067 | @@ -320,7 +327,7 @@ |
2068 | if revid_list is None: |
2069 | # Just yield the mainline, starting at start_revid |
2070 | revid = start_revid |
2071 | - is_null = bzrlib.revision.is_null |
2072 | + is_null = breezy.revision.is_null |
2073 | while not is_null(revid): |
2074 | yield revid |
2075 | parents = self._rev_info[self._rev_indices[revid]][2] |
2076 | @@ -341,7 +348,7 @@ |
2077 | i += 1 |
2078 | return r |
2079 | while revid_set: |
2080 | - if bzrlib.revision.is_null(revid): |
2081 | + if breezy.revision.is_null(revid): |
2082 | return |
2083 | rev_introduced = introduced_revisions(revid) |
2084 | matching = rev_introduced.intersection(revid_set) |
2085 | @@ -360,11 +367,11 @@ |
2086 | possible_keys = [(file_id, revid) for revid in self._rev_indices] |
2087 | get_parent_map = self._branch.repository.texts.get_parent_map |
2088 | # We chunk the requests as this works better with GraphIndex. |
2089 | - # See _filter_revisions_touching_file_id in bzrlib/log.py |
2090 | + # See _filter_revisions_touching_file_id in breezy/log.py |
2091 | # for more information. |
2092 | revids = [] |
2093 | chunk_size = 1000 |
2094 | - for start in xrange(0, len(possible_keys), chunk_size): |
2095 | + for start in range(0, len(possible_keys), chunk_size): |
2096 | next_keys = possible_keys[start:start + chunk_size] |
2097 | revids += [k[1] for k in get_parent_map(next_keys)] |
2098 | del possible_keys, next_keys |
2099 | @@ -405,8 +412,6 @@ |
2100 | # ignore the passed-in revid_list |
2101 | revid = self.fix_revid(query) |
2102 | if revid is not None: |
2103 | - if isinstance(revid, unicode): |
2104 | - revid = revid.encode('utf-8') |
2105 | changes = self.get_changes([revid]) |
2106 | if (changes is not None) and (len(changes) > 0): |
2107 | return [revid] |
2108 | @@ -448,13 +453,17 @@ |
2109 | # if a "revid" is actually a dotted revno, convert it to a revid |
2110 | if revid is None: |
2111 | return revid |
2112 | + if not isinstance(revid, (str, text_type)): |
2113 | + raise TypeError(revid) |
2114 | if revid == 'head:': |
2115 | return self.last_revid |
2116 | try: |
2117 | if self.revno_re.match(revid): |
2118 | revid = self._revno_revid[revid] |
2119 | except KeyError: |
2120 | - raise bzrlib.errors.NoSuchRevision(self._branch_nick, revid) |
2121 | + raise breezy.errors.NoSuchRevision(self._branch_nick, revid) |
2122 | + if not isinstance(revid, bytes): |
2123 | + revid = revid.encode('utf-8') |
2124 | return revid |
2125 | |
2126 | def get_file_view(self, revid, file_id): |
2127 | @@ -564,16 +573,13 @@ |
2128 | # search index. |
2129 | return None, None, [] |
2130 | |
2131 | - def get_inventory(self, revid): |
2132 | - if revid not in self._inventory_cache: |
2133 | - self._inventory_cache[revid] = ( |
2134 | - self._branch.repository.get_inventory(revid)) |
2135 | - return self._inventory_cache[revid] |
2136 | + def revision_tree(self, revid): |
2137 | + return self._branch.repository.revision_tree(revid) |
2138 | |
2139 | def get_path(self, revid, file_id): |
2140 | if (file_id is None) or (file_id == ''): |
2141 | return '' |
2142 | - path = self.get_inventory(revid).id2path(file_id) |
2143 | + path = self.revision_tree(revid).id2path(file_id) |
2144 | if (len(path) > 0) and not path.startswith('/'): |
2145 | path = '/' + path |
2146 | return path |
2147 | @@ -581,7 +587,7 @@ |
2148 | def get_file_id(self, revid, path): |
2149 | if (len(path) > 0) and not path.startswith('/'): |
2150 | path = '/' + path |
2151 | - return self.get_inventory(revid).path2id(path) |
2152 | + return self.revision_tree(revid).path2id(path) |
2153 | |
2154 | def get_merge_point_list(self, revid): |
2155 | """ |
2156 | @@ -618,7 +624,7 @@ |
2157 | else: |
2158 | d[revnos] = (revnolast, revid) |
2159 | |
2160 | - return [revid for (_, revid) in d.itervalues()] |
2161 | + return [revid for (_, revid) in viewvalues(d)] |
2162 | |
2163 | def add_branch_nicks(self, change): |
2164 | """ |
2165 | @@ -631,7 +637,7 @@ |
2166 | for p in change.merge_points: |
2167 | fetch_set.add(p.revid) |
2168 | p_changes = self.get_changes(list(fetch_set)) |
2169 | - p_change_dict = dict([(c.revid, c) for c in p_changes]) |
2170 | + p_change_dict = {c.revid: c for c in p_changes} |
2171 | for p in change.parents: |
2172 | if p.revid in p_change_dict: |
2173 | p.branch_nick = p_change_dict[p.revid].branch_nick |
2174 | @@ -648,6 +654,9 @@ |
2175 | |
2176 | Revisions not present and NULL_REVISION will be ignored. |
2177 | """ |
2178 | + for revid in revid_list: |
2179 | + if not isinstance(revid, bytes): |
2180 | + raise TypeError(revid_list) |
2181 | changes = self.get_changes_uncached(revid_list) |
2182 | if len(changes) == 0: |
2183 | return changes |
2184 | @@ -674,8 +683,8 @@ |
2185 | |
2186 | def get_changes_uncached(self, revid_list): |
2187 | # FIXME: deprecated method in getting a null revision |
2188 | - revid_list = filter(lambda revid: not bzrlib.revision.is_null(revid), |
2189 | - revid_list) |
2190 | + revid_list = list(filter(lambda revid: not breezy.revision.is_null(revid), |
2191 | + revid_list)) |
2192 | parent_map = self._branch.repository.get_graph().get_parent_map( |
2193 | revid_list) |
2194 | # We need to return the answer in the same order as the input, |
2195 | @@ -688,7 +697,7 @@ |
2196 | |
2197 | def _change_from_revision(self, revision): |
2198 | """ |
2199 | - Given a bzrlib Revision, return a processed "change" for use in |
2200 | + Given a breezy Revision, return a processed "change" for use in |
2201 | templates. |
2202 | """ |
2203 | message, short_message = clean_message(revision.message) |
2204 | @@ -712,6 +721,7 @@ |
2205 | 'revid': revision.revision_id, |
2206 | 'date': datetime.datetime.fromtimestamp(revision.timestamp), |
2207 | 'utc_date': datetime.datetime.utcfromtimestamp(revision.timestamp), |
2208 | + 'timestamp': revision.timestamp, |
2209 | 'committer': revision.committer, |
2210 | 'authors': revision.get_apparent_authors(), |
2211 | 'branch_nick': revision.properties.get('branch-nick', None), |
2212 | @@ -722,15 +732,15 @@ |
2213 | 'bugs': [bug.split()[0] for bug in revision.properties.get('bugs', '').splitlines()], |
2214 | 'tags': revtags, |
2215 | } |
2216 | - if isinstance(revision, bzrlib.foreign.ForeignRevision): |
2217 | + if isinstance(revision, breezy.foreign.ForeignRevision): |
2218 | foreign_revid, mapping = ( |
2219 | revision.foreign_revid, revision.mapping) |
2220 | - elif ":" in revision.revision_id: |
2221 | + elif b":" in revision.revision_id: |
2222 | try: |
2223 | foreign_revid, mapping = \ |
2224 | - bzrlib.foreign.foreign_vcs_registry.parse_revision_id( |
2225 | + breezy.foreign.foreign_vcs_registry.parse_revision_id( |
2226 | revision.revision_id) |
2227 | - except bzrlib.errors.InvalidRevisionId: |
2228 | + except breezy.errors.InvalidRevisionId: |
2229 | foreign_revid = None |
2230 | mapping = None |
2231 | else: |
2232 | @@ -744,7 +754,7 @@ |
2233 | if entry.parents: |
2234 | old_revid = entry.parents[0].revid |
2235 | else: |
2236 | - old_revid = bzrlib.revision.NULL_REVISION |
2237 | + old_revid = breezy.revision.NULL_REVISION |
2238 | return self.file_changes_for_revision_ids(old_revid, entry.revid) |
2239 | |
2240 | def add_changes(self, entry): |
2241 | @@ -753,13 +763,17 @@ |
2242 | |
2243 | def get_file(self, file_id, revid): |
2244 | """Returns (path, filename, file contents)""" |
2245 | - inv = self.get_inventory(revid) |
2246 | - inv_entry = inv[file_id] |
2247 | - rev_tree = self._branch.repository.revision_tree(inv_entry.revision) |
2248 | - path = inv.id2path(file_id) |
2249 | - if not path.startswith('/'): |
2250 | + if not isinstance(file_id, bytes): |
2251 | + raise TypeError(file_id) |
2252 | + if not isinstance(revid, bytes): |
2253 | + raise TypeError(revid) |
2254 | + rev_tree = self._branch.repository.revision_tree(revid) |
2255 | + path = rev_tree.id2path(file_id) |
2256 | + display_path = path |
2257 | + if not display_path.startswith('/'): |
2258 | path = '/' + path |
2259 | - return path, inv_entry.name, rev_tree.get_file_text(file_id) |
2260 | + return (display_path, breezy.osutils.basename(path), |
2261 | + rev_tree.get_file_text(path)) |
2262 | |
2263 | def file_changes_for_revision_ids(self, old_revid, new_revid): |
2264 | """ |
2265 | @@ -775,17 +789,17 @@ |
2266 | text_changes: list((filename, file_id)), |
2267 | """ |
2268 | repo = self._branch.repository |
2269 | - if (bzrlib.revision.is_null(old_revid) or |
2270 | - bzrlib.revision.is_null(new_revid) or |
2271 | - old_revid == new_revid): |
2272 | + if (breezy.revision.is_null(old_revid) or |
2273 | + breezy.revision.is_null(new_revid) or |
2274 | + old_revid == new_revid): |
2275 | old_tree, new_tree = map( |
2276 | repo.revision_tree, [old_revid, new_revid]) |
2277 | else: |
2278 | old_tree, new_tree = repo.revision_trees([old_revid, new_revid]) |
2279 | |
2280 | - reporter = FileChangeReporter(old_tree.inventory, new_tree.inventory) |
2281 | + reporter = FileChangeReporter(old_tree, new_tree) |
2282 | |
2283 | - bzrlib.delta.report_changes(new_tree.iter_changes(old_tree), reporter) |
2284 | + breezy.delta.report_changes(new_tree.iter_changes(old_tree), reporter) |
2285 | |
2286 | return util.Container( |
2287 | added=sorted(reporter.added, key=lambda x: x.filename), |
2288 | |
2289 | === modified file 'loggerhead/load_test.py' |
2290 | --- loggerhead/load_test.py 2012-02-08 01:50:02 +0000 |
2291 | +++ loggerhead/load_test.py 2019-09-18 16:50:15 +0000 |
2292 | @@ -65,17 +65,21 @@ |
2293 | |
2294 | import threading |
2295 | import time |
2296 | -import Queue |
2297 | +try: |
2298 | + from queue import Queue, Empty |
2299 | +except ImportError: # Python < 3 |
2300 | + from Queue import Queue, Empty |
2301 | |
2302 | import simplejson |
2303 | |
2304 | -from bzrlib import ( |
2305 | +from breezy import ( |
2306 | errors, |
2307 | transport, |
2308 | urlutils, |
2309 | ) |
2310 | +from breezy.sixish import viewvalues |
2311 | |
2312 | -# This code will be doing multi-threaded requests against bzrlib.transport |
2313 | +# This code will be doing multi-threaded requests against breezy.transport |
2314 | # code. We want to make sure to load everything ahead of time, so we don't get |
2315 | # lazy-import failures |
2316 | _ = transport.get_transport('http://example.com') |
2317 | @@ -96,7 +100,7 @@ |
2318 | |
2319 | def __init__(self, identifier, blocking_time=1.0, _queue_size=1): |
2320 | self.identifier = identifier |
2321 | - self.queue = Queue.Queue(_queue_size) |
2322 | + self.queue = Queue(_queue_size) |
2323 | self.start_time = self.end_time = None |
2324 | self.stats = [] |
2325 | self.blocking_time = blocking_time |
2326 | @@ -118,7 +122,7 @@ |
2327 | while not stop_event.isSet(): |
2328 | try: |
2329 | self.step_next() |
2330 | - except Queue.Empty: |
2331 | + except Empty: |
2332 | pass |
2333 | |
2334 | def process(self, url): |
2335 | @@ -189,7 +193,7 @@ |
2336 | |
2337 | def finish_queues(self): |
2338 | """Wait for all queues of all children to finish.""" |
2339 | - for h, t in self._threads.itervalues(): |
2340 | + for h, t in viewvalues(self._threads): |
2341 | h.queue.join() |
2342 | |
2343 | def stop_and_join(self): |
2344 | @@ -198,7 +202,7 @@ |
2345 | This will stop even if workers still have work items. |
2346 | """ |
2347 | self.stop_event.set() |
2348 | - for h, t in self._threads.itervalues(): |
2349 | + for h, t in viewvalues(self._threads): |
2350 | # Signal the queue that it should stop blocking, we don't have to |
2351 | # wait for the queue to empty, because we may see stop_event before |
2352 | # we see the <noop> |
2353 | |
2354 | === modified file 'loggerhead/lsprof.py' |
2355 | --- loggerhead/lsprof.py 2009-07-07 23:52:24 +0000 |
2356 | +++ loggerhead/lsprof.py 2019-09-18 16:50:15 +0000 |
2357 | @@ -6,7 +6,10 @@ |
2358 | # instead of just the Stats object |
2359 | |
2360 | import sys |
2361 | -import thread |
2362 | +try: |
2363 | + from threading import get_ident |
2364 | +except ImportError: # python < 3 |
2365 | + from thread import get_ident |
2366 | import threading |
2367 | from _lsprof import Profiler, profiler_entry |
2368 | |
2369 | @@ -19,7 +22,7 @@ |
2370 | # we lose the first profile point for a new thread in order to trampoline |
2371 | # a new Profile object into place |
2372 | global _g_threadmap |
2373 | - thr = thread.get_ident() |
2374 | + thr = get_ident() |
2375 | _g_threadmap[thr] = p = Profiler() |
2376 | # this overrides our sys.setprofile hook: |
2377 | p.enable(subcalls=True, builtins=True) |
2378 | |
2379 | === modified file 'loggerhead/main.py' |
2380 | --- loggerhead/main.py 2012-02-08 01:50:02 +0000 |
2381 | +++ loggerhead/main.py 2019-09-18 16:50:15 +0000 |
2382 | @@ -21,25 +21,26 @@ |
2383 | import os |
2384 | import sys |
2385 | |
2386 | -from bzrlib.plugin import load_plugins |
2387 | +from breezy.plugin import load_plugins |
2388 | +from breezy.transport import location_to_url |
2389 | |
2390 | from paste import httpserver |
2391 | from paste.httpexceptions import HTTPExceptionHandler, HTTPInternalServerError |
2392 | from paste.translogger import TransLogger |
2393 | |
2394 | -from loggerhead import __version__ |
2395 | -from loggerhead.apps.transport import ( |
2396 | +from . import __version__ |
2397 | +from .apps.transport import ( |
2398 | BranchesFromTransportRoot, UserBranchesFromTransportRoot) |
2399 | -from loggerhead.config import LoggerheadConfig |
2400 | -from loggerhead.util import Reloader |
2401 | -from loggerhead.apps.error import ErrorHandlerApp |
2402 | - |
2403 | - |
2404 | -def get_config_and_path(args): |
2405 | +from .config import LoggerheadConfig |
2406 | +from .util import Reloader |
2407 | +from .apps.error import ErrorHandlerApp |
2408 | + |
2409 | + |
2410 | +def get_config_and_base(args): |
2411 | config = LoggerheadConfig(args) |
2412 | |
2413 | if config.get_option('show_version'): |
2414 | - print "loggerhead %s" % (__version__,) |
2415 | + print("loggerhead %s" % (__version__,)) |
2416 | sys.exit(0) |
2417 | |
2418 | if config.arg_count > 1: |
2419 | @@ -50,6 +51,8 @@ |
2420 | else: |
2421 | base = '.' |
2422 | |
2423 | + base = location_to_url(base) |
2424 | + |
2425 | if not config.get_option('allow_writes'): |
2426 | base = 'readonly+' + base |
2427 | |
2428 | @@ -70,9 +73,9 @@ |
2429 | else: |
2430 | if config.get_option('log_folder'): |
2431 | logfile_path = os.path.join( |
2432 | - config.get_option('log_folder'), 'serve-branches.log') |
2433 | + config.get_option('log_folder'), 'loggerhead-serve.log') |
2434 | else: |
2435 | - logfile_path = 'serve-branches.log' |
2436 | + logfile_path = 'loggerhead-serve.log' |
2437 | handler = logging.FileHandler(logfile_path, 'a') |
2438 | formatter = logging.Formatter('%(asctime)s %(levelname)-8s %(name)s:' |
2439 | ' %(message)s') |
2440 | @@ -92,9 +95,9 @@ |
2441 | return logger |
2442 | |
2443 | |
2444 | -def make_app_for_config_and_path(config, base): |
2445 | +def make_app_for_config_and_base(config, base): |
2446 | if config.get_option('trunk_dir') and not config.get_option('user_dirs'): |
2447 | - print "--trunk-dir is only valid with --user-dirs" |
2448 | + print("--trunk-dir is only valid with --user-dirs") |
2449 | sys.exit(1) |
2450 | |
2451 | if config.get_option('reload'): |
2452 | @@ -105,7 +108,7 @@ |
2453 | |
2454 | if config.get_option('user_dirs'): |
2455 | if not config.get_option('trunk_dir'): |
2456 | - print "You didn't specify a directory for the trunk directories." |
2457 | + print("You didn't specify a directory for the trunk directories.") |
2458 | sys.exit(1) |
2459 | app = UserBranchesFromTransportRoot(base, config) |
2460 | else: |
2461 | @@ -141,6 +144,9 @@ |
2462 | raise exc |
2463 | return app(environ, start_response) |
2464 | return wrapped |
2465 | + logging.warning( |
2466 | + 'PasteDeploy not available; unable to support ' |
2467 | + 'access through a reverse proxy.') |
2468 | app = check_not_proxied(app) |
2469 | else: |
2470 | app = PrefixMiddleware(app, prefix=prefix) |
2471 | @@ -155,9 +161,9 @@ |
2472 | def main(args): |
2473 | load_plugins() |
2474 | |
2475 | - config, path = get_config_and_path(args) |
2476 | + config, base = get_config_and_base(args) |
2477 | |
2478 | - app = make_app_for_config_and_path(config, path) |
2479 | + app = make_app_for_config_and_base(config, base) |
2480 | |
2481 | if not config.get_option('user_port'): |
2482 | port = '8080' |
2483 | @@ -184,6 +190,6 @@ |
2484 | elif protocol == 'ajp': |
2485 | from flup.server.ajp import WSGIServer |
2486 | else: |
2487 | - print 'Unknown protocol: %s.' % (protocol) |
2488 | + print('Unknown protocol: %s.' % (protocol)) |
2489 | sys.exit(1) |
2490 | WSGIServer(app, bindAddress=(host, int(port))).run() |
2491 | |
2492 | === modified file 'loggerhead/middleware/profile.py' |
2493 | --- loggerhead/middleware/profile.py 2009-10-17 08:47:38 +0000 |
2494 | +++ loggerhead/middleware/profile.py 2019-09-18 16:50:15 +0000 |
2495 | @@ -2,7 +2,7 @@ |
2496 | |
2497 | import threading |
2498 | |
2499 | -from bzrlib.lsprof import profile |
2500 | +from breezy.lsprof import profile |
2501 | |
2502 | |
2503 | class LSProfMiddleware(object): |
2504 | |
2505 | === modified file 'loggerhead/search.py' |
2506 | --- loggerhead/search.py 2012-02-08 01:50:02 +0000 |
2507 | +++ loggerhead/search.py 2019-09-18 16:50:15 +0000 |
2508 | @@ -24,9 +24,9 @@ |
2509 | if _mod_index is not None: |
2510 | return |
2511 | try: |
2512 | - from bzrlib.plugins.search import errors |
2513 | - from bzrlib.plugins.search import index as _mod_index |
2514 | - from bzrlib.plugins.search.index import FileTextHit, RevisionHit |
2515 | + from breezy.plugins.search import errors |
2516 | + from breezy.plugins.search import index as _mod_index |
2517 | + from breezy.plugins.search.index import FileTextHit, RevisionHit |
2518 | except ImportError: |
2519 | _mod_index = None |
2520 | |
2521 | |
2522 | === modified file 'loggerhead/static/css/global.css' |
2523 | --- loggerhead/static/css/global.css 2015-03-17 11:38:32 +0000 |
2524 | +++ loggerhead/static/css/global.css 2019-09-18 16:50:15 +0000 |
2525 | @@ -230,11 +230,11 @@ |
2526 | } |
2527 | th.datecell, |
2528 | td.date { |
2529 | - width: 180px; |
2530 | + width: 100px; |
2531 | } |
2532 | th.timedate, |
2533 | td.timedate2 { |
2534 | - width: 80px; |
2535 | + width: 60px; |
2536 | } |
2537 | th.downloadcell, |
2538 | td.downr { |
2539 | |
2540 | === modified file 'loggerhead/static/css/view.css' |
2541 | --- loggerhead/static/css/view.css 2019-06-20 16:18:17 +0000 |
2542 | +++ loggerhead/static/css/view.css 2019-09-18 16:50:15 +0000 |
2543 | @@ -5,8 +5,7 @@ |
2544 | } |
2545 | .viewRev { |
2546 | border-right: none; |
2547 | - white-space: nowrap; |
2548 | - width: 1px; |
2549 | + width: 20%; |
2550 | padding: .3em .6em; |
2551 | } |
2552 | .viewComm, |
2553 | |
2554 | === modified file 'loggerhead/templatefunctions.py' |
2555 | --- loggerhead/templatefunctions.py 2012-05-02 22:23:34 +0000 |
2556 | +++ loggerhead/templatefunctions.py 2019-09-18 16:50:15 +0000 |
2557 | @@ -15,15 +15,18 @@ |
2558 | # |
2559 | |
2560 | import os |
2561 | -import urllib |
2562 | |
2563 | import pkg_resources |
2564 | |
2565 | -import bzrlib |
2566 | +import breezy |
2567 | +from breezy import urlutils |
2568 | |
2569 | -import loggerhead |
2570 | -from loggerhead.zptsupport import zpt |
2571 | -from loggerhead.util import html_format |
2572 | +from . import ( |
2573 | + __version__, |
2574 | + __revision__, |
2575 | + ) |
2576 | +from .zptsupport import zpt |
2577 | +from .util import html_format |
2578 | |
2579 | |
2580 | templatefunctions = {} |
2581 | @@ -52,18 +55,18 @@ |
2582 | if currently_showing and filename == currently_showing: |
2583 | return html_format( |
2584 | '<b><a href="#%s">%s</a></b>', |
2585 | - urllib.quote(filename.encode('utf-8')), filename) |
2586 | + urlutils.quote(filename), filename) |
2587 | else: |
2588 | return revision_link( |
2589 | url, entry.revno, filename, |
2590 | - '#' + urllib.quote(filename.encode('utf-8'))) |
2591 | + '#' + urlutils.quote(filename)) |
2592 | else: |
2593 | def file_link(filename): |
2594 | return html_format( |
2595 | '<a href="%s%s" title="View changes to %s in revision %s">' |
2596 | '%s</a>', |
2597 | url(['/revision', entry.revno]), |
2598 | - '#' + urllib.quote(filename.encode('utf-8')), |
2599 | + '#' + urlutils.quote(filename), |
2600 | filename, entry.revno, filename) |
2601 | return _pt('revisionfilechanges').expand( |
2602 | entry=entry, file_changes=file_changes, file_link=file_link, **templatefunctions) |
2603 | @@ -71,7 +74,7 @@ |
2604 | |
2605 | @templatefunc |
2606 | def revisioninfo(url, branch, entry, file_changes=None, currently_showing=None, merged_in=None): |
2607 | - from loggerhead import util |
2608 | + from . import util |
2609 | return _pt('revisioninfo').expand( |
2610 | url=url, change=entry, branch=branch, util=util, |
2611 | file_changes=file_changes, currently_showing=currently_showing, |
2612 | @@ -142,11 +145,11 @@ |
2613 | |
2614 | @templatefunc |
2615 | def loggerhead_version(): |
2616 | - return loggerhead.__version__ |
2617 | - |
2618 | + return __version__ |
2619 | + |
2620 | @templatefunc |
2621 | def loggerhead_revision(): |
2622 | - return loggerhead.__revision__ |
2623 | + return __revision__ |
2624 | |
2625 | _cached_generator_string = None |
2626 | |
2627 | @@ -159,13 +162,13 @@ |
2628 | # TODO: Errors -- e.g. from a missing/invalid __version__ attribute, or |
2629 | # ValueError accessing Distribution.version -- should be non-fatal. |
2630 | |
2631 | - versions.append(('Loggerhead', loggerhead.__version__)) |
2632 | + versions.append(('Loggerhead', __version__)) |
2633 | |
2634 | import sys |
2635 | - python_version = bzrlib._format_version_tuple(sys.version_info) |
2636 | + python_version = breezy._format_version_tuple(sys.version_info) |
2637 | versions.append(('Python', python_version)) |
2638 | |
2639 | - versions.append(('Bazaar', bzrlib.__version__)) |
2640 | + versions.append(('Breezy', breezy.__version__)) |
2641 | |
2642 | Paste = pkg_resources.get_distribution('Paste') |
2643 | versions.append(('Paste', Paste.version)) |
2644 | @@ -188,11 +191,11 @@ |
2645 | versions.append(('Pygments', pygments.__version__)) |
2646 | |
2647 | try: |
2648 | - from bzrlib.plugins import search |
2649 | + from breezy.plugins import search |
2650 | except ImportError: |
2651 | pass |
2652 | else: |
2653 | - bzr_search_version = bzrlib._format_version_tuple( |
2654 | + bzr_search_version = breezy._format_version_tuple( |
2655 | search.version_info) |
2656 | versions.append(('bzr-search', bzr_search_version)) |
2657 | |
2658 | |
2659 | === modified file 'loggerhead/templates/directory.pt' |
2660 | --- loggerhead/templates/directory.pt 2011-02-17 19:51:25 +0000 |
2661 | +++ loggerhead/templates/directory.pt 2019-09-18 16:50:15 +0000 |
2662 | @@ -2,6 +2,11 @@ |
2663 | <html xmlns="http://www.w3.org/1999/xhtml" > |
2664 | <head> |
2665 | <title tal:content="string:Browsing ${name}"></title> |
2666 | + <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> |
2667 | + <meta name="generator" |
2668 | + tal:attributes="content generator_string" /> |
2669 | + |
2670 | + |
2671 | <link rel="stylesheet" |
2672 | tal:attributes="href python:static_url('/static/css/global.css')" /> |
2673 | <link rel="shortcut icon" |
2674 | @@ -17,16 +22,16 @@ |
2675 | <div > |
2676 | <table id="logentries"> |
2677 | <tr class="logheader"> |
2678 | - <th class="summarycell" colspan="2">Filename</th> |
2679 | - <th class="datecell">Latest Rev</th> |
2680 | + <th class="datecell">Filename</th> |
2681 | + <th class="timedate">Latest Rev</th> |
2682 | <th class="datecell">Last Changed</th> |
2683 | + <th class="datecell">Committer</th> |
2684 | + <th class="summarycell">Comment</th> |
2685 | </tr> |
2686 | |
2687 | <tr class="blueRow0" tal:condition="python:name != '/'"> |
2688 | - <td class="icocell"> |
2689 | + <td class="summcell" colspan="5"> |
2690 | <a href="../"><img tal:attributes="src python:static_url('/static/images/ico_folder_up.gif')" /></a> |
2691 | - </td> |
2692 | - <td class="summcell" colspan="3"> |
2693 | <a href="../">..</a> |
2694 | </td> |
2695 | </tr> |
2696 | @@ -34,37 +39,42 @@ |
2697 | |
2698 | <tal:branch-row tal:condition="dir/branch"> |
2699 | <tr tal:attributes="class string:blueRow${dir/parity}"> |
2700 | - <td class="icocell"> |
2701 | + <td class="date"> |
2702 | <a tal:attributes="href string:${dir/dirname}/files"> |
2703 | <img tal:attributes="src python:static_url('/static/images/ico_branch.gif')" alt="Branch" /> |
2704 | </a> |
2705 | - </td> |
2706 | - <td class="autcell"> |
2707 | <a tal:attributes="href string:${dir/dirname}/files" tal:content="dir/dirname" /></td> |
2708 | <td class="date"> |
2709 | <a tal:attributes="href string:${dir/dirname}/revision/${dir/branch/revno}; |
2710 | title string:Show revision ${dir/branch/revno}" |
2711 | tal:content="dir/branch/revno"></a> |
2712 | </td> |
2713 | - <td class="date" tal:content="python:util.date_time(dir.last_change)"></td> |
2714 | + <td class="date" tal:content="python:util._approximatedate(dir.last_change_time)"></td> |
2715 | + <td class="date" tal:content="python:util.hide_email(dir.last_revision.committer) if dir.last_revision is not None else 'Nobody'"></td> |
2716 | + <td class="autcell" tal:content="python:dir.last_revision.message[:50] if dir.last_revision is not None else ''"></td> |
2717 | </tr> |
2718 | + |
2719 | </tal:branch-row> |
2720 | <tal:non-branch-row tal:condition="not:dir/branch"> |
2721 | <tr tal:attributes="class string:blueRow${dir/parity}"> |
2722 | - <td class="icocell"> |
2723 | + <td class="date"> |
2724 | <a tal:attributes="href string:${dir/dirname}/"> |
2725 | <img tal:attributes="src python:static_url('/static/images/ico_folder.gif')" alt="Folder" /> |
2726 | </a> |
2727 | - </td> |
2728 | - <td class="autcell"> |
2729 | <a tal:attributes="href string:${dir/dirname}/" tal:content="dir/dirname" /></td> |
2730 | <td class="date"></td> |
2731 | - <td class="date" tal:content="dir/last_change"></td> |
2732 | + <td class="date" colspan="4" tal:content="dir/last_change"></td> |
2733 | </tr> |
2734 | </tal:non-branch-row> |
2735 | </tal:block> |
2736 | </table> |
2737 | </div> |
2738 | + |
2739 | + <p id="footer" class="fl"> |
2740 | + Loggerhead is a web-based interface for <a href="https://www.breezy-vcs.org/">Breezy</a> |
2741 | + <br /> |
2742 | + Version: <tal:version content="loggerhead_version" /><span tal:condition="loggerhead_revision">, Revision: <tal:revision content="loggerhead_revision" /></span> |
2743 | + </p> |
2744 | </div> |
2745 | </body> |
2746 | </html> |
2747 | |
2748 | === modified file 'loggerhead/templates/inventory.pt' |
2749 | --- loggerhead/templates/inventory.pt 2012-02-02 07:42:24 +0000 |
2750 | +++ loggerhead/templates/inventory.pt 2019-09-18 16:50:15 +0000 |
2751 | @@ -30,7 +30,7 @@ |
2752 | <tal:no-link condition="not: branch/branch_link"> |
2753 | <span metal:use-macro="breadcrumbs/directory"></span> |
2754 | </tal:no-link> |
2755 | - <span>: <span metal:use-macro="breadcrumbs/branch" /> (revision <tal:revno content="change/revno"></tal:revno>)</span> |
2756 | + <span>: <span metal:use-macro="breadcrumbs/branch" /> (Revision <tal:revno content="change/revno"></tal:revno>)</span> |
2757 | </div> |
2758 | </tal:block> |
2759 | |
2760 | @@ -54,10 +54,12 @@ |
2761 | |
2762 | <table id="logentries"> |
2763 | <tr class="logheader"> |
2764 | - <th class="summarycell"><a tal:attributes="href python:url(['/files', revid], sort='filename')">Filename</a></th> |
2765 | - <th class="datecell">Latest Rev</th> |
2766 | - <th class="datecell"><a tal:attributes="href python:url(['/files', revid], sort='date')">Last Changed</a></th> |
2767 | - <th class="timedate"><a tal:attributes="href python:url(['/files', revid], sort='size')">Size</a></th> |
2768 | + <th class="datecell"><a tal:attributes="href python:branch.sort_url(['/files', revid], sort='filename')">Filename</a></th> |
2769 | + <th class="timedate">Latest Rev</th> |
2770 | + <th class="datecell"><a tal:attributes="href python:branch.sort_url(['/files', revid], sort='date')">Last Changed</a></th> |
2771 | + <th class="datecell">Committer</th> |
2772 | + <th class="summarycell">Comment</th> |
2773 | + <th class="timedate"><a tal:attributes="href python:branch.sort_url(['/files', revid], sort='size')">Size</a></th> |
2774 | <th class="expandcell"></th> |
2775 | <th class="expandcell"></th> |
2776 | </tr> |
2777 | @@ -68,11 +70,15 @@ |
2778 | <img tal:attributes="src python:branch.static_url('/static/images/ico_folder_up.gif')" />..</a> |
2779 | </td> |
2780 | </tr> |
2781 | + <tr class="blueRow0" tal:condition="python:updir is None"> |
2782 | + <td class="summcell" colspan="6"> |
2783 | + <a tal:attributes="href python:'/'.join(branch.friendly_name.split('/')[:-1])"><img tal:attributes="src python:static_url('/static/images/ico_folder_up.gif')" />..</a></td> |
2784 | + </tr> |
2785 | |
2786 | <!-- Show this if it's a directory --> |
2787 | <tal:block repeat="file filelist"> |
2788 | <tr tal:attributes="class string:blueRow${repeat/file/even}" tal:condition="python:file.kind=='directory'"> |
2789 | - <td class="autcell"><a tal:attributes="href python:url(['/files', revno_url, file.absolutepath])"> |
2790 | + <td class="date"><a tal:attributes="href python:url(['/files', revno_url, file.absolutepath])"> |
2791 | <img tal:attributes="src python:branch.static_url('/static/images/ico_folder.gif'); |
2792 | title string:Go to ${file/filename}" /> |
2793 | </a> |
2794 | @@ -84,8 +90,10 @@ |
2795 | title string:Show revision ${file/change/revno}" |
2796 | tal:content="file/change/revno"></a> |
2797 | </td> |
2798 | - <td class="date" tal:content="python:util.date_time(file.change.utc_date)"></td> |
2799 | - <td class="timedate2"></td> |
2800 | + <td class="date" tal:content="python:util._approximatedate(file.change.utc_date)"></td> |
2801 | + <td class="date" tal:content="python:util.hide_email(file.change.committer)"></td> |
2802 | + <td class="autcell" tal:content="python:file.change.comment[:50]"></td> |
2803 | + <td class="timedate2"></td><!-- not showing sizes of folders --> |
2804 | <td class="expcell"><a tal:attributes="href python:url(['/changes'], start_revid=start_revid, filter_file_id=file.file_id); |
2805 | title string:Show revision ${file/change/revno}"> |
2806 | <img tal:attributes="src python:branch.static_url('/static/images/ico_planilla.gif')" alt="Diff" /> |
2807 | @@ -96,7 +104,7 @@ |
2808 | |
2809 | <!-- Show this if it's a symlink --> |
2810 | <tr tal:attributes="class string:blueRow${repeat/file/even}" tal:condition="python:file.kind=='symlink'"> |
2811 | - <td class="autcell"><a tal:attributes="href python:url(['/view', change.revno, file.absolutepath])"> |
2812 | + <td class="date"><a tal:attributes="href python:url(['/view', change.revno, file.absolutepath])"> |
2813 | <img tal:attributes="src python:branch.static_url('/static/images/ico_file_flecha.gif')" alt="Symlink" /> |
2814 | </a> |
2815 | |
2816 | @@ -107,7 +115,9 @@ |
2817 | title string:Show revision ${file/change/revno}" |
2818 | tal:content="file/change/revno"></a> |
2819 | </td> |
2820 | - <td class="date" tal:content="python:util.date_time(file.change.utc_date)"></td> |
2821 | + <td class="date" tal:content="python:util._approximatedate(file.change.utc_date)"></td> |
2822 | + <td class="date" tal:content="python:util.hide_email(file.change.committer)"></td> |
2823 | + <td class="autcell" tal:content="python:file.change.comment[:50]"></td> |
2824 | <td class="timedate2">.</td> |
2825 | <td class="expcell"><a tal:attributes="href python:url(['/changes'], start_revid=start_revid, filter_file_id=file.file_id); |
2826 | title string:Show revision ${file/change/revno}"> |
2827 | @@ -120,7 +130,7 @@ |
2828 | |
2829 | <!-- Show this if it's a regular file --> |
2830 | <tr tal:attributes="class string:blueRow${repeat/file/even}" tal:condition="python:file.kind=='file'"> |
2831 | - <td class="autcell"><a tal:attributes="href python:url(['/view', revno_url, file.absolutepath])"> |
2832 | + <td class="date"><a tal:attributes="href python:url(['/view', revno_url, file.absolutepath])"> |
2833 | <img tal:attributes="src python:branch.static_url('/static/images/ico_file.gif'); |
2834 | title string:View ${file/filename}" |
2835 | tal:condition="python:file.executable is False" /> |
2836 | @@ -136,7 +146,10 @@ |
2837 | title string:Show revision ${file/change/revno}" |
2838 | tal:content="file/change/revno"></a> |
2839 | </td> |
2840 | - <td class="date" tal:content="python:util.date_time(file.change.utc_date)"></td> |
2841 | + <td class="date" tal:content="python:util._approximatedate(file.change.utc_date)"></td> |
2842 | + <td class="date" tal:content="python:util.hide_email(file.change.committer)"></td> |
2843 | + <td class="autcell" tal:content="python:file.change.comment[:50]"></td> |
2844 | + |
2845 | <td class="timedate2" tal:content="python:util.human_size(file.size)"></td> |
2846 | <td class="expcell"><a tal:attributes="href python:url(['/view', revno_url, file.absolutepath]); |
2847 | title string:View ${file/filename}"> |
2848 | @@ -144,7 +157,7 @@ |
2849 | </a> |
2850 | </td> |
2851 | <td class="expcell"> |
2852 | - <a tal:attributes="href python:url(['/download', file.revid, file.file_id, file.filename]); |
2853 | + <a tal:attributes="href python:url(['/download', file.revid.decode('utf-8'), file.file_id.decode('utf-8'), file.filename]); |
2854 | title string:Download ${file/filename} at revision ${file/change/revno}"> |
2855 | <img tal:attributes="src python:branch.static_url('/static/images/ico_file_download.gif')" alt="Download File" /> |
2856 | </a> |
2857 | |
2858 | === modified file 'loggerhead/templates/macros.pt' |
2859 | --- loggerhead/templates/macros.pt 2012-05-03 21:39:50 +0000 |
2860 | +++ loggerhead/templates/macros.pt 2019-09-18 16:50:15 +0000 |
2861 | @@ -60,7 +60,7 @@ |
2862 | <div metal:define-slot="content"></div> |
2863 | |
2864 | <p id="footer" class="fl"> |
2865 | - Loggerhead is a web-based interface for <a href="http://bazaar-vcs.org/">Bazaar</a> branches |
2866 | + Loggerhead is a web-based interface for <a href="https://www.breezy-vcs.org/">Breezy</a> |
2867 | <br /> |
2868 | Version: <tal:version content="loggerhead_version" /><span tal:condition="loggerhead_revision">, Revision: <tal:revision content="loggerhead_revision" /></span> |
2869 | </p> |
2870 | |
2871 | === modified file 'loggerhead/tests/__init__.py' |
2872 | --- loggerhead/tests/__init__.py 2011-09-08 00:33:28 +0000 |
2873 | +++ loggerhead/tests/__init__.py 2019-09-18 16:50:15 +0000 |
2874 | @@ -15,8 +15,13 @@ |
2875 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
2876 | |
2877 | |
2878 | -def load_tests(standard_tests, module, loader): |
2879 | - standard_tests.addTests(loader.loadTestsFromModuleNames([ |
2880 | +from __future__ import absolute_import |
2881 | + |
2882 | + |
2883 | +def test_suite(): |
2884 | + import unittest |
2885 | + loader = unittest.TestLoader() |
2886 | + return loader.loadTestsFromNames([ |
2887 | (__name__ + '.' + x) for x in [ |
2888 | 'test_controllers', |
2889 | 'test_corners', |
2890 | @@ -27,5 +32,4 @@ |
2891 | 'test_revision_ui', |
2892 | 'test_templating', |
2893 | 'test_util', |
2894 | - ]])) |
2895 | - return standard_tests |
2896 | + ]]) |
2897 | |
2898 | === modified file 'loggerhead/tests/fixtures.py' |
2899 | --- loggerhead/tests/fixtures.py 2011-11-25 02:28:56 +0000 |
2900 | +++ loggerhead/tests/fixtures.py 2019-09-18 16:50:15 +0000 |
2901 | @@ -37,7 +37,7 @@ |
2902 | self.testcase.build_tree_contents( |
2903 | (filename, self.filecontents) for filename in filenames) |
2904 | for filename in filenames: |
2905 | - self.tree.add(filename, '%s-id' % filename) |
2906 | + self.tree.add(filename, ('%s-id' % filename).encode('utf-8')) |
2907 | self.fileid = self.tree.path2id('myfilename') |
2908 | self.msg = 'a very exciting commit message <' |
2909 | self.revid = self.tree.commit(message=self.msg) |
2910 | |
2911 | === modified file 'loggerhead/tests/test_controllers.py' |
2912 | --- loggerhead/tests/test_controllers.py 2016-09-04 15:13:21 +0000 |
2913 | +++ loggerhead/tests/test_controllers.py 2019-09-18 16:50:15 +0000 |
2914 | @@ -14,6 +14,8 @@ |
2915 | # along with this program; if not, write to the Free Software |
2916 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
2917 | |
2918 | +from __future__ import absolute_import |
2919 | + |
2920 | import tarfile |
2921 | import tempfile |
2922 | |
2923 | @@ -27,10 +29,10 @@ |
2924 | Mismatch, |
2925 | ) |
2926 | |
2927 | -from loggerhead.apps.branch import BranchWSGIApp |
2928 | -from loggerhead.controllers.annotate_ui import AnnotateUI |
2929 | -from loggerhead.controllers.inventory_ui import InventoryUI |
2930 | -from loggerhead.tests.test_simple import ( |
2931 | +from ..apps.branch import BranchWSGIApp |
2932 | +from ..controllers.annotate_ui import AnnotateUI |
2933 | +from ..controllers.inventory_ui import InventoryUI |
2934 | +from .test_simple import ( |
2935 | BasicTests, |
2936 | consume_app, |
2937 | TestWithSimpleTree, |
2938 | @@ -55,8 +57,8 @@ |
2939 | def test_get_filelist(self): |
2940 | bzrbranch, inv_ui = self.make_bzrbranch_and_inventory_ui_for_tree_shape( |
2941 | ['filename']) |
2942 | - inv = bzrbranch.repository.get_inventory(bzrbranch.last_revision()) |
2943 | - self.assertEqual(1, len(inv_ui.get_filelist(inv, '', 'filename', 'head'))) |
2944 | + revtree = bzrbranch.repository.revision_tree(bzrbranch.last_revision()) |
2945 | + self.assertEqual(1, len(inv_ui.get_filelist(revtree, '', 'filename', 'head'))) |
2946 | |
2947 | def test_smoke(self): |
2948 | bzrbranch, inv_ui = self.make_bzrbranch_and_inventory_ui_for_tree_shape( |
2949 | @@ -65,23 +67,29 @@ |
2950 | {'SCRIPT_NAME': '/files', 'PATH_INFO': ''}) |
2951 | self.assertEqual(('200 OK', [('Content-Type', 'text/html')], None), |
2952 | start) |
2953 | - self.assertContainsRe(content, 'filename') |
2954 | + self.assertContainsRe(content, b'filename') |
2955 | |
2956 | def test_no_content_for_HEAD(self): |
2957 | bzrbranch, inv_ui = self.make_bzrbranch_and_inventory_ui_for_tree_shape( |
2958 | ['filename']) |
2959 | start, content = consume_app(inv_ui, |
2960 | {'SCRIPT_NAME': '/files', 'PATH_INFO': '', |
2961 | - 'REQUEST_METHOD': 'HEAD'}) |
2962 | + 'REQUEST_METHOD': 'HEAD', |
2963 | + 'wsgi.url_scheme': 'http', |
2964 | + 'SERVER_NAME': 'localhost', |
2965 | + 'SERVER_PORT': '80'}) |
2966 | self.assertEqual(('200 OK', [('Content-Type', 'text/html')], None), |
2967 | start) |
2968 | - self.assertEqual('', content) |
2969 | + self.assertEqual(b'', content) |
2970 | |
2971 | def test_get_values_smoke(self): |
2972 | branch = self.make_bzrbranch_for_tree_shape(['a-file']) |
2973 | branch_app = self.make_branch_app(branch) |
2974 | env = {'SCRIPT_NAME': '', 'PATH_INFO': '/files', |
2975 | - 'REQUEST_METHOD': 'GET'} |
2976 | + 'REQUEST_METHOD': 'GET', |
2977 | + 'wsgi.url_scheme': 'http', |
2978 | + 'SERVER_NAME': 'localhost', |
2979 | + 'SERVER_PORT': '80'} |
2980 | inv_ui = branch_app.lookup_app(env) |
2981 | inv_ui.parse_args(env) |
2982 | values = inv_ui.get_values('', {}, {}) |
2983 | @@ -91,7 +99,10 @@ |
2984 | branch = self.make_bzrbranch_for_tree_shape(['a-file']) |
2985 | branch_app = self.make_branch_app(branch) |
2986 | env = {'SCRIPT_NAME': '', 'PATH_INFO': '/+json/files', |
2987 | - 'REQUEST_METHOD': 'GET'} |
2988 | + 'REQUEST_METHOD': 'GET', |
2989 | + 'wsgi.url_scheme': 'http', |
2990 | + 'SERVER_NAME': 'localhost', |
2991 | + 'SERVER_PORT': '80'} |
2992 | inv_ui = branch_app.lookup_app(env) |
2993 | self.assertOkJsonResponse(inv_ui, env) |
2994 | |
2995 | @@ -102,10 +113,10 @@ |
2996 | tree = self.make_branch_and_tree('.') |
2997 | self.build_tree_contents(shape1) |
2998 | tree.smart_add([]) |
2999 | - tree.commit('msg 1', rev_id='rev-1') |
3000 | + tree.commit('msg 1', rev_id=b'rev-1') |
3001 | self.build_tree_contents(shape2) |
3002 | tree.smart_add([]) |
3003 | - tree.commit('msg 2', rev_id='rev-2') |
3004 | + tree.commit('msg 2', rev_id=b'rev-2') |
3005 | branch = tree.branch |
3006 | self.addCleanup(branch.lock_read().unlock) |
3007 | return self.make_branch_app(branch) |
3008 | @@ -113,18 +124,24 @@ |
3009 | def test_get_values(self): |
3010 | branch_app = self.make_branch_app_for_revision_ui([], []) |
3011 | env = {'SCRIPT_NAME': '', 'PATH_INFO': '/revision/2', |
3012 | - 'REQUEST_METHOD': 'GET'} |
3013 | + 'REQUEST_METHOD': 'GET', |
3014 | + 'wsgi.url_scheme': 'http', |
3015 | + 'SERVER_NAME': 'localhost', |
3016 | + 'SERVER_PORT': '80'} |
3017 | rev_ui = branch_app.lookup_app(env) |
3018 | rev_ui.parse_args(env) |
3019 | self.assertIsInstance(rev_ui.get_values('', {}, []), dict) |
3020 | |
3021 | def test_add_template_values(self): |
3022 | branch_app = self.make_branch_app_for_revision_ui( |
3023 | - [('file', 'content\n')], [('file', 'new content\n')]) |
3024 | + [('file', b'content\n')], [('file', b'new content\n')]) |
3025 | env = {'SCRIPT_NAME': '/', |
3026 | 'PATH_INFO': '/revision/1/non-existent-file', |
3027 | 'QUERY_STRING':'start_revid=1', |
3028 | - 'REQUEST_METHOD': 'GET'} |
3029 | + 'REQUEST_METHOD': 'GET', |
3030 | + 'wsgi.url_scheme': 'http', |
3031 | + 'SERVER_NAME': 'localhost', |
3032 | + 'SERVER_PORT': '80'} |
3033 | revision_ui = branch_app.lookup_app(env) |
3034 | path = revision_ui.parse_args(env) |
3035 | values = revision_ui.get_values(path, revision_ui.kwargs, {}) |
3036 | @@ -133,11 +150,14 @@ |
3037 | |
3038 | def test_get_values_smoke(self): |
3039 | branch_app = self.make_branch_app_for_revision_ui( |
3040 | - [('file', 'content\n'), ('other-file', 'other\n')], |
3041 | - [('file', 'new content\n')]) |
3042 | + [('file', b'content\n'), ('other-file', b'other\n')], |
3043 | + [('file', b'new content\n')]) |
3044 | env = {'SCRIPT_NAME': '/', |
3045 | 'PATH_INFO': '/revision/head:', |
3046 | - 'REQUEST_METHOD': 'GET'} |
3047 | + 'REQUEST_METHOD': 'GET', |
3048 | + 'wsgi.url_scheme': 'http', |
3049 | + 'SERVER_NAME': 'localhost', |
3050 | + 'SERVER_PORT': '80'} |
3051 | revision_ui = branch_app.lookup_app(env) |
3052 | revision_ui.parse_args(env) |
3053 | values = revision_ui.get_values('', {}, {}) |
3054 | @@ -149,10 +169,13 @@ |
3055 | |
3056 | def test_json_render_smoke(self): |
3057 | branch_app = self.make_branch_app_for_revision_ui( |
3058 | - [('file', 'content\n'), ('other-file', 'other\n')], |
3059 | - [('file', 'new content\n')]) |
3060 | + [('file', b'content\n'), ('other-file', b'other\n')], |
3061 | + [('file', b'new content\n')]) |
3062 | env = {'SCRIPT_NAME': '', 'PATH_INFO': '/+json/revision/head:', |
3063 | - 'REQUEST_METHOD': 'GET'} |
3064 | + 'REQUEST_METHOD': 'GET', |
3065 | + 'wsgi.url_scheme': 'http', |
3066 | + 'SERVER_NAME': 'localhost', |
3067 | + 'SERVER_PORT': '80'} |
3068 | revision_ui = branch_app.lookup_app(env) |
3069 | self.assertOkJsonResponse(revision_ui, env) |
3070 | |
3071 | @@ -172,8 +195,8 @@ |
3072 | return AnnotateUI(branch_app, branch_app.get_history) |
3073 | |
3074 | def test_annotate_file(self): |
3075 | - history = [('rev1', 'old\nold\n', '.'), ('rev2', 'new\nold\n', '.')] |
3076 | - ann_ui = self.make_annotate_ui_for_file_history('file_id', history) |
3077 | + history = [(b'rev1', b'old\nold\n', '.'), (b'rev2', b'new\nold\n', '.')] |
3078 | + ann_ui = self.make_annotate_ui_for_file_history(b'file_id', history) |
3079 | # A lot of this state is set up by __call__, but we'll do it directly |
3080 | # here. |
3081 | ann_ui.args = ['rev2'] |
3082 | @@ -186,8 +209,8 @@ |
3083 | |
3084 | def test_annotate_empty_comment(self): |
3085 | # Testing empty comment handling without breaking |
3086 | - history = [('rev1', 'old\nold\n', '.'), ('rev2', 'new\nold\n', '')] |
3087 | - ann_ui = self.make_annotate_ui_for_file_history('file_id', history) |
3088 | + history = [(b'rev1', b'old\nold\n', '.'), (b'rev2', b'new\nold\n', '')] |
3089 | + ann_ui = self.make_annotate_ui_for_file_history(b'file_id', history) |
3090 | ann_ui.args = ['rev2'] |
3091 | ann_ui.get_values( |
3092 | 'filename', kwargs={'file_id': 'file_id'}, headers={}) |
3093 | @@ -195,8 +218,8 @@ |
3094 | def test_annotate_file_zero_sized(self): |
3095 | # Test against a zero-sized file without breaking. No annotation |
3096 | # must be present. |
3097 | - history = [('rev1', '', '.')] |
3098 | - ann_ui = self.make_annotate_ui_for_file_history('file_id', history) |
3099 | + history = [(b'rev1', b'', '.')] |
3100 | + ann_ui = self.make_annotate_ui_for_file_history(b'file_id', history) |
3101 | ann_ui.args = ['rev1'] |
3102 | annotate_info = ann_ui.get_values('filename', |
3103 | kwargs={'file_id': 'file_id'}, headers={}) |
3104 | @@ -204,15 +227,15 @@ |
3105 | self.assertEqual(0, len(annotated)) |
3106 | |
3107 | def test_annotate_nonexistent_file(self): |
3108 | - history = [('rev1', '', '.')] |
3109 | - ann_ui = self.make_annotate_ui_for_file_history('file_id', history) |
3110 | + history = [(b'rev1', b'', '.')] |
3111 | + ann_ui = self.make_annotate_ui_for_file_history(b'file_id', history) |
3112 | ann_ui.args = ['rev1'] |
3113 | self.assertRaises( |
3114 | HTTPNotFound, ann_ui.get_values, 'not-filename', {}, {}) |
3115 | |
3116 | def test_annotate_nonexistent_rev(self): |
3117 | - history = [('rev1', '', '.')] |
3118 | - ann_ui = self.make_annotate_ui_for_file_history('file_id', history) |
3119 | + history = [(b'rev1', b'', '.')] |
3120 | + ann_ui = self.make_annotate_ui_for_file_history(b'file_id', history) |
3121 | ann_ui.args = ['norev'] |
3122 | self.assertRaises( |
3123 | HTTPNotFound, ann_ui.get_values, 'not-filename', {}, {}) |
3124 | @@ -223,22 +246,25 @@ |
3125 | def make_branch_app_for_filediff_ui(self): |
3126 | builder = self.make_branch_builder('branch') |
3127 | builder.start_series() |
3128 | - builder.build_snapshot('rev-1-id', None, [ |
3129 | - ('add', ('', 'root-id', 'directory', '')), |
3130 | - ('add', ('filename', 'f-id', 'file', 'content\n'))], |
3131 | + rev1 = builder.build_snapshot(None, [ |
3132 | + ('add', ('', b'root-id', 'directory', '')), |
3133 | + ('add', ('filename', b'f-id', 'file', b'content\n'))], |
3134 | message="First commit.") |
3135 | - builder.build_snapshot('rev-2-id', None, [ |
3136 | - ('modify', ('f-id', 'new content\n'))]) |
3137 | + rev2 = builder.build_snapshot(None, [ |
3138 | + ('modify', ('filename', b'new content\n'))]) |
3139 | builder.finish_series() |
3140 | branch = builder.get_branch() |
3141 | self.addCleanup(branch.lock_read().unlock) |
3142 | - return self.make_branch_app(branch) |
3143 | + return self.make_branch_app(branch), (rev1, rev2) |
3144 | |
3145 | def test_get_values_smoke(self): |
3146 | - branch_app = self.make_branch_app_for_filediff_ui() |
3147 | + branch_app, (rev1, rev2) = self.make_branch_app_for_filediff_ui() |
3148 | env = {'SCRIPT_NAME': '/', |
3149 | - 'PATH_INFO': '/+filediff/rev-2-id/rev-1-id/f-id', |
3150 | - 'REQUEST_METHOD': 'GET'} |
3151 | + 'PATH_INFO': '/+filediff/%s/%s/f-id' % (rev2.decode('utf-8'), rev1.decode('utf-8')), |
3152 | + 'REQUEST_METHOD': 'GET', |
3153 | + 'wsgi.url_scheme': 'http', |
3154 | + 'SERVER_NAME': 'localhost', |
3155 | + 'SERVER_PORT': '80'} |
3156 | filediff_ui = branch_app.lookup_app(env) |
3157 | filediff_ui.parse_args(env) |
3158 | values = filediff_ui.get_values('', {}, {}) |
3159 | @@ -247,10 +273,13 @@ |
3160 | self.assertEqual('new content', chunks[0].diff[1].line) |
3161 | |
3162 | def test_json_render_smoke(self): |
3163 | - branch_app = self.make_branch_app_for_filediff_ui() |
3164 | + branch_app, (rev1, rev2) = self.make_branch_app_for_filediff_ui() |
3165 | env = {'SCRIPT_NAME': '/', |
3166 | - 'PATH_INFO': '/+json/+filediff/rev-2-id/rev-1-id/f-id', |
3167 | - 'REQUEST_METHOD': 'GET'} |
3168 | + 'PATH_INFO': '/+json/+filediff/%s/%s/f-id' % (rev2.decode('utf-8'), rev1.decode('utf-8')), |
3169 | + 'REQUEST_METHOD': 'GET', |
3170 | + 'wsgi.url_scheme': 'http', |
3171 | + 'SERVER_NAME': 'localhost', |
3172 | + 'SERVER_PORT': '80'} |
3173 | filediff_ui = branch_app.lookup_app(env) |
3174 | self.assertOkJsonResponse(filediff_ui, env) |
3175 | |
3176 | @@ -260,20 +289,23 @@ |
3177 | def make_branch_app_for_revlog_ui(self): |
3178 | builder = self.make_branch_builder('branch') |
3179 | builder.start_series() |
3180 | - builder.build_snapshot('rev-id', None, [ |
3181 | - ('add', ('', 'root-id', 'directory', '')), |
3182 | - ('add', ('filename', 'f-id', 'file', 'content\n'))], |
3183 | + revid = builder.build_snapshot(None, [ |
3184 | + ('add', ('', b'root-id', 'directory', '')), |
3185 | + ('add', ('filename', b'f-id', 'file', b'content\n'))], |
3186 | message="First commit.") |
3187 | builder.finish_series() |
3188 | branch = builder.get_branch() |
3189 | self.addCleanup(branch.lock_read().unlock) |
3190 | - return self.make_branch_app(branch) |
3191 | + return self.make_branch_app(branch), revid |
3192 | |
3193 | def test_get_values_smoke(self): |
3194 | - branch_app = self.make_branch_app_for_revlog_ui() |
3195 | + branch_app, revid = self.make_branch_app_for_revlog_ui() |
3196 | env = {'SCRIPT_NAME': '/', |
3197 | - 'PATH_INFO': '/+revlog/rev-id', |
3198 | - 'REQUEST_METHOD': 'GET'} |
3199 | + 'PATH_INFO': '/+revlog/%s' % revid.decode('utf-8'), |
3200 | + 'REQUEST_METHOD': 'GET', |
3201 | + 'wsgi.url_scheme': 'http', |
3202 | + 'SERVER_NAME': 'localhost', |
3203 | + 'SERVER_PORT': '80'} |
3204 | revlog_ui = branch_app.lookup_app(env) |
3205 | revlog_ui.parse_args(env) |
3206 | values = revlog_ui.get_values('', {}, {}) |
3207 | @@ -281,9 +313,12 @@ |
3208 | self.assertEqual(values['entry'].comment, "First commit.") |
3209 | |
3210 | def test_json_render_smoke(self): |
3211 | - branch_app = self.make_branch_app_for_revlog_ui() |
3212 | - env = {'SCRIPT_NAME': '', 'PATH_INFO': '/+json/+revlog/rev-id', |
3213 | - 'REQUEST_METHOD': 'GET'} |
3214 | + branch_app, revid = self.make_branch_app_for_revlog_ui() |
3215 | + env = {'SCRIPT_NAME': '', 'PATH_INFO': '/+json/+revlog/%s' % revid.decode('utf-8'), |
3216 | + 'REQUEST_METHOD': 'GET', |
3217 | + 'wsgi.url_scheme': 'http', |
3218 | + 'SERVER_NAME': 'localhost', |
3219 | + 'SERVER_PORT': '80'} |
3220 | revlog_ui = branch_app.lookup_app(env) |
3221 | self.assertOkJsonResponse(revlog_ui, env) |
3222 | |
3223 | @@ -295,7 +330,10 @@ |
3224 | # A hook that returns None doesn't influence the searching for |
3225 | # a controller. |
3226 | env = {'SCRIPT_NAME': '', 'PATH_INFO': '/custom', |
3227 | - 'REQUEST_METHOD': 'GET'} |
3228 | + 'REQUEST_METHOD': 'GET', |
3229 | + 'wsgi.url_scheme': 'http', |
3230 | + 'SERVER_NAME': 'localhost', |
3231 | + 'SERVER_PORT': '80'} |
3232 | myhook = lambda app, environ: None |
3233 | branch = self.make_branch('.') |
3234 | self.addCleanup(branch.lock_read().unlock) |
3235 | @@ -308,7 +346,10 @@ |
3236 | def test_working_hook(self): |
3237 | # A hook can provide an app to use for a particular request. |
3238 | env = {'SCRIPT_NAME': '', 'PATH_INFO': '/custom', |
3239 | - 'REQUEST_METHOD': 'GET'} |
3240 | + 'REQUEST_METHOD': 'GET', |
3241 | + 'wsgi.url_scheme': 'http', |
3242 | + 'SERVER_NAME': 'localhost', |
3243 | + 'SERVER_PORT': '80'} |
3244 | myhook = lambda app, environ: "I am hooked" |
3245 | branch = self.make_branch('.') |
3246 | self.addCleanup(branch.lock_read().unlock) |
3247 | @@ -348,7 +389,7 @@ |
3248 | app = self.setUpLoggerhead() |
3249 | response = app.get('/download/1/myfilename-id/myfilename') |
3250 | self.assertEqual( |
3251 | - 'some\nmultiline\ndata\nwith<htmlspecialchars\n', response.body) |
3252 | + b'some\nmultiline\ndata\nwith<htmlspecialchars\n', response.body) |
3253 | self.assertThat( |
3254 | response, |
3255 | MatchesDownloadHeaders('myfilename', 'application/octet-stream')) |
3256 | |
3257 | === modified file 'loggerhead/tests/test_corners.py' |
3258 | --- loggerhead/tests/test_corners.py 2009-04-02 20:32:12 +0000 |
3259 | +++ loggerhead/tests/test_corners.py 2019-09-18 16:50:15 +0000 |
3260 | @@ -1,6 +1,8 @@ |
3261 | +from __future__ import absolute_import |
3262 | + |
3263 | import os |
3264 | |
3265 | -from loggerhead.tests.test_simple import BasicTests |
3266 | +from .test_simple import BasicTests |
3267 | |
3268 | |
3269 | class TestCornerCases(BasicTests): |
3270 | @@ -26,19 +28,19 @@ |
3271 | self.addFileAndCommit('myfilename', msg) |
3272 | |
3273 | # Make a commit that changes the execute bit of 'myfilename'. |
3274 | - os.chmod('myfilename', 0755) |
3275 | + os.chmod('myfilename', 0o755) |
3276 | newrevid = self.tree.commit(message='make something executable') |
3277 | |
3278 | # Check that it didn't break things. |
3279 | app = self.setUpLoggerhead() |
3280 | - res = app.get('/revision/'+newrevid) |
3281 | - res.mustcontain('executable') |
3282 | + res = app.get('/revision/'+newrevid.decode('utf-8')) |
3283 | + res.mustcontain(b'executable') |
3284 | |
3285 | def test_revision_escapes_commit_message(self): |
3286 | """XXX.""" |
3287 | self.createBranch() |
3288 | |
3289 | - msg = '<b>hi</b>' |
3290 | + msg = b'<b>hi</b>' |
3291 | self.addFileAndCommit('myfilename', msg) |
3292 | app = self.setUpLoggerhead() |
3293 | res = app.get('/revision/1') |
3294 | |
3295 | === modified file 'loggerhead/tests/test_history.py' |
3296 | --- loggerhead/tests/test_history.py 2011-03-25 13:09:10 +0000 |
3297 | +++ loggerhead/tests/test_history.py 2019-09-18 16:50:15 +0000 |
3298 | @@ -17,16 +17,16 @@ |
3299 | |
3300 | """Direct tests of the loggerhead/history.py module""" |
3301 | |
3302 | -from bzrlib.foreign import ( |
3303 | +from breezy.foreign import ( |
3304 | ForeignRevision, |
3305 | ForeignVcs, |
3306 | VcsMapping, |
3307 | ) |
3308 | |
3309 | from datetime import datetime |
3310 | -from bzrlib import tag, tests |
3311 | +from breezy import tag, tests |
3312 | |
3313 | -from loggerhead import history as _mod_history |
3314 | +from .. import history as _mod_history |
3315 | |
3316 | |
3317 | class TestCaseWithExamples(tests.TestCaseWithMemoryTransport): |
3318 | @@ -40,26 +40,27 @@ |
3319 | # rev-1 |
3320 | builder = self.make_branch_builder('branch') |
3321 | builder.start_series() |
3322 | - builder.build_snapshot('rev-1', None, [ |
3323 | - ('add', ('', 'root-id', 'directory', None))]) |
3324 | - builder.build_snapshot('rev-2', ['rev-1'], []) |
3325 | - builder.build_snapshot('rev-3', ['rev-2'], []) |
3326 | + rev1 = builder.build_snapshot(None, [ |
3327 | + ('add', ('', b'root-id', 'directory', None))]) |
3328 | + rev2 = builder.build_snapshot([rev1], []) |
3329 | + rev3 = builder.build_snapshot([rev2], []) |
3330 | builder.finish_series() |
3331 | b = builder.get_branch() |
3332 | self.addCleanup(b.lock_read().unlock) |
3333 | - return _mod_history.History(b, {}) |
3334 | + return _mod_history.History(b, {}), [rev1, rev2, rev3] |
3335 | |
3336 | def make_long_linear_ancestry(self): |
3337 | builder = self.make_branch_builder('branch') |
3338 | + revs = [] |
3339 | builder.start_series() |
3340 | - builder.build_snapshot('A', None, [ |
3341 | - ('add', ('', 'root-id', 'directory', None))]) |
3342 | + revs.append(builder.build_snapshot(None, [ |
3343 | + ('add', ('', b'root-id', 'directory', None))])) |
3344 | for r in "BCDEFGHIJKLMNOPQRSTUVWXYZ": |
3345 | - builder.build_snapshot(r, None, []) |
3346 | + revs.append(builder.build_snapshot(None, [])) |
3347 | builder.finish_series() |
3348 | b = builder.get_branch() |
3349 | self.addCleanup(b.lock_read().unlock) |
3350 | - return _mod_history.History(b, {}) |
3351 | + return _mod_history.History(b, {}), revs |
3352 | |
3353 | def make_merged_ancestry(self): |
3354 | # Time goes up |
3355 | @@ -70,14 +71,14 @@ |
3356 | # rev-1 |
3357 | builder = self.make_branch_builder('branch') |
3358 | builder.start_series() |
3359 | - builder.build_snapshot('rev-1', None, [ |
3360 | - ('add', ('', 'root-id', 'directory', None))]) |
3361 | - builder.build_snapshot('rev-2', ['rev-1'], []) |
3362 | - builder.build_snapshot('rev-3', ['rev-1', 'rev-2'], []) |
3363 | + rev1 = builder.build_snapshot(None, [ |
3364 | + ('add', ('', b'root-id', 'directory', None))]) |
3365 | + rev2 = builder.build_snapshot([rev1], []) |
3366 | + rev3 = builder.build_snapshot([rev1, rev2], []) |
3367 | builder.finish_series() |
3368 | b = builder.get_branch() |
3369 | self.addCleanup(b.lock_read().unlock) |
3370 | - return _mod_history.History(b, {}) |
3371 | + return _mod_history.History(b, {}), [rev1, rev2, rev3] |
3372 | |
3373 | def make_deep_merged_ancestry(self): |
3374 | # Time goes up |
3375 | @@ -92,17 +93,18 @@ |
3376 | # A |
3377 | builder = self.make_branch_builder('branch') |
3378 | builder.start_series() |
3379 | - builder.build_snapshot('A', None, [ |
3380 | - ('add', ('', 'root-id', 'directory', None))]) |
3381 | - builder.build_snapshot('B', ['A'], []) |
3382 | - builder.build_snapshot('C', ['A'], []) |
3383 | - builder.build_snapshot('D', ['C'], []) |
3384 | - builder.build_snapshot('E', ['C', 'D'], []) |
3385 | - builder.build_snapshot('F', ['B', 'E'], []) |
3386 | + rev_a = builder.build_snapshot(None, [ |
3387 | + ('add', ('', b'root-id', 'directory', None))]) |
3388 | + rev_b = builder.build_snapshot([rev_a], []) |
3389 | + rev_c = builder.build_snapshot([rev_a], []) |
3390 | + rev_d = builder.build_snapshot([rev_c], []) |
3391 | + rev_e = builder.build_snapshot([rev_c, rev_d], []) |
3392 | + rev_f = builder.build_snapshot([rev_b, rev_e], []) |
3393 | builder.finish_series() |
3394 | b = builder.get_branch() |
3395 | self.addCleanup(b.lock_read().unlock) |
3396 | - return _mod_history.History(b, {}) |
3397 | + return (_mod_history.History(b, {}), |
3398 | + [rev_a, rev_b, rev_c, rev_d, rev_e, rev_f]) |
3399 | |
3400 | def assertRevidsFrom(self, expected, history, search_revs, tip_rev): |
3401 | self.assertEqual(expected, |
3402 | @@ -136,59 +138,58 @@ |
3403 | class TestHistoryGetRevidsFrom(TestCaseWithExamples): |
3404 | |
3405 | def test_get_revids_from_simple_mainline(self): |
3406 | - history = self.make_linear_ancestry() |
3407 | - self.assertRevidsFrom(['rev-3', 'rev-2', 'rev-1'], |
3408 | - history, None, 'rev-3') |
3409 | + history, revs = self.make_linear_ancestry() |
3410 | + self.assertRevidsFrom(list(reversed(revs)), history, None, revs[2]) |
3411 | |
3412 | def test_get_revids_from_merged_mainline(self): |
3413 | - history = self.make_merged_ancestry() |
3414 | - self.assertRevidsFrom(['rev-3', 'rev-1'], |
3415 | - history, None, 'rev-3') |
3416 | + history, revs = self.make_merged_ancestry() |
3417 | + self.assertRevidsFrom([revs[2], revs[0]], |
3418 | + history, None, revs[2]) |
3419 | |
3420 | def test_get_revids_given_one_rev(self): |
3421 | - history = self.make_merged_ancestry() |
3422 | + history, revs = self.make_merged_ancestry() |
3423 | # rev-3 was the first mainline revision to see rev-2. |
3424 | - self.assertRevidsFrom(['rev-3'], history, ['rev-2'], 'rev-3') |
3425 | + self.assertRevidsFrom([revs[2]], history, [revs[1]], revs[2]) |
3426 | |
3427 | def test_get_revids_deep_ancestry(self): |
3428 | - history = self.make_deep_merged_ancestry() |
3429 | - self.assertRevidsFrom(['F'], history, ['F'], 'F') |
3430 | - self.assertRevidsFrom(['F'], history, ['E'], 'F') |
3431 | - self.assertRevidsFrom(['F'], history, ['D'], 'F') |
3432 | - self.assertRevidsFrom(['F'], history, ['C'], 'F') |
3433 | - self.assertRevidsFrom(['B'], history, ['B'], 'F') |
3434 | - self.assertRevidsFrom(['A'], history, ['A'], 'F') |
3435 | + history, revs = self.make_deep_merged_ancestry() |
3436 | + self.assertRevidsFrom([revs[-1]], history, [revs[-1]], revs[-1]) |
3437 | + self.assertRevidsFrom([revs[-1]], history, [revs[-2]], revs[-1]) |
3438 | + self.assertRevidsFrom([revs[-1]], history, [revs[-3]], revs[-1]) |
3439 | + self.assertRevidsFrom([revs[-1]], history, [revs[-4]], revs[-1]) |
3440 | + self.assertRevidsFrom([revs[1]], history, [revs[-5]], revs[-1]) |
3441 | + self.assertRevidsFrom([revs[0]], history, [revs[-6]], revs[-1]) |
3442 | |
3443 | def test_get_revids_doesnt_over_produce_simple_mainline(self): |
3444 | # get_revids_from shouldn't walk the whole ancestry just to get the |
3445 | # answers for the first few revisions. |
3446 | - history = self.make_long_linear_ancestry() |
3447 | + history, revs = self.make_long_linear_ancestry() |
3448 | accessed = track_rev_info_accesses(history) |
3449 | - result = history.get_revids_from(None, 'Z') |
3450 | - self.assertEqual(set(), accessed) |
3451 | - self.assertEqual('Z', result.next()) |
3452 | - # We already know 'Z' because we passed it in. |
3453 | - self.assertEqual(set(), accessed) |
3454 | - self.assertEqual('Y', result.next()) |
3455 | - self.assertEqual(set([history._rev_indices['Z']]), accessed) |
3456 | + result = history.get_revids_from(None, revs[-1]) |
3457 | + self.assertEqual(set(), accessed) |
3458 | + self.assertEqual(revs[-1], next(result)) |
3459 | + # We already know revs[-1] because we passed it in. |
3460 | + self.assertEqual(set(), accessed) |
3461 | + self.assertEqual(revs[-2], next(result)) |
3462 | + self.assertEqual(set([history._rev_indices[revs[-1]]]), accessed) |
3463 | |
3464 | def test_get_revids_doesnt_over_produce_for_merges(self): |
3465 | # get_revids_from shouldn't walk the whole ancestry just to get the |
3466 | # answers for the first few revisions. |
3467 | - history = self.make_long_linear_ancestry() |
3468 | + history, revs = self.make_long_linear_ancestry() |
3469 | accessed = track_rev_info_accesses(history) |
3470 | - result = history.get_revids_from(['X', 'V'], 'Z') |
3471 | + result = history.get_revids_from([revs[-3], revs[-5]], revs[-1]) |
3472 | self.assertEqual(set(), accessed) |
3473 | - self.assertEqual('X', result.next()) |
3474 | + self.assertEqual(revs[-3], next(result)) |
3475 | # We access 'W' because we are checking that W wasn't merged into X. |
3476 | # The important bit is that we aren't getting the whole ancestry. |
3477 | - self.assertEqual(set([history._rev_indices[x] for x in 'ZYXW']), |
3478 | - accessed) |
3479 | - self.assertEqual('V', result.next()) |
3480 | - self.assertEqual(set([history._rev_indices[x] for x in 'ZYXWVU']), |
3481 | - accessed) |
3482 | - self.assertRaises(StopIteration, result.next) |
3483 | - self.assertEqual(set([history._rev_indices[x] for x in 'ZYXWVU']), |
3484 | + self.assertEqual(set([history._rev_indices[x] for x in list(reversed(revs))[:4]]), |
3485 | + accessed) |
3486 | + self.assertEqual(revs[-5], next(result)) |
3487 | + self.assertEqual(set([history._rev_indices[x] for x in list(reversed(revs))[:6]]), |
3488 | + accessed) |
3489 | + self.assertRaises(StopIteration, next, result) |
3490 | + self.assertEqual(set([history._rev_indices[x] for x in list(reversed(revs))[:6]]), |
3491 | accessed) |
3492 | |
3493 | |
3494 | @@ -291,32 +292,32 @@ |
3495 | def test_get_view_limited_history(self): |
3496 | # get_view should only load enough history to serve the result, not all |
3497 | # history. |
3498 | - history = self.make_long_linear_ancestry() |
3499 | + history, revs = self.make_long_linear_ancestry() |
3500 | accessed = track_rev_info_accesses(history) |
3501 | - revid, start_revid, revid_list = history.get_view('Z', 'Z', None, |
3502 | + revid, start_revid, revid_list = history.get_view(revs[-1], revs[-1], None, |
3503 | extra_rev_count=5) |
3504 | - self.assertEqual(['Z', 'Y', 'X', 'W', 'V', 'U'], revid_list) |
3505 | - self.assertEqual('Z', revid) |
3506 | - self.assertEqual('Z', start_revid) |
3507 | - self.assertEqual(set([history._rev_indices[x] for x in 'ZYXWVU']), |
3508 | + self.assertEqual(list(reversed(revs))[:6], revid_list) |
3509 | + self.assertEqual(revs[-1], revid) |
3510 | + self.assertEqual(revs[-1], start_revid) |
3511 | + self.assertEqual(set([history._rev_indices[x] for x in list(reversed(revs))[:6]]), |
3512 | accessed) |
3513 | |
3514 | |
3515 | class TestHistoryGetChangedUncached(TestCaseWithExamples): |
3516 | |
3517 | def test_native(self): |
3518 | - history = self.make_linear_ancestry() |
3519 | - changes = history.get_changes_uncached(['rev-1', 'rev-2']) |
3520 | + history, revs = self.make_linear_ancestry() |
3521 | + changes = history.get_changes_uncached([revs[0], revs[1]]) |
3522 | self.assertEquals(2, len(changes)) |
3523 | - self.assertEquals('rev-1', changes[0].revid) |
3524 | - self.assertEquals('rev-2', changes[1].revid) |
3525 | + self.assertEquals(revs[0], changes[0].revid) |
3526 | + self.assertEquals(revs[1], changes[1].revid) |
3527 | self.assertIs(None, getattr(changes[0], 'foreign_vcs', None)) |
3528 | self.assertIs(None, getattr(changes[0], 'foreign_revid', None)) |
3529 | |
3530 | def test_foreign(self): |
3531 | # Test with a mocked foreign revision, as it's not possible |
3532 | # to rely on any foreign plugins being installed. |
3533 | - history = self.make_linear_ancestry() |
3534 | + history, revs = self.make_linear_ancestry() |
3535 | foreign_vcs = ForeignVcs(None, "vcs") |
3536 | foreign_vcs.show_foreign_revid = repr |
3537 | foreign_rev = ForeignRevision(("uuid", 1234), VcsMapping(foreign_vcs), |
3538 | |
3539 | === modified file 'loggerhead/tests/test_http_head.py' |
3540 | --- loggerhead/tests/test_http_head.py 2011-02-10 02:33:15 +0000 |
3541 | +++ loggerhead/tests/test_http_head.py 2019-09-18 16:50:15 +0000 |
3542 | @@ -16,17 +16,17 @@ |
3543 | |
3544 | """Tests for the HeadMiddleware app.""" |
3545 | |
3546 | -from cStringIO import StringIO |
3547 | - |
3548 | -from bzrlib import tests |
3549 | - |
3550 | -from loggerhead.apps import http_head |
3551 | - |
3552 | - |
3553 | -content = ["<html>", |
3554 | - "<head><title>Listed</title></head>", |
3555 | - "<body>Content</body>", |
3556 | - "</html>", |
3557 | +from io import BytesIO |
3558 | + |
3559 | +from breezy import tests |
3560 | + |
3561 | +from ..apps import http_head |
3562 | + |
3563 | + |
3564 | +content = [b"<html>", |
3565 | + b"<head><title>Listed</title></head>", |
3566 | + b"<body>Content</body>", |
3567 | + b"</html>", |
3568 | ] |
3569 | headers = {'X-Ignored-Header': 'Value'} |
3570 | |
3571 | @@ -51,7 +51,7 @@ |
3572 | class TestHeadMiddleware(tests.TestCase): |
3573 | |
3574 | def _trap_start_response(self, status, response_headers, exc_info=None): |
3575 | - self._write_buffer = StringIO() |
3576 | + self._write_buffer = BytesIO() |
3577 | self._start_response_passed = (status, response_headers, exc_info) |
3578 | return self._write_buffer.write |
3579 | |
3580 | @@ -64,13 +64,13 @@ |
3581 | app = http_head.HeadMiddleware(app) |
3582 | self._consume_app(app, 'GET') |
3583 | self.assertEqual(('200 OK', headers, None), self._start_response_passed) |
3584 | - self.assertEqualDiff(''.join(content), self._write_buffer.getvalue()) |
3585 | + self.assertEqualDiff(b''.join(content), self._write_buffer.getvalue()) |
3586 | |
3587 | def _verify_head_no_body(self, app): |
3588 | app = http_head.HeadMiddleware(app) |
3589 | self._consume_app(app, 'HEAD') |
3590 | self.assertEqual(('200 OK', headers, None), self._start_response_passed) |
3591 | - self.assertEqualDiff('', self._write_buffer.getvalue()) |
3592 | + self.assertEqualDiff(b'', self._write_buffer.getvalue()) |
3593 | |
3594 | def test_get_passthrough_yielding(self): |
3595 | self._verify_get_passthrough(yielding_app) |
3596 | |
3597 | === modified file 'loggerhead/tests/test_load_test.py' |
3598 | --- loggerhead/tests/test_load_test.py 2011-04-14 14:10:04 +0000 |
3599 | +++ loggerhead/tests/test_load_test.py 2019-09-18 16:50:15 +0000 |
3600 | @@ -15,12 +15,15 @@ |
3601 | import socket |
3602 | import time |
3603 | import threading |
3604 | -import Queue |
3605 | - |
3606 | -from bzrlib import tests |
3607 | -from bzrlib.tests import http_server |
3608 | - |
3609 | -from loggerhead import load_test |
3610 | +try: |
3611 | + from queue import Empty |
3612 | +except ImportError: # Python < 3 |
3613 | + from Queue import Empty |
3614 | + |
3615 | +from breezy import tests |
3616 | +from breezy.tests import http_server |
3617 | + |
3618 | +from .. import load_test |
3619 | |
3620 | |
3621 | empty_script = """{ |
3622 | @@ -90,7 +93,7 @@ |
3623 | def test_step_next_will_timeout(self): |
3624 | # We don't want step_next to block forever |
3625 | rt = NoopRequestWorker('id', blocking_time=0.001) |
3626 | - self.assertRaises(Queue.Empty, rt.step_next) |
3627 | + self.assertRaises(Empty, rt.step_next) |
3628 | |
3629 | def test_run_stops_for_stop_event(self): |
3630 | rt = NoopRequestWorker('id', blocking_time=0.001, _queue_size=2) |
3631 | |
3632 | === modified file 'loggerhead/tests/test_revision_ui.py' |
3633 | --- loggerhead/tests/test_revision_ui.py 2011-03-16 12:37:17 +0000 |
3634 | +++ loggerhead/tests/test_revision_ui.py 2019-09-18 16:50:15 +0000 |
3635 | @@ -15,8 +15,9 @@ |
3636 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
3637 | # |
3638 | |
3639 | +from __future__ import absolute_import |
3640 | |
3641 | -from loggerhead.tests.test_simple import BasicTests |
3642 | +from .test_simple import BasicTests |
3643 | |
3644 | |
3645 | class TestRevisionUI(BasicTests): |
3646 | @@ -43,4 +44,4 @@ |
3647 | # and the Authors are connected. However, that requires asserting the |
3648 | # exact HTML connections, which I wanted to avoid. |
3649 | res.mustcontain('Committer', 'Joe Example') |
3650 | - self.assertFalse('Author(s)' in res.body) |
3651 | + self.assertFalse(b'Author(s)' in res.body) |
3652 | |
3653 | === modified file 'loggerhead/tests/test_simple.py' |
3654 | --- loggerhead/tests/test_simple.py 2011-11-25 02:28:56 +0000 |
3655 | +++ loggerhead/tests/test_simple.py 2019-09-18 16:50:15 +0000 |
3656 | @@ -15,25 +15,27 @@ |
3657 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
3658 | # |
3659 | |
3660 | +from __future__ import absolute_import |
3661 | + |
3662 | import cgi |
3663 | import logging |
3664 | import re |
3665 | import simplejson |
3666 | -from cStringIO import StringIO |
3667 | +from io import BytesIO |
3668 | |
3669 | -from bzrlib.tests import TestCaseWithTransport |
3670 | +from breezy.tests import TestCaseWithTransport |
3671 | try: |
3672 | - from bzrlib.util.configobj.configobj import ConfigObj |
3673 | + from breezy.util.configobj.configobj import ConfigObj |
3674 | except ImportError: |
3675 | from configobj import ConfigObj |
3676 | -from bzrlib import config |
3677 | +from breezy import config |
3678 | |
3679 | -from loggerhead.apps.branch import BranchWSGIApp |
3680 | -from loggerhead.apps.http_head import HeadMiddleware |
3681 | +from ..apps.branch import BranchWSGIApp |
3682 | +from ..apps.http_head import HeadMiddleware |
3683 | from paste.fixture import TestApp |
3684 | from paste.httpexceptions import HTTPExceptionHandler, HTTPMovedPermanently |
3685 | |
3686 | -from loggerhead.tests.fixtures import ( |
3687 | +from .fixtures import ( |
3688 | SampleBranch, |
3689 | ) |
3690 | |
3691 | @@ -105,12 +107,6 @@ |
3692 | self.failUnless("To get this branch, use:" in res) |
3693 | self.failUnless("lp:loggerhead" in res) |
3694 | |
3695 | - def test_no_empty_download_location(self): |
3696 | - """With no served_url, no instructions how to get it""" |
3697 | - app = self.setUpLoggerhead() |
3698 | - res = app.get('/changes') |
3699 | - self.failIf("To get this branch, use:" in res) |
3700 | - |
3701 | def test_changes_search(self): |
3702 | app = self.setUpLoggerhead() |
3703 | res = app.get('/changes', params={'q': 'foo'}) |
3704 | @@ -127,10 +123,10 @@ |
3705 | # '<span class='pyg-n'>with</span><span class='pyg-o'><</span>' |
3706 | # '<span class='pyg-n'>htmlspecialchars</span> |
3707 | # So we pre-filter the body, to make sure remove spans of that type. |
3708 | - body_no_span = re.sub(r'<span class="pyg-.">', '', res.body) |
3709 | - body_no_span = body_no_span.replace('</span>', '') |
3710 | + body_no_span = re.sub(b'<span class="pyg-.">', b'', res.body) |
3711 | + body_no_span = body_no_span.replace(b'</span>', b'') |
3712 | for line in self.filecontents.splitlines(): |
3713 | - escaped = cgi.escape(line) |
3714 | + escaped = cgi.escape(line).encode('utf-8') |
3715 | self.assertTrue(escaped in body_no_span, |
3716 | "did not find %r in %r" % (escaped, body_no_span)) |
3717 | |
3718 | @@ -144,7 +140,7 @@ |
3719 | res.mustcontain('myfilename') |
3720 | res = app.get('/files/1/') |
3721 | res.mustcontain('myfilename') |
3722 | - res = app.get('/files/1/?file_id=' + self.tree.path2id('')) |
3723 | + res = app.get('/files/1/?file_id=' + self.tree.path2id('').decode('utf-8')) |
3724 | res.mustcontain('myfilename') |
3725 | |
3726 | def test_inventory_bad_rev_404(self): |
3727 | @@ -192,10 +188,18 @@ |
3728 | def setUp(self): |
3729 | BasicTests.setUp(self) |
3730 | self.createBranch() |
3731 | - locations = config.locations_config_filename() |
3732 | - config.ensure_config_dir_exists() |
3733 | - open(locations, 'wb').write('[%s]\nhttp_serve = False' |
3734 | - % (self.tree.branch.base,)) |
3735 | + try: |
3736 | + locations = config.locations_config_filename() |
3737 | + except AttributeError: |
3738 | + from breezy import bedding |
3739 | + locations = bedding.locations_config_path() |
3740 | + ensure_config_dir_exists = bedding.ensure_config_dir_exists |
3741 | + else: |
3742 | + ensure_config_dir_exists = config.ensure_config_dir_exists |
3743 | + ensure_config_dir_exists() |
3744 | + with open(locations, 'w') as f: |
3745 | + f.write('[%s]\nhttp_serve = False' % ( |
3746 | + self.tree.branch.base,)) |
3747 | |
3748 | def test_no_access(self): |
3749 | app = self.setUpLoggerhead() |
3750 | @@ -252,11 +256,11 @@ |
3751 | app = self.setUpLoggerhead() |
3752 | res = app.get('/changes', extra_environ={'REQUEST_METHOD': 'HEAD'}) |
3753 | self.assertEqual('text/html', res.header('Content-Type')) |
3754 | - self.assertEqualDiff('', res.body) |
3755 | + self.assertEqualDiff(b'', res.body) |
3756 | |
3757 | |
3758 | def consume_app(app, env): |
3759 | - body = StringIO() |
3760 | + body = BytesIO() |
3761 | start = [] |
3762 | def start_response(status, headers, exc_info=None): |
3763 | start.append((status, headers, exc_info)) |
3764 | |
3765 | === modified file 'loggerhead/tests/test_templating.py' |
3766 | --- loggerhead/tests/test_templating.py 2008-10-24 02:26:05 +0000 |
3767 | +++ loggerhead/tests/test_templating.py 2019-09-18 16:50:15 +0000 |
3768 | @@ -1,4 +1,4 @@ |
3769 | -from loggerhead.zptsupport import load_template |
3770 | +from ..zptsupport import load_template |
3771 | |
3772 | RENDERED = u"<html>\n<head>\n<title>%s</title>\n</head>\n\ |
3773 | <body>\n<div>Hello, %s</div>\n</body>\n</html>" |
3774 | |
3775 | === modified file 'loggerhead/tests/test_util.py' |
3776 | --- loggerhead/tests/test_util.py 2011-09-08 00:33:28 +0000 |
3777 | +++ loggerhead/tests/test_util.py 2019-09-18 16:50:15 +0000 |
3778 | @@ -14,9 +14,9 @@ |
3779 | # along with this program; if not, write to the Free Software |
3780 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
3781 | |
3782 | -from bzrlib import tests |
3783 | +from breezy import tests |
3784 | |
3785 | -from loggerhead.util import html_escape, html_format |
3786 | +from ..util import html_escape, html_format |
3787 | |
3788 | |
3789 | class TestHTMLEscaping(tests.TestCase): |
3790 | |
3791 | === modified file 'loggerhead/util.py' |
3792 | --- loggerhead/util.py 2012-04-28 00:57:06 +0000 |
3793 | +++ loggerhead/util.py 2019-09-18 16:50:15 +0000 |
3794 | @@ -19,6 +19,8 @@ |
3795 | # Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
3796 | # |
3797 | |
3798 | +from __future__ import print_function |
3799 | + |
3800 | import base64 |
3801 | import datetime |
3802 | import logging |
3803 | @@ -30,14 +32,19 @@ |
3804 | import os |
3805 | import subprocess |
3806 | |
3807 | +from breezy.sixish import ( |
3808 | + text_type, |
3809 | + viewitems, |
3810 | + ) |
3811 | + |
3812 | try: |
3813 | from xml.etree import ElementTree as ET |
3814 | except ImportError: |
3815 | from elementtree import ElementTree as ET |
3816 | |
3817 | -from bzrlib import urlutils |
3818 | +from breezy import urlutils |
3819 | |
3820 | -from simpletal.simpleTALUtils import HTMLStructureCleaner |
3821 | +import bleach |
3822 | |
3823 | log = logging.getLogger("loggerhead.controllers") |
3824 | |
3825 | @@ -73,20 +80,27 @@ |
3826 | |
3827 | |
3828 | def _approximatedate(date): |
3829 | - delta = datetime.datetime.now() - date |
3830 | - if abs(delta) > datetime.timedelta(1, 0, 0): |
3831 | - # far in the past or future, display the date |
3832 | - return date_day(date) |
3833 | + if date is None: |
3834 | + return 'Never' |
3835 | + delta = datetime.datetime.utcnow() - date |
3836 | future = delta < datetime.timedelta(0, 0, 0) |
3837 | delta = abs(delta) |
3838 | + years = delta.days // 365 |
3839 | + months = delta.days // 30 # This is approximate. |
3840 | days = delta.days |
3841 | - hours = delta.seconds / 3600 |
3842 | + hours = delta.seconds // 3600 |
3843 | minutes = (delta.seconds - (3600*hours)) / 60 |
3844 | seconds = delta.seconds % 60 |
3845 | result = '' |
3846 | if future: |
3847 | result += 'in ' |
3848 | - if days != 0: |
3849 | + if years != 0: |
3850 | + amount = years |
3851 | + unit = 'year' |
3852 | + elif months != 0: |
3853 | + amount = months |
3854 | + unit = 'month' |
3855 | + elif days != 0: |
3856 | amount = days |
3857 | unit = 'day' |
3858 | elif hours != 0: |
3859 | @@ -100,10 +114,10 @@ |
3860 | unit = 'second' |
3861 | if amount != 1: |
3862 | unit += 's' |
3863 | - result += '%s %s' % (amount, unit) |
3864 | + result += '%s %s' % (int(amount), unit) |
3865 | if not future: |
3866 | result += ' ago' |
3867 | - return result |
3868 | + return result |
3869 | |
3870 | |
3871 | def _wrap_with_date_time_title(date, formatted_date): |
3872 | @@ -126,14 +140,14 @@ |
3873 | def __init__(self, _dict=None, **kw): |
3874 | self._properties = {} |
3875 | if _dict is not None: |
3876 | - for key, value in _dict.iteritems(): |
3877 | + for key, value in viewitems(_dict): |
3878 | setattr(self, key, value) |
3879 | - for key, value in kw.iteritems(): |
3880 | + for key, value in viewitems(kw): |
3881 | setattr(self, key, value) |
3882 | |
3883 | def __repr__(self): |
3884 | out = '{ ' |
3885 | - for key, value in self.__dict__.iteritems(): |
3886 | + for key, value in viewitems(self.__dict__): |
3887 | if key.startswith('_') or (getattr(self.__dict__[key], |
3888 | '__call__', None) is not None): |
3889 | continue |
3890 | @@ -262,21 +276,24 @@ |
3891 | return s |
3892 | elif not s.strip(): |
3893 | return ' ' |
3894 | - else: |
3895 | + elif isinstance(s, bytes): |
3896 | try: |
3897 | s = s.decode('utf-8') |
3898 | except UnicodeDecodeError: |
3899 | s = s.decode('iso-8859-15') |
3900 | return s |
3901 | + elif isinstance(s, text_type): |
3902 | + return s |
3903 | + else: |
3904 | + return repr(s) |
3905 | |
3906 | -HSC = HTMLStructureCleaner() |
3907 | |
3908 | def fixed_width(s): |
3909 | """ |
3910 | expand tabs and turn spaces into "non-breaking spaces", so browsers won't |
3911 | chop up the string. |
3912 | """ |
3913 | - if not isinstance(s, unicode): |
3914 | + if not isinstance(s, text_type): |
3915 | # this kinda sucks. file contents are just binary data, and no |
3916 | # encoding metadata is stored, so we need to guess. this is probably |
3917 | # okay for most code, but for people using things like KOI-8, this |
3918 | @@ -289,7 +306,7 @@ |
3919 | |
3920 | s = html_escape(s).expandtabs().replace(' ', NONBREAKING_SPACE) |
3921 | |
3922 | - return HSC.clean(s).replace('\n', '<br/>') |
3923 | + return bleach.clean(s).replace('\n', '<br/>') |
3924 | |
3925 | |
3926 | def fake_permissions(kind, executable): |
3927 | @@ -456,7 +473,7 @@ |
3928 | return breadcrumbs |
3929 | |
3930 | |
3931 | -def branch_breadcrumbs(path, inv, view): |
3932 | +def branch_breadcrumbs(path, tree, view): |
3933 | """ |
3934 | Generate breadcrumb information from the branch path given |
3935 | |
3936 | @@ -464,7 +481,7 @@ |
3937 | |
3938 | Arguments: |
3939 | path -- The path to convert into breadcrumbs |
3940 | - inv -- Inventory to get file information from |
3941 | + tree -- Tree to get file information from |
3942 | view -- The type of view we are showing (files, changes etc) |
3943 | """ |
3944 | dir_parts = path.strip('/').split('/') |
3945 | @@ -497,7 +514,7 @@ |
3946 | def lsprof(f): |
3947 | |
3948 | def _f(*a, **kw): |
3949 | - from loggerhead.lsprof import profile |
3950 | + from .loggerhead.lsprof import profile |
3951 | import cPickle |
3952 | z = time.time() |
3953 | ret, stats = profile(f, *a, **kw) |
3954 | @@ -548,7 +565,7 @@ |
3955 | |
3956 | |
3957 | def set_context(map): |
3958 | - t_context.map = dict((k, v) for (k, v) in map.iteritems() if k in _valid) |
3959 | + t_context.map = dict((k, v) for (k, v) in viewitems(map) if k in _valid) |
3960 | |
3961 | |
3962 | def get_context(**overrides): |
3963 | @@ -567,7 +584,7 @@ |
3964 | map['remember'] = t_context.map.get('remember', None) |
3965 | else: |
3966 | map.update(t_context.map) |
3967 | - overrides = dict((k, v) for (k, v) in overrides.iteritems() if k in _valid) |
3968 | + overrides = dict((k, v) for (k, v) in viewitems(overrides) if k in _valid) |
3969 | map.update(overrides) |
3970 | return map |
3971 | |
3972 | @@ -605,7 +622,7 @@ |
3973 | @classmethod |
3974 | def restart_with_reloader(cls): |
3975 | """Based on restart_with_monitor from paste.script.serve.""" |
3976 | - print 'Starting subprocess with file monitor' |
3977 | + print('Starting subprocess with file monitor') |
3978 | while True: |
3979 | args = [sys.executable] + sys.argv |
3980 | new_environ = os.environ.copy() |
3981 | @@ -618,7 +635,7 @@ |
3982 | exit_code = proc.wait() |
3983 | proc = None |
3984 | except KeyboardInterrupt: |
3985 | - print '^C caught in monitor process' |
3986 | + print('^C caught in monitor process') |
3987 | return 1 |
3988 | finally: |
3989 | if (proc is not None |
3990 | @@ -633,7 +650,7 @@ |
3991 | # a monitor, any exit code will restart |
3992 | if exit_code != 3: |
3993 | return exit_code |
3994 | - print '-'*20, 'Restarting', '-'*20 |
3995 | + print('-'*20, 'Restarting', '-'*20) |
3996 | |
3997 | |
3998 | def convert_file_errors(application): |
3999 | @@ -641,7 +658,7 @@ |
4000 | def new_application(environ, start_response): |
4001 | try: |
4002 | return application(environ, start_response) |
4003 | - except (IOError, OSError), e: |
4004 | + except (IOError, OSError) as e: |
4005 | import errno |
4006 | from paste import httpexceptions |
4007 | if e.errno == errno.ENOENT: |
4008 | |
4009 | === modified file 'loggerhead/wholehistory.py' |
4010 | --- loggerhead/wholehistory.py 2012-02-08 01:50:02 +0000 |
4011 | +++ loggerhead/wholehistory.py 2019-09-18 16:50:15 +0000 |
4012 | @@ -20,19 +20,23 @@ |
4013 | import logging |
4014 | import time |
4015 | |
4016 | -from bzrlib.revision import is_null, NULL_REVISION |
4017 | -from bzrlib.tsort import merge_sort |
4018 | +from breezy.revision import is_null, NULL_REVISION |
4019 | +from breezy.sixish import ( |
4020 | + viewitems, |
4021 | + viewkeys, |
4022 | + ) |
4023 | +from breezy.tsort import merge_sort |
4024 | |
4025 | |
4026 | def _strip_NULL_ghosts(revision_graph): |
4027 | """ |
4028 | - Copied over from bzrlib meant as a temporary workaround for |
4029 | + Copied over from breezy meant as a temporary workaround for |
4030 | deprecated methods. |
4031 | """ |
4032 | # Filter ghosts, and null: |
4033 | if NULL_REVISION in revision_graph: |
4034 | del revision_graph[NULL_REVISION] |
4035 | - for key, parents in revision_graph.iteritems(): |
4036 | + for key, parents in viewitems(revision_graph): |
4037 | revision_graph[key] = tuple(parent for parent in parents if parent |
4038 | in revision_graph) |
4039 | return revision_graph |
4040 | @@ -72,7 +76,7 @@ |
4041 | _rev_indices[revid] = len(_rev_info) |
4042 | _rev_info.append([(seq, revid, merge_depth, revno_str, end_of_merge), (), parents]) |
4043 | |
4044 | - for revid in _revision_graph.iterkeys(): |
4045 | + for revid in viewkeys(_revision_graph): |
4046 | if _rev_info[_rev_indices[revid]][0][2] == 0: |
4047 | continue |
4048 | for parent in _revision_graph[revid]: |
4049 | |
4050 | === modified file 'loggerhead/zptsupport.py' |
4051 | --- loggerhead/zptsupport.py 2012-02-08 01:50:02 +0000 |
4052 | +++ loggerhead/zptsupport.py 2019-09-18 16:50:15 +0000 |
4053 | @@ -19,7 +19,9 @@ |
4054 | import os |
4055 | import pkg_resources |
4056 | import re |
4057 | -import StringIO |
4058 | +from io import StringIO |
4059 | + |
4060 | +from breezy.sixish import viewitems |
4061 | |
4062 | from simpletal import simpleTAL, simpleTALES |
4063 | |
4064 | @@ -30,7 +32,8 @@ |
4065 | tinstance = _zpt_cache.get(tfile) |
4066 | stat = os.stat(tfile) |
4067 | if tinstance is None or tinstance.stat != stat: |
4068 | - text = open(tfile).read() |
4069 | + with open(tfile) as tf: |
4070 | + text = tf.read() |
4071 | text = re.sub(r'\s*\n\s*', '\n', text) |
4072 | text = re.sub(r'[ \t]+', ' ', text) |
4073 | tinstance = _zpt_cache[tfile] = TemplateWrapper( |
4074 | @@ -47,17 +50,17 @@ |
4075 | |
4076 | def expand(self, **info): |
4077 | context = simpleTALES.Context(allowPythonPath=1) |
4078 | - for k, v in info.iteritems(): |
4079 | + for k, v in viewitems(info): |
4080 | context.addGlobal(k, v) |
4081 | - s = StringIO.StringIO() |
4082 | + s = StringIO() |
4083 | self.template.expandInline(context, s) |
4084 | return s.getvalue() |
4085 | |
4086 | def expand_into(self, f, **info): |
4087 | context = simpleTALES.Context(allowPythonPath=1) |
4088 | - for k, v in info.iteritems(): |
4089 | + for k, v in viewitems(info): |
4090 | context.addGlobal(k, v) |
4091 | - self.template.expand(context, f, 'utf-8') |
4092 | + self.template.expand(context, f, outputEncoding='utf-8') |
4093 | |
4094 | @property |
4095 | def macros(self): |
4096 | |
4097 | === modified file 'loggerheadd' |
4098 | --- loggerheadd 2009-04-30 10:39:05 +0000 |
4099 | +++ loggerheadd 2019-09-18 16:50:15 +0000 |
4100 | @@ -22,8 +22,8 @@ |
4101 | SUDO="sudo -H -u $LHUSER" |
4102 | fi |
4103 | |
4104 | -# If serve-branches is not in your path, you will need to specify the full path: |
4105 | -SERVE_BRANCHES_CMD=serve-branches |
4106 | +# If loggerhead-serve is not in your path, you will need to specify the full path: |
4107 | +SERVE_BRANCHES_CMD=loggerhead-serve |
4108 | |
4109 | LOG_FOLDER=/var/log/loggerhead |
4110 | LOG_FILE=$LOG_FOLDER/loggerheadd.log |
4111 | @@ -33,7 +33,7 @@ |
4112 | #please specify the base directory to serve: |
4113 | BZRROOT=/bzrroot |
4114 | |
4115 | -# You can add additional options to serve-branches here: |
4116 | +# You can add additional options to loggerhead-serve here: |
4117 | START_CMD="$SERVE_BRANCHES_CMD --prefix=$URL_PREFIX --log-folder=$LOG_FOLDER --port=$PORT $BZRROOT" |
4118 | |
4119 | |
4120 | |
4121 | === modified file 'setup.py' |
4122 | --- setup.py 2015-03-17 11:23:13 +0000 |
4123 | +++ setup.py 2019-09-18 16:50:15 +0000 |
4124 | @@ -18,7 +18,7 @@ |
4125 | |
4126 | """Loggerhead is a web viewer for projects in bazaar""" |
4127 | |
4128 | -from distutils.core import setup |
4129 | +from setuptools import setup |
4130 | |
4131 | import loggerhead |
4132 | |
4133 | @@ -31,16 +31,15 @@ |
4134 | maintainer = "Michael Hudson", |
4135 | maintainer_email = "michael.hudson@canonical.com", |
4136 | scripts = [ |
4137 | - "serve-branches", |
4138 | - "loggerhead.wsgi", |
4139 | + "loggerhead-serve", |
4140 | ], |
4141 | packages = ["loggerhead", |
4142 | "loggerhead/apps", |
4143 | "loggerhead/controllers", |
4144 | "loggerhead/middleware", |
4145 | "loggerhead/templates", |
4146 | - "bzrlib.plugins.loggerhead"], |
4147 | - package_dir={'bzrlib.plugins.loggerhead':'.'}, |
4148 | + "breezy.plugins.loggerhead"], |
4149 | + package_dir={'breezy.plugins.loggerhead':'.'}, |
4150 | package_data = {"loggerhead": ["templates/*.pt", |
4151 | "static/css/*.css", |
4152 | "static/javascript/*.js", |
4153 | @@ -68,9 +67,11 @@ |
4154 | "static/javascript/yui/build/yui-base/*", |
4155 | "static/images/*"]}, |
4156 | data_files = [ |
4157 | - ('share/man/man1', ['serve-branches.1']), |
4158 | + ('share/man/man1', ['loggerhead-serve.1']), |
4159 | ('share/doc/loggerhead', ['apache-loggerhead.conf', |
4160 | 'loggerheadd', |
4161 | - 'bazaar.conf']), |
4162 | + 'breezy.conf']), |
4163 | ], |
4164 | + install_requires=['simplejson', 'paste', 'bleach'], |
4165 | + testsuite='loggerhead.tests.test_suite', |
4166 | ) |
Sorry for the long delay here; it took me a long time to get a suitable Breezy-using Launchpad branch set up so that I could test the integration.
As well as the minor comments here, https:/ /code.launchpad .net/~cjwatson/ loggerhead/ more-no- file-ids/ +merge/ 372951 is needed.