Merge lp:~jelmer/loggerhead/more-columns into lp:loggerhead

Proposed by Jelmer Vernooij
Status: Superseded
Proposed branch: lp:~jelmer/loggerhead/more-columns
Merge into: lp:loggerhead
Diff against target: 2166 lines (+424/-415)
48 files modified
.bzrignore (+2/-0)
.testr.conf (+4/-0)
.travis.yml (+22/-0)
MANIFEST.in (+1/-1)
Makefile (+1/-1)
README.rst (+6/-5)
__init__.py (+14/-16)
docs/index.rst (+16/-15)
docs/serve-branches.rst (+1/-1)
loggerhead.wsgi (+8/-5)
loggerhead/__init__.py (+1/-10)
loggerhead/apps/branch.py (+23/-13)
loggerhead/apps/transport.py (+11/-14)
loggerhead/config.py (+2/-2)
loggerhead/controllers/__init__.py (+2/-2)
loggerhead/controllers/annotate_ui.py (+2/-1)
loggerhead/controllers/diff_ui.py (+2/-2)
loggerhead/controllers/directory_ui.py (+7/-7)
loggerhead/controllers/download_ui.py (+5/-5)
loggerhead/controllers/filediff_ui.py (+5/-5)
loggerhead/controllers/inventory_ui.py (+33/-22)
loggerhead/controllers/view_ui.py (+16/-19)
loggerhead/exporter.py (+0/-60)
loggerhead/highlight.py (+3/-3)
loggerhead/history.py (+42/-43)
loggerhead/load_test.py (+2/-2)
loggerhead/main.py (+11/-5)
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 (+5/-5)
loggerhead/templates/directory.pt (+12/-13)
loggerhead/templates/inventory.pt (+25/-12)
loggerhead/templates/macros.pt (+1/-1)
loggerhead/tests/__init__.py (+3/-3)
loggerhead/tests/test_controllers.py (+26/-24)
loggerhead/tests/test_corners.py (+3/-1)
loggerhead/tests/test_history.py (+63/-62)
loggerhead/tests/test_http_head.py (+1/-1)
loggerhead/tests/test_load_test.py (+2/-2)
loggerhead/tests/test_revision_ui.py (+2/-1)
loggerhead/tests/test_simple.py (+8/-6)
loggerhead/tests/test_util.py (+1/-1)
loggerhead/util.py (+16/-9)
loggerhead/wholehistory.py (+3/-3)
serve-branches.1 (+1/-1)
setup.py (+3/-3)
To merge this branch: bzr merge lp:~jelmer/loggerhead/more-columns
Reviewer Review Type Date Requested Status
Loggerhead Reviewers Pending
Review via email: mp+354527@code.launchpad.net

This proposal has been superseded by a proposal from 2018-09-08.

Commit message

Add more columns to the directory view.

Description of the change

To post a comment you must log in.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2011-07-10 22:53:59 +0000
3+++ .bzrignore 2018-09-08 16:37:25 +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 2018-09-08 16:37:25 +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 2018-09-08 16:37:25 +0000
23@@ -0,0 +1,22 @@
24+language: python
25+addons:
26+ apt:
27+ update: true
28+sudo: false
29+cache: pip
30+git:
31+ depth: false
32+
33+python:
34+ - 2.7
35+
36+script:
37+ - make check
38+
39+install:
40+ - sudo apt install python-all subunit python-testtools adduser libjs-yui3-min
41+ - travis_retry pip install -U setuptools
42+ - 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-4.3.tar.gz
43+
44+after_success:
45+ - codecov
46
47=== renamed file 'HACKING' => 'HACKING.rst'
48=== modified file 'MANIFEST.in'
49--- MANIFEST.in 2012-02-08 00:25:23 +0000
50+++ MANIFEST.in 2018-09-08 16:37:25 +0000
51@@ -3,7 +3,7 @@
52 include NEWS
53 include README.txt
54 include apache-loggerhead.conf
55-include bazaar.conf
56+include breezy.conf
57 include loggerhead.conf.example
58 include loggerheadd
59 include Makefile
60
61=== modified file 'Makefile'
62--- Makefile 2011-03-14 08:47:03 +0000
63+++ Makefile 2018-09-08 16:37:25 +0000
64@@ -8,4 +8,4 @@
65 rm -rf dist/
66
67 check:
68- BZR_PLUGINS_AT=loggerhead@$$(pwd) bzr selftest -s bp.loggerhead
69+ BRZ_PLUGINS_AT=loggerhead@$$(pwd) brz selftest -s bp.loggerhead
70
71=== renamed file 'README' => 'README.rst'
72--- README 2010-04-23 01:30:29 +0000
73+++ README.rst 2018-09-08 16:37:25 +0000
74@@ -4,8 +4,7 @@
75 Overview
76 --------
77
78-Loggerhead is a web viewer for Bazaar branches. Its lets users do
79-stuff like:
80+Loggerhead is a web viewer for Breezy. Its lets users do stuff like:
81
82 * navigate through branch history
83 * view the files in a given revision
84@@ -23,6 +22,8 @@
85 Licensing
86 ---------
87
88-This software is (C) Copyright Canonical Limited 2006-10 under the
89-GPL Version 2 or later. Please see the file COPYING.txt for the
90-licence details.
91+This software is licensed under the GPL Version 2 or later.
92+Please see the file COPYING.txt for the licence details.
93+
94+ (C) Copyright Canonical Limited 2006-10
95+ (C) Copyright Breezy Developers 2018
96
97=== modified file '__init__.py'
98--- __init__.py 2012-02-08 01:50:02 +0000
99+++ __init__.py 2018-09-08 16:37:25 +0000
100@@ -18,8 +18,8 @@
101 # This file allows loggerhead to be treated as a plugin for bzr.
102 #
103 # XXX: Because loggerhead already contains a loggerhead directory, much of the
104-# code is going to appear loaded at bzrlib.plugins.loggerhead.loggerhead.
105-# This seems like the easiest thing, because bzrlib wants the top-level plugin
106+# code is going to appear loaded at breezy.plugins.loggerhead.loggerhead.
107+# This seems like the easiest thing, because breezy wants the top-level plugin
108 # directory to be the module, but when it's used as a library people expect
109 # the source directory to contain a directory called loggerhead. -- mbp
110 # 20090123
111@@ -37,14 +37,11 @@
112 bzr_compatible_versions,
113 )
114
115-if __name__ == 'bzrlib.plugins.loggerhead':
116- import bzrlib
117- from bzrlib.api import require_any_api
118- from bzrlib import commands
119-
120- require_any_api(bzrlib, bzr_compatible_versions)
121-
122- from bzrlib.transport import transport_server_registry
123+if __name__ == 'breezy.plugins.loggerhead':
124+ import breezy
125+ from breezy import commands
126+
127+ from breezy.transport import transport_server_registry
128
129 DEFAULT_HOST = '0.0.0.0'
130 DEFAULT_PORT = 8080
131@@ -61,7 +58,7 @@
132 import os.path, sys
133 sys.path.append(os.path.dirname(__file__))
134
135- def serve_http(transport, host=None, port=None, inet=None):
136+ def serve_http(transport, host=None, port=None, inet=None, client_timeout=None):
137 # TODO: if we supported inet to pass requests in and respond to them,
138 # then it would be easier to test the full stack, but it probably
139 # means routing around paste.httpserver.serve which probably
140@@ -102,10 +99,11 @@
141 for a description of the file format.
142 """
143
144+ hidden = True
145 takes_args = ["filename"]
146
147 def run(self, filename):
148- from bzrlib.plugins.loggerhead.loggerhead import load_test
149+ from breezy.plugins.loggerhead.loggerhead import load_test
150 script = load_test.run_script(filename)
151 for thread_id in sorted(script._threads):
152 worker = script._threads[thread_id][0]
153@@ -115,8 +113,8 @@
154
155 commands.register_command(cmd_load_test_loggerhead)
156
157- def load_tests(standard_tests, module, loader):
158+ def load_tests(loader, basic_tests, pattern):
159 _ensure_loggerhead_path()
160- standard_tests.addTests(loader.loadTestsFromModuleNames(
161- ['bzrlib.plugins.loggerhead.loggerhead.tests']))
162- return standard_tests
163+ basic_tests.addTest(loader.loadTestsFromModuleNames(
164+ ['%s.loggerhead.tests' % __name__]))
165+ return basic_tests
166
167=== renamed file 'bazaar.conf' => 'breezy.conf'
168=== modified file 'docs/index.rst'
169--- docs/index.rst 2012-02-02 04:58:46 +0000
170+++ docs/index.rst 2018-09-08 16:37:25 +0000
171@@ -1,7 +1,7 @@
172 Loggerhead: A web viewer for ``bzr`` branches
173 ==============================================
174
175-Loggerhead is a web viewer for projects in Bazaar. It can be used to navigate
176+Loggerhead is a web viewer for projects in . It can be used to navigate
177 a branch history, annotate files, view patches, perform searches, etc.
178 Loggerhead is heavily based on `bazaar-webserve
179 <https://launchpad.net/bzr-webserve>`_, which was, in turn, loosely
180@@ -101,16 +101,16 @@
181 $ sudo chkconfig --add loggerheadd
182
183
184-Using Loggerhead as a Bazaar Plugin
185-------------------------------------
186+Using Loggerhead as a Breezy Plugin
187+-----------------------------------
188
189-This branch contains experimental support for using Loggerhead as a Bazaar
190+This branch contains experimental support for using Loggerhead as a Breezy
191 plugin. To use it, place the top-level Loggerhead directory (the one
192-containing COPYING.txt) at ``~/.bazaar/plugins/loggerhead``. E.g.:
193+containing COPYING.txt) at ``~/.config/breezy/plugins/loggerhead``. E.g.:
194
195 .. code-block:: sh
196
197- $ bzr branch lp:loggerhead ~/.bazaar/plugins/loggerhead
198+ $ bzr branch lp:loggerhead ~/.config/breezy/plugins/loggerhead
199 $ cd ~/myproject
200 $ bzr serve --http
201
202@@ -118,7 +118,7 @@
203 Using a Config File
204 -------------------
205
206-To hide branches from being displayed, add to ``~/.bazaar/locations.conf``,
207+To hide branches from being displayed, add to ``~/.config/breezy/locations.conf``,
208 under the branch's section:
209
210 .. code-block:: ini
211@@ -132,7 +132,7 @@
212 Serving Loggerhead behind Apache
213 --------------------------------
214
215-If you want to view Bazaar branches from your existing Apache
216+If you want to view Breezy branches from your existing Apache
217 installation, you'll need to configure Apache to proxy certain
218 requests to Loggerhead. Adding lines like this to your Apache
219 configuration is one way to do this:
220@@ -154,8 +154,8 @@
221
222 A second method for using Loggerhead with apache is to have apache itself
223 execute Loggerhead via mod_wsgi. You need to add configuration for apache and
224-for bazaar to make this work. Example config files are in the Loggerhead doc
225-directory as apache-loggerhead.conf and bazaar.conf. You can copy them into
226+for breezy to make this work. Example config files are in the Loggerhead doc
227+directory as apache-loggerhead.conf and breezy.conf. You can copy them into
228 place and use them as a starting point following these directions:
229
230 1) Install mod_wsgi. On Ubuntu and other Debian derived distros::
231@@ -166,19 +166,20 @@
232
233 su -c yum install mod_wsgi
234
235-2) Copy the bazaar.conf file where apache will find it (May be done for you if
236+2) Copy the breezy.conf file where apache will find it (May be done for you if
237 you installed Loggerhead from a distribution package)::
238
239 # install -d -o apache -g apache -m 0755 /etc/loggerhead
240- # cp -p /usr/share/doc/loggerhead*/bazaar.conf /etc/loggerhead/
241- # ln -s /etc/loggerhead /var/www/.bazaar
242+ # cp -p /usr/share/doc/loggerhead*/breezy.conf /etc/loggerhead/
243+ # mkdir -p /var/www/.config
244+ # ln -s /etc/loggerhead /var/www/.config/breezy
245
246 3) Create the cache directory (May be done for you if you installed Loggerhead
247 from a distribution package)::
248
249 # install -d -o apache -g apache -m 0700 /var/cache/loggerhead/
250
251-4) Edit /etc/loggerhead/bazaar.conf. You need to set http_root_dir to the filesystem
252+4) Edit /etc/loggerhead/breezy.conf. You need to set http_root_dir to the filesystem
253 path that you will find your bzr branches under. Note that normal
254 directories under that path will also be visible in Loggerhead.
255
256@@ -188,7 +189,7 @@
257
258 6) Edit /etc/httpd/conf.d/loggerhead.conf to point to the url you desire to
259 serve Loggerhead on. This should match with the setting for
260- http_user_prefix in bazaar.conf
261+ http_user_prefix in breezy.conf
262
263 7) Restart apache and you should be able to start browsing
264
265
266=== modified file 'docs/serve-branches.rst'
267--- docs/serve-branches.rst 2010-03-25 10:32:47 +0000
268+++ docs/serve-branches.rst 2018-09-08 16:37:25 +0000
269@@ -76,7 +76,7 @@
270
271 .. cmdoption:: --allow-writes
272
273- Allow writing to the Bazaar server.
274+ Allow writing to the Breezy server.
275
276 Setting this option keeps Loggerhead from adding a 'readonly+' prefix
277 to the base URL of the branch. The only effect of suppressing this prefix
278
279=== modified file 'loggerhead.wsgi'
280--- loggerhead.wsgi 2012-02-08 01:50:02 +0000
281+++ loggerhead.wsgi 2018-09-08 16:37:25 +0000
282@@ -23,9 +23,9 @@
283 from loggerhead.apps.transport import BranchesFromTransportRoot
284 from loggerhead.apps.error import ErrorHandlerApp
285 from loggerhead.config import LoggerheadConfig
286-from bzrlib import config as bzrconfig
287+from breezy import config as bzrconfig
288 from paste.deploy.config import PrefixMiddleware
289-from bzrlib.plugin import load_plugins
290+from breezy.plugin import load_plugins
291
292 class NotConfiguredError(Exception):
293 pass
294@@ -36,9 +36,12 @@
295 prefix = config.get_option('user_prefix') or ''
296 # Note we could use LoggerheadConfig here if it didn't fail when a
297 # config option is not also a commandline option
298-root_dir = bzrconfig.GlobalConfig().get_user_option('http_root_dir')
299-if not root_dir:
300- raise NotConfiguredError('You must have a ~/.bazaar/bazaar.conf file for'
301+root_dir = os.getenv('LOGGERHEAD_ROOT_DIR')
302+if not root_dir:
303+ root_dir = bzrconfig.GlobalConfig().get_user_option('http_root_dir')
304+if not root_dir:
305+ raise NotConfiguredError('You must set LOGGERHEAD_ROOT_DIR or have '
306+ 'a ~/.config/breezy/breezy.conf file for'
307 ' %(user)s with http_root_dir set to the base directory you want'
308 ' to serve bazaar repositories from' %
309 {'user': pwd.getpwuid(os.geteuid()).pw_name})
310
311=== modified file 'loggerhead/__init__.py'
312--- loggerhead/__init__.py 2012-09-11 20:49:32 +0000
313+++ loggerhead/__init__.py 2018-09-08 16:37:25 +0000
314@@ -24,7 +24,7 @@
315
316 __version__ = '1.18.2' # Keep in sync with ../info.py.
317 __revision__ = None
318-required_bzrlib = (1, 17)
319+required_breezy = (1, 17)
320
321 pkg_resources.get_distribution('Paste>=1.6')
322 try:
323@@ -32,12 +32,3 @@
324 except pkg_resources.DistributionNotFound:
325 # No paste.deploy is OK, but an old paste.deploy is bad.
326 pass
327-
328-try:
329- from bzrlib.branch import Branch
330- branch = Branch.open('./');
331-
332- __revision__ = branch.revno()
333-
334-except:
335- pass
336
337=== modified file 'loggerhead/apps/branch.py'
338--- loggerhead/apps/branch.py 2012-02-08 01:50:02 +0000
339+++ loggerhead/apps/branch.py 2018-09-08 16:37:25 +0000
340@@ -19,11 +19,12 @@
341 import logging
342 import urllib
343 import sys
344+import wsgiref.util
345
346-import bzrlib.branch
347-import bzrlib.errors
348-from bzrlib.hooks import Hooks
349-import bzrlib.lru_cache
350+import breezy.branch
351+import breezy.errors
352+from breezy.hooks import Hooks
353+import breezy.lru_cache
354
355 from paste import request
356 from paste import httpexceptions
357@@ -63,7 +64,7 @@
358 self.branch_link = branch_link # Currently only used in Launchpad
359 self.log = logging.getLogger('loggerhead.%s' % (friendly_name,))
360 if graph_cache is None:
361- graph_cache = bzrlib.lru_cache.LRUCache(10)
362+ graph_cache = breezy.lru_cache.LRUCache(10)
363 self.graph_cache = graph_cache
364 self.is_root = is_root
365 self.served_url = served_url
366@@ -93,6 +94,20 @@
367 return History(
368 self.branch, self.graph_cache,
369 revinfo_disk_cache=revinfo_disk_cache, cache_key=self.friendly_name)
370+
371+ # Before the addition of this method, clicking to sort by date from
372+ # within a branch caused a jump up to the top of that branch.
373+ def sort_url(self, *args, **kw):
374+ if isinstance(args[0], list):
375+ args = args[0]
376+ qs = []
377+ for k, v in kw.iteritems():
378+ if v is not None:
379+ qs.append('%s=%s' % (k, urllib.quote(v)))
380+ qs = '&'.join(qs)
381+ path_info = self._path_info.strip('/').split('?')[0]
382+ path_info += '?' + qs
383+ return self._url_base + '/' + path_info
384
385 def url(self, *args, **kw):
386 if isinstance(args[0], list):
387@@ -155,6 +170,7 @@
388 if self.branch.get_config().get_user_option('http_serve') == 'False':
389 raise httpexceptions.HTTPNotFound()
390 self._url_base = environ['SCRIPT_NAME']
391+ self._path_info = environ['PATH_INFO']
392 self._static_url_base = environ.get('loggerhead.static.url')
393 if self._static_url_base is None:
394 self._static_url_base = self._url_base
395@@ -164,13 +180,7 @@
396 if public_branch is not None:
397 self.served_url = public_branch
398 else:
399- # Loggerhead only supports serving .bzr/ on local branches, so
400- # we shouldn't suggest something that won't work.
401- try:
402- util.local_path_from_url(self.branch.base)
403- self.served_url = self.url([])
404- except bzrlib.errors.InvalidURL:
405- self.served_url = None
406+ self.served_url = wsgiref.util.application_uri(environ)
407 for hook in self.hooks['controller']:
408 controller = hook(self, environ)
409 if controller is not None:
410@@ -210,7 +220,7 @@
411 def __init__(self):
412 """Create the default hooks.
413 """
414- Hooks.__init__(self, "bzrlib.plugins.loggerhead.apps.branch",
415+ Hooks.__init__(self, "breezy.plugins.loggerhead.apps.branch",
416 "BranchWSGIApp.hooks")
417 self.add_hook('controller',
418 "Invoked when looking for the controller to use for a "
419
420=== modified file 'loggerhead/apps/transport.py'
421--- loggerhead/apps/transport.py 2012-02-08 01:50:02 +0000
422+++ loggerhead/apps/transport.py 2018-09-08 16:37:25 +0000
423@@ -18,11 +18,11 @@
424
425 import threading
426
427-from bzrlib import branch, errors, lru_cache, urlutils
428-from bzrlib.config import LocationConfig
429-from bzrlib.smart import request
430-from bzrlib.transport import get_transport
431-from bzrlib.transport.http import wsgi
432+from breezy import branch, errors, lru_cache, urlutils
433+from breezy.config import LocationConfig
434+from breezy.bzr.smart import request
435+from breezy.transport import get_transport
436+from breezy.transport.http import wsgi
437
438 from paste.request import path_info_pop
439 from paste import httpexceptions
440@@ -33,13 +33,6 @@
441 from loggerhead.apps import favicon_app, robots_app, static_app
442 from loggerhead.controllers.directory_ui import DirectoryUI
443
444-# TODO: Use bzrlib.ui.bool_from_string(), added in bzr 1.18
445-_bools = {
446- 'yes': True, 'no': False,
447- 'on': True, 'off': False,
448- '1': True, '0': False,
449- 'true': True, 'false': False,
450- }
451
452 class BranchesFromTransportServer(object):
453
454@@ -106,8 +99,12 @@
455 value = config.get_user_option('http_serve')
456 if value is None:
457 return
458- elif not _bools.get(value.lower(), True):
459- raise httpexceptions.HTTPNotFound()
460+ else:
461+ serveable = breezy.ui.bool_from_string(value)
462+ if serveable is None:
463+ serveable = True
464+ if not serveable:
465+ raise httpexceptions.HTTPNotFound()
466
467 def __call__(self, environ, start_response):
468 path = environ['PATH_INFO']
469
470=== modified file 'loggerhead/config.py'
471--- loggerhead/config.py 2011-07-07 19:09:11 +0000
472+++ loggerhead/config.py 2018-09-08 16:37:25 +0000
473@@ -17,7 +17,7 @@
474 import sys
475 import tempfile
476
477-from bzrlib import config
478+from breezy import config
479
480 _temporary_sql_dir = None
481
482@@ -120,7 +120,7 @@
483
484 def get_option(self, option):
485 """Get the value for the config option, either
486- from ~/.bazaar/bazaar.conf or from the command line.
487+ from ~/.config/breezy/breezy.conf or from the command line.
488 All loggerhead-specific settings start with 'http_'
489 """
490 global_config = config.GlobalConfig().get_user_option('http_'+option)
491
492=== modified file 'loggerhead/controllers/__init__.py'
493--- loggerhead/controllers/__init__.py 2012-02-08 01:50:02 +0000
494+++ loggerhead/controllers/__init__.py 2018-09-08 16:37:25 +0000
495@@ -17,7 +17,7 @@
496 # along with this program; if not, write to the Free Software
497 # Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
498
499-import bzrlib.errors
500+import breezy.errors
501 import simplejson
502 import time
503
504@@ -135,7 +135,7 @@
505 if len(self.args) > 0 and self.args != ['']:
506 try:
507 revid = h.fix_revid(self.args[0])
508- except bzrlib.errors.NoSuchRevision:
509+ except breezy.errors.NoSuchRevision:
510 raise HTTPNotFound;
511 else:
512 revid = h.last_revid
513
514=== modified file 'loggerhead/controllers/annotate_ui.py'
515--- loggerhead/controllers/annotate_ui.py 2012-02-08 01:50:02 +0000
516+++ loggerhead/controllers/annotate_ui.py 2018-09-08 16:37:25 +0000
517@@ -26,6 +26,7 @@
518 def annotate_file(self, info):
519 file_id = info['file_id']
520 revid = info['change'].revid
521+ path = self._history.get_path(revid, file_id)
522
523 tree = self.tree_for(file_id, revid)
524
525@@ -37,7 +38,7 @@
526 revisions = {}
527
528 lineno = 0
529- for (line_revid, text), lineno in zip(tree.annotate_iter(file_id), itertools.count(1)):
530+ for (line_revid, text), lineno in zip(tree.annotate_iter(path, file_id), itertools.count(1)):
531 if line_revid != last_line_revid:
532 last_line_revid = line_revid
533
534
535=== modified file 'loggerhead/controllers/diff_ui.py'
536--- loggerhead/controllers/diff_ui.py 2012-07-31 20:25:42 +0000
537+++ loggerhead/controllers/diff_ui.py 2018-09-08 16:37:25 +0000
538@@ -21,8 +21,8 @@
539
540 from paste.request import path_info_pop, parse_querystring
541
542-from bzrlib.diff import show_diff_trees
543-from bzrlib.revision import NULL_REVISION
544+from breezy.diff import show_diff_trees
545+from breezy.revision import NULL_REVISION
546
547 from loggerhead.controllers import TemplatedBranchView
548
549
550=== modified file 'loggerhead/controllers/directory_ui.py'
551--- loggerhead/controllers/directory_ui.py 2012-02-08 01:50:02 +0000
552+++ loggerhead/controllers/directory_ui.py 2018-09-08 16:37:25 +0000
553@@ -19,8 +19,9 @@
554 import datetime
555 import logging
556 import stat
557+import urllib
558
559-from bzrlib import branch, errors
560+from breezy import branch, errors
561
562 from loggerhead import util
563 from loggerhead.controllers import TemplatedBranchView
564@@ -29,18 +30,17 @@
565 class DirEntry(object):
566
567 def __init__(self, dirname, parity, branch):
568- self.dirname = dirname
569+ self.dirname = urllib.unquote(dirname)
570 self.parity = parity
571 self.branch = branch
572 if branch is not None:
573 # If a branch is empty, bzr raises an exception when trying this
574 try:
575- self.last_change = datetime.datetime.utcfromtimestamp(
576- branch.repository.get_revision(
577- branch.last_revision()).timestamp)
578+ self.last_revision = branch.repository.get_revision(branch.last_revision())
579+ self.last_change_time = datetime.datetime.utcfromtimestamp(self.last_revision.timestamp)
580 except:
581- self.last_change = None
582-
583+ self.last_revision = None
584+ self.last_change_time = None
585
586 class DirectoryUI(TemplatedBranchView):
587 """
588
589=== modified file 'loggerhead/controllers/download_ui.py'
590--- loggerhead/controllers/download_ui.py 2012-03-22 14:09:52 +0000
591+++ loggerhead/controllers/download_ui.py 2018-09-08 16:37:25 +0000
592@@ -21,7 +21,7 @@
593 import mimetypes
594 import urllib
595
596-from bzrlib.errors import (
597+from breezy.errors import (
598 NoSuchId,
599 NoSuchRevision,
600 )
601@@ -29,7 +29,6 @@
602 from paste.request import path_info_pop
603
604 from loggerhead.controllers import TemplatedBranchView
605-from loggerhead.exporter import export_archive
606
607 log = logging.getLogger("loggerhead.controllers")
608
609@@ -102,12 +101,13 @@
610 # TODO: Perhaps set the tarball suggested mtime to the revision
611 # mtime.
612 root = self._branch.friendly_name or 'branch'
613- encoded_filename = self.encode_filename(
614- root + version_part + '.' + archive_format)
615+ filename = root + version_part + '.' + archive_format
616+ encoded_filename = self.encode_filename(filename)
617 headers = [
618 ('Content-Type', 'application/octet-stream'),
619 ('Content-Disposition',
620 "attachment; filename*=utf-8''%s" % (encoded_filename,)),
621 ]
622 start_response('200 OK', headers)
623- return export_archive(history, root, revid, archive_format)
624+ tree = history._branch.repository.revision_tree(revid)
625+ return tree.archive(root=root, format=archive_format, name=filename)
626
627=== modified file 'loggerhead/controllers/filediff_ui.py'
628--- loggerhead/controllers/filediff_ui.py 2015-03-19 14:48:47 +0000
629+++ loggerhead/controllers/filediff_ui.py 2018-09-08 16:37:25 +0000
630@@ -1,9 +1,9 @@
631 from StringIO import StringIO
632 import urllib
633
634-from bzrlib import diff
635-from bzrlib import errors
636-from bzrlib import osutils
637+from breezy import diff
638+from breezy import errors
639+from breezy import osutils
640
641 from loggerhead import util
642 from loggerhead.controllers import TemplatedBranchView
643@@ -60,12 +60,12 @@
644 lines = {}
645 args = []
646 for r in (compare_revid, revid):
647- if r == 'null:':
648+ if r == b'null:':
649 lines[r] = []
650 else:
651 args.append((file_id, r, r))
652 for r, bytes_iter in repository.iter_files_bytes(args):
653- lines[r] = osutils.split_lines(''.join(bytes_iter))
654+ lines[r] = osutils.split_lines(b''.join(bytes_iter))
655 buffer = StringIO()
656 try:
657 diff.internal_diff('', lines[compare_revid], '', lines[revid], buffer, context_lines=context_lines)
658
659=== modified file 'loggerhead/controllers/inventory_ui.py'
660--- loggerhead/controllers/inventory_ui.py 2013-03-27 05:29:14 +0000
661+++ loggerhead/controllers/inventory_ui.py 2018-09-08 16:37:25 +0000
662@@ -24,8 +24,8 @@
663
664 from paste.httpexceptions import HTTPNotFound, HTTPMovedPermanently
665
666-from bzrlib import errors
667-from bzrlib.revision import is_null as is_null_rev
668+from breezy import errors
669+from breezy.revision import is_null as is_null_rev
670
671 from loggerhead import util
672 from loggerhead.controllers import TemplatedBranchView
673@@ -44,51 +44,61 @@
674 template_path = 'loggerhead.templates.inventory'
675 supports_json = True
676
677- def get_filelist(self, inv, path, sort_type, revno_url):
678+ def get_filelist(self, tree, path, sort_type, revno_url):
679 """
680 return the list of all files (and their attributes) within a given
681 path subtree.
682
683- @param inv: The inventory.
684- @param path: The path of a directory within the inventory.
685+ @param tree: The tree
686+ @param path: The path of a directory within the tree.
687 @param sort_type: How to sort the results... XXX.
688 """
689- file_id = inv.path2id(path)
690- dir_ie = inv[file_id]
691 file_list = []
692
693- if dir_ie.kind != 'directory':
694+ if tree.kind(path) != 'directory':
695 raise HTTPMovedPermanently(self._branch.context_url(['/view', revno_url, path]))
696
697 revid_set = set()
698
699- for filename, entry in dir_ie.children.iteritems():
700+ child_entries = list(tree.iter_child_entries(path))
701+
702+ for entry in child_entries:
703 revid_set.add(entry.revision)
704
705 change_dict = {}
706 for change in self._history.get_changes(list(revid_set)):
707 change_dict[change.revid] = change
708
709- for filename, entry in dir_ie.children.iteritems():
710- pathname = filename
711- if entry.kind == 'directory':
712- pathname += '/'
713+ for entry in child_entries:
714+ revid = entry.revision
715+ file_timestamp = change_dict[revid].timestamp
716+ pathname = entry.name
717+ contents_changed_rev = None
718 if path == '':
719 absolutepath = pathname
720 else:
721 absolutepath = path + '/' + pathname
722- revid = entry.revision
723-
724+ if entry.kind == 'directory':
725+ # determine the last time something in the folder was changed
726+ pathname += '/'
727+ sub_revid_set = set()
728+ for sub_entry in tree.iter_child_entries(absolutepath):
729+ sub_revid_set.add(sub_entry.revision)
730+ for change in self._history.get_changes(list(sub_revid_set)):
731+ change_dict[change.revid] = change
732+ if(change.timestamp > file_timestamp):
733+ revid = change.revid
734+ file_timestamp = change.timestamp
735 # TODO: For the JSON rendering, this inlines the "change" aka
736 # revision information attached to each file. Consider either
737 # pulling this out as a separate changes dict, or possibly just
738 # including the revision id and having a separate request to get
739 # back the revision info.
740 file = util.Container(
741- filename=filename, executable=entry.executable,
742+ filename=entry.name, executable=entry.executable,
743 kind=entry.kind, absolutepath=absolutepath,
744 file_id=entry.file_id, size=entry.text_size, revid=revid,
745- change=change_dict[revid])
746+ change=change_dict[revid], contents_changed=contents_changed_rev)
747 file_list.append(file)
748
749 if sort_type == 'filename':
750@@ -96,10 +106,11 @@
751 elif sort_type == 'size':
752 file_list.sort(key=lambda x: x.size)
753 elif sort_type == 'date':
754- file_list.sort(key=lambda x: x.change.date)
755-
756- # Always sort directories first.
757- file_list.sort(key=lambda x: x.kind != 'directory')
758+ file_list.sort(key=lambda x: x.change.date, reverse=True)
759+
760+ if sort_type != 'date':
761+ # Don't always sort directories first.
762+ file_list.sort(key=lambda x: x.kind != 'directory')
763
764 return file_list
765
766@@ -144,7 +155,7 @@
767 else:
768 revno_url = history.get_revno(revid)
769 history.add_branch_nicks(change)
770- filelist = self.get_filelist(rev_tree.inventory, path, sort_type, revno_url)
771+ filelist = self.get_filelist(rev_tree, path, sort_type, revno_url)
772
773 else:
774 start_revid = None
775
776=== modified file 'loggerhead/controllers/view_ui.py'
777--- loggerhead/controllers/view_ui.py 2012-03-22 14:09:52 +0000
778+++ loggerhead/controllers/view_ui.py 2018-09-08 16:37:25 +0000
779@@ -19,13 +19,13 @@
780
781 import os
782
783-from bzrlib.errors import (
784+from breezy.errors import (
785 BinaryFile,
786 NoSuchId,
787 NoSuchRevision,
788 )
789-import bzrlib.textfile
790-import bzrlib.osutils
791+import breezy.textfile
792+import breezy.osutils
793
794 from paste.httpexceptions import (
795 HTTPBadRequest,
796@@ -47,14 +47,16 @@
797 template_path = 'loggerhead.templates.view'
798
799 def tree_for(self, file_id, revid):
800- file_revid = self._history.get_inventory(revid)[file_id].revision
801+ rev_tree = self._history.revision_tree(revid)
802+ file_revid = rev_tree.get_file_revision(rev_tree.id2path(file_id), file_id)
803 return self._history._branch.repository.revision_tree(file_revid)
804
805 def text_lines(self, file_id, revid):
806- file_name = os.path.basename(self._history.get_path(revid, file_id))
807+ path = self._history.get_path(revid, file_id)
808+ file_name = os.path.basename(path)
809
810 tree = self.tree_for(file_id, revid)
811- file_text = tree.get_file_text(file_id)
812+ file_text = tree.get_file_text(path, file_id)
813 encoding = 'utf-8'
814 try:
815 file_text = file_text.decode(encoding)
816@@ -62,9 +64,9 @@
817 encoding = 'iso-8859-15'
818 file_text = file_text.decode(encoding)
819
820- file_lines = bzrlib.osutils.split_lines(file_text)
821- # This can throw bzrlib.errors.BinaryFile (which our caller catches).
822- bzrlib.textfile.check_text_lines(file_lines)
823+ file_lines = breezy.osutils.split_lines(file_text)
824+ # This can throw breezy.errors.BinaryFile (which our caller catches).
825+ breezy.textfile.check_text_lines(file_lines)
826
827 if highlight is not None:
828 hl_lines = highlight(file_name, file_text, encoding)
829@@ -119,20 +121,15 @@
830 self._branch.is_root,
831 'files'))
832
833+ tree = history.revision_tree(revid)
834+
835 # Create breadcrumb trail for the path within the branch
836- try:
837- inv = history.get_inventory(revid)
838- except:
839- self.log.exception('Exception fetching changes')
840- raise HTTPServerError('Could not fetch changes')
841- branch_breadcrumbs = util.branch_breadcrumbs(path, inv, 'files')
842+ branch_breadcrumbs = util.branch_breadcrumbs(path, tree, 'files')
843
844- try:
845- file = inv[file_id]
846- except NoSuchId:
847+ if not tree.has_id(file_id):
848 raise HTTPNotFound()
849
850- if file.kind == "directory":
851+ if tree.kind(path, file_id) == "directory":
852 raise HTTPMovedPermanently(self._branch.context_url(['/files', revno_url, path]))
853
854 # no navbar for revisions
855
856=== removed file 'loggerhead/exporter.py'
857--- loggerhead/exporter.py 2011-11-24 07:46:41 +0000
858+++ loggerhead/exporter.py 1970-01-01 00:00:00 +0000
859@@ -1,60 +0,0 @@
860-# Copyright (C) 2011 Canonical Ltd
861-#
862-# This program is free software; you can redistribute it and/or modify
863-# it under the terms of the GNU General Public License as published by
864-# the Free Software Foundation; either version 2 of the License, or
865-# (at your option) any later version.
866-#
867-# This program is distributed in the hope that it will be useful,
868-# but WITHOUT ANY WARRANTY; without even the implied warranty of
869-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
870-# GNU General Public License for more details.
871-#
872-"""Exports an archive from a bazaar branch"""
873-
874-from bzrlib.export import get_export_generator
875-
876-
877-class ExporterFileObject(object):
878- """Shim that accumulates temporarily written out data.
879-
880- There are python tarfile classes that want to write to a file like object.
881- We want to stream data. But wsgi assumes it can pull data from the
882- handler, rather than having bytes pushed.
883-
884- So this class holds the data temporarily, until it is pulled. It
885- should never buffer everything because as soon as a chunk is produced,
886- wsgi will be given the chance to take it.
887- """
888-
889- def __init__(self):
890- self._buffer = []
891-
892- def write(self, s):
893- self._buffer.append(s)
894-
895- def get_buffer(self):
896- try:
897- return ''.join(self._buffer)
898- finally:
899- self._buffer = []
900-
901- def close(self):
902- pass
903-
904-
905-def export_archive(history, root, revid, archive_format):
906- """Export tree contents to an archive
907-
908- :param history: Instance of history to export
909- :param root: Root location inside the archive.
910- :param revid: Revision to export
911- :param archive_format: Format of the archive, eg 'tar.gz'.
912- """
913- fileobj = ExporterFileObject()
914- tree = history._branch.repository.revision_tree(revid)
915- for _ in get_export_generator(tree=tree, root=root, fileobj=fileobj,
916- format=archive_format):
917- yield fileobj.get_buffer()
918- # Might have additonal contents written
919- yield fileobj.get_buffer()
920
921=== modified file 'loggerhead/highlight.py'
922--- loggerhead/highlight.py 2012-02-08 01:50:02 +0000
923+++ loggerhead/highlight.py 2018-09-08 16:37:25 +0000
924@@ -16,7 +16,7 @@
925 # Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
926 #
927
928-import bzrlib.osutils
929+import breezy.osutils
930 import cgi
931
932 from pygments import highlight as _highlight_func
933@@ -37,7 +37,7 @@
934 """
935
936 if len(text) > MAX_HIGHLIGHT_SIZE:
937- return map(cgi.escape, bzrlib.osutils.split_lines(text))
938+ return map(cgi.escape, breezy.osutils.split_lines(text))
939
940 formatter = HtmlFormatter(style=style, nowrap=True, classprefix='pyg-')
941
942@@ -50,6 +50,6 @@
943 lexer = TextLexer(encoding=encoding)
944
945 hl_lines = _highlight_func(text, lexer, formatter)
946- hl_lines = bzrlib.osutils.split_lines(hl_lines)
947+ hl_lines = breezy.osutils.split_lines(hl_lines)
948
949 return hl_lines
950
951=== modified file 'loggerhead/history.py'
952--- loggerhead/history.py 2016-03-30 06:18:39 +0000
953+++ loggerhead/history.py 2018-09-08 16:37:25 +0000
954@@ -35,12 +35,13 @@
955 import threading
956 import tarfile
957
958-from bzrlib import tag
959-import bzrlib.branch
960-import bzrlib.delta
961-import bzrlib.errors
962-import bzrlib.foreign
963-import bzrlib.revision
964+from breezy import tag
965+import breezy.branch
966+import breezy.delta
967+import breezy.errors
968+import breezy.foreign
969+import breezy.osutils
970+import breezy.revision
971
972 from loggerhead import search
973 from loggerhead import util
974@@ -49,7 +50,7 @@
975
976 def is_branch(folder):
977 try:
978- bzrlib.branch.Branch.open(folder)
979+ breezy.branch.Branch.open(folder)
980 return True
981 except:
982 return False
983@@ -108,19 +109,20 @@
984
985 class FileChangeReporter(object):
986
987- def __init__(self, old_inv, new_inv):
988+ def __init__(self, old_tree, new_tree):
989 self.added = []
990 self.modified = []
991 self.renamed = []
992 self.removed = []
993 self.text_changes = []
994- self.old_inv = old_inv
995- self.new_inv = new_inv
996+ self.old_tree = old_tree
997+ self.new_tree = new_tree
998
999- def revid(self, inv, file_id):
1000+ def revid(self, tree, file_id):
1001 try:
1002- return inv[file_id].revision
1003- except bzrlib.errors.NoSuchId:
1004+ path = tree.id2path(file_id)
1005+ return tree.get_file_revision(path, file_id)
1006+ except breezy.errors.NoSuchId:
1007 return 'null:'
1008
1009 def report(self, file_id, paths, versioned, renamed, modified,
1010@@ -132,8 +134,8 @@
1011 filename = rich_filename(paths[1], kind[1])
1012 self.text_changes.append(util.Container(
1013 filename=filename, file_id=file_id,
1014- old_revision=self.revid(self.old_inv, file_id),
1015- new_revision=self.revid(self.new_inv, file_id)))
1016+ old_revision=self.revid(self.old_tree, file_id),
1017+ new_revision=self.revid(self.new_tree, file_id)))
1018 if versioned == 'added':
1019 self.added.append(util.Container(
1020 filename=rich_filename(paths[1], kind), kind=kind[1]))
1021@@ -299,7 +301,7 @@
1022
1023 @property
1024 def has_revisions(self):
1025- return not bzrlib.revision.is_null(self.last_revid)
1026+ return not breezy.revision.is_null(self.last_revid)
1027
1028 def get_config(self):
1029 return self._branch.get_config()
1030@@ -320,7 +322,7 @@
1031 if revid_list is None:
1032 # Just yield the mainline, starting at start_revid
1033 revid = start_revid
1034- is_null = bzrlib.revision.is_null
1035+ is_null = breezy.revision.is_null
1036 while not is_null(revid):
1037 yield revid
1038 parents = self._rev_info[self._rev_indices[revid]][2]
1039@@ -341,7 +343,7 @@
1040 i += 1
1041 return r
1042 while revid_set:
1043- if bzrlib.revision.is_null(revid):
1044+ if breezy.revision.is_null(revid):
1045 return
1046 rev_introduced = introduced_revisions(revid)
1047 matching = rev_introduced.intersection(revid_set)
1048@@ -360,7 +362,7 @@
1049 possible_keys = [(file_id, revid) for revid in self._rev_indices]
1050 get_parent_map = self._branch.repository.texts.get_parent_map
1051 # We chunk the requests as this works better with GraphIndex.
1052- # See _filter_revisions_touching_file_id in bzrlib/log.py
1053+ # See _filter_revisions_touching_file_id in breezy/log.py
1054 # for more information.
1055 revids = []
1056 chunk_size = 1000
1057@@ -454,7 +456,7 @@
1058 if self.revno_re.match(revid):
1059 revid = self._revno_revid[revid]
1060 except KeyError:
1061- raise bzrlib.errors.NoSuchRevision(self._branch_nick, revid)
1062+ raise breezy.errors.NoSuchRevision(self._branch_nick, revid)
1063 return revid
1064
1065 def get_file_view(self, revid, file_id):
1066@@ -564,16 +566,13 @@
1067 # search index.
1068 return None, None, []
1069
1070- def get_inventory(self, revid):
1071- if revid not in self._inventory_cache:
1072- self._inventory_cache[revid] = (
1073- self._branch.repository.get_inventory(revid))
1074- return self._inventory_cache[revid]
1075+ def revision_tree(self, revid):
1076+ return self._branch.repository.revision_tree(revid)
1077
1078 def get_path(self, revid, file_id):
1079 if (file_id is None) or (file_id == ''):
1080 return ''
1081- path = self.get_inventory(revid).id2path(file_id)
1082+ path = self.revision_tree(revid).id2path(file_id)
1083 if (len(path) > 0) and not path.startswith('/'):
1084 path = '/' + path
1085 return path
1086@@ -581,7 +580,7 @@
1087 def get_file_id(self, revid, path):
1088 if (len(path) > 0) and not path.startswith('/'):
1089 path = '/' + path
1090- return self.get_inventory(revid).path2id(path)
1091+ return self.revision_tree(revid).path2id(path)
1092
1093 def get_merge_point_list(self, revid):
1094 """
1095@@ -674,7 +673,7 @@
1096
1097 def get_changes_uncached(self, revid_list):
1098 # FIXME: deprecated method in getting a null revision
1099- revid_list = filter(lambda revid: not bzrlib.revision.is_null(revid),
1100+ revid_list = filter(lambda revid: not breezy.revision.is_null(revid),
1101 revid_list)
1102 parent_map = self._branch.repository.get_graph().get_parent_map(
1103 revid_list)
1104@@ -688,7 +687,7 @@
1105
1106 def _change_from_revision(self, revision):
1107 """
1108- Given a bzrlib Revision, return a processed "change" for use in
1109+ Given a breezy Revision, return a processed "change" for use in
1110 templates.
1111 """
1112 message, short_message = clean_message(revision.message)
1113@@ -712,6 +711,7 @@
1114 'revid': revision.revision_id,
1115 'date': datetime.datetime.fromtimestamp(revision.timestamp),
1116 'utc_date': datetime.datetime.utcfromtimestamp(revision.timestamp),
1117+ 'timestamp': revision.timestamp,
1118 'committer': revision.committer,
1119 'authors': revision.get_apparent_authors(),
1120 'branch_nick': revision.properties.get('branch-nick', None),
1121@@ -722,15 +722,15 @@
1122 'bugs': [bug.split()[0] for bug in revision.properties.get('bugs', '').splitlines()],
1123 'tags': revtags,
1124 }
1125- if isinstance(revision, bzrlib.foreign.ForeignRevision):
1126+ if isinstance(revision, breezy.foreign.ForeignRevision):
1127 foreign_revid, mapping = (
1128 revision.foreign_revid, revision.mapping)
1129 elif ":" in revision.revision_id:
1130 try:
1131 foreign_revid, mapping = \
1132- bzrlib.foreign.foreign_vcs_registry.parse_revision_id(
1133+ breezy.foreign.foreign_vcs_registry.parse_revision_id(
1134 revision.revision_id)
1135- except bzrlib.errors.InvalidRevisionId:
1136+ except breezy.errors.InvalidRevisionId:
1137 foreign_revid = None
1138 mapping = None
1139 else:
1140@@ -744,7 +744,7 @@
1141 if entry.parents:
1142 old_revid = entry.parents[0].revid
1143 else:
1144- old_revid = bzrlib.revision.NULL_REVISION
1145+ old_revid = breezy.revision.NULL_REVISION
1146 return self.file_changes_for_revision_ids(old_revid, entry.revid)
1147
1148 def add_changes(self, entry):
1149@@ -753,13 +753,12 @@
1150
1151 def get_file(self, file_id, revid):
1152 """Returns (path, filename, file contents)"""
1153- inv = self.get_inventory(revid)
1154- inv_entry = inv[file_id]
1155- rev_tree = self._branch.repository.revision_tree(inv_entry.revision)
1156- path = inv.id2path(file_id)
1157- if not path.startswith('/'):
1158+ rev_tree = self._branch.repository.revision_tree(revid)
1159+ path = rev_tree.id2path(file_id)
1160+ display_path = path
1161+ if not display_path.startswith('/'):
1162 path = '/' + path
1163- return path, inv_entry.name, rev_tree.get_file_text(file_id)
1164+ return display_path, breezy.osutils.basename(path), rev_tree.get_file_text(path, file_id)
1165
1166 def file_changes_for_revision_ids(self, old_revid, new_revid):
1167 """
1168@@ -775,17 +774,17 @@
1169 text_changes: list((filename, file_id)),
1170 """
1171 repo = self._branch.repository
1172- if (bzrlib.revision.is_null(old_revid) or
1173- bzrlib.revision.is_null(new_revid) or
1174+ if (breezy.revision.is_null(old_revid) or
1175+ breezy.revision.is_null(new_revid) or
1176 old_revid == new_revid):
1177 old_tree, new_tree = map(
1178 repo.revision_tree, [old_revid, new_revid])
1179 else:
1180 old_tree, new_tree = repo.revision_trees([old_revid, new_revid])
1181
1182- reporter = FileChangeReporter(old_tree.inventory, new_tree.inventory)
1183+ reporter = FileChangeReporter(old_tree, new_tree)
1184
1185- bzrlib.delta.report_changes(new_tree.iter_changes(old_tree), reporter)
1186+ breezy.delta.report_changes(new_tree.iter_changes(old_tree), reporter)
1187
1188 return util.Container(
1189 added=sorted(reporter.added, key=lambda x: x.filename),
1190
1191=== modified file 'loggerhead/load_test.py'
1192--- loggerhead/load_test.py 2012-02-08 01:50:02 +0000
1193+++ loggerhead/load_test.py 2018-09-08 16:37:25 +0000
1194@@ -69,13 +69,13 @@
1195
1196 import simplejson
1197
1198-from bzrlib import (
1199+from breezy import (
1200 errors,
1201 transport,
1202 urlutils,
1203 )
1204
1205-# This code will be doing multi-threaded requests against bzrlib.transport
1206+# This code will be doing multi-threaded requests against breezy.transport
1207 # code. We want to make sure to load everything ahead of time, so we don't get
1208 # lazy-import failures
1209 _ = transport.get_transport('http://example.com')
1210
1211=== modified file 'loggerhead/main.py'
1212--- loggerhead/main.py 2012-02-08 01:50:02 +0000
1213+++ loggerhead/main.py 2018-09-08 16:37:25 +0000
1214@@ -21,7 +21,8 @@
1215 import os
1216 import sys
1217
1218-from bzrlib.plugin import load_plugins
1219+from breezy.plugin import load_plugins
1220+from breezy.transport import location_to_url
1221
1222 from paste import httpserver
1223 from paste.httpexceptions import HTTPExceptionHandler, HTTPInternalServerError
1224@@ -35,7 +36,7 @@
1225 from loggerhead.apps.error import ErrorHandlerApp
1226
1227
1228-def get_config_and_path(args):
1229+def get_config_and_base(args):
1230 config = LoggerheadConfig(args)
1231
1232 if config.get_option('show_version'):
1233@@ -50,6 +51,8 @@
1234 else:
1235 base = '.'
1236
1237+ base = location_to_url(base)
1238+
1239 if not config.get_option('allow_writes'):
1240 base = 'readonly+' + base
1241
1242@@ -92,7 +95,7 @@
1243 return logger
1244
1245
1246-def make_app_for_config_and_path(config, base):
1247+def make_app_for_config_and_base(config, base):
1248 if config.get_option('trunk_dir') and not config.get_option('user_dirs'):
1249 print "--trunk-dir is only valid with --user-dirs"
1250 sys.exit(1)
1251@@ -141,6 +144,9 @@
1252 raise exc
1253 return app(environ, start_response)
1254 return wrapped
1255+ logging.warning(
1256+ 'PasteDeploy not available; unable to support '
1257+ 'access through a reverse proxy.')
1258 app = check_not_proxied(app)
1259 else:
1260 app = PrefixMiddleware(app, prefix=prefix)
1261@@ -155,9 +161,9 @@
1262 def main(args):
1263 load_plugins()
1264
1265- config, path = get_config_and_path(args)
1266+ config, base = get_config_and_base(args)
1267
1268- app = make_app_for_config_and_path(config, path)
1269+ app = make_app_for_config_and_base(config, base)
1270
1271 if not config.get_option('user_port'):
1272 port = '8080'
1273
1274=== modified file 'loggerhead/middleware/profile.py'
1275--- loggerhead/middleware/profile.py 2009-10-17 08:47:38 +0000
1276+++ loggerhead/middleware/profile.py 2018-09-08 16:37:25 +0000
1277@@ -2,7 +2,7 @@
1278
1279 import threading
1280
1281-from bzrlib.lsprof import profile
1282+from breezy.lsprof import profile
1283
1284
1285 class LSProfMiddleware(object):
1286
1287=== modified file 'loggerhead/search.py'
1288--- loggerhead/search.py 2012-02-08 01:50:02 +0000
1289+++ loggerhead/search.py 2018-09-08 16:37:25 +0000
1290@@ -24,9 +24,9 @@
1291 if _mod_index is not None:
1292 return
1293 try:
1294- from bzrlib.plugins.search import errors
1295- from bzrlib.plugins.search import index as _mod_index
1296- from bzrlib.plugins.search.index import FileTextHit, RevisionHit
1297+ from breezy.plugins.search import errors
1298+ from breezy.plugins.search import index as _mod_index
1299+ from breezy.plugins.search.index import FileTextHit, RevisionHit
1300 except ImportError:
1301 _mod_index = None
1302
1303
1304=== modified file 'loggerhead/static/css/global.css'
1305--- loggerhead/static/css/global.css 2015-03-17 11:38:32 +0000
1306+++ loggerhead/static/css/global.css 2018-09-08 16:37:25 +0000
1307@@ -230,11 +230,11 @@
1308 }
1309 th.datecell,
1310 td.date {
1311- width: 180px;
1312+ width: 100px;
1313 }
1314 th.timedate,
1315 td.timedate2 {
1316- width: 80px;
1317+ width: 60px;
1318 }
1319 th.downloadcell,
1320 td.downr {
1321
1322=== modified file 'loggerhead/static/css/view.css'
1323--- loggerhead/static/css/view.css 2012-03-19 04:37:07 +0000
1324+++ loggerhead/static/css/view.css 2018-09-08 16:37:25 +0000
1325@@ -5,8 +5,7 @@
1326 }
1327 .viewRev {
1328 border-right: none;
1329- white-space: nowrap;
1330- width: 1px;
1331+ width: 20%;
1332 padding: .3em .6em;
1333 }
1334 .viewComm,
1335
1336=== modified file 'loggerhead/templatefunctions.py'
1337--- loggerhead/templatefunctions.py 2012-05-02 22:23:34 +0000
1338+++ loggerhead/templatefunctions.py 2018-09-08 16:37:25 +0000
1339@@ -19,7 +19,7 @@
1340
1341 import pkg_resources
1342
1343-import bzrlib
1344+import breezy
1345
1346 import loggerhead
1347 from loggerhead.zptsupport import zpt
1348@@ -162,10 +162,10 @@
1349 versions.append(('Loggerhead', loggerhead.__version__))
1350
1351 import sys
1352- python_version = bzrlib._format_version_tuple(sys.version_info)
1353+ python_version = breezy._format_version_tuple(sys.version_info)
1354 versions.append(('Python', python_version))
1355
1356- versions.append(('Bazaar', bzrlib.__version__))
1357+ versions.append(('Breezy', breezy.__version__))
1358
1359 Paste = pkg_resources.get_distribution('Paste')
1360 versions.append(('Paste', Paste.version))
1361@@ -188,11 +188,11 @@
1362 versions.append(('Pygments', pygments.__version__))
1363
1364 try:
1365- from bzrlib.plugins import search
1366+ from breezy.plugins import search
1367 except ImportError:
1368 pass
1369 else:
1370- bzr_search_version = bzrlib._format_version_tuple(
1371+ bzr_search_version = breezy._format_version_tuple(
1372 search.version_info)
1373 versions.append(('bzr-search', bzr_search_version))
1374
1375
1376=== modified file 'loggerhead/templates/directory.pt'
1377--- loggerhead/templates/directory.pt 2011-02-17 19:51:25 +0000
1378+++ loggerhead/templates/directory.pt 2018-09-08 16:37:25 +0000
1379@@ -17,16 +17,16 @@
1380 <div >
1381 <table id="logentries">
1382 <tr class="logheader">
1383- <th class="summarycell" colspan="2">Filename</th>
1384- <th class="datecell">Latest Rev</th>
1385+ <th class="datecell">Filename</th>
1386+ <th class="timedate">Latest Rev</th>
1387 <th class="datecell">Last Changed</th>
1388+ <th class="datecell">Committer</th>
1389+ <th class="summarycell">Comment</th>
1390 </tr>
1391
1392 <tr class="blueRow0" tal:condition="python:name != '/'">
1393- <td class="icocell">
1394+ <td class="summcell" colspan="5">
1395 <a href="../"><img tal:attributes="src python:static_url('/static/images/ico_folder_up.gif')" /></a>
1396- </td>
1397- <td class="summcell" colspan="3">
1398 <a href="../">..</a>
1399 </td>
1400 </tr>
1401@@ -34,32 +34,31 @@
1402
1403 <tal:branch-row tal:condition="dir/branch">
1404 <tr tal:attributes="class string:blueRow${dir/parity}">
1405- <td class="icocell">
1406+ <td class="date">
1407 <a tal:attributes="href string:${dir/dirname}/files">
1408 <img tal:attributes="src python:static_url('/static/images/ico_branch.gif')" alt="Branch" />
1409 </a>
1410- </td>
1411- <td class="autcell">
1412 <a tal:attributes="href string:${dir/dirname}/files" tal:content="dir/dirname" /></td>
1413 <td class="date">
1414 <a tal:attributes="href string:${dir/dirname}/revision/${dir/branch/revno};
1415 title string:Show revision ${dir/branch/revno}"
1416 tal:content="dir/branch/revno"></a>
1417 </td>
1418- <td class="date" tal:content="python:util.date_time(dir.last_change)"></td>
1419+ <td class="date" tal:content="python:util._approximatedate(dir.last_change_time)"></td>
1420+ <td class="date" tal:content="python:util.hide_email(dir.last_revision.committer) if dir.last_revision is not None else 'Nobody'"></td>
1421+ <td class="autcell" tal:content="python:dir.last_revision.message[:50] if dir.last_revision is not None else ''"></td>
1422 </tr>
1423+
1424 </tal:branch-row>
1425 <tal:non-branch-row tal:condition="not:dir/branch">
1426 <tr tal:attributes="class string:blueRow${dir/parity}">
1427- <td class="icocell">
1428+ <td class="date">
1429 <a tal:attributes="href string:${dir/dirname}/">
1430 <img tal:attributes="src python:static_url('/static/images/ico_folder.gif')" alt="Folder" />
1431 </a>
1432- </td>
1433- <td class="autcell">
1434 <a tal:attributes="href string:${dir/dirname}/" tal:content="dir/dirname" /></td>
1435 <td class="date"></td>
1436- <td class="date" tal:content="dir/last_change"></td>
1437+ <td class="date" colspan="4" tal:content="dir/last_change"></td>
1438 </tr>
1439 </tal:non-branch-row>
1440 </tal:block>
1441
1442=== modified file 'loggerhead/templates/inventory.pt'
1443--- loggerhead/templates/inventory.pt 2012-02-02 07:42:24 +0000
1444+++ loggerhead/templates/inventory.pt 2018-09-08 16:37:25 +0000
1445@@ -30,7 +30,7 @@
1446 <tal:no-link condition="not: branch/branch_link">
1447 <span metal:use-macro="breadcrumbs/directory"></span>
1448 </tal:no-link>
1449- <span>: <span metal:use-macro="breadcrumbs/branch" /> (revision <tal:revno content="change/revno"></tal:revno>)</span>
1450+ <span>: <span metal:use-macro="breadcrumbs/branch" /> (Revision <tal:revno content="change/revno"></tal:revno>)</span>
1451 </div>
1452 </tal:block>
1453
1454@@ -54,10 +54,12 @@
1455
1456 <table id="logentries">
1457 <tr class="logheader">
1458- <th class="summarycell"><a tal:attributes="href python:url(['/files', revid], sort='filename')">Filename</a></th>
1459- <th class="datecell">Latest Rev</th>
1460- <th class="datecell"><a tal:attributes="href python:url(['/files', revid], sort='date')">Last Changed</a></th>
1461- <th class="timedate"><a tal:attributes="href python:url(['/files', revid], sort='size')">Size</a></th>
1462+ <th class="datecell"><a tal:attributes="href python:branch.sort_url(['/files', revid], sort='filename')">Filename</a></th>
1463+ <th class="timedate">Latest Rev</th>
1464+ <th class="datecell"><a tal:attributes="href python:branch.sort_url(['/files', revid], sort='date')">Last Changed</a></th>
1465+ <th class="datecell">Committer</th>
1466+ <th class="summarycell">Comment</th>
1467+ <th class="timedate"><a tal:attributes="href python:branch.sort_url(['/files', revid], sort='size')">Size</a></th>
1468 <th class="expandcell"></th>
1469 <th class="expandcell"></th>
1470 </tr>
1471@@ -68,11 +70,15 @@
1472 <img tal:attributes="src python:branch.static_url('/static/images/ico_folder_up.gif')" />..</a>
1473 </td>
1474 </tr>
1475+ <tr class="blueRow0" tal:condition="python:updir is None">
1476+ <td class="summcell" colspan="6">
1477+ <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>
1478+ </tr>
1479
1480 <!-- Show this if it's a directory -->
1481 <tal:block repeat="file filelist">
1482 <tr tal:attributes="class string:blueRow${repeat/file/even}" tal:condition="python:file.kind=='directory'">
1483- <td class="autcell"><a tal:attributes="href python:url(['/files', revno_url, file.absolutepath])">
1484+ <td class="date"><a tal:attributes="href python:url(['/files', revno_url, file.absolutepath])">
1485 <img tal:attributes="src python:branch.static_url('/static/images/ico_folder.gif');
1486 title string:Go to ${file/filename}" />
1487 </a>
1488@@ -84,8 +90,10 @@
1489 title string:Show revision ${file/change/revno}"
1490 tal:content="file/change/revno"></a>
1491 </td>
1492- <td class="date" tal:content="python:util.date_time(file.change.utc_date)"></td>
1493- <td class="timedate2"></td>
1494+ <td class="date" tal:content="python:util._approximatedate(file.change.utc_date)"></td>
1495+ <td class="date" tal:content="python:util.hide_email(file.change.committer)"></td>
1496+ <td class="autcell" tal:content="python:file.change.comment[:50]"></td>
1497+ <td class="timedate2"></td><!-- not showing sizes of folders -->
1498 <td class="expcell"><a tal:attributes="href python:url(['/changes'], start_revid=start_revid, filter_file_id=file.file_id);
1499 title string:Show revision ${file/change/revno}">
1500 <img tal:attributes="src python:branch.static_url('/static/images/ico_planilla.gif')" alt="Diff" />
1501@@ -96,7 +104,7 @@
1502
1503 <!-- Show this if it's a symlink -->
1504 <tr tal:attributes="class string:blueRow${repeat/file/even}" tal:condition="python:file.kind=='symlink'">
1505- <td class="autcell"><a tal:attributes="href python:url(['/view', change.revno, file.absolutepath])">
1506+ <td class="date"><a tal:attributes="href python:url(['/view', change.revno, file.absolutepath])">
1507 <img tal:attributes="src python:branch.static_url('/static/images/ico_file_flecha.gif')" alt="Symlink" />
1508 </a>
1509
1510@@ -107,7 +115,9 @@
1511 title string:Show revision ${file/change/revno}"
1512 tal:content="file/change/revno"></a>
1513 </td>
1514- <td class="date" tal:content="python:util.date_time(file.change.utc_date)"></td>
1515+ <td class="date" tal:content="python:util._approximatedate(file.change.utc_date)"></td>
1516+ <td class="date" tal:content="python:util.hide_email(file.change.committer)"></td>
1517+ <td class="autcell" tal:content="python:file.change.comment[:50]"></td>
1518 <td class="timedate2">.</td>
1519 <td class="expcell"><a tal:attributes="href python:url(['/changes'], start_revid=start_revid, filter_file_id=file.file_id);
1520 title string:Show revision ${file/change/revno}">
1521@@ -120,7 +130,7 @@
1522
1523 <!-- Show this if it's a regular file -->
1524 <tr tal:attributes="class string:blueRow${repeat/file/even}" tal:condition="python:file.kind=='file'">
1525- <td class="autcell"><a tal:attributes="href python:url(['/view', revno_url, file.absolutepath])">
1526+ <td class="date"><a tal:attributes="href python:url(['/view', revno_url, file.absolutepath])">
1527 <img tal:attributes="src python:branch.static_url('/static/images/ico_file.gif');
1528 title string:View ${file/filename}"
1529 tal:condition="python:file.executable is False" />
1530@@ -136,7 +146,10 @@
1531 title string:Show revision ${file/change/revno}"
1532 tal:content="file/change/revno"></a>
1533 </td>
1534- <td class="date" tal:content="python:util.date_time(file.change.utc_date)"></td>
1535+ <td class="date" tal:content="python:util._approximatedate(file.change.utc_date)"></td>
1536+ <td class="date" tal:content="python:util.hide_email(file.change.committer)"></td>
1537+ <td class="autcell" tal:content="python:file.change.comment[:50]"></td>
1538+
1539 <td class="timedate2" tal:content="python:util.human_size(file.size)"></td>
1540 <td class="expcell"><a tal:attributes="href python:url(['/view', revno_url, file.absolutepath]);
1541 title string:View ${file/filename}">
1542
1543=== modified file 'loggerhead/templates/macros.pt'
1544--- loggerhead/templates/macros.pt 2012-05-03 21:39:50 +0000
1545+++ loggerhead/templates/macros.pt 2018-09-08 16:37:25 +0000
1546@@ -60,7 +60,7 @@
1547 <div metal:define-slot="content"></div>
1548
1549 <p id="footer" class="fl">
1550- Loggerhead is a web-based interface for <a href="http://bazaar-vcs.org/">Bazaar</a> branches
1551+ Loggerhead is a web-based interface for <a href="https://www.breezy-vcs.org/">Breezy</a>
1552 <br />
1553 Version: <tal:version content="loggerhead_version" /><span tal:condition="loggerhead_revision">, Revision: <tal:revision content="loggerhead_revision" /></span>
1554 </p>
1555
1556=== modified file 'loggerhead/tests/__init__.py'
1557--- loggerhead/tests/__init__.py 2011-09-08 00:33:28 +0000
1558+++ loggerhead/tests/__init__.py 2018-09-08 16:37:25 +0000
1559@@ -15,8 +15,8 @@
1560 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1561
1562
1563-def load_tests(standard_tests, module, loader):
1564- standard_tests.addTests(loader.loadTestsFromModuleNames([
1565+def load_tests(loader, basic_tests, pattern):
1566+ basic_tests.addTests(loader.loadTestsFromModuleNames([
1567 (__name__ + '.' + x) for x in [
1568 'test_controllers',
1569 'test_corners',
1570@@ -28,4 +28,4 @@
1571 'test_templating',
1572 'test_util',
1573 ]]))
1574- return standard_tests
1575+ return basic_tests
1576
1577=== modified file 'loggerhead/tests/test_controllers.py'
1578--- loggerhead/tests/test_controllers.py 2016-09-04 15:13:21 +0000
1579+++ loggerhead/tests/test_controllers.py 2018-09-08 16:37:25 +0000
1580@@ -14,6 +14,8 @@
1581 # along with this program; if not, write to the Free Software
1582 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1583
1584+from __future__ import absolute_import
1585+
1586 import tarfile
1587 import tempfile
1588
1589@@ -27,10 +29,10 @@
1590 Mismatch,
1591 )
1592
1593-from loggerhead.apps.branch import BranchWSGIApp
1594-from loggerhead.controllers.annotate_ui import AnnotateUI
1595-from loggerhead.controllers.inventory_ui import InventoryUI
1596-from loggerhead.tests.test_simple import (
1597+from ..apps.branch import BranchWSGIApp
1598+from ..controllers.annotate_ui import AnnotateUI
1599+from ..controllers.inventory_ui import InventoryUI
1600+from .test_simple import (
1601 BasicTests,
1602 consume_app,
1603 TestWithSimpleTree,
1604@@ -55,8 +57,8 @@
1605 def test_get_filelist(self):
1606 bzrbranch, inv_ui = self.make_bzrbranch_and_inventory_ui_for_tree_shape(
1607 ['filename'])
1608- inv = bzrbranch.repository.get_inventory(bzrbranch.last_revision())
1609- self.assertEqual(1, len(inv_ui.get_filelist(inv, '', 'filename', 'head')))
1610+ revtree = bzrbranch.repository.revision_tree(bzrbranch.last_revision())
1611+ self.assertEqual(1, len(inv_ui.get_filelist(revtree, '', 'filename', 'head')))
1612
1613 def test_smoke(self):
1614 bzrbranch, inv_ui = self.make_bzrbranch_and_inventory_ui_for_tree_shape(
1615@@ -223,21 +225,21 @@
1616 def make_branch_app_for_filediff_ui(self):
1617 builder = self.make_branch_builder('branch')
1618 builder.start_series()
1619- builder.build_snapshot('rev-1-id', None, [
1620- ('add', ('', 'root-id', 'directory', '')),
1621- ('add', ('filename', 'f-id', 'file', 'content\n'))],
1622+ rev1 = builder.build_snapshot(None, [
1623+ ('add', ('', b'root-id', 'directory', '')),
1624+ ('add', ('filename', b'f-id', 'file', b'content\n'))],
1625 message="First commit.")
1626- builder.build_snapshot('rev-2-id', None, [
1627- ('modify', ('f-id', 'new content\n'))])
1628+ rev2 = builder.build_snapshot(None, [
1629+ ('modify', (b'filename', b'new content\n'))])
1630 builder.finish_series()
1631 branch = builder.get_branch()
1632 self.addCleanup(branch.lock_read().unlock)
1633- return self.make_branch_app(branch)
1634+ return self.make_branch_app(branch), (rev1, rev2)
1635
1636 def test_get_values_smoke(self):
1637- branch_app = self.make_branch_app_for_filediff_ui()
1638+ branch_app, (rev1, rev2) = self.make_branch_app_for_filediff_ui()
1639 env = {'SCRIPT_NAME': '/',
1640- 'PATH_INFO': '/+filediff/rev-2-id/rev-1-id/f-id',
1641+ 'PATH_INFO': '/+filediff/%s/%s/f-id' % (rev2, rev1),
1642 'REQUEST_METHOD': 'GET'}
1643 filediff_ui = branch_app.lookup_app(env)
1644 filediff_ui.parse_args(env)
1645@@ -247,9 +249,9 @@
1646 self.assertEqual('new content', chunks[0].diff[1].line)
1647
1648 def test_json_render_smoke(self):
1649- branch_app = self.make_branch_app_for_filediff_ui()
1650+ branch_app, (rev1, rev2) = self.make_branch_app_for_filediff_ui()
1651 env = {'SCRIPT_NAME': '/',
1652- 'PATH_INFO': '/+json/+filediff/rev-2-id/rev-1-id/f-id',
1653+ 'PATH_INFO': '/+json/+filediff/%s/%s/f-id' % (rev2, rev1),
1654 'REQUEST_METHOD': 'GET'}
1655 filediff_ui = branch_app.lookup_app(env)
1656 self.assertOkJsonResponse(filediff_ui, env)
1657@@ -260,19 +262,19 @@
1658 def make_branch_app_for_revlog_ui(self):
1659 builder = self.make_branch_builder('branch')
1660 builder.start_series()
1661- builder.build_snapshot('rev-id', None, [
1662- ('add', ('', 'root-id', 'directory', '')),
1663- ('add', ('filename', 'f-id', 'file', 'content\n'))],
1664+ revid = builder.build_snapshot(None, [
1665+ ('add', ('', b'root-id', 'directory', '')),
1666+ ('add', ('filename', b'f-id', 'file', b'content\n'))],
1667 message="First commit.")
1668 builder.finish_series()
1669 branch = builder.get_branch()
1670 self.addCleanup(branch.lock_read().unlock)
1671- return self.make_branch_app(branch)
1672+ return self.make_branch_app(branch), revid
1673
1674 def test_get_values_smoke(self):
1675- branch_app = self.make_branch_app_for_revlog_ui()
1676+ branch_app, revid = self.make_branch_app_for_revlog_ui()
1677 env = {'SCRIPT_NAME': '/',
1678- 'PATH_INFO': '/+revlog/rev-id',
1679+ 'PATH_INFO': '/+revlog/%s' % revid,
1680 'REQUEST_METHOD': 'GET'}
1681 revlog_ui = branch_app.lookup_app(env)
1682 revlog_ui.parse_args(env)
1683@@ -281,8 +283,8 @@
1684 self.assertEqual(values['entry'].comment, "First commit.")
1685
1686 def test_json_render_smoke(self):
1687- branch_app = self.make_branch_app_for_revlog_ui()
1688- env = {'SCRIPT_NAME': '', 'PATH_INFO': '/+json/+revlog/rev-id',
1689+ branch_app, revid = self.make_branch_app_for_revlog_ui()
1690+ env = {'SCRIPT_NAME': '', 'PATH_INFO': '/+json/+revlog/%s' % revid,
1691 'REQUEST_METHOD': 'GET'}
1692 revlog_ui = branch_app.lookup_app(env)
1693 self.assertOkJsonResponse(revlog_ui, env)
1694
1695=== modified file 'loggerhead/tests/test_corners.py'
1696--- loggerhead/tests/test_corners.py 2009-04-02 20:32:12 +0000
1697+++ loggerhead/tests/test_corners.py 2018-09-08 16:37:25 +0000
1698@@ -1,6 +1,8 @@
1699+from __future__ import absolute_import
1700+
1701 import os
1702
1703-from loggerhead.tests.test_simple import BasicTests
1704+from .test_simple import BasicTests
1705
1706
1707 class TestCornerCases(BasicTests):
1708
1709=== modified file 'loggerhead/tests/test_history.py'
1710--- loggerhead/tests/test_history.py 2011-03-25 13:09:10 +0000
1711+++ loggerhead/tests/test_history.py 2018-09-08 16:37:25 +0000
1712@@ -17,14 +17,14 @@
1713
1714 """Direct tests of the loggerhead/history.py module"""
1715
1716-from bzrlib.foreign import (
1717+from breezy.foreign import (
1718 ForeignRevision,
1719 ForeignVcs,
1720 VcsMapping,
1721 )
1722
1723 from datetime import datetime
1724-from bzrlib import tag, tests
1725+from breezy import tag, tests
1726
1727 from loggerhead import history as _mod_history
1728
1729@@ -40,26 +40,27 @@
1730 # rev-1
1731 builder = self.make_branch_builder('branch')
1732 builder.start_series()
1733- builder.build_snapshot('rev-1', None, [
1734+ rev1 = builder.build_snapshot(None, [
1735 ('add', ('', 'root-id', 'directory', None))])
1736- builder.build_snapshot('rev-2', ['rev-1'], [])
1737- builder.build_snapshot('rev-3', ['rev-2'], [])
1738+ rev2 = builder.build_snapshot([rev1], [])
1739+ rev3 = builder.build_snapshot([rev2], [])
1740 builder.finish_series()
1741 b = builder.get_branch()
1742 self.addCleanup(b.lock_read().unlock)
1743- return _mod_history.History(b, {})
1744+ return _mod_history.History(b, {}), [rev1, rev2, rev3]
1745
1746 def make_long_linear_ancestry(self):
1747 builder = self.make_branch_builder('branch')
1748+ revs = []
1749 builder.start_series()
1750- builder.build_snapshot('A', None, [
1751- ('add', ('', 'root-id', 'directory', None))])
1752+ revs.append(builder.build_snapshot(None, [
1753+ ('add', ('', 'root-id', 'directory', None))]))
1754 for r in "BCDEFGHIJKLMNOPQRSTUVWXYZ":
1755- builder.build_snapshot(r, None, [])
1756+ revs.append(builder.build_snapshot(None, []))
1757 builder.finish_series()
1758 b = builder.get_branch()
1759 self.addCleanup(b.lock_read().unlock)
1760- return _mod_history.History(b, {})
1761+ return _mod_history.History(b, {}), revs
1762
1763 def make_merged_ancestry(self):
1764 # Time goes up
1765@@ -70,14 +71,14 @@
1766 # rev-1
1767 builder = self.make_branch_builder('branch')
1768 builder.start_series()
1769- builder.build_snapshot('rev-1', None, [
1770+ rev1 = builder.build_snapshot(None, [
1771 ('add', ('', 'root-id', 'directory', None))])
1772- builder.build_snapshot('rev-2', ['rev-1'], [])
1773- builder.build_snapshot('rev-3', ['rev-1', 'rev-2'], [])
1774+ rev2 = builder.build_snapshot([rev1], [])
1775+ rev3 = builder.build_snapshot([rev1, rev2], [])
1776 builder.finish_series()
1777 b = builder.get_branch()
1778 self.addCleanup(b.lock_read().unlock)
1779- return _mod_history.History(b, {})
1780+ return _mod_history.History(b, {}), [rev1, rev2, rev3]
1781
1782 def make_deep_merged_ancestry(self):
1783 # Time goes up
1784@@ -92,17 +93,18 @@
1785 # A
1786 builder = self.make_branch_builder('branch')
1787 builder.start_series()
1788- builder.build_snapshot('A', None, [
1789+ rev_a = builder.build_snapshot(None, [
1790 ('add', ('', 'root-id', 'directory', None))])
1791- builder.build_snapshot('B', ['A'], [])
1792- builder.build_snapshot('C', ['A'], [])
1793- builder.build_snapshot('D', ['C'], [])
1794- builder.build_snapshot('E', ['C', 'D'], [])
1795- builder.build_snapshot('F', ['B', 'E'], [])
1796+ rev_b = builder.build_snapshot([rev_a], [])
1797+ rev_c = builder.build_snapshot([rev_a], [])
1798+ rev_d = builder.build_snapshot([rev_c], [])
1799+ rev_e = builder.build_snapshot([rev_c, rev_d], [])
1800+ rev_f = builder.build_snapshot([rev_b, rev_e], [])
1801 builder.finish_series()
1802 b = builder.get_branch()
1803 self.addCleanup(b.lock_read().unlock)
1804- return _mod_history.History(b, {})
1805+ return (_mod_history.History(b, {}),
1806+ [rev_a, rev_b, rev_c, rev_d, rev_e, rev_f])
1807
1808 def assertRevidsFrom(self, expected, history, search_revs, tip_rev):
1809 self.assertEqual(expected,
1810@@ -136,59 +138,58 @@
1811 class TestHistoryGetRevidsFrom(TestCaseWithExamples):
1812
1813 def test_get_revids_from_simple_mainline(self):
1814- history = self.make_linear_ancestry()
1815- self.assertRevidsFrom(['rev-3', 'rev-2', 'rev-1'],
1816- history, None, 'rev-3')
1817+ history, revs = self.make_linear_ancestry()
1818+ self.assertRevidsFrom(list(reversed(revs)), history, None, revs[2])
1819
1820 def test_get_revids_from_merged_mainline(self):
1821- history = self.make_merged_ancestry()
1822- self.assertRevidsFrom(['rev-3', 'rev-1'],
1823- history, None, 'rev-3')
1824+ history, revs = self.make_merged_ancestry()
1825+ self.assertRevidsFrom([revs[2], revs[0]],
1826+ history, None, revs[2])
1827
1828 def test_get_revids_given_one_rev(self):
1829- history = self.make_merged_ancestry()
1830+ history, revs = self.make_merged_ancestry()
1831 # rev-3 was the first mainline revision to see rev-2.
1832- self.assertRevidsFrom(['rev-3'], history, ['rev-2'], 'rev-3')
1833+ self.assertRevidsFrom([revs[2]], history, [revs[1]], revs[2])
1834
1835 def test_get_revids_deep_ancestry(self):
1836- history = self.make_deep_merged_ancestry()
1837- self.assertRevidsFrom(['F'], history, ['F'], 'F')
1838- self.assertRevidsFrom(['F'], history, ['E'], 'F')
1839- self.assertRevidsFrom(['F'], history, ['D'], 'F')
1840- self.assertRevidsFrom(['F'], history, ['C'], 'F')
1841- self.assertRevidsFrom(['B'], history, ['B'], 'F')
1842- self.assertRevidsFrom(['A'], history, ['A'], 'F')
1843+ history, revs = self.make_deep_merged_ancestry()
1844+ self.assertRevidsFrom([revs[-1]], history, [revs[-1]], revs[-1])
1845+ self.assertRevidsFrom([revs[-1]], history, [revs[-2]], revs[-1])
1846+ self.assertRevidsFrom([revs[-1]], history, [revs[-3]], revs[-1])
1847+ self.assertRevidsFrom([revs[-1]], history, [revs[-4]], revs[-1])
1848+ self.assertRevidsFrom([revs[1]], history, [revs[-5]], revs[-1])
1849+ self.assertRevidsFrom([revs[0]], history, [revs[-6]], revs[-1])
1850
1851 def test_get_revids_doesnt_over_produce_simple_mainline(self):
1852 # get_revids_from shouldn't walk the whole ancestry just to get the
1853 # answers for the first few revisions.
1854- history = self.make_long_linear_ancestry()
1855+ history, revs = self.make_long_linear_ancestry()
1856 accessed = track_rev_info_accesses(history)
1857- result = history.get_revids_from(None, 'Z')
1858- self.assertEqual(set(), accessed)
1859- self.assertEqual('Z', result.next())
1860- # We already know 'Z' because we passed it in.
1861- self.assertEqual(set(), accessed)
1862- self.assertEqual('Y', result.next())
1863- self.assertEqual(set([history._rev_indices['Z']]), accessed)
1864+ result = history.get_revids_from(None, revs[-1])
1865+ self.assertEqual(set(), accessed)
1866+ self.assertEqual(revs[-1], result.next())
1867+ # We already know revs[-1] because we passed it in.
1868+ self.assertEqual(set(), accessed)
1869+ self.assertEqual(revs[-2], result.next())
1870+ self.assertEqual(set([history._rev_indices[revs[-1]]]), accessed)
1871
1872 def test_get_revids_doesnt_over_produce_for_merges(self):
1873 # get_revids_from shouldn't walk the whole ancestry just to get the
1874 # answers for the first few revisions.
1875- history = self.make_long_linear_ancestry()
1876+ history, revs = self.make_long_linear_ancestry()
1877 accessed = track_rev_info_accesses(history)
1878- result = history.get_revids_from(['X', 'V'], 'Z')
1879+ result = history.get_revids_from([revs[-3], revs[-5]], revs[-1])
1880 self.assertEqual(set(), accessed)
1881- self.assertEqual('X', result.next())
1882+ self.assertEqual(revs[-3], result.next())
1883 # We access 'W' because we are checking that W wasn't merged into X.
1884 # The important bit is that we aren't getting the whole ancestry.
1885- self.assertEqual(set([history._rev_indices[x] for x in 'ZYXW']),
1886+ self.assertEqual(set([history._rev_indices[x] for x in list(reversed(revs))[:4]]),
1887 accessed)
1888- self.assertEqual('V', result.next())
1889- self.assertEqual(set([history._rev_indices[x] for x in 'ZYXWVU']),
1890+ self.assertEqual(revs[-5], result.next())
1891+ self.assertEqual(set([history._rev_indices[x] for x in list(reversed(revs))[:6]]),
1892 accessed)
1893 self.assertRaises(StopIteration, result.next)
1894- self.assertEqual(set([history._rev_indices[x] for x in 'ZYXWVU']),
1895+ self.assertEqual(set([history._rev_indices[x] for x in list(reversed(revs))[:6]]),
1896 accessed)
1897
1898
1899@@ -291,32 +292,32 @@
1900 def test_get_view_limited_history(self):
1901 # get_view should only load enough history to serve the result, not all
1902 # history.
1903- history = self.make_long_linear_ancestry()
1904+ history, revs = self.make_long_linear_ancestry()
1905 accessed = track_rev_info_accesses(history)
1906- revid, start_revid, revid_list = history.get_view('Z', 'Z', None,
1907+ revid, start_revid, revid_list = history.get_view(revs[-1], revs[-1], None,
1908 extra_rev_count=5)
1909- self.assertEqual(['Z', 'Y', 'X', 'W', 'V', 'U'], revid_list)
1910- self.assertEqual('Z', revid)
1911- self.assertEqual('Z', start_revid)
1912- self.assertEqual(set([history._rev_indices[x] for x in 'ZYXWVU']),
1913+ self.assertEqual(list(reversed(revs))[:6], revid_list)
1914+ self.assertEqual(revs[-1], revid)
1915+ self.assertEqual(revs[-1], start_revid)
1916+ self.assertEqual(set([history._rev_indices[x] for x in list(reversed(revs))[:6]]),
1917 accessed)
1918
1919
1920 class TestHistoryGetChangedUncached(TestCaseWithExamples):
1921
1922 def test_native(self):
1923- history = self.make_linear_ancestry()
1924- changes = history.get_changes_uncached(['rev-1', 'rev-2'])
1925+ history, revs = self.make_linear_ancestry()
1926+ changes = history.get_changes_uncached([revs[0], revs[1]])
1927 self.assertEquals(2, len(changes))
1928- self.assertEquals('rev-1', changes[0].revid)
1929- self.assertEquals('rev-2', changes[1].revid)
1930+ self.assertEquals(revs[0], changes[0].revid)
1931+ self.assertEquals(revs[1], changes[1].revid)
1932 self.assertIs(None, getattr(changes[0], 'foreign_vcs', None))
1933 self.assertIs(None, getattr(changes[0], 'foreign_revid', None))
1934
1935 def test_foreign(self):
1936 # Test with a mocked foreign revision, as it's not possible
1937 # to rely on any foreign plugins being installed.
1938- history = self.make_linear_ancestry()
1939+ history, revs = self.make_linear_ancestry()
1940 foreign_vcs = ForeignVcs(None, "vcs")
1941 foreign_vcs.show_foreign_revid = repr
1942 foreign_rev = ForeignRevision(("uuid", 1234), VcsMapping(foreign_vcs),
1943
1944=== modified file 'loggerhead/tests/test_http_head.py'
1945--- loggerhead/tests/test_http_head.py 2011-02-10 02:33:15 +0000
1946+++ loggerhead/tests/test_http_head.py 2018-09-08 16:37:25 +0000
1947@@ -18,7 +18,7 @@
1948
1949 from cStringIO import StringIO
1950
1951-from bzrlib import tests
1952+from breezy import tests
1953
1954 from loggerhead.apps import http_head
1955
1956
1957=== modified file 'loggerhead/tests/test_load_test.py'
1958--- loggerhead/tests/test_load_test.py 2011-04-14 14:10:04 +0000
1959+++ loggerhead/tests/test_load_test.py 2018-09-08 16:37:25 +0000
1960@@ -17,8 +17,8 @@
1961 import threading
1962 import Queue
1963
1964-from bzrlib import tests
1965-from bzrlib.tests import http_server
1966+from breezy import tests
1967+from breezy.tests import http_server
1968
1969 from loggerhead import load_test
1970
1971
1972=== modified file 'loggerhead/tests/test_revision_ui.py'
1973--- loggerhead/tests/test_revision_ui.py 2011-03-16 12:37:17 +0000
1974+++ loggerhead/tests/test_revision_ui.py 2018-09-08 16:37:25 +0000
1975@@ -15,8 +15,9 @@
1976 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1977 #
1978
1979+from __future__ import absolute_import
1980
1981-from loggerhead.tests.test_simple import BasicTests
1982+from .test_simple import BasicTests
1983
1984
1985 class TestRevisionUI(BasicTests):
1986
1987=== modified file 'loggerhead/tests/test_simple.py'
1988--- loggerhead/tests/test_simple.py 2011-11-25 02:28:56 +0000
1989+++ loggerhead/tests/test_simple.py 2018-09-08 16:37:25 +0000
1990@@ -15,25 +15,27 @@
1991 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1992 #
1993
1994+from __future__ import absolute_import
1995+
1996 import cgi
1997 import logging
1998 import re
1999 import simplejson
2000 from cStringIO import StringIO
2001
2002-from bzrlib.tests import TestCaseWithTransport
2003+from breezy.tests import TestCaseWithTransport
2004 try:
2005- from bzrlib.util.configobj.configobj import ConfigObj
2006+ from breezy.util.configobj.configobj import ConfigObj
2007 except ImportError:
2008 from configobj import ConfigObj
2009-from bzrlib import config
2010+from breezy import config
2011
2012-from loggerhead.apps.branch import BranchWSGIApp
2013-from loggerhead.apps.http_head import HeadMiddleware
2014+from ..apps.branch import BranchWSGIApp
2015+from ..apps.http_head import HeadMiddleware
2016 from paste.fixture import TestApp
2017 from paste.httpexceptions import HTTPExceptionHandler, HTTPMovedPermanently
2018
2019-from loggerhead.tests.fixtures import (
2020+from .fixtures import (
2021 SampleBranch,
2022 )
2023
2024
2025=== modified file 'loggerhead/tests/test_util.py'
2026--- loggerhead/tests/test_util.py 2011-09-08 00:33:28 +0000
2027+++ loggerhead/tests/test_util.py 2018-09-08 16:37:25 +0000
2028@@ -14,7 +14,7 @@
2029 # along with this program; if not, write to the Free Software
2030 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2031
2032-from bzrlib import tests
2033+from breezy import tests
2034
2035 from loggerhead.util import html_escape, html_format
2036
2037
2038=== modified file 'loggerhead/util.py'
2039--- loggerhead/util.py 2012-04-28 00:57:06 +0000
2040+++ loggerhead/util.py 2018-09-08 16:37:25 +0000
2041@@ -35,7 +35,7 @@
2042 except ImportError:
2043 from elementtree import ElementTree as ET
2044
2045-from bzrlib import urlutils
2046+from breezy import urlutils
2047
2048 from simpletal.simpleTALUtils import HTMLStructureCleaner
2049
2050@@ -73,12 +73,13 @@
2051
2052
2053 def _approximatedate(date):
2054- delta = datetime.datetime.now() - date
2055- if abs(delta) > datetime.timedelta(1, 0, 0):
2056- # far in the past or future, display the date
2057- return date_day(date)
2058+ if date is None:
2059+ return 'Never'
2060+ delta = datetime.datetime.utcnow() - date
2061 future = delta < datetime.timedelta(0, 0, 0)
2062 delta = abs(delta)
2063+ years = delta.days / 365
2064+ months = delta.days / 30 # This is approximate.
2065 days = delta.days
2066 hours = delta.seconds / 3600
2067 minutes = (delta.seconds - (3600*hours)) / 60
2068@@ -86,7 +87,13 @@
2069 result = ''
2070 if future:
2071 result += 'in '
2072- if days != 0:
2073+ if years != 0:
2074+ amount = years
2075+ unit = 'year'
2076+ elif months != 0:
2077+ amount = months
2078+ unit = 'month'
2079+ elif days != 0:
2080 amount = days
2081 unit = 'day'
2082 elif hours != 0:
2083@@ -103,7 +110,7 @@
2084 result += '%s %s' % (amount, unit)
2085 if not future:
2086 result += ' ago'
2087- return result
2088+ return result
2089
2090
2091 def _wrap_with_date_time_title(date, formatted_date):
2092@@ -456,7 +463,7 @@
2093 return breadcrumbs
2094
2095
2096-def branch_breadcrumbs(path, inv, view):
2097+def branch_breadcrumbs(path, tree, view):
2098 """
2099 Generate breadcrumb information from the branch path given
2100
2101@@ -464,7 +471,7 @@
2102
2103 Arguments:
2104 path -- The path to convert into breadcrumbs
2105- inv -- Inventory to get file information from
2106+ tree -- Tree to get file information from
2107 view -- The type of view we are showing (files, changes etc)
2108 """
2109 dir_parts = path.strip('/').split('/')
2110
2111=== modified file 'loggerhead/wholehistory.py'
2112--- loggerhead/wholehistory.py 2012-02-08 01:50:02 +0000
2113+++ loggerhead/wholehistory.py 2018-09-08 16:37:25 +0000
2114@@ -20,13 +20,13 @@
2115 import logging
2116 import time
2117
2118-from bzrlib.revision import is_null, NULL_REVISION
2119-from bzrlib.tsort import merge_sort
2120+from breezy.revision import is_null, NULL_REVISION
2121+from breezy.tsort import merge_sort
2122
2123
2124 def _strip_NULL_ghosts(revision_graph):
2125 """
2126- Copied over from bzrlib meant as a temporary workaround for
2127+ Copied over from breezy meant as a temporary workaround for
2128 deprecated methods.
2129 """
2130 # Filter ghosts, and null:
2131
2132=== modified file 'serve-branches.1'
2133--- serve-branches.1 2008-09-10 23:12:59 +0000
2134+++ serve-branches.1 2018-09-08 16:37:25 +0000
2135@@ -5,7 +5,7 @@
2136 .B serve-branches
2137 [\fIoptions\fR] \fI<path>\fR
2138 .SH DESCRIPTION
2139-Loggerhead is a web viewer for projects in bazaar. It can be used to navigate
2140+Loggerhead is a web viewer for projects in Breezy. It can be used to navigate
2141 a branch history, annotate files, view patches, perform searches, etc. It's
2142 heavily based on bazaar-webserve, which is itself based on hgweb for Mercurial.
2143 .PP
2144
2145=== modified file 'setup.py'
2146--- setup.py 2015-03-17 11:23:13 +0000
2147+++ setup.py 2018-09-08 16:37:25 +0000
2148@@ -39,8 +39,8 @@
2149 "loggerhead/controllers",
2150 "loggerhead/middleware",
2151 "loggerhead/templates",
2152- "bzrlib.plugins.loggerhead"],
2153- package_dir={'bzrlib.plugins.loggerhead':'.'},
2154+ "breezy.plugins.loggerhead"],
2155+ package_dir={'breezy.plugins.loggerhead':'.'},
2156 package_data = {"loggerhead": ["templates/*.pt",
2157 "static/css/*.css",
2158 "static/javascript/*.js",
2159@@ -71,6 +71,6 @@
2160 ('share/man/man1', ['serve-branches.1']),
2161 ('share/doc/loggerhead', ['apache-loggerhead.conf',
2162 'loggerheadd',
2163- 'bazaar.conf']),
2164+ 'breezy.conf']),
2165 ],
2166 )

Subscribers

People subscribed via source and target branches