1from gitlint.rules import LineRule, RuleViolation, CommitMessageTitle 2import re 3 4 5class TitleStartsWithComponent(LineRule): 6 """This rule will enforce that the commit message title starts with valid 7 component name 8 """ 9 10 # A rule MUST have a human friendly name 11 name = "title-has-valid-component" 12 13 # A rule MUST have a *unique* id. 14 # We recommend starting with UL (for User-defined Line-rule) 15 id = "UL1" 16 17 # A line-rule MUST have a target (not required for CommitRules). 18 target = CommitMessageTitle 19 20 def validate(self, line, _commit): 21 valid_components = [ 22 'api_client', 23 'arch', 24 'block', 25 'build', 26 'ch-remote', 27 'ci', 28 'devices', 29 'docs', 30 'event_monitor', 31 'fuzz', 32 'github', 33 'gitignore', 34 'hypervisor', 35 'Jenkinsfile', 36 'misc', 37 'net_gen', 38 'net_util', 39 'option_parser', 40 'pci', 41 'performance-metrics', 42 'rate_limiter', 43 'README', 44 'resources', 45 'scripts', 46 'serial_buffer', 47 'test_data', 48 'test_infra', 49 'tests', 50 'tpm', 51 'tracer', 52 'vhost_user_block', 53 'vhost_user_net', 54 'virtio-devices', 55 'vm-allocator', 56 'vm-device', 57 'vmm', 58 'vm-migration', 59 'vm-virtio'] 60 61 pattern = re.compile(r'^(.+):\s(.+)$') 62 match = pattern.match(line) 63 64 if not match: 65 self.log.debug("Invalid commit title {}", line) 66 return [RuleViolation(self.id, "Commit title does not comply with " 67 "rule: 'component: change summary'")] 68 component = match.group(1) 69 summary = match.group(2) 70 self.log.debug(f"\nComponent: {component}\nSummary: {summary}") 71 72 if component not in valid_components: 73 return [RuleViolation(self.id, 74 f"Invalid component: {component}, " 75 f"valid components are: {valid_components}")] 76