xref: /cloud-hypervisor/scripts/gitlint/rules/TitleStartsWithComponent.py (revision 07475d2bc1bd706bcdc5e029c0a920969937daa7)
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            'gitlint',
35            'hypervisor',
36            'Jenkinsfile',
37            'misc',
38            'net_gen',
39            'net_util',
40            'option_parser',
41            'pci',
42            'performance-metrics',
43            'rate_limiter',
44            'README',
45            'resources',
46            'scripts',
47            'serial_buffer',
48            'test_data',
49            'test_infra',
50            'tests',
51            'tpm',
52            'tracer',
53            'vhost_user_block',
54            'vhost_user_net',
55            'virtio-devices',
56            'vm-allocator',
57            'vm-device',
58            'vmm',
59            'vm-migration',
60            'vm-virtio']
61
62        pattern = re.compile(r'^(.+):\s(.+)$')
63        match = pattern.match(line)
64
65        if not match:
66            self.log.debug("Invalid commit title {}", line)
67            return [RuleViolation(self.id, "Commit title does not comply with "
68                                  "rule: 'component: change summary'")]
69        component = match.group(1)
70        summary = match.group(2)
71        self.log.debug(f"\nComponent: {component}\nSummary: {summary}")
72
73        if component not in valid_components:
74            return [RuleViolation(self.id,
75                                  f"Invalid component: {component}, "
76                                  f"valid components are: {valid_components}")]
77