Skip to content

Commit

Permalink
AddNewlineAction: New action for GitCommitBear
Browse files Browse the repository at this point in the history
This adds a new action which adds a newline between
shortlog and body of commit message when applied.
This also make changes in CommitBear.py to pass
AddNewlineAction when Result is yielded.
  • Loading branch information
akshatkarani committed Sep 7, 2019
1 parent 6fee471 commit bc41a68
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 1 deletion.
4 changes: 3 additions & 1 deletion bears/vcs/CommitBear.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from coalib.settings.FunctionMetadata import FunctionMetadata
from dependency_management.requirements.PipRequirement import PipRequirement
from bears.vcs.actions.EditCommitMessageAction import EditCommitMessageAction
from bears.vcs.actions.AddNewlineAction import AddNewlineAction


class _CommitBear(GlobalBear):
Expand Down Expand Up @@ -280,7 +281,8 @@ def check_body(self, body,
yield Result(self,
'No newline found between shortlog and body at '
'HEAD commit. Please add one.',
actions=[EditCommitMessageAction()])
actions=[EditCommitMessageAction(),
AddNewlineAction()])
return

if body_regex and not re.fullmatch(body_regex, body.strip()):
Expand Down
35 changes: 35 additions & 0 deletions bears/vcs/actions/AddNewlineAction.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from coalib.misc.Shell import run_shell_command
from coalib.results.result_actions.ResultAction import ResultAction


class AddNewlineAction(ResultAction):
"""
Adds a newline between shortlog and body of the commit message
of the HEAD commit.
"""

SUCCESS_MESSAGE = 'New Line added successfully.'

def is_applicable(self,
result,
original_file_dict,
file_diff_dict,
applied_actions=()):
new_message, _ = run_shell_command('git log -1 --pretty=%B')
new_message = new_message.rstrip('\n')
pos = new_message.find('\n')
self.shortlog = new_message[:pos] if pos != -1 else new_message
self.body = new_message[pos+1:] if pos != -1 else ''
if self.body[0] != '\n':
return True
else:
return False

def apply(self, result, original_file_dict, file_diff_dict):
"""
Add New(L)ine [Note: This may rewrite your commit history]
"""
new_commit_message = '{}\n\n{}'.format(self.shortlog, self.body)
command = 'git commit -o --amend -m "{}"'.format(new_commit_message)
stdout, err = run_shell_command(command)
return file_diff_dict
Empty file added bears/vcs/actions/__init__.py
Empty file.
96 changes: 96 additions & 0 deletions tests/vcs/actions/AddNewlineActionTest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import unittest
import os
import platform
import shutil
from tempfile import mkdtemp, mkstemp
from unittest.mock import Mock

from coalib.results.Result import Result
from bears.vcs.actions.AddNewlineAction import AddNewlineAction
from coala_utils.ContextManagers import retrieve_stdout
from coalib.misc.Shell import run_shell_command


class AddNewlineActionTest(unittest.TestCase):

@staticmethod
def run_git_command(*args, stdin=None):
return run_shell_command(' '.join(('git',) + args), stdin)

def setUp(self):
self.shortlog = 'file.py: Add something'
self.body = ('Added something, wrote some things\n'
'Wrote tests\n'
'\n'
'Fixes #issue')
self.uut = AddNewlineAction()
self.result = Result('origin', 'message')

# Creating a temporary git repository and
# adding a commit to test
self._old_cwd = os.getcwd()
self.gitdir = mkdtemp()
os.chdir(self.gitdir)
self.gitfile = mkstemp(dir=self.gitdir)
self.run_git_command('init')
self.run_git_command('config', 'user.email coala@coala.io')
self.run_git_command('config', 'user.name coala')
self.msg = self.shortlog + '\n' + self.body
self.run_git_command('add .')
self.run_git_command('commit',
'--file=-',
stdin=self.msg)

def tearDown(self):
# Deleting the temporary repository
os.chdir(self._old_cwd)
if platform.system() == 'Windows':
onerror = self._windows_rmtree_remove_readonly
else:
onerror = None
shutil.rmtree(self.gitdir, onerror=onerror)

def test_is_applicable_apply(self):
# Applicable because there is no newline between shortlog and body
self.assertTrue(self.uut.is_applicable(self.result, {}, {}))

with retrieve_stdout() as stdout:
self.uut.apply(self.result, {}, {})
new_message, _ = run_shell_command('git log -1 --pretty=%B')
new_message = new_message.rstrip('\n')
self.assertEqual(new_message,
self.shortlog + '\n\n' + self.body)
self.assertEqual(stdout.getvalue(), '')

# Not applicable after action is applied
self.assertFalse(self.uut.is_applicable(self.result, {}, {}))

# Undoing the amend done by applying the action
self.run_git_command('commit',
'--amend',
'--file=-',
stdin=self.msg)

def test_is_applicable_edited_message(self):
# Applicable because there is no newline between shortlog and body
self.assertTrue(self.uut.is_applicable(self.result, {}, {}))

# Mocking EditCommitMessageAction to test cases where user first
# changes commit message by appying EditCommitMessageAction, then
# checking the applicability of AddNewlineAction
EditCommitMessageAction = Mock()
edited_msg1 = ('This is new commit message\n'
'Still no new line')
edited_msg2 = ('This is lastest commit message\n'
'\n'
'Finally a new line!!')

EditCommitMessageAction.apply.side_effect = self.run_git_command(
'commit', '--amend', '--file=-', stdin=edited_msg1)
EditCommitMessageAction.apply()
self.assertTrue(self.uut.is_applicable(self.result, {}, {}))

EditCommitMessageAction.apply.side_effect = self.run_git_command(
'commit', '--amend', '--file=-', stdin=edited_msg2)
EditCommitMessageAction.apply()
self.assertFalse(self.uut.is_applicable(self.result, {}, {}))
Empty file added tests/vcs/actions/__init__.py
Empty file.

0 comments on commit bc41a68

Please sign in to comment.