From 1be470a84ca3094c1ed5599a60681cd8b1db32c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Koh=C3=A1nyi=20R=C3=B3bert?= Date: Sat, 22 Feb 2025 21:56:57 +0100 Subject: [PATCH 1/2] feat: allow emojis (gitmoji) in messages --- commit_check/__init__.py | 2 +- tests/commit_test.py | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/commit_check/__init__.py b/commit_check/__init__.py index 61de524f..b750cf1c 100644 --- a/commit_check/__init__.py +++ b/commit_check/__init__.py @@ -16,7 +16,7 @@ 'checks': [ { 'check': 'message', - 'regex': r'^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test){1}(\([\w\-\.]+\))?(!)?: ([\w ])+([\s\S]*)|(Merge).*|(fixup!.*)', + 'regex': r'^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test){1}(\([\w\-\.]+\))?(!)?: ([\U0001F600-\U0001F64F\U0001F300-\U0001F5FF\U0001F680-\U0001F6FF\U0001F700-\U0001F77F\U0001F780-\U0001F7FF\U0001F800-\U0001F8FF\U0001F900-\U0001F9FF\U0001FA00-\U0001FA6F\U0001FA70-\U0001FAFF\u2600-\u26FF\u2700-\u27BF] )?([\w ])+([\s\S]*)|(Merge).*|(fixup!.*)', 'error': 'The commit message should be structured as follows:\n\n' '[optional scope]: \n' '[optional body]\n' diff --git a/tests/commit_test.py b/tests/commit_test.py index a4586366..8a64a5ef 100644 --- a/tests/commit_test.py +++ b/tests/commit_test.py @@ -1,4 +1,4 @@ -from commit_check import PASS, FAIL +from commit_check import PASS, FAIL, DEFAULT_CONFIG from commit_check.commit import check_commit_msg, get_default_commit_msg_file, read_commit_msg, check_commit_signoff # used by get_commit_info mock @@ -48,6 +48,24 @@ def test_check_commit_msg_no_commit_msg_file(mocker): mock_read_commit_msg.assert_called_once_with(".git/COMMIT_EDITMSG") assert result == 0 +def test_check_commit_msg_with_emoji_commit_msg_file_using_defaults(mocker): + mock_get_default_commit_msg_file = mocker.patch( + "commit_check.commit.get_default_commit_msg_file", + return_value=".git/COMMIT_EDITMSG" + ) + mock_read_commit_msg = mocker.patch( + "commit_check.commit.read_commit_msg", + return_value="fix: 🐛 sample" + ) + + checks = [next(c for c in DEFAULT_CONFIG['checks'] if c['check'] == 'message')] + + result = check_commit_msg(checks, commit_msg_file="") + + mock_get_default_commit_msg_file.assert_called_once() + mock_read_commit_msg.assert_called_once_with(".git/COMMIT_EDITMSG") + assert result == 0 + def test_check_commit_with_empty_checks(mocker): checks = [] From ca0bdc6dba1ed6e315796b70d47af395e99bed0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Koh=C3=A1nyi=20R=C3=B3bert?= Date: Sat, 22 Feb 2025 23:24:13 +0100 Subject: [PATCH 2/2] fix: match grapheme cluster emojis too There are emojis out there that consist of a Unicode code point for the emoji and a variation selector too (another code point). See related test. --- commit_check/__init__.py | 2 +- tests/commit_test.py | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/commit_check/__init__.py b/commit_check/__init__.py index b750cf1c..afaeb673 100644 --- a/commit_check/__init__.py +++ b/commit_check/__init__.py @@ -16,7 +16,7 @@ 'checks': [ { 'check': 'message', - 'regex': r'^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test){1}(\([\w\-\.]+\))?(!)?: ([\U0001F600-\U0001F64F\U0001F300-\U0001F5FF\U0001F680-\U0001F6FF\U0001F700-\U0001F77F\U0001F780-\U0001F7FF\U0001F800-\U0001F8FF\U0001F900-\U0001F9FF\U0001FA00-\U0001FA6F\U0001FA70-\U0001FAFF\u2600-\u26FF\u2700-\u27BF] )?([\w ])+([\s\S]*)|(Merge).*|(fixup!.*)', + 'regex': r'^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test){1}(\([\w\-\.]+\))?(!)?: ([\u2600-\u26FF\u2700-\u27BF\U0001F000-\U0001F02F\U0001F0A0-\U0001F0FF\U0001F100-\U0001F1FF\U0001F300-\U0001F5FF\U0001F600-\U0001F64F\U0001F680-\U0001F6FF\U0001F900-\U0001F9FF]\uFE0F? )?([\w ])+([\s\S]*)|(Merge).*|(fixup!.*)', 'error': 'The commit message should be structured as follows:\n\n' '[optional scope]: \n' '[optional body]\n' diff --git a/tests/commit_test.py b/tests/commit_test.py index 8a64a5ef..a55b7b08 100644 --- a/tests/commit_test.py +++ b/tests/commit_test.py @@ -48,6 +48,7 @@ def test_check_commit_msg_no_commit_msg_file(mocker): mock_read_commit_msg.assert_called_once_with(".git/COMMIT_EDITMSG") assert result == 0 + def test_check_commit_msg_with_emoji_commit_msg_file_using_defaults(mocker): mock_get_default_commit_msg_file = mocker.patch( "commit_check.commit.get_default_commit_msg_file", @@ -67,6 +68,25 @@ def test_check_commit_msg_with_emoji_commit_msg_file_using_defaults(mocker): assert result == 0 +def test_check_commit_msg_with_grapheme_cluster_emoji_commit_msg_file_using_defaults(mocker): + mock_get_default_commit_msg_file = mocker.patch( + "commit_check.commit.get_default_commit_msg_file", + return_value=".git/COMMIT_EDITMSG" + ) + mock_read_commit_msg = mocker.patch( + "commit_check.commit.read_commit_msg", + return_value="docs: 📚️ mention commit-check and rulesets" # watch out emoji is U+1F4DA followed by U+FE0F + ) + + checks = [next(c for c in DEFAULT_CONFIG['checks'] if c['check'] == 'message')] + + result = check_commit_msg(checks, commit_msg_file="") + + mock_get_default_commit_msg_file.assert_called_once() + mock_read_commit_msg.assert_called_once_with(".git/COMMIT_EDITMSG") + assert result == 0 + + def test_check_commit_with_empty_checks(mocker): checks = [] m_re_match = mocker.patch(