diff options
author | Jim OLeary <jim.oleary@gmail.com> | 2020-04-29 19:00:37 +0100 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-05-05 21:07:44 +0000 |
commit | 0684c1761e399146a3a1760162d017d747bc3d3e (patch) | |
tree | 67ef028fb2a1f34ff334d129251e48888fad9a22 /buildscripts | |
parent | 8602f5f7b69d2ae71ed7a50acfc779ac57eba107 (diff) | |
download | mongo-0684c1761e399146a3a1760162d017d747bc3d3e.tar.gz |
SERVER-45949 Update validate commit message client to work with new patch description standard
(cherry picked from commit 09b9e9316877084501db453d08510345465a6770)
Diffstat (limited to 'buildscripts')
-rw-r--r-- | buildscripts/tests/test_validate_commit_message.py | 58 | ||||
-rwxr-xr-x | buildscripts/validate_commit_message.py | 78 |
2 files changed, 109 insertions, 27 deletions
diff --git a/buildscripts/tests/test_validate_commit_message.py b/buildscripts/tests/test_validate_commit_message.py index 1cfd37a1d0c..0539776fd71 100644 --- a/buildscripts/tests/test_validate_commit_message.py +++ b/buildscripts/tests/test_validate_commit_message.py @@ -1,5 +1,5 @@ """Unit tests for the evergreen_task_timeout script.""" - +import itertools import unittest from mock import MagicMock, patch @@ -8,11 +8,11 @@ from buildscripts.validate_commit_message import main, STATUS_OK, STATUS_ERROR, # pylint: disable=missing-docstring,no-self-use INVALID_MESSAGES = [ - [""], # You must provide a message - ["RevertEVG-1"], # revert and ticket must be formatted - ["revert EVG-1"], # revert must be capitalized - ["This is not a valid message"], # message must be valid - ["Fix lint plus extras is not a valid message"], # Fix lint is strict + "", # You must provide a message + "RevertEVG-1", # revert and ticket must be formatted + "revert EVG-1", # revert must be capitalized + "This is not a valid message", # message must be valid + "Fix Lint", # Fix lint is strict in terms of caps ] NS = "buildscripts.validate_commit_message" @@ -23,33 +23,49 @@ def ns(relative_name): # pylint: disable=invalid-name return NS + "." + relative_name +def interleave_new_format(older): + """Create a new list containing a new and old format copy of each string.""" + newer = [ + f"Commit Queue Merge: '{old}' into 'mongodb/mongo:SERVER-45949-validate-message-format'" + for old in older + ] + return list(itertools.chain(*zip(older, newer))) + + class ValidateCommitMessageTest(unittest.TestCase): def test_valid(self): messages = [ - ["Fix lint"], - ["EVG-1"], # Test valid projects with various number lengths - ["SERVER-20"], - ["WT-300"], - ["SERVER-44338"], - ["Revert EVG-5"], - ["Revert SERVER-60"], - ["Revert WT-700"], - ["Revert 'SERVER-8000"], - ['Revert "SERVER-90000'], - ["Import wiredtiger: 58115abb6fbb3c1cc7bfd087d41a47347bce9a69 from branch mongodb-4.4"], - ["Import tools: 58115abb6fbb3c1cc7bfd087d41a47347bce9a69 from branch mongodb-4.4"] + "Fix lint", + "EVG-1", # Test valid projects with various number lengths + "SERVER-20", + "WT-300", + "SERVER-44338", + "Revert EVG-5", + "Revert SERVER-60", + "Revert WT-700", + "Revert 'SERVER-8000", + 'Revert "SERVER-90000', + "Import wiredtiger: 58115abb6fbb3c1cc7bfd087d41a47347bce9a69 from branch mongodb-4.4", + "Import tools: 58115abb6fbb3c1cc7bfd087d41a47347bce9a69 from branch mongodb-4.4" ] - self.assertTrue(all(main(message) == STATUS_OK for message in messages)) + self.assertTrue( + all(main([message]) == STATUS_OK for message in interleave_new_format(messages))) def test_private(self): self.assertEqual(main(["XYZ-1"]), STATUS_ERROR) def test_catch_all(self): - self.assertTrue(all(main(message) == STATUS_ERROR for message in INVALID_MESSAGES)) + self.assertTrue( + all( + main([message]) == STATUS_ERROR + for message in interleave_new_format(INVALID_MESSAGES))) def test_ignore_warnings(self): - self.assertTrue(all(main(["-i"] + message) == STATUS_OK for message in INVALID_MESSAGES)) + self.assertTrue( + all( + main(["-i"] + [message]) == STATUS_OK + for message in interleave_new_format(INVALID_MESSAGES))) def test_last_git_commit_success(self): with patch( diff --git a/buildscripts/validate_commit_message.py b/buildscripts/validate_commit_message.py index 03283b9d940..e9e186dd25c 100755 --- a/buildscripts/validate_commit_message.py +++ b/buildscripts/validate_commit_message.py @@ -33,12 +33,26 @@ import re import subprocess import sys -VALID_PATTERNS = [ - re.compile(r"^Fix lint$"), # Allow "Fix lint" as the sole commit summary - re.compile(r'^(Revert ["\']?)?(EVG|SERVER|WT)-[0-9]+'), # These are public tickets - re.compile(r'^Import (wiredtiger|tools):'), # These are public tickets -] -PRIVATE_PATTERNS = [re.compile(r"^[A-Z]+-[0-9]+")] +COMMON_PUBLIC_PATTERN = r''' + ((?P<revert>Revert)\s+[\"\']?)? # Revert (optional) + ((?P<ticket>(?:EVG|SERVER|WT)-[0-9]+)[\"\']?\s*) # ticket identifier + (?P<body>(?:(?!\(cherry\spicked\sfrom).)*)? # To also capture the body + (?P<backport>\(cherry\spicked\sfrom.*)? # back port (optional) + ''' +"""Common Public pattern format.""" + +COMMON_LINT_PATTERN = r'(?P<lint>Fix\slint)' +"""Common Lint pattern format.""" + +COMMON_IMPORT_PATTERN = r'(?P<imported>Import\s(wiredtiger|tools):\s.*)' +"""Common Import pattern format.""" + +COMMON_PRIVATE_PATTERN = r''' + ((?P<revert>Revert)\s+[\"\']?)? # Revert (optional) + ((?P<ticket>[A-Z]+-[0-9]+)[\"\']?\s*) # ticket identifier + (?P<body>(?:(?!('\s(into\s'(([^/]+))/(([^:]+)):(([^']+))'))).)*)? # To also capture the body +''' +"""Common Private pattern format.""" STATUS_OK = 0 STATUS_ERROR = 1 @@ -46,6 +60,58 @@ STATUS_ERROR = 1 GIT_SHOW_COMMAND = ["git", "show", "-1", "-s", "--format=%s"] +def new_patch_description(pattern: str) -> str: + """ + Wrap the pattern to conform to the new commit queue patch description format. + + Add the commit queue prefix and suffix to the pattern. The format looks like: + + Commit Queue Merge: '<commit message>' into '<owner>/<repo>:<branch>' + + :param pattern: The pattern to wrap. + :return: A pattern to match the new format for the patch description. + """ + return (r"""^((?P<commitqueue>Commit\sQueue\sMerge:)\s')""" + f'{pattern}' + # r"""('\s(?P<into>into\s'((?P<owner>[^/]+))/((?P<repo>[^:]+)):((?P<branch>[^']+))'))""" + ) + + +def old_patch_description(pattern: str) -> str: + """ + Wrap the pattern to conform to the new commit queue patch description format. + + Just add a start anchor. The format looks like: + + <commit message> + + :param pattern: The pattern to wrap. + :return: A pattern to match the old format for the patch description. + """ + return r'^' f'{pattern}' + + +# NOTE: re.VERBOSE is for visibility / debugging. As such significant white space must be +# escaped (e.g ' ' to \s). +VALID_PATTERNS = [ + re.compile(new_patch_description(COMMON_PUBLIC_PATTERN), re.MULTILINE | re.DOTALL | re.VERBOSE), + re.compile(old_patch_description(COMMON_PUBLIC_PATTERN), re.MULTILINE | re.DOTALL | re.VERBOSE), + re.compile(new_patch_description(COMMON_LINT_PATTERN), re.MULTILINE | re.DOTALL | re.VERBOSE), + re.compile(old_patch_description(COMMON_LINT_PATTERN), re.MULTILINE | re.DOTALL | re.VERBOSE), + re.compile(new_patch_description(COMMON_IMPORT_PATTERN), re.MULTILINE | re.DOTALL | re.VERBOSE), + re.compile(old_patch_description(COMMON_IMPORT_PATTERN), re.MULTILINE | re.DOTALL | re.VERBOSE), +] +"""valid public patterns.""" + +PRIVATE_PATTERNS = [ + re.compile( + new_patch_description(COMMON_PRIVATE_PATTERN), re.MULTILINE | re.DOTALL | re.VERBOSE), + re.compile( + old_patch_description(COMMON_PRIVATE_PATTERN), re.MULTILINE | re.DOTALL | re.VERBOSE), +] +"""private patterns.""" + + def main(argv=None): """Execute Main function to validate commit messages.""" parser = argparse.ArgumentParser( |