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@91f048c056a66eb78a102c095e714eff5f28e36e.) Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
9ce7c52a10
commit
d1b3ac8d94
|
@ -10,276 +10,70 @@ from gitlint.rules import CommitMessageTitle, LineRule, RuleViolation
|
||||||
# Copyright (c) 2015 Mike Foley
|
# Copyright (c) 2015 Mike Foley
|
||||||
# License: MIT
|
# License: MIT
|
||||||
# Ref: fit_commit/validators/tense.rb
|
# Ref: fit_commit/validators/tense.rb
|
||||||
WORD_SET = {
|
TENSE_DATA = [
|
||||||
"adds",
|
(["adds", "adding", "added"], "add"),
|
||||||
"adding",
|
(["allows", "allowing", "allowed"], "allow"),
|
||||||
"added",
|
(["amends", "amending", "amended"], "amend"),
|
||||||
"allows",
|
(["bumps", "bumping", "bumped"], "bump"),
|
||||||
"allowing",
|
(["calculates", "calculating", "calculated"], "calculate"),
|
||||||
"allowed",
|
(["changes", "changing", "changed"], "change"),
|
||||||
"amends",
|
(["cleans", "cleaning", "cleaned"], "clean"),
|
||||||
"amending",
|
(["commits", "committing", "committed"], "commit"),
|
||||||
"amended",
|
(["corrects", "correcting", "corrected"], "correct"),
|
||||||
"bumps",
|
(["creates", "creating", "created"], "create"),
|
||||||
"bumping",
|
(["darkens", "darkening", "darkened"], "darken"),
|
||||||
"bumped",
|
(["disables", "disabling", "disabled"], "disable"),
|
||||||
"calculates",
|
(["displays", "displaying", "displayed"], "display"),
|
||||||
"calculating",
|
(["documents", "documenting", "documented"], "document"),
|
||||||
"calculated",
|
(["drys", "drying", "dryed"], "dry"),
|
||||||
"changes",
|
(["ends", "ending", "ended"], "end"),
|
||||||
"changing",
|
(["enforces", "enforcing", "enforced"], "enforce"),
|
||||||
"changed",
|
(["enqueues", "enqueuing", "enqueued"], "enqueue"),
|
||||||
"cleans",
|
(["extracts", "extracting", "extracted"], "extract"),
|
||||||
"cleaning",
|
(["finishes", "finishing", "finished"], "finish"),
|
||||||
"cleaned",
|
(["fixes", "fixing", "fixed"], "fix"),
|
||||||
"commits",
|
(["formats", "formatting", "formatted"], "format"),
|
||||||
"committing",
|
(["guards", "guarding", "guarded"], "guard"),
|
||||||
"committed",
|
(["handles", "handling", "handled"], "handle"),
|
||||||
"corrects",
|
(["hides", "hiding", "hid"], "hide"),
|
||||||
"correcting",
|
(["increases", "increasing", "increased"], "increase"),
|
||||||
"corrected",
|
(["ignores", "ignoring", "ignored"], "ignore"),
|
||||||
"creates",
|
(["implements", "implementing", "implemented"], "implement"),
|
||||||
"creating",
|
(["improves", "improving", "improved"], "improve"),
|
||||||
"created",
|
(["keeps", "keeping", "kept"], "keep"),
|
||||||
"darkens",
|
(["kills", "killing", "killed"], "kill"),
|
||||||
"darkening",
|
(["makes", "making", "made"], "make"),
|
||||||
"darkened",
|
(["merges", "merging", "merged"], "merge"),
|
||||||
"disables",
|
(["moves", "moving", "moved"], "move"),
|
||||||
"disabling",
|
(["permits", "permitting", "permitted"], "permit"),
|
||||||
"disabled",
|
(["prevents", "preventing", "prevented"], "prevent"),
|
||||||
"displays",
|
(["pushes", "pushing", "pushed"], "push"),
|
||||||
"displaying",
|
(["rebases", "rebasing", "rebased"], "rebase"),
|
||||||
"displayed",
|
(["refactors", "refactoring", "refactored"], "refactor"),
|
||||||
"documents",
|
(["removes", "removing", "removed"], "remove"),
|
||||||
"documenting",
|
(["renames", "renaming", "renamed"], "rename"),
|
||||||
"documented",
|
(["reorders", "reordering", "reordered"], "reorder"),
|
||||||
"drys",
|
(["replaces", "replacing", "replaced"], "replace"),
|
||||||
"drying",
|
(["requires", "requiring", "required"], "require"),
|
||||||
"dryed",
|
(["restores", "restoring", "restored"], "restore"),
|
||||||
"ends",
|
(["sends", "sending", "sent"], "send"),
|
||||||
"ending",
|
(["sets", "setting"], "set"),
|
||||||
"ended",
|
(["separates", "separating", "separated"], "separate"),
|
||||||
"enforces",
|
(["shows", "showing", "showed"], "show"),
|
||||||
"enforcing",
|
(["simplifies", "simplifying", "simplified"], "simplify"),
|
||||||
"enforced",
|
(["skips", "skipping", "skipped"], "skip"),
|
||||||
"enqueues",
|
(["sorts", "sorting"], "sort"),
|
||||||
"enqueuing",
|
(["speeds", "speeding", "sped"], "speed"),
|
||||||
"enqueued",
|
(["starts", "starting", "started"], "start"),
|
||||||
"extracts",
|
(["supports", "supporting", "supported"], "support"),
|
||||||
"extracting",
|
(["takes", "taking", "took"], "take"),
|
||||||
"extracted",
|
(["testing", "tested"], "test"), # "tests" excluded to reduce false negatives
|
||||||
"finishes",
|
(["truncates", "truncating", "truncated"], "truncate"),
|
||||||
"finishing",
|
(["updates", "updating", "updated"], "update"),
|
||||||
"finished",
|
(["uses", "using", "used"], "use"),
|
||||||
"fixes",
|
|
||||||
"fixing",
|
|
||||||
"fixed",
|
|
||||||
"formats",
|
|
||||||
"formatting",
|
|
||||||
"formatted",
|
|
||||||
"guards",
|
|
||||||
"guarding",
|
|
||||||
"guarded",
|
|
||||||
"handles",
|
|
||||||
"handling",
|
|
||||||
"handled",
|
|
||||||
"hides",
|
|
||||||
"hiding",
|
|
||||||
"hid",
|
|
||||||
"increases",
|
|
||||||
"increasing",
|
|
||||||
"increased",
|
|
||||||
"ignores",
|
|
||||||
"ignoring",
|
|
||||||
"ignored",
|
|
||||||
"implements",
|
|
||||||
"implementing",
|
|
||||||
"implemented",
|
|
||||||
"improves",
|
|
||||||
"improving",
|
|
||||||
"improved",
|
|
||||||
"keeps",
|
|
||||||
"keeping",
|
|
||||||
"kept",
|
|
||||||
"kills",
|
|
||||||
"killing",
|
|
||||||
"killed",
|
|
||||||
"makes",
|
|
||||||
"making",
|
|
||||||
"made",
|
|
||||||
"merges",
|
|
||||||
"merging",
|
|
||||||
"merged",
|
|
||||||
"moves",
|
|
||||||
"moving",
|
|
||||||
"moved",
|
|
||||||
"permits",
|
|
||||||
"permitting",
|
|
||||||
"permitted",
|
|
||||||
"prevents",
|
|
||||||
"preventing",
|
|
||||||
"prevented",
|
|
||||||
"pushes",
|
|
||||||
"pushing",
|
|
||||||
"pushed",
|
|
||||||
"rebases",
|
|
||||||
"rebasing",
|
|
||||||
"rebased",
|
|
||||||
"refactors",
|
|
||||||
"refactoring",
|
|
||||||
"refactored",
|
|
||||||
"removes",
|
|
||||||
"removing",
|
|
||||||
"removed",
|
|
||||||
"renames",
|
|
||||||
"renaming",
|
|
||||||
"renamed",
|
|
||||||
"reorders",
|
|
||||||
"reordering",
|
|
||||||
"reordered",
|
|
||||||
"replaces",
|
|
||||||
"replacing",
|
|
||||||
"replaced",
|
|
||||||
"requires",
|
|
||||||
"requiring",
|
|
||||||
"required",
|
|
||||||
"restores",
|
|
||||||
"restoring",
|
|
||||||
"restored",
|
|
||||||
"sends",
|
|
||||||
"sending",
|
|
||||||
"sent",
|
|
||||||
"sets",
|
|
||||||
"setting",
|
|
||||||
"separates",
|
|
||||||
"separating",
|
|
||||||
"separated",
|
|
||||||
"shows",
|
|
||||||
"showing",
|
|
||||||
"showed",
|
|
||||||
"simplifies",
|
|
||||||
"simplifying",
|
|
||||||
"simplified",
|
|
||||||
"skips",
|
|
||||||
"skipping",
|
|
||||||
"skipped",
|
|
||||||
"sorts",
|
|
||||||
"sorting",
|
|
||||||
"speeds",
|
|
||||||
"speeding",
|
|
||||||
"sped",
|
|
||||||
"starts",
|
|
||||||
"starting",
|
|
||||||
"started",
|
|
||||||
"supports",
|
|
||||||
"supporting",
|
|
||||||
"supported",
|
|
||||||
"takes",
|
|
||||||
"taking",
|
|
||||||
"took",
|
|
||||||
"testing",
|
|
||||||
"tested", # 'tests' excluded to reduce false negative
|
|
||||||
"truncates",
|
|
||||||
"truncating",
|
|
||||||
"truncated",
|
|
||||||
"updates",
|
|
||||||
"updating",
|
|
||||||
"updated",
|
|
||||||
"uses",
|
|
||||||
"using",
|
|
||||||
"used",
|
|
||||||
}
|
|
||||||
|
|
||||||
imperative_forms = [
|
|
||||||
"add",
|
|
||||||
"allow",
|
|
||||||
"amend",
|
|
||||||
"bump",
|
|
||||||
"calculate",
|
|
||||||
"change",
|
|
||||||
"clean",
|
|
||||||
"commit",
|
|
||||||
"correct",
|
|
||||||
"create",
|
|
||||||
"darken",
|
|
||||||
"disable",
|
|
||||||
"display",
|
|
||||||
"document",
|
|
||||||
"dry",
|
|
||||||
"end",
|
|
||||||
"enforce",
|
|
||||||
"enqueue",
|
|
||||||
"extract",
|
|
||||||
"finish",
|
|
||||||
"fix",
|
|
||||||
"format",
|
|
||||||
"guard",
|
|
||||||
"handle",
|
|
||||||
"hide",
|
|
||||||
"ignore",
|
|
||||||
"implement",
|
|
||||||
"improve",
|
|
||||||
"increase",
|
|
||||||
"keep",
|
|
||||||
"kill",
|
|
||||||
"make",
|
|
||||||
"merge",
|
|
||||||
"move",
|
|
||||||
"permit",
|
|
||||||
"prevent",
|
|
||||||
"push",
|
|
||||||
"rebase",
|
|
||||||
"refactor",
|
|
||||||
"remove",
|
|
||||||
"rename",
|
|
||||||
"reorder",
|
|
||||||
"replace",
|
|
||||||
"require",
|
|
||||||
"restore",
|
|
||||||
"send",
|
|
||||||
"separate",
|
|
||||||
"set",
|
|
||||||
"show",
|
|
||||||
"simplify",
|
|
||||||
"skip",
|
|
||||||
"sort",
|
|
||||||
"speed",
|
|
||||||
"start",
|
|
||||||
"support",
|
|
||||||
"take",
|
|
||||||
"test",
|
|
||||||
"truncate",
|
|
||||||
"update",
|
|
||||||
"use",
|
|
||||||
]
|
]
|
||||||
imperative_forms.sort()
|
|
||||||
|
|
||||||
|
TENSE_CORRECTIONS = {word: imperative for words, imperative in TENSE_DATA for word in words}
|
||||||
def head_binary_search(key: str, words: List[str]) -> str:
|
|
||||||
"""Find the imperative mood version of `word` by looking at the first
|
|
||||||
3 characters."""
|
|
||||||
|
|
||||||
# Edge case: 'disable' and 'display' have the same 3 starting letters.
|
|
||||||
if key in ["displays", "displaying", "displayed"]:
|
|
||||||
return "display"
|
|
||||||
|
|
||||||
lower = 0
|
|
||||||
upper = len(words) - 1
|
|
||||||
|
|
||||||
while True:
|
|
||||||
if lower > upper:
|
|
||||||
# Should not happen
|
|
||||||
raise Exception(f"Cannot find imperative mood of {key}")
|
|
||||||
|
|
||||||
mid = (lower + upper) // 2
|
|
||||||
imperative_form = words[mid]
|
|
||||||
|
|
||||||
if key[:3] == imperative_form[:3]:
|
|
||||||
return imperative_form
|
|
||||||
elif key < imperative_form:
|
|
||||||
upper = mid - 1
|
|
||||||
elif key > imperative_form:
|
|
||||||
lower = mid + 1
|
|
||||||
|
|
||||||
|
|
||||||
class ImperativeMood(LineRule):
|
class ImperativeMood(LineRule):
|
||||||
|
@ -303,8 +97,8 @@ class ImperativeMood(LineRule):
|
||||||
words = line.split(": ", 1)[-1].split()
|
words = line.split(": ", 1)[-1].split()
|
||||||
first_word = words[0].lower()
|
first_word = words[0].lower()
|
||||||
|
|
||||||
if first_word in WORD_SET:
|
if first_word in TENSE_CORRECTIONS:
|
||||||
imperative = head_binary_search(first_word, imperative_forms)
|
imperative = TENSE_CORRECTIONS[first_word]
|
||||||
violation = RuleViolation(
|
violation = RuleViolation(
|
||||||
self.id,
|
self.id,
|
||||||
self.error_msg.format(
|
self.error_msg.format(
|
||||||
|
|
Loading…
Reference in a new issue