/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
6690.6.1 by Jelmer Vernooij
Bundle the commitfromnews plugin.
19
from __future__ import absolute_import
20
7290.14.1 by Jelmer Vernooij
Use external patiencediff.
21
import patiencediff
22
23
from ... import bugtracker, osutils
0.192.2 by Jelmer Vernooij
Initial work on extract bug numbers from NEWS.
24
import re
25
0.192.3 by Jelmer Vernooij
Match on lp:BUGNO rather than #BUGNO
26
_BUG_MATCH = re.compile(r'lp:(\d+)')
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
27
6690.6.3 by Jelmer Vernooij
The 'commitfromnews' plugin is now bundled.
28
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
29
class CommitTemplate(object):
30
6739 by Jelmer Vernooij
Merge lp:~jelmer/brz/bundle-commitfromnews.
31
    def __init__(self, commit, message, filespec):
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
32
        """Create a commit template for commit with initial message message.
33
34
        :param commit: A Commit object for the in progress commit.
35
        :param message: The current message (which may be None).
6739 by Jelmer Vernooij
Merge lp:~jelmer/brz/bundle-commitfromnews.
36
        :param filespec: List of files to match
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
37
        """
38
        self.commit = commit
39
        self.message = message
6739 by Jelmer Vernooij
Merge lp:~jelmer/brz/bundle-commitfromnews.
40
        self.filespec = filespec
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
41
42
    def make(self):
43
        """Make the template.
44
45
        If NEWS is missing or not not modified, the original template is
46
        returned unaltered. Otherwise the changes from NEWS are concatenated
47
        with whatever message was provided to __init__.
48
        """
6690.6.3 by Jelmer Vernooij
The 'commitfromnews' plugin is now bundled.
49
        delta = self.commit.builder.get_basis_delta()
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
50
        found_old_path = None
51
        found_entry = None
52
        for old_path, new_path, fileid, entry in delta:
6739 by Jelmer Vernooij
Merge lp:~jelmer/brz/bundle-commitfromnews.
53
            if new_path in self.filespec:
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
54
                found_entry = entry
55
                found_old_path = old_path
56
                break
57
        if not found_entry:
58
            return self.message
59
        if found_old_path is None:
60
            # New file
6690.6.3 by Jelmer Vernooij
The 'commitfromnews' plugin is now bundled.
61
            _, new_chunks = list(
62
                self.commit.builder.repository.iter_files_bytes(
63
                    [(found_entry.file_id, found_entry.revision, None)]))[0]
7027.8.1 by Jelmer Vernooij
Fix commitfromnews tests on python3.
64
            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
65
            return self.merge_message(content)
66
        else:
67
            # Get a diff. XXX Is this hookable? I thought it was, can't find it
7143.15.2 by Jelmer Vernooij
Run autopep8.
68
            # 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
69
            # right level: we want to identify the changed lines, not have the
7143.15.2 by Jelmer Vernooij
Run autopep8.
70
            # 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
71
            # changed in new version of the file. So for now a direct diff
72
            # using patiencediff is done.
7141.7.1 by Jelmer Vernooij
Get rid of file_ids in most of Tree.
73
            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
74
            needed = [(found_entry.file_id, found_entry.revision, 'new'),
6690.6.1 by Jelmer Vernooij
Bundle the commitfromnews plugin.
75
                      (found_entry.file_id, old_revision, 'old')]
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
76
            contents = self.commit.builder.repository.iter_files_bytes(needed)
77
            lines = {}
78
            for name, chunks in contents:
79
                lines[name] = osutils.chunks_to_lines(chunks)
80
            new = lines['new']
81
            sequence_matcher = patiencediff.PatienceSequenceMatcher(
82
                None, lines['old'], new)
83
            new_lines = []
84
            for group in sequence_matcher.get_opcodes():
85
                tag, i1, i2, j1, j2 = group
86
                if tag == 'equal':
87
                    continue
88
                if tag == 'delete':
89
                    continue
7027.8.1 by Jelmer Vernooij
Fix commitfromnews tests on python3.
90
                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.
91
            if not self.commit.revprops.get('bugs'):
92
                # TODO: Allow the user to configure the bug tracker to use
93
                # rather than hardcoding Launchpad.
94
                bt = bugtracker.tracker_registry.get('launchpad')
95
                bugids = []
96
                for line in new_lines:
97
                    bugids.extend(_BUG_MATCH.findall(line))
98
                self.commit.revprops['bugs'] = \
99
                    bugtracker.encode_fixes_bug_urls(
7131.10.3 by Jelmer Vernooij
Fix remaining tests.
100
                        [(bt.get_bug_url(bugid), bugtracker.FIXED)
101
                         for bugid in bugids])
0.191.2 by Robert Collins
* Merge messages in the changed-NEWS file case.
102
            return self.merge_message(''.join(new_lines))
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
103
104
    def merge_message(self, new_message):
105
        """Merge new_message with self.message.
6690.6.3 by Jelmer Vernooij
The 'commitfromnews' plugin is now bundled.
106
0.191.1 by Robert Collins
Created plugin, basic functionality of looking for NEWS and including the
107
        :param new_message: A string message to merge with self.message.
108
        :return: A string with the merged messages.
109
        """
110
        if self.message is None:
111
            return new_message
112
        return self.message + new_message