From ed5a523745ad2fd67a09829dbefd75ca03b9cd95 Mon Sep 17 00:00:00 2001 From: "Shakya, Milind" Date: Tue, 25 Dec 2018 23:08:28 -0500 Subject: [PATCH] Add update_commit_msg Update hooks file Update description Simplify approach Remove redundant statement Add test Add more tests Updates lints Use io.open instead Update setup.py Remove unused import Rename update-commit-msg to prepend-ticket-number-to-commit-msg --- .pre-commit-hooks.yaml | 6 ++ README.md | 1 + .../prepend_ticket_number_to_commit_msg.py | 63 +++++++++++++++++++ setup.py | 1 + ...repend_ticket_number_to_commit_msg_test.py | 53 ++++++++++++++++ 5 files changed, 124 insertions(+) create mode 100644 pre_commit_hooks/prepend_ticket_number_to_commit_msg.py create mode 100644 tests/prepend_ticket_number_to_commit_msg_test.py diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 5157783..0908473 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -183,3 +183,9 @@ entry: trailing-whitespace-fixer language: python types: [text] +- id: prepend-ticket-number-to-commit-msg + name: prepend-ticket-number-to-commit-msg + entry: prepend-ticket-number-to-commit-msg + language: python + stages: [commit-msg] + description: prepend-ticket-number-to-commit-msg - Use it to prepend your commits with info from your branch. See Readme for info. diff --git a/README.md b/README.md index 43b9887..c386881 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,7 @@ Add this to your `.pre-commit-config.yaml` use `args: [--markdown-linebreak-ext=md]` (or other extensions used by your markdownfiles). If for some reason you want to treat all files as markdown, use `--markdown-linebreak-ext=*`. +- `prepend-ticket-number-to-commit-msg` - Use it to prepend your commits with info from your branch, like ticket numbers. For e.g. if you name your branch `JIRA-1234_awesome_feature` and commit `Fix some bug`, the commit will be updated to `JIRA-1234 Fix some bug`. Pass `--regex=` or update `args: [--regex=]` in your .yaml file if you have custom ticket regex. By default its `[A-Z]+-\d+`. ### Deprecated / replaced hooks diff --git a/pre_commit_hooks/prepend_ticket_number_to_commit_msg.py b/pre_commit_hooks/prepend_ticket_number_to_commit_msg.py new file mode 100644 index 0000000..2274a13 --- /dev/null +++ b/pre_commit_hooks/prepend_ticket_number_to_commit_msg.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import absolute_import +from __future__ import unicode_literals + +import argparse +import io +import re +import subprocess +import sys + +import six + + +def update_commit_message(filename, regex): + with io.open(filename, 'r+') as fd: + contents = fd.readlines() + commit_msg = contents[0] + # Check if we can grab ticket info from branch name. + branch = get_branch_name() + if all([ + not re.search(regex, commit_msg), + re.search(regex, branch), + ]): + ticket = branch.split(six.text_type('_'))[0] + new_commit_msg = '{} {}'.format(ticket, commit_msg) + fd.seek(0) + fd.write( + six.text_type( + new_commit_msg, + ), + ) + fd.truncate() + + +def get_branch_name(): + # Only git support for right now. + return subprocess.check_output( + [ + 'git', + 'rev-parse', + '--abbrev-ref', + 'HEAD', + ], + ).decode('UTF-8') + + +def main(argv=None): + """This hook saves developers time by prepending ticket numbers to commit-msgs. + For this to work the following two conditions must be met: + - The ticket format regex specified must match. + - The branch name format must be _ + """ + parser = argparse.ArgumentParser() + parser.add_argument('filenames', nargs='+') + parser.add_argument('--regex') + args = parser.parse_args(argv) + regex = args.regex or '[A-Z]+-\d+' # noqa + update_commit_message(args.filenames[0], regex) + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/setup.py b/setup.py index 4bca2b0..5935878 100644 --- a/setup.py +++ b/setup.py @@ -59,6 +59,7 @@ setup( 'requirements-txt-fixer = pre_commit_hooks.requirements_txt_fixer:fix_requirements_txt', 'sort-simple-yaml = pre_commit_hooks.sort_simple_yaml:main', 'trailing-whitespace-fixer = pre_commit_hooks.trailing_whitespace_fixer:main', + 'prepend-ticket-number-to-commit-msg = pre_commit_hooks.prepend_ticket_number_to_commit_msg:main', ], }, ) diff --git a/tests/prepend_ticket_number_to_commit_msg_test.py b/tests/prepend_ticket_number_to_commit_msg_test.py new file mode 100644 index 0000000..58b6082 --- /dev/null +++ b/tests/prepend_ticket_number_to_commit_msg_test.py @@ -0,0 +1,53 @@ +from __future__ import absolute_import +from __future__ import unicode_literals + +import mock +import pytest +import six + +from pre_commit_hooks.prepend_ticket_number_to_commit_msg import get_branch_name +from pre_commit_hooks.prepend_ticket_number_to_commit_msg import main +from pre_commit_hooks.prepend_ticket_number_to_commit_msg import update_commit_message + + +TESTING_MODULE = 'pre_commit_hooks.prepend_ticket_number_to_commit_msg' + + +@pytest.mark.parametrize( + ('msg'), + ( + 'Test', + 'JIRA-1234_Test', + ), +) +@mock.patch(TESTING_MODULE + '.get_branch_name') +def test_update_commit_message(mock_branch_name, msg, tmpdir): + mock_branch_name.return_value = 'JIRA-1234_new_feature' + path = tmpdir.join('file.txt') + path.write(msg) + update_commit_message(six.text_type(path), '[A-Z]+-\d+') # noqa + assert 'JIRA-1234' in path.read() + + +@mock.patch(TESTING_MODULE + '.subprocess') +def test_get_branch_name(mock_subprocess): + get_branch_name() + mock_subprocess.check_output.assert_called_once_with( + [ + 'git', + 'rev-parse', + '--abbrev-ref', + 'HEAD', + ], + ) + + +@mock.patch(TESTING_MODULE + '.argparse') +@mock.patch(TESTING_MODULE + '.update_commit_message') +def test_main(mock_update_commit_message, mock_argparse): + mock_args = mock.Mock() + mock_args.filenames = ['foo.txt'] + mock_args.regex = None + mock_argparse.ArgumentParser.return_value.parse_args.return_value = mock_args + main() + mock_update_commit_message.assert_called_once_with('foo.txt', '[A-Z]+-\d+') # noqa