Skip to content

Commit

Permalink
Add handle of git scissors cleanup and custom comment char (#34)
Browse files Browse the repository at this point in the history
* Add handle of git cutline

Git commit command has `cleanup` argument (
https://git-scm.com/docs/git-commit#git-commit---cleanupltmodegt)
which can clean up commit messages after some cutline.

This cutline appears when you make commit with
git commit -v
(-v, --verbose add diff to commit message)

This commit add cutting of commit message after this cutline

* Add handle of custom commentchar

Git has oppurtunity to set custom comment char.
Add retriving this char from config and handle on message parsing

* Add non-commented text after cutline in sample

Suggested by @jorisroovers to properly test use-case for git scissors
line since commented lines are being ignored regardless.
  • Loading branch information
ron8mcr authored and jorisroovers committed Jul 14, 2017
1 parent 3489743 commit bc05276
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 3 deletions.
20 changes: 19 additions & 1 deletion gitlint/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,26 @@ def git_version():
return version


def git_commentchar():
""" Shortcut for retrieving comment char from git config
"""
try:
commentchar = ustr(sh.git.config('--get', 'core.commentchar')).replace(u"\n", u"")
except sh.ErrorReturnCode_1: # pylint: disable=no-member
# exception means that default commentchar used
commentchar = '#'
return commentchar


class GitCommitMessage(object):
""" Class representing a git commit message. A commit message consists of the following:
- original: The actual commit message as returned by `git log`
- full: original, but stripped of any comments
- title: the first line of full
- body: all lines following the title
"""
COMMENT_CHAR = git_commentchar()
CUTLINE = '{0} ------------------------ >8 ------------------------'.format(COMMENT_CHAR)

def __init__(self, original=None, full=None, title=None, body=None):
self.original = original
Expand All @@ -48,7 +61,12 @@ def __init__(self, original=None, full=None, title=None, body=None):
@staticmethod
def from_full_message(commit_msg_str):
""" Parses a full git commit message by parsing a given string into the different parts of a commit message """
lines = [line for line in commit_msg_str.splitlines() if not line.startswith("#")]
all_lines = commit_msg_str.splitlines()
try:
cutline_index = all_lines.index(GitCommitMessage.CUTLINE)
except ValueError:
cutline_index = None
lines = [line for line in all_lines[:cutline_index] if not line.startswith(GitCommitMessage.COMMENT_CHAR)]
full = "\n".join(lines)
title = lines[0] if len(lines) > 0 else ""
body = lines[1:] if len(lines) > 1 else []
Expand Down
8 changes: 8 additions & 0 deletions gitlint/tests/samples/commit_message/sample1
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,11 @@ This is the first line of the commit message body and it is meant to test a line
This line has a tråiling space.
This line has a trailing tab.
# This is a cömmented line
# ------------------------ >8 ------------------------
# Anything after this line should be cleaned up
# this line appears on `git commit -v` command
diff --git a/gitlint/tests/samples/commit_message/sample1 b/gitlint/tests/samples/commit_message/sample1
index 82dbe7f..ae71a14 100644
--- a/gitlint/tests/samples/commit_message/sample1
+++ b/gitlint/tests/samples/commit_message/sample1
@@ -1 +1 @@
29 changes: 27 additions & 2 deletions gitlint/tests/test_git.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import datetime
import dateutil
from mock import patch, call
from mock import patch, call, PropertyMock
from sh import ErrorReturnCode, CommandNotFound

from gitlint.tests.base import BaseTestCase
Expand Down Expand Up @@ -126,7 +126,18 @@ def test_from_commit_msg_full(self):
u"This line has a tråiling space. ",
"This line has a trailing tab.\t"]
expected_full = expected_title + "\n" + "\n".join(expected_body)
expected_original = expected_full + u"\n# This is a cömmented line\n"
expected_original = expected_full + (
u"\n# This is a cömmented line\n"
u"# ------------------------ >8 ------------------------\n"
u"# Anything after this line should be cleaned up\n"
u"# this line appears on `git commit -v` command\n"
u"diff --git a/gitlint/tests/samples/commit_message/sample1 "
u"b/gitlint/tests/samples/commit_message/sample1\n"
u"index 82dbe7f..ae71a14 100644\n"
u"--- a/gitlint/tests/samples/commit_message/sample1\n"
u"+++ b/gitlint/tests/samples/commit_message/sample1\n"
u"@@ -1 +1 @@\n"
)

commit = gitcontext.commits[-1]
self.assertEqual(commit.message.title, expected_title)
Expand Down Expand Up @@ -226,3 +237,17 @@ def test_gitcommit_equality(self):
self.assertNotEqual(commit1, commit2)
setattr(commit1, attr, prev_val)
self.assertEqual(commit1, commit2)

@patch('gitlint.git.sh')
def test_custom_commitchar(self, sh):
sh.git.config.return_value = ';'
from gitlint.git import GitCommitMessage # pylint: disable=redefined-outer-name,reimported

with patch.object(GitCommitMessage, 'COMMENT_CHAR', new_callable=PropertyMock) as commit_char_mock:
commit_char_mock.return_value = ';'
message = GitCommitMessage.from_full_message(u"Tïtle\n\nBödy 1\n;Cömment\nBody 2")

self.assertEqual(message.title, u"Tïtle")
self.assertEqual(message.body, ["", u"Bödy 1", "Body 2"])
self.assertEqual(message.full, u"Tïtle\n\nBödy 1\nBody 2")
self.assertEqual(message.original, u"Tïtle\n\nBödy 1\n;Cömment\nBody 2")

0 comments on commit bc05276

Please sign in to comment.