diff --git a/semantic_release/defaults.cfg b/semantic_release/defaults.cfg index a88098654..d7a914028 100644 --- a/semantic_release/defaults.cfg +++ b/semantic_release/defaults.cfg @@ -1,4 +1,8 @@ [semantic_release] +parser_angular_allowed_types=build,chore,ci,docs,feat,fix,perf,style,refactor,test +parser_angular_default_level_bump=0 +parser_angular_minor_types=feat +parser_angular_patch_types=fix,perf branch=master build_command=python setup.py sdist bdist_wheel changelog_components=semantic_release.changelog.changelog_headers diff --git a/semantic_release/history/parser_angular.py b/semantic_release/history/parser_angular.py index acb7b135b..b4bece205 100644 --- a/semantic_release/history/parser_angular.py +++ b/semantic_release/history/parser_angular.py @@ -8,26 +8,23 @@ from ..errors import UnknownCommitMessageStyleError from ..helpers import LoggedFunction +from ..settings import config from .parser_helpers import ParsedCommit, parse_paragraphs, re_breaking logger = logging.getLogger(__name__) # Supported commit types for parsing +allowed_types = config.get('parser_angular_allowed_types').split(',') + +# types with long names in changelog TYPES = { "feat": "feature", - "fix": "fix", - "test": "test", "docs": "documentation", - "style": "style", - "refactor": "refactor", - "build": "build", - "ci": "ci", "perf": "performance", - "chore": "chore", } re_parser = re.compile( - r"(?P" + "|".join(TYPES.keys()) + ")" + r"(?P" + "|".join(allowed_types) + ")" r"(?:\((?P[^\n]+)\))?" r"(?P!)?: " r"(?P[^\n]+)" @@ -35,15 +32,8 @@ re.DOTALL, ) -MINOR_TYPES = [ - "feat", -] - -PATCH_TYPES = [ - "fix", - "perf", -] - +MINOR_TYPES = config.get('parser_angular_minor_types').split(',') +PATCH_TYPES = config.get('parser_angular_patch_types').split(',') @LoggedFunction(logger) def parse_commit_message(message: str) -> ParsedCommit: @@ -60,13 +50,19 @@ def parse_commit_message(message: str) -> ParsedCommit: raise UnknownCommitMessageStyleError( f"Unable to parse the given commit message: {message}" ) + parsed_break = parsed.group('break') + parsed_scope = parsed.group('scope') + parsed_subject = parsed.group('subject') + parsed_text = parsed.group('text') + parsed_type = parsed.group('type') - if parsed.group("text"): - descriptions = parse_paragraphs(parsed.group("text")) + + if parsed_text: + descriptions = parse_paragraphs(parsed_text) else: descriptions = list() # Insert the subject before the other paragraphs - descriptions.insert(0, parsed.group("subject")) + descriptions.insert(0, parsed_subject) # Look for descriptions of breaking changes breaking_descriptions = [ @@ -75,18 +71,23 @@ def parse_commit_message(message: str) -> ParsedCommit: if match ] - level_bump = 0 - if parsed.group("break") or breaking_descriptions: + level_bump = int(config.get('parser_angular_default_level_bump')) + if parsed_break or breaking_descriptions: level_bump = 3 # Major - elif parsed.group("type") in MINOR_TYPES: + elif parsed_type in MINOR_TYPES: level_bump = 2 # Minor - elif parsed.group("type") in PATCH_TYPES: + elif parsed_type in PATCH_TYPES: level_bump = 1 # Patch + parsed_type_long = TYPES.get(parsed_type, parsed_type) + # first param is the key you're getting from the dict, + # second param is the default value + # allows only putting types with a long name in the TYPES dict + return ParsedCommit( level_bump, - TYPES[parsed.group("type")], - parsed.group("scope"), + parsed_type_long, + parsed_scope, descriptions, breaking_descriptions, ) diff --git a/tests/parsers/test_angular.py b/tests/parsers/test_angular.py index 765534d99..006dde402 100644 --- a/tests/parsers/test_angular.py +++ b/tests/parsers/test_angular.py @@ -3,6 +3,8 @@ from semantic_release.errors import UnknownCommitMessageStyleError from semantic_release.history import angular_parser +from .. import mock,wrapped_config_get + text = ( "This is an long explanatory part of a commit message. It should give " "some insight to the fix this commit adds to the codebase." @@ -97,3 +99,33 @@ def test_parser_return_footer_from_commit_message(): def test_parser_should_accept_message_without_scope(): assert angular_parser("fix: superfix")[0] == 1 assert angular_parser("fix: superfix")[3][0] == "superfix" + +############################## +# test custom parser options # +############################## +@mock.patch("semantic_release.history.parser_angular.config.get", + wrapped_config_get(parser_angular_default_level_bump='50')) +def test_parser_custom_default_level(): + assert angular_parser("test(parser): Add a test for angular parser")[0] == 50 + + +@mock.patch("semantic_release.history.parser_angular.config.get", + wrapped_config_get( + parser_angular_allowed_types= + 'custom,build,chore,ci,docs,fix,perf,style,refactor,test')) +def test_parser_custom_allowed_types(): + assert angular_parser("custom: ...")[0] == 0 + assert angular_parser("custom(parser): ...")[1] == "custom" + pytest.raises(UnknownCommitMessageStyleError, angular_parser, "feat(parser): ...") + + +@mock.patch("semantic_release.history.parser_angular.config.get", + wrapped_config_get(parser_angular_minor_types='docs')) +def test_parser_custom_minor_types(): + assert angular_parser("docs: write some docs")[0] == 2 + + +@mock.patch("semantic_release.history.parser_angular.config.get", + wrapped_config_get(parser_angular_patch_types='test')) +def test_parser_custom_patch_types(): + assert angular_parser("test(this): added a test")[0] == 1