2020-04-19 22:36:58 +02:00
|
|
|
from gitlint.git import GitCommit
|
2020-06-11 00:54:34 +02:00
|
|
|
from gitlint.rules import CommitMessageTitle, LineRule, RuleViolation
|
2017-04-04 19:27:12 +02:00
|
|
|
|
|
|
|
# Word list from https://github.com/m1foley/fit-commit
|
|
|
|
# Copyright (c) 2015 Mike Foley
|
|
|
|
# License: MIT
|
|
|
|
# Ref: fit_commit/validators/tense.rb
|
2021-03-22 22:45:08 +01:00
|
|
|
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"),
|
2022-02-08 00:13:33 +01:00
|
|
|
(["drys", "drying", "dried"], "dry"),
|
2021-03-22 22:45:08 +01:00
|
|
|
(["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"),
|
2020-09-02 02:50:08 +02:00
|
|
|
]
|
2017-04-04 19:27:12 +02:00
|
|
|
|
2021-03-22 22:45:08 +01:00
|
|
|
TENSE_CORRECTIONS = {word: imperative for words, imperative in TENSE_DATA for word in words}
|
2017-04-04 19:27:12 +02:00
|
|
|
|
|
|
|
|
|
|
|
class ImperativeMood(LineRule):
|
2021-02-12 08:19:30 +01:00
|
|
|
"""This rule will enforce that the commit message title uses imperative
|
2017-05-05 21:14:51 +02:00
|
|
|
mood. This is done by checking if the first word is in `WORD_SET`, if so
|
2021-02-12 08:19:30 +01:00
|
|
|
show the word in the correct mood."""
|
2017-04-04 19:27:12 +02:00
|
|
|
|
|
|
|
name = "title-imperative-mood"
|
|
|
|
id = "Z1"
|
|
|
|
target = CommitMessageTitle
|
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
error_msg = (
|
2021-02-12 08:20:45 +01:00
|
|
|
"The first word in commit title should be in imperative mood "
|
2021-02-12 08:19:30 +01:00
|
|
|
'("{word}" -> "{imperative}"): "{title}"'
|
|
|
|
)
|
2017-04-04 19:27:12 +02:00
|
|
|
|
2024-07-12 02:30:17 +02:00
|
|
|
def validate(self, line: str, commit: GitCommit) -> list[RuleViolation]:
|
2017-04-04 19:27:12 +02:00
|
|
|
violations = []
|
2017-05-05 21:14:51 +02:00
|
|
|
|
|
|
|
# Ignore the section tag (ie `<section tag>: <message body>.`)
|
2021-02-12 08:20:45 +01:00
|
|
|
words = line.split(": ", 1)[-1].split()
|
2017-05-05 21:14:51 +02:00
|
|
|
first_word = words[0].lower()
|
|
|
|
|
2021-03-22 22:45:08 +01:00
|
|
|
if first_word in TENSE_CORRECTIONS:
|
|
|
|
imperative = TENSE_CORRECTIONS[first_word]
|
2021-02-12 08:19:30 +01:00
|
|
|
violation = RuleViolation(
|
|
|
|
self.id,
|
|
|
|
self.error_msg.format(
|
2021-02-23 23:26:07 +01:00
|
|
|
word=first_word,
|
|
|
|
imperative=imperative,
|
|
|
|
title=commit.message.title,
|
2021-02-12 08:19:30 +01:00
|
|
|
),
|
|
|
|
)
|
2017-05-05 21:14:51 +02:00
|
|
|
|
|
|
|
violations.append(violation)
|
2017-04-04 19:27:12 +02:00
|
|
|
|
|
|
|
return violations
|