commit.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. # SPDX-License-Identifier: GPL-2.0+
  2. # Copyright (c) 2011 The Chromium OS Authors.
  3. #
  4. import collections
  5. import re
  6. # Separates a tag: at the beginning of the subject from the rest of it
  7. re_subject_tag = re.compile('([^:\s]*):\s*(.*)')
  8. class Commit:
  9. """Holds information about a single commit/patch in the series.
  10. Args:
  11. hash: Commit hash (as a string)
  12. Variables:
  13. hash: Commit hash
  14. subject: Subject line
  15. tags: List of maintainer tag strings
  16. changes: Dict containing a list of changes (single line strings).
  17. The dict is indexed by change version (an integer)
  18. cc_list: List of people to aliases/emails to cc on this commit
  19. notes: List of lines in the commit (not series) notes
  20. change_id: the Change-Id: tag that was stripped from this commit
  21. and can be used to generate the Message-Id.
  22. rtags: Response tags (e.g. Reviewed-by) collected by the commit, dict:
  23. key: rtag type (e.g. 'Reviewed-by')
  24. value: Set of people who gave that rtag, each a name/email string
  25. warn: List of warnings for this commit, each a str
  26. patch (str): Filename of the patch file for this commit
  27. future (concurrent.futures.Future): Future object for processing this
  28. commit, or None
  29. """
  30. def __init__(self, hash):
  31. self.hash = hash
  32. self.subject = ''
  33. self.tags = []
  34. self.changes = {}
  35. self.cc_list = []
  36. self.signoff_set = set()
  37. self.notes = []
  38. self.change_id = None
  39. self.rtags = collections.defaultdict(set)
  40. self.warn = []
  41. self.patch = ''
  42. self.future = None
  43. def __str__(self):
  44. return self.subject
  45. def add_change(self, version, info):
  46. """Add a new change line to the change list for a version.
  47. Args:
  48. version: Patch set version (integer: 1, 2, 3)
  49. info: Description of change in this version
  50. """
  51. if not self.changes.get(version):
  52. self.changes[version] = []
  53. self.changes[version].append(info)
  54. def check_tags(self):
  55. """Create a list of subject tags in the commit
  56. Subject tags look like this:
  57. propounder: fort: Change the widget to propound correctly
  58. Here the tags are propounder and fort. Multiple tags are supported.
  59. The list is updated in self.tag.
  60. Returns:
  61. None if ok, else the name of a tag with no email alias
  62. """
  63. str = self.subject
  64. m = True
  65. while m:
  66. m = re_subject_tag.match(str)
  67. if m:
  68. tag = m.group(1)
  69. self.tags.append(tag)
  70. str = m.group(2)
  71. return None
  72. def add_cc(self, cc_list):
  73. """Add a list of people to Cc when we send this patch.
  74. Args:
  75. cc_list: List of aliases or email addresses
  76. """
  77. self.cc_list += cc_list
  78. def check_duplicate_signoff(self, signoff):
  79. """Check a list of signoffs we have send for this patch
  80. Args:
  81. signoff: Signoff line
  82. Returns:
  83. True if this signoff is new, False if we have already seen it.
  84. """
  85. if signoff in self.signoff_set:
  86. return False
  87. self.signoff_set.add(signoff)
  88. return True
  89. def add_rtag(self, rtag_type, who):
  90. """Add a response tag to a commit
  91. Args:
  92. key: rtag type (e.g. 'Reviewed-by')
  93. who: Person who gave that rtag, e.g. 'Fred Bloggs <fred@bloggs.org>'
  94. """
  95. self.rtags[rtag_type].add(who)