Skip to content

Commit d1b3ac8

Browse files
committed
gitlint-rules: Remove convoluted binary search for imperative forms.
This also fixes the suggestions for the following words: disabled, disables, disabling, implemented, implementing, implements, kept, made, took, using. (Copied from zulip/zulip@91f048c.) Signed-off-by: Anders Kaseorg <[email protected]>
1 parent 9ce7c52 commit d1b3ac8

File tree

1 file changed

+64
-270
lines changed

1 file changed

+64
-270
lines changed

tools/gitlint-rules.py

Lines changed: 64 additions & 270 deletions
Original file line numberDiff line numberDiff line change
@@ -10,276 +10,70 @@
1010
# Copyright (c) 2015 Mike Foley
1111
# License: MIT
1212
# Ref: fit_commit/validators/tense.rb
13-
WORD_SET = {
14-
"adds",
15-
"adding",
16-
"added",
17-
"allows",
18-
"allowing",
19-
"allowed",
20-
"amends",
21-
"amending",
22-
"amended",
23-
"bumps",
24-
"bumping",
25-
"bumped",
26-
"calculates",
27-
"calculating",
28-
"calculated",
29-
"changes",
30-
"changing",
31-
"changed",
32-
"cleans",
33-
"cleaning",
34-
"cleaned",
35-
"commits",
36-
"committing",
37-
"committed",
38-
"corrects",
39-
"correcting",
40-
"corrected",
41-
"creates",
42-
"creating",
43-
"created",
44-
"darkens",
45-
"darkening",
46-
"darkened",
47-
"disables",
48-
"disabling",
49-
"disabled",
50-
"displays",
51-
"displaying",
52-
"displayed",
53-
"documents",
54-
"documenting",
55-
"documented",
56-
"drys",
57-
"drying",
58-
"dryed",
59-
"ends",
60-
"ending",
61-
"ended",
62-
"enforces",
63-
"enforcing",
64-
"enforced",
65-
"enqueues",
66-
"enqueuing",
67-
"enqueued",
68-
"extracts",
69-
"extracting",
70-
"extracted",
71-
"finishes",
72-
"finishing",
73-
"finished",
74-
"fixes",
75-
"fixing",
76-
"fixed",
77-
"formats",
78-
"formatting",
79-
"formatted",
80-
"guards",
81-
"guarding",
82-
"guarded",
83-
"handles",
84-
"handling",
85-
"handled",
86-
"hides",
87-
"hiding",
88-
"hid",
89-
"increases",
90-
"increasing",
91-
"increased",
92-
"ignores",
93-
"ignoring",
94-
"ignored",
95-
"implements",
96-
"implementing",
97-
"implemented",
98-
"improves",
99-
"improving",
100-
"improved",
101-
"keeps",
102-
"keeping",
103-
"kept",
104-
"kills",
105-
"killing",
106-
"killed",
107-
"makes",
108-
"making",
109-
"made",
110-
"merges",
111-
"merging",
112-
"merged",
113-
"moves",
114-
"moving",
115-
"moved",
116-
"permits",
117-
"permitting",
118-
"permitted",
119-
"prevents",
120-
"preventing",
121-
"prevented",
122-
"pushes",
123-
"pushing",
124-
"pushed",
125-
"rebases",
126-
"rebasing",
127-
"rebased",
128-
"refactors",
129-
"refactoring",
130-
"refactored",
131-
"removes",
132-
"removing",
133-
"removed",
134-
"renames",
135-
"renaming",
136-
"renamed",
137-
"reorders",
138-
"reordering",
139-
"reordered",
140-
"replaces",
141-
"replacing",
142-
"replaced",
143-
"requires",
144-
"requiring",
145-
"required",
146-
"restores",
147-
"restoring",
148-
"restored",
149-
"sends",
150-
"sending",
151-
"sent",
152-
"sets",
153-
"setting",
154-
"separates",
155-
"separating",
156-
"separated",
157-
"shows",
158-
"showing",
159-
"showed",
160-
"simplifies",
161-
"simplifying",
162-
"simplified",
163-
"skips",
164-
"skipping",
165-
"skipped",
166-
"sorts",
167-
"sorting",
168-
"speeds",
169-
"speeding",
170-
"sped",
171-
"starts",
172-
"starting",
173-
"started",
174-
"supports",
175-
"supporting",
176-
"supported",
177-
"takes",
178-
"taking",
179-
"took",
180-
"testing",
181-
"tested", # 'tests' excluded to reduce false negative
182-
"truncates",
183-
"truncating",
184-
"truncated",
185-
"updates",
186-
"updating",
187-
"updated",
188-
"uses",
189-
"using",
190-
"used",
191-
}
192-
193-
imperative_forms = [
194-
"add",
195-
"allow",
196-
"amend",
197-
"bump",
198-
"calculate",
199-
"change",
200-
"clean",
201-
"commit",
202-
"correct",
203-
"create",
204-
"darken",
205-
"disable",
206-
"display",
207-
"document",
208-
"dry",
209-
"end",
210-
"enforce",
211-
"enqueue",
212-
"extract",
213-
"finish",
214-
"fix",
215-
"format",
216-
"guard",
217-
"handle",
218-
"hide",
219-
"ignore",
220-
"implement",
221-
"improve",
222-
"increase",
223-
"keep",
224-
"kill",
225-
"make",
226-
"merge",
227-
"move",
228-
"permit",
229-
"prevent",
230-
"push",
231-
"rebase",
232-
"refactor",
233-
"remove",
234-
"rename",
235-
"reorder",
236-
"replace",
237-
"require",
238-
"restore",
239-
"send",
240-
"separate",
241-
"set",
242-
"show",
243-
"simplify",
244-
"skip",
245-
"sort",
246-
"speed",
247-
"start",
248-
"support",
249-
"take",
250-
"test",
251-
"truncate",
252-
"update",
253-
"use",
13+
TENSE_DATA = [
14+
(["adds", "adding", "added"], "add"),
15+
(["allows", "allowing", "allowed"], "allow"),
16+
(["amends", "amending", "amended"], "amend"),
17+
(["bumps", "bumping", "bumped"], "bump"),
18+
(["calculates", "calculating", "calculated"], "calculate"),
19+
(["changes", "changing", "changed"], "change"),
20+
(["cleans", "cleaning", "cleaned"], "clean"),
21+
(["commits", "committing", "committed"], "commit"),
22+
(["corrects", "correcting", "corrected"], "correct"),
23+
(["creates", "creating", "created"], "create"),
24+
(["darkens", "darkening", "darkened"], "darken"),
25+
(["disables", "disabling", "disabled"], "disable"),
26+
(["displays", "displaying", "displayed"], "display"),
27+
(["documents", "documenting", "documented"], "document"),
28+
(["drys", "drying", "dryed"], "dry"),
29+
(["ends", "ending", "ended"], "end"),
30+
(["enforces", "enforcing", "enforced"], "enforce"),
31+
(["enqueues", "enqueuing", "enqueued"], "enqueue"),
32+
(["extracts", "extracting", "extracted"], "extract"),
33+
(["finishes", "finishing", "finished"], "finish"),
34+
(["fixes", "fixing", "fixed"], "fix"),
35+
(["formats", "formatting", "formatted"], "format"),
36+
(["guards", "guarding", "guarded"], "guard"),
37+
(["handles", "handling", "handled"], "handle"),
38+
(["hides", "hiding", "hid"], "hide"),
39+
(["increases", "increasing", "increased"], "increase"),
40+
(["ignores", "ignoring", "ignored"], "ignore"),
41+
(["implements", "implementing", "implemented"], "implement"),
42+
(["improves", "improving", "improved"], "improve"),
43+
(["keeps", "keeping", "kept"], "keep"),
44+
(["kills", "killing", "killed"], "kill"),
45+
(["makes", "making", "made"], "make"),
46+
(["merges", "merging", "merged"], "merge"),
47+
(["moves", "moving", "moved"], "move"),
48+
(["permits", "permitting", "permitted"], "permit"),
49+
(["prevents", "preventing", "prevented"], "prevent"),
50+
(["pushes", "pushing", "pushed"], "push"),
51+
(["rebases", "rebasing", "rebased"], "rebase"),
52+
(["refactors", "refactoring", "refactored"], "refactor"),
53+
(["removes", "removing", "removed"], "remove"),
54+
(["renames", "renaming", "renamed"], "rename"),
55+
(["reorders", "reordering", "reordered"], "reorder"),
56+
(["replaces", "replacing", "replaced"], "replace"),
57+
(["requires", "requiring", "required"], "require"),
58+
(["restores", "restoring", "restored"], "restore"),
59+
(["sends", "sending", "sent"], "send"),
60+
(["sets", "setting"], "set"),
61+
(["separates", "separating", "separated"], "separate"),
62+
(["shows", "showing", "showed"], "show"),
63+
(["simplifies", "simplifying", "simplified"], "simplify"),
64+
(["skips", "skipping", "skipped"], "skip"),
65+
(["sorts", "sorting"], "sort"),
66+
(["speeds", "speeding", "sped"], "speed"),
67+
(["starts", "starting", "started"], "start"),
68+
(["supports", "supporting", "supported"], "support"),
69+
(["takes", "taking", "took"], "take"),
70+
(["testing", "tested"], "test"), # "tests" excluded to reduce false negatives
71+
(["truncates", "truncating", "truncated"], "truncate"),
72+
(["updates", "updating", "updated"], "update"),
73+
(["uses", "using", "used"], "use"),
25474
]
255-
imperative_forms.sort()
256-
257-
258-
def head_binary_search(key: str, words: List[str]) -> str:
259-
"""Find the imperative mood version of `word` by looking at the first
260-
3 characters."""
261-
262-
# Edge case: 'disable' and 'display' have the same 3 starting letters.
263-
if key in ["displays", "displaying", "displayed"]:
264-
return "display"
265-
266-
lower = 0
267-
upper = len(words) - 1
268-
269-
while True:
270-
if lower > upper:
271-
# Should not happen
272-
raise Exception(f"Cannot find imperative mood of {key}")
273-
274-
mid = (lower + upper) // 2
275-
imperative_form = words[mid]
27675

277-
if key[:3] == imperative_form[:3]:
278-
return imperative_form
279-
elif key < imperative_form:
280-
upper = mid - 1
281-
elif key > imperative_form:
282-
lower = mid + 1
76+
TENSE_CORRECTIONS = {word: imperative for words, imperative in TENSE_DATA for word in words}
28377

28478

28579
class ImperativeMood(LineRule):
@@ -303,8 +97,8 @@ def validate(self, line: str, commit: GitCommit) -> List[RuleViolation]:
30397
words = line.split(": ", 1)[-1].split()
30498
first_word = words[0].lower()
30599

306-
if first_word in WORD_SET:
307-
imperative = head_binary_search(first_word, imperative_forms)
100+
if first_word in TENSE_CORRECTIONS:
101+
imperative = TENSE_CORRECTIONS[first_word]
308102
violation = RuleViolation(
309103
self.id,
310104
self.error_msg.format(

0 commit comments

Comments
 (0)