forked from zulip/python-zulip-api
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgitlint-rules.py
113 lines (100 loc) · 4.72 KB
/
gitlint-rules.py
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
105
106
107
108
109
110
111
112
113
# This file is copied from the original at tools/lib/gitlint-rules.py in zulip/zulip.
# Please don't edit here; instead update the zulip/zulip copy and then resync this file.
from typing import List
from gitlint.git import GitCommit
from gitlint.rules import CommitMessageTitle, LineRule, RuleViolation
# Word list from https://github.com/m1foley/fit-commit
# Copyright (c) 2015 Mike Foley
# License: MIT
# Ref: fit_commit/validators/tense.rb
TENSE_DATA = [
(["adds", "adding", "added"], "add"),
(["allows", "allowing", "allowed"], "allow"),
(["amends", "amending", "amended"], "amend"),
(["bumps", "bumping", "bumped"], "bump"),
(["calculates", "calculating", "calculated"], "calculate"),
(["changes", "changing", "changed"], "change"),
(["cleans", "cleaning", "cleaned"], "clean"),
(["commits", "committing", "committed"], "commit"),
(["corrects", "correcting", "corrected"], "correct"),
(["creates", "creating", "created"], "create"),
(["darkens", "darkening", "darkened"], "darken"),
(["disables", "disabling", "disabled"], "disable"),
(["displays", "displaying", "displayed"], "display"),
(["documents", "documenting", "documented"], "document"),
(["drys", "drying", "dryed"], "dry"),
(["ends", "ending", "ended"], "end"),
(["enforces", "enforcing", "enforced"], "enforce"),
(["enqueues", "enqueuing", "enqueued"], "enqueue"),
(["extracts", "extracting", "extracted"], "extract"),
(["finishes", "finishing", "finished"], "finish"),
(["fixes", "fixing", "fixed"], "fix"),
(["formats", "formatting", "formatted"], "format"),
(["guards", "guarding", "guarded"], "guard"),
(["handles", "handling", "handled"], "handle"),
(["hides", "hiding", "hid"], "hide"),
(["increases", "increasing", "increased"], "increase"),
(["ignores", "ignoring", "ignored"], "ignore"),
(["implements", "implementing", "implemented"], "implement"),
(["improves", "improving", "improved"], "improve"),
(["keeps", "keeping", "kept"], "keep"),
(["kills", "killing", "killed"], "kill"),
(["makes", "making", "made"], "make"),
(["merges", "merging", "merged"], "merge"),
(["moves", "moving", "moved"], "move"),
(["permits", "permitting", "permitted"], "permit"),
(["prevents", "preventing", "prevented"], "prevent"),
(["pushes", "pushing", "pushed"], "push"),
(["rebases", "rebasing", "rebased"], "rebase"),
(["refactors", "refactoring", "refactored"], "refactor"),
(["removes", "removing", "removed"], "remove"),
(["renames", "renaming", "renamed"], "rename"),
(["reorders", "reordering", "reordered"], "reorder"),
(["replaces", "replacing", "replaced"], "replace"),
(["requires", "requiring", "required"], "require"),
(["restores", "restoring", "restored"], "restore"),
(["sends", "sending", "sent"], "send"),
(["sets", "setting"], "set"),
(["separates", "separating", "separated"], "separate"),
(["shows", "showing", "showed"], "show"),
(["simplifies", "simplifying", "simplified"], "simplify"),
(["skips", "skipping", "skipped"], "skip"),
(["sorts", "sorting"], "sort"),
(["speeds", "speeding", "sped"], "speed"),
(["starts", "starting", "started"], "start"),
(["supports", "supporting", "supported"], "support"),
(["takes", "taking", "took"], "take"),
(["testing", "tested"], "test"), # "tests" excluded to reduce false negatives
(["truncates", "truncating", "truncated"], "truncate"),
(["updates", "updating", "updated"], "update"),
(["uses", "using", "used"], "use"),
]
TENSE_CORRECTIONS = {word: imperative for words, imperative in TENSE_DATA for word in words}
class ImperativeMood(LineRule):
"""This rule will enforce that the commit message title uses imperative
mood. This is done by checking if the first word is in `WORD_SET`, if so
show the word in the correct mood."""
name = "title-imperative-mood"
id = "Z1"
target = CommitMessageTitle
error_msg = (
"The first word in commit title should be in imperative mood "
'("{word}" -> "{imperative}"): "{title}"'
)
def validate(self, line: str, commit: GitCommit) -> List[RuleViolation]:
violations = []
# Ignore the section tag (ie `<section tag>: <message body>.`)
words = line.split(": ", 1)[-1].split()
first_word = words[0].lower()
if first_word in TENSE_CORRECTIONS:
imperative = TENSE_CORRECTIONS[first_word]
violation = RuleViolation(
self.id,
self.error_msg.format(
word=first_word,
imperative=imperative,
title=commit.message.title,
),
)
violations.append(violation)
return violations