summaryrefslogtreecommitdiff
path: root/tools/patman/commit.py
blob: 8d583c4ed393a093d2b13f006da7a3508001de60 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# SPDX-License-Identifier: GPL-2.0+
# Copyright (c) 2011 The Chromium OS Authors.
#

import collections
import re

# Separates a tag: at the beginning of the subject from the rest of it
re_subject_tag = re.compile('([^:\s]*):\s*(.*)')

class Commit:
    """Holds information about a single commit/patch in the series.

    Args:
        hash: Commit hash (as a string)

    Variables:
        hash: Commit hash
        subject: Subject line
        tags: List of maintainer tag strings
        changes: Dict containing a list of changes (single line strings).
            The dict is indexed by change version (an integer)
        cc_list: List of people to aliases/emails to cc on this commit
        notes: List of lines in the commit (not series) notes
        change_id: the Change-Id: tag that was stripped from this commit
            and can be used to generate the Message-Id.
        rtags: Response tags (e.g. Reviewed-by) collected by the commit, dict:
            key: rtag type (e.g. 'Reviewed-by')
            value: Set of people who gave that rtag, each a name/email string
    """
    def __init__(self, hash):
        self.hash = hash
        self.subject = None
        self.tags = []
        self.changes = {}
        self.cc_list = []
        self.signoff_set = set()
        self.notes = []
        self.change_id = None
        self.rtags = collections.defaultdict(set)

    def AddChange(self, version, info):
        """Add a new change line to the change list for a version.

        Args:
            version: Patch set version (integer: 1, 2, 3)
            info: Description of change in this version
        """
        if not self.changes.get(version):
            self.changes[version] = []
        self.changes[version].append(info)

    def CheckTags(self):
        """Create a list of subject tags in the commit

        Subject tags look like this:

            propounder: fort: Change the widget to propound correctly

        Here the tags are propounder and fort. Multiple tags are supported.
        The list is updated in self.tag.

        Returns:
            None if ok, else the name of a tag with no email alias
        """
        str = self.subject
        m = True
        while m:
            m = re_subject_tag.match(str)
            if m:
                tag = m.group(1)
                self.tags.append(tag)
                str = m.group(2)
        return None

    def AddCc(self, cc_list):
        """Add a list of people to Cc when we send this patch.

        Args:
            cc_list:    List of aliases or email addresses
        """
        self.cc_list += cc_list

    def CheckDuplicateSignoff(self, signoff):
        """Check a list of signoffs we have send for this patch

        Args:
            signoff:    Signoff line
        Returns:
            True if this signoff is new, False if we have already seen it.
        """
        if signoff in self.signoff_set:
          return False
        self.signoff_set.add(signoff)
        return True

    def AddRtag(self, rtag_type, who):
        """Add a response tag to a commit

        Args:
            key: rtag type (e.g. 'Reviewed-by')
            who: Person who gave that rtag, e.g. 'Fred Bloggs <fred@bloggs.org>'
        """
        self.rtags[rtag_type].add(who)