-
Notifications
You must be signed in to change notification settings - Fork 1
Suites
You can define and even propose new suites to be incorporated into mkcommit. We provide e.g. the semantic commits suite by default.
The most basic example creates a default short commit message which consists of {keywords}({scope}): {message}, e.g. feat: blah blah or fix(some scope): blah blah.
from mkcommit import CommitMessage, to_stdout
from mkcommit.suites import semantic
def commit():
return CommitMessage(semantic.default_short(), semantic.default_long())
if __name__ == "__main__":
to_stdout(commit())You can mix and match with the building blocks, for example a message with longer length allowed:
from mkcommit import CommitMessage, to_stdout, CommaSeparatedList, ask
from mkcommit.validators import max_len
from mkcommit.suites import semantic
def commit():
keywords = CommaSeparatedList(*semantic.ask_keywords())
short = ask("Short commit message: ", check=max_len(70))
return CommitMessage(
f"{keywords}: {short}"
)
if __name__ == "__main__":
to_stdout(commit())Conventional commits are the most widely used in the open-source community.
Conventional commits suite extends the definition of semantic suite and disallows having multiple descriptors in a commit message. For example feat(scope), fix: message is valid in semantic suite but not in conventional suite.
It also extends the definition of the possible keywords to choose from.
It is recommended as the first sensible default for new projects.
from mkcommit import CommitMessage, to_stdout
from mkcommit.suites import conventional
def commit():
return CommitMessage(*conventional.default())
if __name__ == "__main__":
to_stdout(commit())Note *conventional.default() notation unpacks the short and the long commit message portions into the CommitMessage wrapper.
At Technica Engineering we're using a modified semantic suite, where it will almost always be prepended by a Jira Ticket identifier and committer's initials. If your git config is set up properly your initials are automatically injected from git config. The typical config used at Technica looks like this:
from mkcommit import CommitMessage, to_stdout, Project
from mkcommit.suites import technica
def commit():
project = Project("Some project", "SOMEPROJ")
return CommitMessage(
technica.default_short(project, ticket_first=True),
technica.default_long()
)
def on_commit(msg: CommitMessage):
technica.is_technica(msg.first_line)
if __name__ == "__main__":
to_stdout(commit())The message looks typically like [SOMEPROJ-123/KrCz] feat: something. Since many teams invert the order of these two elements in the beginning we provide the ticket_first flag which is by default False. If you remove it from the example above, you'll end up with messages like: [KrCz/SOMEPROJ-123] feat: something.
The ticket number will be prefilled with SOMEPROJ- and the developer only needs to type in the integers of the Jira Ticket number for an associated project.
When you want to propose a new suite, open a GitHub issue. In general a suite should define two functions:
-
default_short- to generate a default short message with the guidelines fully compliant with the suite. -
default_long- to generage a default long message.
Intermediate functions should follow the pattern of cross-calling ask at some point. For example from our own semantic module:
ask_keywords = lambda: ask(
"Select one or more keywords applicable (use TAB): ",
one_or_more=semantic_commit_keywords
)
ask_scope = lambda: ask(
"(Optional) provide change scope: "
)
ask_short_commit_msg = lambda: ask(
"Provide the short commit msg, max 55 characters long: ",
check=max_len(55)
)