diff --git a/commitizen/bump.py b/commitizen/bump.py index d9fcbc1564..bb80e2ba6a 100644 --- a/commitizen/bump.py +++ b/commitizen/bump.py @@ -1,5 +1,5 @@ import re -from collections import defaultdict +from collections import OrderedDict from itertools import zip_longest from string import Template from typing import List, Optional, Union @@ -18,28 +18,36 @@ def find_increment( - commits: List[GitCommit], regex: str = bump_pattern, increments_map: dict = bump_map + commits: List[GitCommit], + regex: str = bump_pattern, + increments_map: Union[dict, OrderedDict] = bump_map, ) -> Optional[str]: + if isinstance(increments_map, dict): + increments_map = OrderedDict(increments_map) + # Most important cases are major and minor. # Everything else will be considered patch. - increments_map_default = defaultdict(lambda: None, increments_map) - pattern = re.compile(regex) + select_pattern = re.compile(regex) increment = None for commit in commits: for message in commit.message.split("\n"): - result = pattern.search(message) - if not result: - continue - found_keyword = result.group(0) - new_increment = increments_map_default[found_keyword] - if increment == "MAJOR": - continue - elif increment == "MINOR" and new_increment == "MAJOR": - increment = new_increment - elif increment == "PATCH" or increment is None: - increment = new_increment + result = select_pattern.search(message) + if result: + found_keyword = result.group(0) + new_increment = None + for match_pattern in increments_map.keys(): + if re.match(match_pattern, found_keyword): + new_increment = increments_map[match_pattern] + break + + if increment == "MAJOR": + continue + elif increment == "MINOR" and new_increment == "MAJOR": + increment = new_increment + elif increment == "PATCH" or increment is None: + increment = new_increment return increment diff --git a/commitizen/defaults.py b/commitizen/defaults.py index 0dfee12246..e38ef01bf0 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -1,10 +1,12 @@ +from collections import OrderedDict + name: str = "cz_conventional_commits" # TODO: .cz, setup.cfg, .cz.cfg should be removed in 2.0 long_term_support_config_files: list = ["pyproject.toml", ".cz.toml"] deprcated_config_files: list = [".cz", "setup.cfg", ".cz.cfg"] config_files: list = long_term_support_config_files + deprcated_config_files -DEFAULT_SETTINGS = { +DEFAULT_SETTINGS: dict = { "name": "cz_conventional_commits", "version": None, "version_files": [], @@ -16,12 +18,15 @@ MINOR = "MINOR" PATCH = "PATCH" -bump_pattern = r"^(BREAKING CHANGE|feat|fix|refactor|perf)" -bump_map = { - "BREAKING CHANGE": MAJOR, - "feat": MINOR, - "fix": PATCH, - "refactor": PATCH, - "perf": PATCH, -} +bump_pattern = r"^(BREAKING[\-\ ]CHANGE|feat|fix|refactor|perf)(\(.+\))?(!)?" +bump_map = OrderedDict( + ( + (r"^.+!$", MAJOR), + (r"^BREAKING[\-\ ]CHANGE", MAJOR), + (r"^feat", MINOR), + (r"^fix", PATCH), + (r"^refactor", PATCH), + (r"^perf", PATCH), + ) +) bump_message = "bump: version $current_version → $new_version" diff --git a/tests/test_bump_find_increment.py b/tests/test_bump_find_increment.py index 5930be078f..1f98694a2b 100644 --- a/tests/test_bump_find_increment.py +++ b/tests/test_bump_find_increment.py @@ -20,13 +20,26 @@ "fix(setup.py): future is now required for every python version", ] -MAJOR_INCREMENTS_CC = [ +MAJOR_INCREMENTS_BREAKING_CHANGE_CC = [ "feat(cli): added version", "docs(README): motivation", "BREAKING CHANGE: `extends` key in config file is now used for extending other config files", # noqa "fix(setup.py): future is now required for every python version", ] +MAJOR_INCREMENTS_BREAKING_CHANGE_ALT_CC = [ + "feat(cli): added version", + "docs(README): motivation", + "BREAKING-CHANGE: `extends` key in config file is now used for extending other config files", # noqa + "fix(setup.py): future is now required for every python version", +] + +MAJOR_INCREMENTS_EXCLAMATION_CC = [ + "feat(cli)!: added version", + "docs(README): motivation", + "fix(setup.py): future is now required for every python version", +] + PATCH_INCREMENTS_SVE = ["readme motivation PATCH", "fix setup.py PATCH"] MINOR_INCREMENTS_SVE = [ @@ -51,7 +64,9 @@ ( (PATCH_INCREMENTS_CC, "PATCH"), (MINOR_INCREMENTS_CC, "MINOR"), - (MAJOR_INCREMENTS_CC, "MAJOR"), + (MAJOR_INCREMENTS_BREAKING_CHANGE_CC, "MAJOR"), + (MAJOR_INCREMENTS_BREAKING_CHANGE_ALT_CC, "MAJOR"), + (MAJOR_INCREMENTS_EXCLAMATION_CC, "MAJOR"), (NONE_INCREMENT_CC, None), ), )