commitizen 4.8.2__tar.gz → 4.8.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. commitizen-4.8.4/PKG-INFO +392 -0
  2. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/__init__.py +1 -1
  3. commitizen-4.8.4/commitizen/__version__.py +1 -0
  4. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/bump.py +17 -17
  5. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/changelog.py +26 -23
  6. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/changelog_formats/__init__.py +12 -7
  7. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/changelog_formats/base.py +1 -1
  8. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/cli.py +62 -40
  9. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/cmd.py +4 -1
  10. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/commands/bump.py +110 -104
  11. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/commands/changelog.py +77 -52
  12. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/commands/check.py +36 -25
  13. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/commands/commit.py +54 -48
  14. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/commands/example.py +2 -2
  15. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/commands/info.py +2 -2
  16. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/commands/init.py +7 -7
  17. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/commands/list_cz.py +2 -2
  18. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/commands/schema.py +2 -2
  19. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/commands/version.py +10 -3
  20. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/config/base_config.py +21 -7
  21. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/config/json_config.py +14 -4
  22. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/config/toml_config.py +17 -7
  23. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/config/yaml_config.py +14 -4
  24. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/cz/base.py +6 -13
  25. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/cz/conventional_commits/conventional_commits.py +42 -39
  26. commitizen-4.8.4/commitizen/cz/customize/__init__.py +1 -0
  27. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/cz/customize/customize.py +9 -7
  28. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/cz/jira/jira.py +10 -18
  29. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/cz/utils.py +7 -8
  30. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/defaults.py +61 -25
  31. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/exceptions.py +4 -3
  32. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/factory.py +1 -3
  33. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/git.py +132 -111
  34. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/hooks.py +3 -2
  35. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/out.py +4 -3
  36. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/providers/base_provider.py +11 -10
  37. commitizen-4.8.4/commitizen/providers/cargo_provider.py +94 -0
  38. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/providers/commitizen_provider.py +2 -2
  39. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/providers/npm_provider.py +3 -2
  40. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/providers/poetry_provider.py +3 -3
  41. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/providers/scm_provider.py +1 -1
  42. commitizen-4.8.4/commitizen/question.py +32 -0
  43. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/tags.py +10 -14
  44. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/version_schemes.py +51 -51
  45. commitizen-4.8.4/docs/README.md +326 -0
  46. {commitizen-4.8.2 → commitizen-4.8.4}/pyproject.toml +31 -29
  47. commitizen-4.8.2/PKG-INFO +0 -248
  48. commitizen-4.8.2/commitizen/__version__.py +0 -1
  49. commitizen-4.8.2/commitizen/cz/customize/__init__.py +0 -1
  50. commitizen-4.8.2/commitizen/providers/cargo_provider.py +0 -57
  51. commitizen-4.8.2/docs/README.md +0 -183
  52. {commitizen-4.8.2 → commitizen-4.8.4}/LICENSE +0 -0
  53. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/__main__.py +0 -0
  54. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/changelog_formats/asciidoc.py +0 -0
  55. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/changelog_formats/markdown.py +0 -0
  56. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/changelog_formats/restructuredtext.py +0 -0
  57. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/changelog_formats/textile.py +0 -0
  58. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/commands/__init__.py +2 -2
  59. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/config/__init__.py +0 -0
  60. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/cz/__init__.py +0 -0
  61. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/cz/conventional_commits/__init__.py +0 -0
  62. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/cz/conventional_commits/conventional_commits_info.txt +0 -0
  63. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/cz/customize/customize_info.txt +0 -0
  64. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/cz/exceptions.py +0 -0
  65. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/cz/jira/__init__.py +0 -0
  66. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/cz/jira/jira_info.txt +0 -0
  67. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/providers/__init__.py +1 -1
  68. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/providers/composer_provider.py +0 -0
  69. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/providers/pep621_provider.py +0 -0
  70. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/providers/uv_provider.py +0 -0
  71. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/py.typed +0 -0
  72. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/templates/CHANGELOG.adoc.j2 +0 -0
  73. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/templates/CHANGELOG.md.j2 +0 -0
  74. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/templates/CHANGELOG.rst.j2 +0 -0
  75. {commitizen-4.8.2 → commitizen-4.8.4}/commitizen/templates/CHANGELOG.textile.j2 +0 -0
@@ -0,0 +1,392 @@
1
+ Metadata-Version: 2.3
2
+ Name: commitizen
3
+ Version: 4.8.4
4
+ Summary: Python commitizen client tool
5
+ License: MIT License
6
+
7
+ Copyright (c) 2017 Santiago
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in all
17
+ copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
26
+ Keywords: commitizen,conventional,commits,git
27
+ Author: Santiago Fraire
28
+ Author-email: santiwilly@gmail.com
29
+ Maintainer: Wei Lee
30
+ Maintainer-email: weilee.rx@gmail.com
31
+ Requires-Python: >=3.9,<4.0
32
+ Classifier: Development Status :: 5 - Production/Stable
33
+ Classifier: Environment :: Console
34
+ Classifier: Intended Audience :: Developers
35
+ Classifier: Natural Language :: English
36
+ Classifier: Operating System :: OS Independent
37
+ Classifier: Programming Language :: Python
38
+ Classifier: Programming Language :: Python :: 3
39
+ Classifier: Programming Language :: Python :: 3.9
40
+ Classifier: Programming Language :: Python :: 3.10
41
+ Classifier: Programming Language :: Python :: 3.11
42
+ Classifier: Programming Language :: Python :: 3.12
43
+ Classifier: Programming Language :: Python :: 3.13
44
+ Classifier: Programming Language :: Python :: Implementation :: CPython
45
+ Classifier: License :: OSI Approved :: MIT License
46
+ Requires-Dist: argcomplete (>=1.12.1,<3.7)
47
+ Requires-Dist: charset-normalizer (>=2.1.0,<4)
48
+ Requires-Dist: colorama (>=0.4.1,<1.0)
49
+ Requires-Dist: decli (>=0.6.0,<1.0)
50
+ Requires-Dist: importlib-metadata (>=8.0.0,<8.7.0) ; python_version < "3.10"
51
+ Requires-Dist: jinja2 (>=2.10.3)
52
+ Requires-Dist: packaging (>=19)
53
+ Requires-Dist: prompt_toolkit (!=3.0.52)
54
+ Requires-Dist: pyyaml (>=3.08)
55
+ Requires-Dist: questionary (>=2.0,<3.0)
56
+ Requires-Dist: termcolor (>=1.1.0,<4.0.0)
57
+ Requires-Dist: tomlkit (>=0.5.3,<1.0.0)
58
+ Requires-Dist: typing-extensions (>=4.0.1,<5.0.0) ; python_version < "3.11"
59
+ Project-URL: Changelog, https://github.com/commitizen-tools/commitizen/blob/master/CHANGELOG.md
60
+ Project-URL: Documentation, https://commitizen-tools.github.io/commitizen/
61
+ Project-URL: Homepage, https://github.com/commitizen-tools/commitizen
62
+ Project-URL: Issues, https://github.com/commitizen-tools/commitizen/issues
63
+ Project-URL: Repository, https://github.com/commitizen-tools/commitizen
64
+ Description-Content-Type: text/markdown
65
+
66
+ [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/commitizen-tools/commitizen/pythonpackage.yml?label=python%20package&logo=github&logoColor=white&style=flat-square)](https://github.com/commitizen-tools/commitizen/actions)
67
+ [![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg?style=flat-square)](https://conventionalcommits.org)
68
+ [![PyPI Package latest release](https://img.shields.io/pypi/v/commitizen.svg?style=flat-square)](https://pypi.org/project/commitizen/)
69
+ [![PyPI Package download count (per month)](https://img.shields.io/pypi/dm/commitizen?style=flat-square)](https://pypi.org/project/commitizen/)
70
+ [![Supported versions](https://img.shields.io/pypi/pyversions/commitizen.svg?style=flat-square)](https://pypi.org/project/commitizen/)
71
+ [![Conda Version](https://img.shields.io/conda/vn/conda-forge/commitizen?style=flat-square)](https://anaconda.org/conda-forge/commitizen)
72
+ [![homebrew](https://img.shields.io/homebrew/v/commitizen?color=teal&style=flat-square)](https://formulae.brew.sh/formula/commitizen)
73
+ [![Codecov](https://img.shields.io/codecov/c/github/commitizen-tools/commitizen.svg?style=flat-square)](https://codecov.io/gh/commitizen-tools/commitizen)
74
+ [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?style=flat-square&logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit)
75
+
76
+ ![Using Commitizen cli](images/demo.gif)
77
+
78
+ ---
79
+
80
+ [**Commitizen Documentation Site**](https://commitizen-tools.github.io/commitizen/)
81
+
82
+ ---
83
+
84
+ ## About
85
+
86
+ Commitizen is a powerful release management tool that helps teams maintain consistent and meaningful commit messages while automating version management.
87
+
88
+ ### What Commitizen Does
89
+
90
+ By enforcing standardized commit conventions (defaulting to [Conventional Commits][conventional_commits]), Commitizen helps teams:
91
+
92
+ - Write clear, structured commit messages
93
+ - Automatically manage version numbers using semantic versioning
94
+ - Generate and maintain changelogs
95
+ - Streamline the release process
96
+
97
+ ### Key Benefits
98
+
99
+ With just a simple `cz bump` command, Commitizen handles:
100
+
101
+ 1. **Version Management**: Automatically bumps version numbers and updates version files based on your commit history
102
+ 2. **Changelog Generation**: Creates and updates changelogs following the [Keep a changelog][keepchangelog] format
103
+ 3. **Commit Standardization**: Enforces consistent commit message formats across your team
104
+
105
+ This standardization makes your commit history more readable and meaningful, while the automation reduces manual work and potential errors in the release process.
106
+
107
+ ### Features
108
+
109
+ - Interactive CLI for standardized commits with default [Conventional Commits][conventional_commits] support
110
+ - Intelligent [version bumping](https://commitizen-tools.github.io/commitizen/commands/bump/) using [Semantic Versioning][semver]
111
+ - Automatic [keep a changelog][keepchangelog] generation
112
+ - Built-in commit validation with pre-commit hooks
113
+ - [Customizable](https://commitizen-tools.github.io/commitizen/customization/) commit rules and templates
114
+ - Multi-format version file support
115
+ - Custom rules and plugins via pip
116
+
117
+ ## Getting Started
118
+
119
+ ### Requirements
120
+
121
+ Before installing Commitizen, ensure you have:
122
+
123
+ - [Python](https://www.python.org/downloads/) `3.9+`
124
+ - [Git][gitscm] `1.8.5.2+`
125
+
126
+ ### Installation
127
+
128
+ #### Global Installation (Recommended)
129
+
130
+ The recommended way to install Commitizen is using [`pipx`](https://pipx.pypa.io/) or [`uv`](https://docs.astral.sh/uv/), which ensures a clean, isolated installation:
131
+
132
+ **Using pipx:**
133
+ ```bash
134
+ # Install Commitizen
135
+ pipx install commitizen
136
+
137
+ # Keep it updated
138
+ pipx upgrade commitizen
139
+ ```
140
+
141
+ **Using uv:**
142
+ ```bash
143
+ # Install commitizen
144
+ uv tool install commitizen
145
+
146
+ # Keep it updated
147
+ uv tool upgrade commitizen
148
+ ```
149
+
150
+ **(For macOS users) Using Homebrew:**
151
+ ```bash
152
+ brew install commitizen
153
+ ```
154
+
155
+ #### Project-Specific Installation
156
+
157
+ You can add Commitizen to your Python project using any of these package managers:
158
+
159
+ **Using pip:**
160
+ ```bash
161
+ pip install -U commitizen
162
+ ```
163
+
164
+ **Using conda:**
165
+ ```bash
166
+ conda install -c conda-forge commitizen
167
+ ```
168
+
169
+ **Using Poetry:**
170
+ ```bash
171
+ # For Poetry >= 1.2.0
172
+ poetry add commitizen --group dev
173
+
174
+ # For Poetry < 1.2.0
175
+ poetry add commitizen --dev
176
+ ```
177
+
178
+ **Using uv:**
179
+ ```bash
180
+ uv add --dev commitizen
181
+ ```
182
+
183
+ **Using pdm:**
184
+ ```bash
185
+ pdm add -d commitizen
186
+ ```
187
+
188
+ ### Basic Commands
189
+
190
+ #### Initialize Commitizen
191
+
192
+ To get started, you'll need to set up your configuration. You have two options:
193
+
194
+ 1. Use the interactive setup:
195
+ ```sh
196
+ cz init
197
+ ```
198
+
199
+ 2. Manually create a configuration file (`.cz.toml` or `cz.toml`):
200
+ ```toml
201
+ [tool.commitizen]
202
+ version = "0.1.0"
203
+ update_changelog_on_bump = true
204
+ ```
205
+
206
+ #### Create Commits
207
+
208
+ Create standardized commits using:
209
+ ```sh
210
+ cz commit
211
+ # or use the shortcut
212
+ cz c
213
+ ```
214
+
215
+ To sign off your commits:
216
+ ```sh
217
+ cz commit -- --signoff
218
+ # or use the shortcut
219
+ cz commit -- -s
220
+ ```
221
+
222
+ For more commit options, run `cz commit --help`.
223
+
224
+ #### Version Management
225
+
226
+ The most common command you'll use is:
227
+ ```sh
228
+ cz bump
229
+ ```
230
+
231
+ This command:
232
+
233
+ - Bumps your project's version
234
+ - Creates a git tag
235
+ - Updates the changelog (if `update_changelog_on_bump` is enabled)
236
+ - Updates version files
237
+
238
+ You can customize:
239
+
240
+ - [Version files](https://commitizen-tools.github.io/commitizen/commands/bump/#version_files)
241
+ - [Version scheme](https://commitizen-tools.github.io/commitizen/commands/bump/#version_scheme)
242
+ - [Version provider](https://commitizen-tools.github.io/commitizen/config/#version-providers)
243
+
244
+ For all available options, see the [bump command documentation](https://commitizen-tools.github.io/commitizen/commands/bump/).
245
+
246
+ ### Advanced Usage
247
+
248
+ #### Get Project Version
249
+
250
+ ```sh
251
+ # Get your project's version (instead of Commitizen's version)
252
+ cz version -p
253
+ # Preview changelog changes
254
+ cz changelog --dry-run "$(cz version -p)"
255
+ ```
256
+
257
+ This command is particularly useful for automation scripts and CI/CD pipelines.
258
+
259
+ For example, you can use the output of the command `cz changelog --dry-run "$(cz version -p)"` to notify your team about a new release in Slack.
260
+
261
+ #### Pre-commit Integration
262
+
263
+ Commitizen can automatically validate your commit messages using pre-commit hooks.
264
+
265
+ 1. Add to your `.pre-commit-config.yaml`:
266
+ ```yaml
267
+ ---
268
+ repos:
269
+ - repo: https://github.com/commitizen-tools/commitizen
270
+ rev: master # Replace with latest tag
271
+ hooks:
272
+ - id: commitizen
273
+ - id: commitizen-branch
274
+ stages: [pre-push]
275
+ ```
276
+
277
+ 2. Install the hooks:
278
+ ```sh
279
+ pre-commit install --hook-type commit-msg --hook-type pre-push
280
+ ```
281
+
282
+ | Hook | Recommended Stage |
283
+ | ----------------- | ----------------- |
284
+ | commitizen | commit-msg |
285
+ | commitizen-branch | pre-push |
286
+
287
+ > **Note**: Replace `master` with the [latest tag](https://github.com/commitizen-tools/commitizen/tags) to avoid warnings. You can automatically update this with:
288
+ > ```sh
289
+ > pre-commit autoupdate
290
+ > ```
291
+
292
+ For more details about commit validation, see the [check command documentation](https://commitizen-tools.github.io/commitizen/commands/check/).
293
+
294
+ ## Help & Reference
295
+
296
+ ### Command Line Interface
297
+
298
+ Commitizen provides a comprehensive CLI with various commands. Here's the complete reference:
299
+
300
+ ![cz --help](images/cli_help/cz___help.svg)
301
+
302
+ ### Quick Reference
303
+
304
+ | Command | Description | Alias |
305
+ |---------|-------------|-------|
306
+ | `cz init` | Initialize Commitizen configuration | - |
307
+ | `cz commit` | Create a new commit | `cz c` |
308
+ | `cz bump` | Bump version and update changelog | - |
309
+ | `cz changelog` | Generate changelog | `cz ch` |
310
+ | `cz check` | Validate commit messages | - |
311
+ | `cz version` | Show version information | - |
312
+
313
+ ### Additional Resources
314
+
315
+ - [Conventional Commits Specification][conventional_commits]
316
+ - [Exit Codes Reference](https://commitizen-tools.github.io/commitizen/exit_codes/)
317
+ - [Configuration Guide](https://commitizen-tools.github.io/commitizen/config/)
318
+ - [Command Documentation](https://commitizen-tools.github.io/commitizen/commands/init/)
319
+
320
+ ### Getting Help
321
+
322
+ For each command, you can get detailed help by adding `--help`:
323
+
324
+ ```sh
325
+ cz commit --help
326
+ cz bump --help
327
+ cz changelog --help
328
+ ```
329
+
330
+ For more details, visit our [documentation site](https://commitizen-tools.github.io/commitizen/).
331
+
332
+ ## Setting up bash completion
333
+
334
+ Commitizen supports command-line completion through [argcomplete](https://kislyuk.github.io/argcomplete/), which is automatically installed as a dependency. This feature provides intelligent auto-completion for all Commitizen commands and options.
335
+
336
+ ### Supported Shells
337
+
338
+ - **Bash**: Full support
339
+ - **Zsh**: Limited support
340
+ - **Fish**: Limited support
341
+ - **Tcsh**: Limited support
342
+
343
+ ### Installation Methods
344
+
345
+ #### Global Installation (Recommended)
346
+
347
+ If you installed Commitizen globally (e.g., using `pipx` or `brew`), you can enable global completion:
348
+
349
+ ```bash
350
+ # Enable global completion for all Python applications
351
+ sudo activate-global-python-argcomplete
352
+ ```
353
+
354
+ #### User-Specific Installation
355
+
356
+ For a user-specific installation that persists across sessions:
357
+
358
+ ```bash
359
+ # Add to your shell's startup file (e.g., ~/.bashrc, ~/.zshrc)
360
+ register-python-argcomplete cz >> ~/.bashrc
361
+ ```
362
+
363
+ #### Temporary Installation
364
+
365
+ For one-time activation in your current shell session:
366
+
367
+ ```bash
368
+ # Activate completion for current session only
369
+ eval "$(register-python-argcomplete cz)"
370
+ ```
371
+
372
+ ### Verification
373
+
374
+ After installation, you can verify the completion is working by:
375
+
376
+ 1. Opening a new terminal session
377
+ 2. Typing `cz` followed by a space and pressing `TAB` twice
378
+ 3. You should see a list of available commands
379
+
380
+ For more detailed information about argcomplete configuration and troubleshooting, visit the [argcomplete documentation](https://kislyuk.github.io/argcomplete/).
381
+
382
+ ## Sponsors
383
+
384
+ These are our cool sponsors!
385
+
386
+ <!-- sponsors --><!-- sponsors -->
387
+
388
+ [conventional_commits]: https://www.conventionalcommits.org
389
+ [semver]: https://semver.org/
390
+ [keepchangelog]: https://keepachangelog.com/
391
+ [gitscm]: https://git-scm.com/downloads
392
+
@@ -1,7 +1,7 @@
1
1
  import logging
2
2
  import logging.config
3
3
 
4
- from colorama import init # type: ignore
4
+ from colorama import init
5
5
 
6
6
  from commitizen.cz.base import BaseCommitizen
7
7
 
@@ -0,0 +1 @@
1
+ __version__ = "4.8.4"
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  import os
4
4
  import re
5
5
  from collections import OrderedDict
6
+ from collections.abc import Iterable
6
7
  from glob import iglob
7
8
  from logging import getLogger
8
9
  from string import Template
@@ -61,7 +62,7 @@ def find_increment(
61
62
  def update_version_in_files(
62
63
  current_version: str,
63
64
  new_version: str,
64
- files: list[str],
65
+ files: Iterable[str],
65
66
  *,
66
67
  check_consistency: bool = False,
67
68
  encoding: str = ENCODING,
@@ -76,7 +77,7 @@ def update_version_in_files(
76
77
  """
77
78
  # TODO: separate check step and write step
78
79
  updated = []
79
- for path, regex in files_and_regexs(files, current_version):
80
+ for path, regex in _files_and_regexes(files, current_version):
80
81
  current_version_found, version_file = _bump_with_regex(
81
82
  path,
82
83
  current_version,
@@ -99,21 +100,22 @@ def update_version_in_files(
99
100
  return updated
100
101
 
101
102
 
102
- def files_and_regexs(patterns: list[str], version: str) -> list[tuple[str, str]]:
103
+ def _files_and_regexes(patterns: Iterable[str], version: str) -> list[tuple[str, str]]:
103
104
  """
104
105
  Resolve all distinct files with their regexp from a list of glob patterns with optional regexp
105
106
  """
106
- out = []
107
+ out: set[tuple[str, str]] = set()
107
108
  for pattern in patterns:
108
109
  drive, tail = os.path.splitdrive(pattern)
109
110
  path, _, regex = tail.partition(":")
110
111
  filepath = drive + path
111
112
  if not regex:
112
- regex = _version_to_regex(version)
113
+ regex = re.escape(version)
113
114
 
114
- for path in iglob(filepath):
115
- out.append((path, regex))
116
- return sorted(list(set(out)))
115
+ for file in iglob(filepath):
116
+ out.add((file, regex))
117
+
118
+ return sorted(out)
117
119
 
118
120
 
119
121
  def _bump_with_regex(
@@ -128,18 +130,16 @@ def _bump_with_regex(
128
130
  pattern = re.compile(regex)
129
131
  with open(version_filepath, encoding=encoding) as f:
130
132
  for line in f:
131
- if pattern.search(line):
132
- bumped_line = line.replace(current_version, new_version)
133
- if bumped_line != line:
134
- current_version_found = True
135
- lines.append(bumped_line)
136
- else:
133
+ if not pattern.search(line):
137
134
  lines.append(line)
138
- return current_version_found, "".join(lines)
135
+ continue
139
136
 
137
+ bumped_line = line.replace(current_version, new_version)
138
+ if bumped_line != line:
139
+ current_version_found = True
140
+ lines.append(bumped_line)
140
141
 
141
- def _version_to_regex(version: str) -> str:
142
- return version.replace(".", r"\.").replace("+", r"\+")
142
+ return current_version_found, "".join(lines)
143
143
 
144
144
 
145
145
  def create_commit_message(
@@ -29,10 +29,10 @@ from __future__ import annotations
29
29
 
30
30
  import re
31
31
  from collections import OrderedDict, defaultdict
32
- from collections.abc import Iterable
32
+ from collections.abc import Generator, Iterable, Mapping, Sequence
33
33
  from dataclasses import dataclass
34
34
  from datetime import date
35
- from typing import TYPE_CHECKING
35
+ from typing import TYPE_CHECKING, Any
36
36
 
37
37
  from jinja2 import (
38
38
  BaseLoader,
@@ -63,7 +63,7 @@ class Metadata:
63
63
  latest_version_position: int | None = None
64
64
  latest_version_tag: str | None = None
65
65
 
66
- def __post_init__(self):
66
+ def __post_init__(self) -> None:
67
67
  if self.latest_version and not self.latest_version_tag:
68
68
  # Test syntactic sugar
69
69
  # latest version tag is optional if same as latest version
@@ -84,7 +84,7 @@ def generate_tree_from_commits(
84
84
  changelog_message_builder_hook: MessageBuilderHook | None = None,
85
85
  changelog_release_hook: ChangelogReleaseHook | None = None,
86
86
  rules: TagRules | None = None,
87
- ) -> Iterable[dict]:
87
+ ) -> Generator[dict[str, Any], None, None]:
88
88
  pat = re.compile(changelog_pattern)
89
89
  map_pat = re.compile(commit_parser, re.MULTILINE)
90
90
  body_map_pat = re.compile(commit_parser, re.MULTILINE | re.DOTALL)
@@ -169,8 +169,8 @@ def process_commit_message(
169
169
  commit: GitCommit,
170
170
  changes: dict[str | None, list],
171
171
  change_type_map: dict[str, str] | None = None,
172
- ):
173
- message: dict = {
172
+ ) -> None:
173
+ message: dict[str, Any] = {
174
174
  "sha1": commit.rev,
175
175
  "parents": commit.parents,
176
176
  "author": commit.author,
@@ -187,24 +187,27 @@ def process_commit_message(
187
187
  changes[change_type].append(msg)
188
188
 
189
189
 
190
- def order_changelog_tree(tree: Iterable, change_type_order: list[str]) -> Iterable:
190
+ def generate_ordered_changelog_tree(
191
+ tree: Iterable[Mapping[str, Any]], change_type_order: list[str]
192
+ ) -> Generator[dict[str, Any], None, None]:
191
193
  if len(set(change_type_order)) != len(change_type_order):
192
194
  raise InvalidConfigurationError(
193
- f"Change types contain duplicates types ({change_type_order})"
195
+ f"Change types contain duplicated types ({change_type_order})"
194
196
  )
195
197
 
196
- sorted_tree = []
197
198
  for entry in tree:
198
- ordered_change_types = change_type_order + sorted(
199
- set(entry["changes"].keys()) - set(change_type_order)
200
- )
201
- changes = [
202
- (ct, entry["changes"][ct])
203
- for ct in ordered_change_types
204
- if ct in entry["changes"]
205
- ]
206
- sorted_tree.append({**entry, **{"changes": OrderedDict(changes)}})
207
- return sorted_tree
199
+ yield {
200
+ **entry,
201
+ "changes": _calculate_sorted_changes(change_type_order, entry["changes"]),
202
+ }
203
+
204
+
205
+ def _calculate_sorted_changes(
206
+ change_type_order: list[str], changes: Mapping[str, Any]
207
+ ) -> OrderedDict[str, Any]:
208
+ remaining_change_types = set(changes.keys()) - set(change_type_order)
209
+ sorted_change_types = change_type_order + sorted(remaining_change_types)
210
+ return OrderedDict((ct, changes[ct]) for ct in sorted_change_types if ct in changes)
208
211
 
209
212
 
210
213
  def get_changelog_template(loader: BaseLoader, template: str) -> Template:
@@ -222,7 +225,7 @@ def render_changelog(
222
225
  tree: Iterable,
223
226
  loader: BaseLoader,
224
227
  template: str,
225
- **kwargs,
228
+ **kwargs: Any,
226
229
  ) -> str:
227
230
  jinja_template = get_changelog_template(loader, template)
228
231
  changelog: str = jinja_template.render(tree=tree, **kwargs)
@@ -279,7 +282,7 @@ def incremental_build(
279
282
 
280
283
 
281
284
  def get_smart_tag_range(
282
- tags: list[GitTag], newest: str, oldest: str | None = None
285
+ tags: Sequence[GitTag], newest: str, oldest: str | None = None
283
286
  ) -> list[GitTag]:
284
287
  """Smart because it finds the N+1 tag.
285
288
 
@@ -305,10 +308,10 @@ def get_smart_tag_range(
305
308
 
306
309
 
307
310
  def get_oldest_and_newest_rev(
308
- tags: list[GitTag],
311
+ tags: Sequence[GitTag],
309
312
  version: str,
310
313
  rules: TagRules,
311
- ) -> tuple[str | None, str | None]:
314
+ ) -> tuple[str | None, str]:
312
315
  """Find the tags for the given version.
313
316
 
314
317
  `version` may come in different formats:
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import sys
4
- from typing import ClassVar, Protocol
4
+ from typing import Callable, ClassVar, Protocol
5
5
 
6
6
  if sys.version_info >= (3, 10):
7
7
  from importlib import metadata
@@ -25,7 +25,7 @@ class ChangelogFormat(Protocol):
25
25
 
26
26
  config: BaseConfig
27
27
 
28
- def __init__(self, config: BaseConfig):
28
+ def __init__(self, config: BaseConfig) -> None:
29
29
  self.config = config
30
30
 
31
31
  @property
@@ -64,10 +64,9 @@ def get_changelog_format(
64
64
  :raises FormatUnknown: if a non-empty name is provided but cannot be found in the known formats
65
65
  """
66
66
  name: str | None = config.settings.get("changelog_format")
67
- format: type[ChangelogFormat] | None = guess_changelog_format(filename)
68
-
69
- if name and name in KNOWN_CHANGELOG_FORMATS:
70
- format = KNOWN_CHANGELOG_FORMATS[name]
67
+ format = (
68
+ name and KNOWN_CHANGELOG_FORMATS.get(name) or _guess_changelog_format(filename)
69
+ )
71
70
 
72
71
  if not format:
73
72
  raise ChangelogFormatUnknown(f"Unknown changelog format '{name}'")
@@ -75,7 +74,7 @@ def get_changelog_format(
75
74
  return format(config)
76
75
 
77
76
 
78
- def guess_changelog_format(filename: str | None) -> type[ChangelogFormat] | None:
77
+ def _guess_changelog_format(filename: str | None) -> type[ChangelogFormat] | None:
79
78
  """
80
79
  Try guessing the file format from the filename.
81
80
 
@@ -91,3 +90,9 @@ def guess_changelog_format(filename: str | None) -> type[ChangelogFormat] | None
91
90
  if filename.endswith(f".{alt_extension}"):
92
91
  return format
93
92
  return None
93
+
94
+
95
+ def __getattr__(name: str) -> Callable[[str], type[ChangelogFormat] | None]:
96
+ if name == "guess_changelog_format":
97
+ return _guess_changelog_format
98
+ raise AttributeError(f"module {__name__} has no attribute {name}")
@@ -20,7 +20,7 @@ class BaseFormat(ChangelogFormat, metaclass=ABCMeta):
20
20
  extension: ClassVar[str] = ""
21
21
  alternative_extensions: ClassVar[set[str]] = set()
22
22
 
23
- def __init__(self, config: BaseConfig):
23
+ def __init__(self, config: BaseConfig) -> None:
24
24
  # Constructor needs to be redefined because `Protocol` prevent instantiation by default
25
25
  # See: https://bugs.python.org/issue44807
26
26
  self.config = config