From f91b7365b445939f3b76ed13672157a3d594a874 Mon Sep 17 00:00:00 2001 From: Milind Shakya Date: Thu, 14 May 2026 15:34:56 -0400 Subject: [PATCH 1/5] Add an option to be passed, the can capitalize the first character of the commit message --- giticket/giticket.py | 13 ++++++++++-- tests/test_giticket.py | 47 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/giticket/giticket.py b/giticket/giticket.py index 076154e..1412d03 100644 --- a/giticket/giticket.py +++ b/giticket/giticket.py @@ -14,7 +14,11 @@ regex_match_mode = 'regex_match' conventionalcommit_regex = r'^(?Pbuild|chore|ci|docs|feat|fix|perf|refactor|style|test)(\((?P.+)\))?: (?P.+)' -def update_commit_message(filename, regex, mode, format_string, conventionalcommits=False): +def capitalize_first(text): + return text[:1].upper() + text[1:] if text else text + + +def update_commit_message(filename, regex, mode, format_string, conventionalcommits=False, capitalize=False): with io.open(filename, 'r+') as fd: contents = fd.readlines() commit_msg = contents[0].rstrip('\r\n') @@ -40,11 +44,15 @@ def update_commit_message(filename, regex, mode, format_string, conventionalcomm else: scope = ', '.join(tickets) subject = match.group('subject') + if capitalize: + subject = capitalize_first(subject) format_string = '{type}({scope}): {subject}' new_commit_msg = format_string.format( type=type, scope=scope, subject=subject ) else: + if capitalize: + commit_msg = capitalize_first(commit_msg) new_commit_msg = format_string.format( ticket=tickets[0], tickets=', '.join(tickets), commit_msg=commit_msg @@ -78,6 +86,7 @@ def main(argv=None): parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='+') parser.add_argument('--conventionalcommits', action='store_true') + parser.add_argument('--capitalize', action='store_true') parser.add_argument('--regex') parser.add_argument('--format', nargs='?') parser.add_argument('--mode', nargs='?', const=underscore_split_mode, @@ -89,7 +98,7 @@ def main(argv=None): return 1 regex = args.regex or r'[A-Z]+-\d+' # noqa format_string = args.format or '{ticket} {commit_msg}' # noqa - update_commit_message(args.filenames[0], regex, args.mode, format_string, args.conventionalcommits) + update_commit_message(args.filenames[0], regex, args.mode, format_string, args.conventionalcommits, args.capitalize) if __name__ == '__main__': diff --git a/tests/test_giticket.py b/tests/test_giticket.py index 31ff0ab..60765a8 100644 --- a/tests/test_giticket.py +++ b/tests/test_giticket.py @@ -135,6 +135,49 @@ def test_update_commit_message_conventionalcommits(mock_branch_name, tmpdir): 'regex_match', '{commit_msg}', conventionalcommits=True) assert path.read() == "feat(JIRA-5678): add new feature\n" +@mock.patch(TESTING_MODULE + '.get_branch_name') +def test_update_commit_message_capitalize(mock_branch_name, tmpdir): + mock_branch_name.return_value = "JIRA-1234_new_feature" + path = tmpdir.join('file.txt') + path.write("test commit message") + update_commit_message(six.text_type(path), r'[A-Z]+-\d+', + 'regex_match', '{ticket}: {commit_msg}', + capitalize=True) + assert path.read() == "JIRA-1234: Test commit message\n" + + +@mock.patch(TESTING_MODULE + '.get_branch_name') +def test_update_commit_message_capitalize_already_uppercase(mock_branch_name, tmpdir): + mock_branch_name.return_value = "JIRA-1234_new_feature" + path = tmpdir.join('file.txt') + path.write("Test commit message") + update_commit_message(six.text_type(path), r'[A-Z]+-\d+', + 'regex_match', '{ticket}: {commit_msg}', + capitalize=True) + assert path.read() == "JIRA-1234: Test commit message\n" + + +@mock.patch(TESTING_MODULE + '.get_branch_name') +def test_update_commit_message_capitalize_conventionalcommits(mock_branch_name, tmpdir): + mock_branch_name.return_value = "JIRA-5678_new_feature" + path = tmpdir.join('file.txt') + path.write("feat: add new feature") + update_commit_message(six.text_type(path), r'[A-Z]+-\d+', + 'regex_match', '{commit_msg}', + conventionalcommits=True, capitalize=True) + assert path.read() == "feat(JIRA-5678): Add new feature\n" + + +@mock.patch(TESTING_MODULE + '.get_branch_name') +def test_update_commit_message_capitalize_disabled_by_default(mock_branch_name, tmpdir): + mock_branch_name.return_value = "JIRA-1234_new_feature" + path = tmpdir.join('file.txt') + path.write("test commit message") + update_commit_message(six.text_type(path), r'[A-Z]+-\d+', + 'regex_match', '{ticket}: {commit_msg}') + assert path.read() == "JIRA-1234: test commit message\n" + + @pytest.mark.parametrize('msg', ( """A descriptive header @@ -189,9 +232,11 @@ def test_main(mock_update_commit_message, mock_argparse): mock_args.format = None mock_args.mode = 'underscore_split' mock_args.conventionalcommits = True + mock_args.capitalize = False mock_argparse.ArgumentParser.return_value.parse_args.return_value = mock_args main() mock_update_commit_message.assert_called_once_with('foo.txt', r'[A-Z]+-\d+', 'underscore_split', '{ticket} {commit_msg}', - True) + True, + False) From 7d3e37ed4f5feaa5f8021cc8dd850dbc9810b726 Mon Sep 17 00:00:00 2001 From: Milind Shakya Date: Thu, 14 May 2026 15:47:56 -0400 Subject: [PATCH 2/5] Add github workflow --- .github/workflows/ci.yml | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..1f16355 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,39 @@ +name: CI + +on: + push: + branches: [master] + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ['3.9', '3.10', '3.11', '3.12'] + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pytest mock six + pip install -e . + - name: Run tests + run: pytest tests/ -v + + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + - name: Install flake8 + run: pip install flake8 + - name: Run flake8 + run: flake8 giticket From 747fdd175eda456c5563130fc7f2c0eb262bae49 Mon Sep 17 00:00:00 2001 From: Milind Shakya Date: Thu, 14 May 2026 15:50:07 -0400 Subject: [PATCH 3/5] Add pre-commit --- giticket/giticket.py | 1 + requirements_dev.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/giticket/giticket.py b/giticket/giticket.py index 1412d03..6aaf4d1 100644 --- a/giticket/giticket.py +++ b/giticket/giticket.py @@ -14,6 +14,7 @@ regex_match_mode = 'regex_match' conventionalcommit_regex = r'^(?Pbuild|chore|ci|docs|feat|fix|perf|refactor|style|test)(\((?P.+)\))?: (?P.+)' + def capitalize_first(text): return text[:1].upper() + text[1:] if text else text diff --git a/requirements_dev.txt b/requirements_dev.txt index e982e59..5bfdeb2 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -9,6 +9,7 @@ Sphinx==1.8.1 twine==1.12.1 six mock +pre-commit pytest==3.8.2 pytest-runner==4.2 From 0b336ff43a8fce7ea174e83a81c14f5508bf0e41 Mon Sep 17 00:00:00 2001 From: Milind Shakya Date: Thu, 14 May 2026 15:52:46 -0400 Subject: [PATCH 4/5] Add testcase --- tests/test_giticket.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_giticket.py b/tests/test_giticket.py index 60765a8..3dd49b7 100644 --- a/tests/test_giticket.py +++ b/tests/test_giticket.py @@ -33,6 +33,7 @@ def test_update_commit_message_no_modification(mock_branch_name, msg, tmpdir): @pytest.mark.parametrize('test_data', ( ('JIRA-1234', 'JIRA-1234'), ('JIRA-1234_bar', 'JIRA-1234'), + ('jira-1234', 'Jira-1234'), ('foo-JIRA-1234_bar', 'foo-JIRA-1234'), ('foo/JIRA-1234-bar', 'foo/JIRA-1234-bar'), ('foo_JIRA-1234_bar', 'foo'), @@ -124,6 +125,7 @@ def test_ci_message_with_nl_regex_match_mode(mock_branch_name, msg, tmpdir): 'regex_match', '{commit_msg} - {ticket}') assert path.read().split('\n')[0] == "{first_line} - {ticket}".format(first_line=first_line, ticket="JIRA-239") + # create a unit test to verify that if the --conventionalcommits flag is set, # the commit message is updated according to the conventional commit format @mock.patch(TESTING_MODULE + '.get_branch_name') @@ -135,6 +137,7 @@ def test_update_commit_message_conventionalcommits(mock_branch_name, tmpdir): 'regex_match', '{commit_msg}', conventionalcommits=True) assert path.read() == "feat(JIRA-5678): add new feature\n" + @mock.patch(TESTING_MODULE + '.get_branch_name') def test_update_commit_message_capitalize(mock_branch_name, tmpdir): mock_branch_name.return_value = "JIRA-1234_new_feature" From 711e63e71144736004f86c51f58ce9a697e7dd39 Mon Sep 17 00:00:00 2001 From: Milind Shakya Date: Thu, 14 May 2026 16:18:07 -0400 Subject: [PATCH 5/5] Updates --- giticket/giticket.py | 4 ++-- requirements_dev.txt | 5 ++--- tests/test_giticket.py | 9 ++++----- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/giticket/giticket.py b/giticket/giticket.py index 6aaf4d1..0b82437 100644 --- a/giticket/giticket.py +++ b/giticket/giticket.py @@ -52,12 +52,12 @@ def update_commit_message(filename, regex, mode, format_string, conventionalcomm type=type, scope=scope, subject=subject ) else: - if capitalize: - commit_msg = capitalize_first(commit_msg) new_commit_msg = format_string.format( ticket=tickets[0], tickets=', '.join(tickets), commit_msg=commit_msg ) + if capitalize: + new_commit_msg = capitalize_first(new_commit_msg) contents[0] = six.text_type(new_commit_msg + "\n") fd.seek(0) diff --git a/requirements_dev.txt b/requirements_dev.txt index 5bfdeb2..6c2cec6 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -3,7 +3,6 @@ bumpversion==0.5.3 wheel==0.32.1 watchdog==0.9.0 flake8==3.5.0 -tox==3.5.2 coverage==4.5.1 Sphinx==1.8.1 twine==1.12.1 @@ -11,5 +10,5 @@ six mock pre-commit -pytest==3.8.2 -pytest-runner==4.2 +pytest +pytest-runner diff --git a/tests/test_giticket.py b/tests/test_giticket.py index 3dd49b7..dc8dc87 100644 --- a/tests/test_giticket.py +++ b/tests/test_giticket.py @@ -33,7 +33,6 @@ def test_update_commit_message_no_modification(mock_branch_name, msg, tmpdir): @pytest.mark.parametrize('test_data', ( ('JIRA-1234', 'JIRA-1234'), ('JIRA-1234_bar', 'JIRA-1234'), - ('jira-1234', 'Jira-1234'), ('foo-JIRA-1234_bar', 'foo-JIRA-1234'), ('foo/JIRA-1234-bar', 'foo/JIRA-1234-bar'), ('foo_JIRA-1234_bar', 'foo'), @@ -140,13 +139,13 @@ def test_update_commit_message_conventionalcommits(mock_branch_name, tmpdir): @mock.patch(TESTING_MODULE + '.get_branch_name') def test_update_commit_message_capitalize(mock_branch_name, tmpdir): - mock_branch_name.return_value = "JIRA-1234_new_feature" + mock_branch_name.return_value = "jira-1234_new_feature" path = tmpdir.join('file.txt') - path.write("test commit message") - update_commit_message(six.text_type(path), r'[A-Z]+-\d+', + path.write("Test commit message") + update_commit_message(six.text_type(path), r'[a-zA-Z]+-\d+', 'regex_match', '{ticket}: {commit_msg}', capitalize=True) - assert path.read() == "JIRA-1234: Test commit message\n" + assert path.read() == "Jira-1234: Test commit message\n" @mock.patch(TESTING_MODULE + '.get_branch_name')