/loggerhead/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/loggerhead/trunk

« back to all changes in this revision

Viewing changes to loggerhead/controllers/filediff_ui.py

  • Committer: Ubuntu One Auto Copilot
  • Author(s): Jelmer Vernooij
  • Date: 2022-08-30 10:28:23 UTC
  • mfrom: (533.1.1 trunk)
  • Revision ID: otto-copilot@canonical.com-20220830102823-u3w6efosxw5s086s
Cope with moved errors NoSuchFile and FileExists in newer versions of Breezy.

Merged from https://code.launchpad.net/~jelmer/loggerhead/moved-errors/+merge/429073

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
from StringIO import StringIO
2
 
import urllib
3
 
 
4
 
from breezy import diff
5
 
from breezy import errors
6
 
from breezy import osutils
7
 
 
8
 
from loggerhead import util
9
 
from loggerhead.controllers import TemplatedBranchView
 
1
from io import BytesIO
 
2
 
 
3
from breezy import (
 
4
    diff,
 
5
    errors,
 
6
    urlutils,
 
7
    )
 
8
try:
 
9
    from breezy.transport import NoSuchFile
 
10
except ImportError:
 
11
    from breezy.errors import NoSuchFile
 
12
from breezy.tree import find_previous_path
 
13
 
 
14
from .. import util
 
15
from ..controllers import TemplatedBranchView
 
16
 
10
17
 
11
18
def _process_diff(difftext):
12
19
    chunks = []
13
20
    chunk = None
 
21
 
 
22
    def decode_line(line):
 
23
        return line.decode('utf-8', 'replace')
14
24
    for line in difftext.splitlines():
15
25
        if len(line) == 0:
16
26
            continue
17
 
        if line.startswith('+++ ') or line.startswith('--- '):
 
27
        if line.startswith(b'+++ ') or line.startswith(b'--- '):
18
28
            continue
19
 
        if line.startswith('@@ '):
 
29
        if line.startswith(b'@@ '):
20
30
            # new chunk
21
31
            if chunk is not None:
22
32
                chunks.append(chunk)
23
33
            chunk = util.Container()
24
34
            chunk.diff = []
25
 
            split_lines = line.split(' ')[1:3]
26
 
            lines = [int(x.split(',')[0][1:]) for x in split_lines]
 
35
            split_lines = line.split(b' ')[1:3]
 
36
            lines = [int(x.split(b',')[0][1:]) for x in split_lines]
27
37
            old_lineno = lines[0]
28
38
            new_lineno = lines[1]
29
 
        elif line.startswith(' '):
 
39
        elif line.startswith(b' '):
30
40
            chunk.diff.append(util.Container(old_lineno=old_lineno,
31
41
                                             new_lineno=new_lineno,
32
42
                                             type='context',
33
 
                                             line=line[1:]))
 
43
                                             line=decode_line(line[1:])))
34
44
            old_lineno += 1
35
45
            new_lineno += 1
36
 
        elif line.startswith('+'):
37
 
            chunk.diff.append(util.Container(old_lineno=None,
38
 
                                             new_lineno=new_lineno,
39
 
                                             type='insert', line=line[1:]))
 
46
        elif line.startswith(b'+'):
 
47
            chunk.diff.append(util.Container(
 
48
                old_lineno=None,
 
49
                new_lineno=new_lineno,
 
50
                type='insert', line=decode_line(line[1:])))
40
51
            new_lineno += 1
41
 
        elif line.startswith('-'):
42
 
            chunk.diff.append(util.Container(old_lineno=old_lineno,
43
 
                                             new_lineno=None,
44
 
                                             type='delete', line=line[1:]))
 
52
        elif line.startswith(b'-'):
 
53
            chunk.diff.append(util.Container(
 
54
                old_lineno=old_lineno,
 
55
                new_lineno=None,
 
56
                type='delete', line=decode_line(line[1:])))
45
57
            old_lineno += 1
46
58
        else:
47
 
            chunk.diff.append(util.Container(old_lineno=None,
48
 
                                             new_lineno=None,
49
 
                                             type='unknown',
50
 
                                             line=repr(line)))
 
59
            chunk.diff.append(util.Container(
 
60
                old_lineno=None,
 
61
                new_lineno=None,
 
62
                type='unknown',
 
63
                line=repr(line)))
51
64
    if chunk is not None:
52
65
        chunks.append(chunk)
53
66
    return chunks
54
67
 
55
68
 
56
 
def diff_chunks_for_file(repository, file_id, compare_revid, revid,
 
69
def diff_chunks_for_file(repository, filename, compare_revid, revid,
57
70
                         context_lines=None):
58
71
    if context_lines is None:
59
72
        context_lines = 3
60
73
    lines = {}
61
 
    args = []
62
 
    for r in (compare_revid, revid):
63
 
        if r == 'null:':
64
 
            lines[r] = []
 
74
    compare_tree = repository.revision_tree(compare_revid)
 
75
    tree = repository.revision_tree(revid)
 
76
    try:
 
77
        lines[revid] = tree.get_file_lines(filename)
 
78
    except NoSuchFile:
 
79
        lines[revid] = []
 
80
        lines[compare_revid] = compare_tree.get_file_lines(filename)
 
81
    else:
 
82
        compare_filename = find_previous_path(tree, compare_tree, filename)
 
83
        if compare_filename is not None:
 
84
            lines[compare_revid] = compare_tree.get_file_lines(compare_filename)
65
85
        else:
66
 
            args.append((file_id, r, r))
67
 
    for r, bytes_iter in repository.iter_files_bytes(args):
68
 
        lines[r] = osutils.split_lines(''.join(bytes_iter))
69
 
    buffer = StringIO()
 
86
            lines[compare_revid] = []
 
87
 
 
88
    buffer = BytesIO()
70
89
    try:
71
 
        diff.internal_diff('', lines[compare_revid], '', lines[revid], buffer, context_lines=context_lines)
 
90
        diff.internal_diff(
 
91
            '', lines[compare_revid], '', lines[revid], buffer,
 
92
            context_lines=context_lines)
72
93
    except errors.BinaryFile:
73
 
        difftext = ''
 
94
        difftext = b''
74
95
    else:
75
96
        difftext = buffer.getvalue()
76
97
 
79
100
 
80
101
class FileDiffUI(TemplatedBranchView):
81
102
 
82
 
    template_path = 'loggerhead.templates.filediff'
 
103
    template_name = 'filediff'
83
104
    supports_json = True
84
105
 
85
106
    def get_values(self, path, kwargs, headers):
86
 
        revid = urllib.unquote(self.args[0])
87
 
        compare_revid = urllib.unquote(self.args[1])
88
 
        file_id = urllib.unquote(self.args[2])
 
107
        revid = urlutils.unquote_to_bytes(self.args[0])
 
108
        compare_revid = urlutils.unquote_to_bytes(self.args[1])
 
109
        filename = urlutils.unquote(self.args[2])
89
110
 
90
111
        try:
91
112
            context_lines = int(kwargs['context'])
93
114
            context_lines = None
94
115
 
95
116
        chunks = diff_chunks_for_file(
96
 
            self._history._branch.repository, file_id, compare_revid, revid,
 
117
            self._history._branch.repository, filename, compare_revid, revid,
97
118
            context_lines=context_lines)
98
119
 
99
120
        return {