|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
| 3 | +from collections import OrderedDict |
3 | 4 | from pathlib import Path |
4 | 5 | from typing import TYPE_CHECKING, TypedDict |
5 | 6 |
|
6 | 7 | from commitizen import defaults |
7 | 8 | from commitizen.cz.base import BaseCommitizen |
8 | 9 | from commitizen.cz.utils import multiple_line_breaker, required_validator |
| 10 | +from commitizen.question import Choice |
9 | 11 |
|
10 | 12 | if TYPE_CHECKING: |
| 13 | + from commitizen.config import BaseConfig |
11 | 14 | from commitizen.question import CzQuestion |
12 | 15 |
|
13 | 16 | __all__ = ["ConventionalCommitsCz"] |
@@ -41,74 +44,123 @@ class ConventionalCommitsCz(BaseCommitizen): |
41 | 44 | "refactor": "Refactor", |
42 | 45 | "perf": "Perf", |
43 | 46 | } |
| 47 | + change_type_choices = [ |
| 48 | + Choice( |
| 49 | + value="fix", |
| 50 | + name=("fix: A bug fix. Correlates with PATCH in SemVer"), |
| 51 | + key="x", |
| 52 | + ), |
| 53 | + Choice( |
| 54 | + value="feat", |
| 55 | + name="feat: A new feature. Correlates with MINOR in SemVer", |
| 56 | + key="f", |
| 57 | + ), |
| 58 | + Choice( |
| 59 | + value="docs", |
| 60 | + name="docs: Documentation only changes", |
| 61 | + key="d", |
| 62 | + ), |
| 63 | + Choice( |
| 64 | + value="style", |
| 65 | + name=( |
| 66 | + "style: Changes that do not affect the " |
| 67 | + "meaning of the code (white-space, formatting," |
| 68 | + " missing semi-colons, etc)" |
| 69 | + ), |
| 70 | + key="s", |
| 71 | + ), |
| 72 | + Choice( |
| 73 | + value="refactor", |
| 74 | + name=( |
| 75 | + "refactor: A code change that neither fixes a bug nor adds a feature" |
| 76 | + ), |
| 77 | + key="r", |
| 78 | + ), |
| 79 | + Choice( |
| 80 | + value="perf", |
| 81 | + name="perf: A code change that improves performance", |
| 82 | + key="p", |
| 83 | + ), |
| 84 | + Choice( |
| 85 | + value="test", |
| 86 | + name="test: Adding missing or correcting existing tests", |
| 87 | + key="t", |
| 88 | + ), |
| 89 | + Choice( |
| 90 | + value="build", |
| 91 | + name=( |
| 92 | + "build: Changes that affect the build system or " |
| 93 | + "external dependencies (example scopes: pip, docker, npm)" |
| 94 | + ), |
| 95 | + key="b", |
| 96 | + ), |
| 97 | + Choice( |
| 98 | + value="ci", |
| 99 | + name=( |
| 100 | + "ci: Changes to CI configuration files and " |
| 101 | + "scripts (example scopes: GitLabCI)" |
| 102 | + ), |
| 103 | + key="c", |
| 104 | + ), |
| 105 | + ] |
| 106 | + |
44 | 107 | changelog_pattern = defaults.BUMP_PATTERN |
45 | 108 |
|
| 109 | + def __init__(self, config: BaseConfig) -> None: |
| 110 | + super().__init__(config) |
| 111 | + self._isolate_mutable_defaults() |
| 112 | + |
| 113 | + if override_settings := self.config.settings.get("override"): |
| 114 | + self._apply_override_settings(override_settings) |
| 115 | + elif extend_settings := self.config.settings.get("extend"): |
| 116 | + self._apply_extend_settings(extend_settings) |
| 117 | + |
| 118 | + def _isolate_mutable_defaults(self) -> None: |
| 119 | + # Keep mutable class defaults isolated per instance. |
| 120 | + self.bump_map = OrderedDict(self.bump_map) |
| 121 | + self.bump_map_major_version_zero = OrderedDict(self.bump_map_major_version_zero) |
| 122 | + self.change_type_map = dict(self.change_type_map) |
| 123 | + self.change_type_choices = [*self.change_type_choices] |
| 124 | + |
| 125 | + def _apply_override_settings(self, settings: defaults.CzOverrideSettings) -> None: |
| 126 | + if bump_pattern := settings.get("bump_pattern"): |
| 127 | + self.bump_pattern = bump_pattern |
| 128 | + if bump_map := settings.get("bump_map"): |
| 129 | + self.bump_map = OrderedDict(bump_map) |
| 130 | + if bump_map_major_version_zero := settings.get("bump_map_major_version_zero"): |
| 131 | + self.bump_map_major_version_zero = OrderedDict(bump_map_major_version_zero) |
| 132 | + if commit_parser := settings.get("commit_parser"): |
| 133 | + self.commit_parser = commit_parser |
| 134 | + if changelog_pattern := settings.get("changelog_pattern"): |
| 135 | + self.changelog_pattern = changelog_pattern |
| 136 | + if change_type_map := settings.get("change_type_map"): |
| 137 | + self.change_type_map = dict(change_type_map) |
| 138 | + if change_type_choices := settings.get("change_type_choices"): |
| 139 | + self.change_type_choices = [*change_type_choices] |
| 140 | + |
| 141 | + def _apply_extend_settings(self, settings: defaults.CzExtendSettings) -> None: |
| 142 | + if bump_pattern := settings.get("bump_pattern"): |
| 143 | + self.bump_pattern = bump_pattern |
| 144 | + if bump_map := settings.get("bump_map"): |
| 145 | + self.bump_map.update(bump_map) |
| 146 | + if bump_map_major_version_zero := settings.get("bump_map_major_version_zero"): |
| 147 | + self.bump_map_major_version_zero.update(bump_map_major_version_zero) |
| 148 | + if commit_parser := settings.get("commit_parser"): |
| 149 | + self.commit_parser = commit_parser |
| 150 | + if changelog_pattern := settings.get("changelog_pattern"): |
| 151 | + self.changelog_pattern = changelog_pattern |
| 152 | + if change_type_map := settings.get("change_type_map"): |
| 153 | + self.change_type_map.update(change_type_map) |
| 154 | + if change_type_choices := settings.get("change_type_choices"): |
| 155 | + self.change_type_choices.extend(change_type_choices) |
| 156 | + |
46 | 157 | def questions(self) -> list[CzQuestion]: |
47 | 158 | return [ |
48 | 159 | { |
49 | 160 | "type": "list", |
50 | 161 | "name": "prefix", |
51 | 162 | "message": "Select the type of change you are committing", |
52 | | - "choices": [ |
53 | | - { |
54 | | - "value": "fix", |
55 | | - "name": "fix: A bug fix. Correlates with PATCH in SemVer", |
56 | | - "key": "x", |
57 | | - }, |
58 | | - { |
59 | | - "value": "feat", |
60 | | - "name": "feat: A new feature. Correlates with MINOR in SemVer", |
61 | | - "key": "f", |
62 | | - }, |
63 | | - { |
64 | | - "value": "docs", |
65 | | - "name": "docs: Documentation only changes", |
66 | | - "key": "d", |
67 | | - }, |
68 | | - { |
69 | | - "value": "style", |
70 | | - "name": ( |
71 | | - "style: Changes that do not affect the " |
72 | | - "meaning of the code (white-space, formatting," |
73 | | - " missing semi-colons, etc)" |
74 | | - ), |
75 | | - "key": "s", |
76 | | - }, |
77 | | - { |
78 | | - "value": "refactor", |
79 | | - "name": ( |
80 | | - "refactor: A code change that neither fixes " |
81 | | - "a bug nor adds a feature" |
82 | | - ), |
83 | | - "key": "r", |
84 | | - }, |
85 | | - { |
86 | | - "value": "perf", |
87 | | - "name": "perf: A code change that improves performance", |
88 | | - "key": "p", |
89 | | - }, |
90 | | - { |
91 | | - "value": "test", |
92 | | - "name": ("test: Adding missing or correcting existing tests"), |
93 | | - "key": "t", |
94 | | - }, |
95 | | - { |
96 | | - "value": "build", |
97 | | - "name": ( |
98 | | - "build: Changes that affect the build system or " |
99 | | - "external dependencies (example scopes: pip, docker, npm)" |
100 | | - ), |
101 | | - "key": "b", |
102 | | - }, |
103 | | - { |
104 | | - "value": "ci", |
105 | | - "name": ( |
106 | | - "ci: Changes to CI configuration files and " |
107 | | - "scripts (example scopes: GitLabCI)" |
108 | | - ), |
109 | | - "key": "c", |
110 | | - }, |
111 | | - ], |
| 163 | + "choices": self.change_type_choices, |
112 | 164 | }, |
113 | 165 | { |
114 | 166 | "type": "input", |
|
0 commit comments