|
| 1 | +From 1ebb34f4b8f3f030997fe0c619c798bcece2bfba Mon Sep 17 00:00:00 2001 |
| 2 | +From: akshatkarani < [email protected]> |
| 3 | +Date: Sat, 29 Jun 2019 15:58:08 +0530 |
| 4 | +Subject: [PATCH] AddNewlineAction: New action for GitCommitBear |
| 5 | + |
| 6 | +This adds a new action which adds a newline between |
| 7 | +shortlog and body of commit message when applied. |
| 8 | +This also make changes in CommitBear.py to pass |
| 9 | +AddNewlineAction when Result is yielded. |
| 10 | +--- |
| 11 | + bears/vcs/CommitBear.py | 4 +- |
| 12 | + bears/vcs/actions/AddNewlineAction.py | 35 +++++++++ |
| 13 | + bears/vcs/actions/__init__.py | 0 |
| 14 | + tests/vcs/actions/AddNewlineActionTest.py | 96 +++++++++++++++++++++++ |
| 15 | + tests/vcs/actions/__init__.py | 0 |
| 16 | + 5 files changed, 134 insertions(+), 1 deletion(-) |
| 17 | + create mode 100644 bears/vcs/actions/AddNewlineAction.py |
| 18 | + create mode 100644 bears/vcs/actions/__init__.py |
| 19 | + create mode 100644 tests/vcs/actions/AddNewlineActionTest.py |
| 20 | + create mode 100644 tests/vcs/actions/__init__.py |
| 21 | + |
| 22 | +diff --git a/bears/vcs/CommitBear.py b/bears/vcs/CommitBear.py |
| 23 | +index 295dace21..69d1062ad 100644 |
| 24 | +--- a/bears/vcs/CommitBear.py |
| 25 | ++++ b/bears/vcs/CommitBear.py |
| 26 | +@@ -14,6 +14,7 @@ |
| 27 | + from coalib.settings.FunctionMetadata import FunctionMetadata |
| 28 | + from dependency_management.requirements.PipRequirement import PipRequirement |
| 29 | + from bears.vcs.actions.EditCommitMessageAction import EditCommitMessageAction |
| 30 | ++from bears.vcs.actions.AddNewlineAction import AddNewlineAction |
| 31 | + |
| 32 | + |
| 33 | + class _CommitBear(GlobalBear): |
| 34 | +@@ -280,7 +281,8 @@ def check_body(self, body, |
| 35 | + yield Result(self, |
| 36 | + 'No newline found between shortlog and body at ' |
| 37 | + 'HEAD commit. Please add one.', |
| 38 | +- actions=[EditCommitMessageAction()]) |
| 39 | ++ actions=[EditCommitMessageAction(), |
| 40 | ++ AddNewlineAction()]) |
| 41 | + return |
| 42 | + |
| 43 | + if body_regex and not re.fullmatch(body_regex, body.strip()): |
| 44 | +diff --git a/bears/vcs/actions/AddNewlineAction.py b/bears/vcs/actions/AddNewlineAction.py |
| 45 | +new file mode 100644 |
| 46 | +index 000000000..a8d39b775 |
| 47 | +--- /dev/null |
| 48 | ++++ b/bears/vcs/actions/AddNewlineAction.py |
| 49 | +@@ -0,0 +1,35 @@ |
| 50 | ++from coalib.misc.Shell import run_shell_command |
| 51 | ++from coalib.results.result_actions.ResultAction import ResultAction |
| 52 | ++ |
| 53 | ++ |
| 54 | ++class AddNewlineAction(ResultAction): |
| 55 | ++ """ |
| 56 | ++ Adds a newline between shortlog and body of the commit message |
| 57 | ++ of the HEAD commit. |
| 58 | ++ """ |
| 59 | ++ |
| 60 | ++ SUCCESS_MESSAGE = 'New Line added successfully.' |
| 61 | ++ |
| 62 | ++ def is_applicable(self, |
| 63 | ++ result, |
| 64 | ++ original_file_dict, |
| 65 | ++ file_diff_dict, |
| 66 | ++ applied_actions=()): |
| 67 | ++ new_message, _ = run_shell_command('git log -1 --pretty=%B') |
| 68 | ++ new_message = new_message.rstrip('\n') |
| 69 | ++ pos = new_message.find('\n') |
| 70 | ++ self.shortlog = new_message[:pos] if pos != -1 else new_message |
| 71 | ++ self.body = new_message[pos+1:] if pos != -1 else '' |
| 72 | ++ if self.body[0] != '\n': |
| 73 | ++ return True |
| 74 | ++ else: |
| 75 | ++ return False |
| 76 | ++ |
| 77 | ++ def apply(self, result, original_file_dict, file_diff_dict): |
| 78 | ++ """ |
| 79 | ++ Add New(L)ine [Note: This may rewrite your commit history] |
| 80 | ++ """ |
| 81 | ++ new_commit_message = '{}\n\n{}'.format(self.shortlog, self.body) |
| 82 | ++ command = 'git commit -o --amend -m "{}"'.format(new_commit_message) |
| 83 | ++ stdout, err = run_shell_command(command) |
| 84 | ++ return file_diff_dict |
| 85 | +diff --git a/bears/vcs/actions/__init__.py b/bears/vcs/actions/__init__.py |
| 86 | +new file mode 100644 |
| 87 | +index 000000000..e69de29bb |
| 88 | +diff --git a/tests/vcs/actions/AddNewlineActionTest.py b/tests/vcs/actions/AddNewlineActionTest.py |
| 89 | +new file mode 100644 |
| 90 | +index 000000000..466296c19 |
| 91 | +--- /dev/null |
| 92 | ++++ b/tests/vcs/actions/AddNewlineActionTest.py |
| 93 | +@@ -0,0 +1,96 @@ |
| 94 | ++import unittest |
| 95 | ++import os |
| 96 | ++import platform |
| 97 | ++import shutil |
| 98 | ++from tempfile import mkdtemp, mkstemp |
| 99 | ++from unittest.mock import Mock |
| 100 | ++ |
| 101 | ++from coalib.results.Result import Result |
| 102 | ++from bears.vcs.actions.AddNewlineAction import AddNewlineAction |
| 103 | ++from coala_utils.ContextManagers import retrieve_stdout |
| 104 | ++from coalib.misc.Shell import run_shell_command |
| 105 | ++ |
| 106 | ++ |
| 107 | ++class AddNewlineActionTest(unittest.TestCase): |
| 108 | ++ |
| 109 | ++ @staticmethod |
| 110 | ++ def run_git_command(*args, stdin=None): |
| 111 | ++ return run_shell_command(' '.join(('git',) + args), stdin) |
| 112 | ++ |
| 113 | ++ def setUp(self): |
| 114 | ++ self.shortlog = 'file.py: Add something' |
| 115 | ++ self.body = ('Added something, wrote some things\n' |
| 116 | ++ 'Wrote tests\n' |
| 117 | ++ '\n' |
| 118 | ++ 'Fixes #issue') |
| 119 | ++ self.uut = AddNewlineAction() |
| 120 | ++ self.result = Result('origin', 'message') |
| 121 | ++ |
| 122 | ++ # Creating a temporary git repository and |
| 123 | ++ # adding a commit to test |
| 124 | ++ self._old_cwd = os.getcwd() |
| 125 | ++ self.gitdir = mkdtemp() |
| 126 | ++ os.chdir(self.gitdir) |
| 127 | ++ self.gitfile = mkstemp(dir=self.gitdir) |
| 128 | ++ self.run_git_command('init') |
| 129 | ++ self.run_git_command('config', 'user.email [email protected]') |
| 130 | ++ self.run_git_command('config', 'user.name coala') |
| 131 | ++ self.msg = self.shortlog + '\n' + self.body |
| 132 | ++ self.run_git_command('add .') |
| 133 | ++ self.run_git_command('commit', |
| 134 | ++ '--file=-', |
| 135 | ++ stdin=self.msg) |
| 136 | ++ |
| 137 | ++ def tearDown(self): |
| 138 | ++ # Deleting the temporary repository |
| 139 | ++ os.chdir(self._old_cwd) |
| 140 | ++ if platform.system() == 'Windows': |
| 141 | ++ onerror = self._windows_rmtree_remove_readonly |
| 142 | ++ else: |
| 143 | ++ onerror = None |
| 144 | ++ shutil.rmtree(self.gitdir, onerror=onerror) |
| 145 | ++ |
| 146 | ++ def test_is_applicable_apply(self): |
| 147 | ++ # Applicable because there is no newline between shortlog and body |
| 148 | ++ self.assertTrue(self.uut.is_applicable(self.result, {}, {})) |
| 149 | ++ |
| 150 | ++ with retrieve_stdout() as stdout: |
| 151 | ++ self.uut.apply(self.result, {}, {}) |
| 152 | ++ new_message, _ = run_shell_command('git log -1 --pretty=%B') |
| 153 | ++ new_message = new_message.rstrip('\n') |
| 154 | ++ self.assertEqual(new_message, |
| 155 | ++ self.shortlog + '\n\n' + self.body) |
| 156 | ++ self.assertEqual(stdout.getvalue(), '') |
| 157 | ++ |
| 158 | ++ # Not applicable after action is applied |
| 159 | ++ self.assertFalse(self.uut.is_applicable(self.result, {}, {})) |
| 160 | ++ |
| 161 | ++ # Undoing the amend done by applying the action |
| 162 | ++ self.run_git_command('commit', |
| 163 | ++ '--amend', |
| 164 | ++ '--file=-', |
| 165 | ++ stdin=self.msg) |
| 166 | ++ |
| 167 | ++ def test_is_applicable_edited_message(self): |
| 168 | ++ # Applicable because there is no newline between shortlog and body |
| 169 | ++ self.assertTrue(self.uut.is_applicable(self.result, {}, {})) |
| 170 | ++ |
| 171 | ++ # Mocking EditCommitMessageAction to test cases where user first |
| 172 | ++ # changes commit message by appying EditCommitMessageAction, then |
| 173 | ++ # checking the applicability of AddNewlineAction |
| 174 | ++ EditCommitMessageAction = Mock() |
| 175 | ++ edited_msg1 = ('This is new commit message\n' |
| 176 | ++ 'Still no new line') |
| 177 | ++ edited_msg2 = ('This is lastest commit message\n' |
| 178 | ++ '\n' |
| 179 | ++ 'Finally a new line!!') |
| 180 | ++ |
| 181 | ++ EditCommitMessageAction.apply.side_effect = self.run_git_command( |
| 182 | ++ 'commit', '--amend', '--file=-', stdin=edited_msg1) |
| 183 | ++ EditCommitMessageAction.apply() |
| 184 | ++ self.assertTrue(self.uut.is_applicable(self.result, {}, {})) |
| 185 | ++ |
| 186 | ++ EditCommitMessageAction.apply.side_effect = self.run_git_command( |
| 187 | ++ 'commit', '--amend', '--file=-', stdin=edited_msg2) |
| 188 | ++ EditCommitMessageAction.apply() |
| 189 | ++ self.assertFalse(self.uut.is_applicable(self.result, {}, {})) |
| 190 | +diff --git a/tests/vcs/actions/__init__.py b/tests/vcs/actions/__init__.py |
| 191 | +new file mode 100644 |
| 192 | +index 000000000..e69de29bb |
0 commit comments