gitlint: validate title components

Valid title format:
component1[, component2, componentN]: submodule: summary

Title should have at least one component
Components are separated by comma+space: ", "
Components are validated to be in valid_components
Components list is ended by a colon
Submodules are not validated

See: #5846

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
This commit is contained in:
Ruslan Mstoi
2023-11-17 17:06:13 +02:00
committed by Bo Chen
parent 70380d289f
commit 851ab0ad43

View File

@@ -3,8 +3,17 @@ import re
class TitleStartsWithComponent(LineRule): class TitleStartsWithComponent(LineRule):
"""This rule will enforce that the commit message title starts with valid """A rule to enforce valid commit message title
component name
Valid title format:
component1[, component2, componentN]: submodule: summary
Title should have at least one component
Components are separated by comma+space: ", "
Components are validated to be in valid_components
Components list is ended by a colon
Submodules are not validated
""" """
# A rule MUST have a human friendly name # A rule MUST have a human friendly name
@@ -18,7 +27,7 @@ class TitleStartsWithComponent(LineRule):
target = CommitMessageTitle target = CommitMessageTitle
def validate(self, line, _commit): def validate(self, line, _commit):
valid_components = [ valid_components = (
'api_client', 'api_client',
'arch', 'arch',
'block', 'block',
@@ -57,20 +66,26 @@ class TitleStartsWithComponent(LineRule):
'vm-device', 'vm-device',
'vmm', 'vmm',
'vm-migration', 'vm-migration',
'vm-virtio'] 'vm-virtio')
pattern = re.compile(r'^(.+):\s(.+)$') ptrn_title = re.compile(r'^(.+?):\s(.+)$')
match = pattern.match(line) match = ptrn_title.match(line)
if not match: if not match:
self.log.debug("Invalid commit title {}", line) self.log.debug("Invalid commit title {}", line)
return [RuleViolation(self.id, "Commit title does not comply with " return [RuleViolation(self.id, "Commit title does not comply with "
"rule: 'component: change summary'")] "rule: 'component: change summary'")]
component = match.group(1) components = match.group(1)
summary = match.group(2) summary = match.group(2)
self.log.debug(f"\nComponent: {component}\nSummary: {summary}") self.log.debug(f"\nComponents: {components}\nSummary: {summary}")
if component not in valid_components: ptrn_components = re.compile(r',\s')
return [RuleViolation(self.id, components_list = re.split(ptrn_components, components)
f"Invalid component: {component}, " self.log.debug("components list: %s" % components_list)
f"valid components are: {valid_components}")]
for component in components_list:
if component not in valid_components:
return [RuleViolation(self.id,
f"Invalid component: {component}, "
"\nValid components are: {}".format(
" ".join(valid_components)))]