/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
1
# Copyright (C) 2010 Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17
"""Logic to create commit templates."""
18
7290.14.1 by Jelmer Vernooij
Use external patiencediff.
19
import patiencediff
20
21
from ... import bugtracker, osutils
0.192.2 by Jelmer Vernooij
Initial work on extract bug numbers from NEWS.
22
import re
23
0.192.3 by Jelmer Vernooij
Match on lp:BUGNO rather than #BUGNO
24
_BUG_MATCH = re.compile(r'lp:(\d+)')
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
25
6690.6.3 by Jelmer Vernooij
The 'commitfromnews' plugin is now bundled.
26
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
27
class CommitTemplate(object):
28
6739 by Jelmer Vernooij
Merge lp:~jelmer/brz/bundle-commitfromnews.
29
    def __init__(self, commit, message, filespec):
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
30
        """Create a commit template for commit with initial message message.
31
32
        :param commit: A Commit object for the in progress commit.
33
        :param message: The current message (which may be None).
6739 by Jelmer Vernooij
Merge lp:~jelmer/brz/bundle-commitfromnews.
34
        :param filespec: List of files to match
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
35
        """
36
        self.commit = commit
37
        self.message = message
6739 by Jelmer Vernooij
Merge lp:~jelmer/brz/bundle-commitfromnews.
38
        self.filespec = filespec
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
39
40
    def make(self):
41
        """Make the template.
42
43
        If NEWS is missing or not not modified, the original template is
44
        returned unaltered. Otherwise the changes from NEWS are concatenated
45
        with whatever message was provided to __init__.
46
        """
6690.6.3 by Jelmer Vernooij
The 'commitfromnews' plugin is now bundled.
47
        delta = self.commit.builder.get_basis_delta()
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
48
        found_old_path = None
49
        found_entry = None
50
        for old_path, new_path, fileid, entry in delta:
6739 by Jelmer Vernooij
Merge lp:~jelmer/brz/bundle-commitfromnews.
51
            if new_path in self.filespec:
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
52
                found_entry = entry
53
                found_old_path = old_path
54
                break
55
        if not found_entry:
56
            return self.message
57
        if found_old_path is None:
58
            # New file
7488.1.2 by Jelmer Vernooij
Fix test.
59
            _, new_chunks = next(
6690.6.3 by Jelmer Vernooij
The 'commitfromnews' plugin is now bundled.
60
                self.commit.builder.repository.iter_files_bytes(
7488.1.2 by Jelmer Vernooij
Fix test.
61
                    [(found_entry.file_id, found_entry.revision, None)]))
7027.8.1 by Jelmer Vernooij
Fix commitfromnews tests on python3.
62
            content = b''.join(new_chunks).decode('utf-8')
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
63
            return self.merge_message(content)
64
        else:
65
            # Get a diff. XXX Is this hookable? I thought it was, can't find it
7143.15.2 by Jelmer Vernooij
Run autopep8.
66
            # though.... add DiffTree.diff_factories. Sadly thats not at the
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
67
            # right level: we want to identify the changed lines, not have the
7143.15.2 by Jelmer Vernooij
Run autopep8.
68
            # final diff: because we want to grab the sections for regions
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
69
            # changed in new version of the file. So for now a direct diff
70
            # using patiencediff is done.
7141.7.1 by Jelmer Vernooij
Get rid of file_ids in most of Tree.
71
            old_revision = self.commit.basis_tree.get_file_revision(old_path)
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
72
            needed = [(found_entry.file_id, found_entry.revision, 'new'),
6690.6.1 by Jelmer Vernooij
Bundle the commitfromnews plugin.
73
                      (found_entry.file_id, old_revision, 'old')]
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
74
            contents = self.commit.builder.repository.iter_files_bytes(needed)
75
            lines = {}
76
            for name, chunks in contents:
7488.1.2 by Jelmer Vernooij
Fix test.
77
                lines[name] = osutils.chunks_to_lines(list(chunks))
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
78
            new = lines['new']
79
            sequence_matcher = patiencediff.PatienceSequenceMatcher(
80
                None, lines['old'], new)
81
            new_lines = []
82
            for group in sequence_matcher.get_opcodes():
83
                tag, i1, i2, j1, j2 = group
84
                if tag == 'equal':
85
                    continue
86
                if tag == 'delete':
87
                    continue
7027.8.1 by Jelmer Vernooij
Fix commitfromnews tests on python3.
88
                new_lines.extend([l.decode('utf-8') for l in new[j1:j2]])
0.192.2 by Jelmer Vernooij
Initial work on extract bug numbers from NEWS.
89
            if not self.commit.revprops.get('bugs'):
90
                # TODO: Allow the user to configure the bug tracker to use
91
                # rather than hardcoding Launchpad.
92
                bt = bugtracker.tracker_registry.get('launchpad')
93
                bugids = []
94
                for line in new_lines:
95
                    bugids.extend(_BUG_MATCH.findall(line))
96
                self.commit.revprops['bugs'] = \
97
                    bugtracker.encode_fixes_bug_urls(
7131.10.3 by Jelmer Vernooij
Fix remaining tests.
98
                        [(bt.get_bug_url(bugid), bugtracker.FIXED)
99
                         for bugid in bugids])
0.191.2 by Robert Collins
* Merge messages in the changed-NEWS file case.
100
            return self.merge_message(''.join(new_lines))
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
101
102
    def merge_message(self, new_message):
103
        """Merge new_message with self.message.
6690.6.3 by Jelmer Vernooij
The 'commitfromnews' plugin is now bundled.
104
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
105
        :param new_message: A string message to merge with self.message.
106
        :return: A string with the merged messages.
107
        """
108
        if self.message is None:
109
            return new_message
110
        return self.message + new_message