Deprecate the `cz_customize` convention and allow for overriding functionality
Description
Related: https://github.com/commitizen-tools/commitizen/pull/1381#issuecomment-2801394198
Back when cz_customize was introduced, it was a brand-new convention that required users to design it from scratch without touching Python code. This might not be what the term "customize" indicates and has confused lots of our users.
Possible Solution
- Rename
cz_customizeascz_emptyor something similar if we want to keep it - Allow existing conventions (e.g.,
cz_jira,cz_conventional_commit) to be overridden.
Additional context
No response
Additional context
No response
Hello. To start, I did a MR that adds customizing to conventional_commits. It can either be done to jira commitizen too, or moved to the base class, as you see fit.
I'm sorry for not getting back to you sooner. Crazy busy since July... (probably till mid Oct...) I have already assigned myself to take a look. Will try to do so when bandwidth allow. Thanks so much for helping out!
https://github.com/commitizen-tools/commitizen/issues/1588 has more details on the user requirements. But let's keep the discussion here :)
+1 to this as i'm facing this now. For our purposes I want to run a much more cut-down version of cz that simply:
- Only gives
feat,fix,test,docs,chore, as my options as these are our general use cases - skips all other questions except "Write a summary of the code changes" and then "Is this breaking change y/n"
I started on customizing this and got this far:
[tool.commitizen] # https://commitizen-tools.github.io/commitizen/config/
bump_message = "bump: v$current_version → v$new_version"
tag_format = "v$version"
update_changelog_on_bump = true
version_provider = "uv"
name = "cz_customize"
[[tool.commitizen.customize.questions]]
type = "list"
name = "change_type"
choices = [
{value = "feat", name = "feat: A new feature. Correlates with MINOR in SemVer"},
{value = "fix", name = "fix: A bug fix. Correlates with PATCH in SemVer"},
{value = "test", name = "test: Test Additions."},
{value = "docs", name = "docs: Documentation Additions."},
{value = "chore", name = "chore: Maintenance/cleanup work"}
]
message = "Select the type of change you are committing"
[[tool.commitizen.customize.questions]]
type = "input"
name = "message"
message = "Write a short and imperative summary of the code changes"
but it's simply not worth the amount of time I've put into this as I was hoping for something drop-in with easy customization and I gave up trying to figure out how to re-implement the "Breaking change y/n" feature.
At the bare minimum it would be nice to have in the docs the current default workflow re-created in cz_customize in .toml format so that users could quickly grab that and tweak it. as it is now I feel as if I am trying to re-invent the whole library to get some minor tweaks for myself. happy to contribute
reg this issue, should we update the doc to let people know we are deprecating this?
#1588 has more details on the user requirements. But let's keep the discussion here :)
That's precisely what I'm facing now too: I wanted to tweak the accepted change types, so I applied cz_customize and naively modified schema_pattern, expecting everything else would have worked just smoothly:
[tool.commitizen]
name = "cz_customize"
tag_format = "v$version"
version_scheme = "semver2"
version_provider = "scm"
major_version_zero = true
[tool.commitizen.customize]
schema_pattern = '''(?s)(build|bump|chore|ci|docs|feat|fix|perf|refactor|revert|style|test|mycustomtype)(\(\S+\))?!?: ([^\n\r]+)((\n\n.*)|(\s*))?$'''
Much to my surprise, that was NOT the case: cz commit (4.10.0) failed miserably (KeyError: 'type') :hushed:
Asking Copilot, it pointed out that the default configuration is hard-coded (!!) in the program (conventional_commits.py) and, in order for the customized configuration to work, it should provide also the other configuration pieces (questions, message_template, change_type_map/order or schema/schema_pattern)...
From a user perspective, that doesn't make sense: the customized configuration should be based on the default one, letting users override just the pieces they actually need — besides a much more straightforward customization, such arrangement would also allow to keep using the fresh settings provided by the program (for example, the default questions) instead of being forced to use statically declared pieces in the customized configuration.
All considered, here are my suggestions:
- declarative default configuration: move the default configuration from program code (conventional_commits.py) to a TOML configuration file — this would make inspection and reuse for customization much more straightforward, satisfying also what @ryanrapini-bep requested
- configuration overriding: let users customize just the pieces they actually need, instead of the whole bulky thing
I think we should go for configuration overriding.
This means: allowing the user to merge what they declare in the toml with the defined tool.commitizen.name.
I think most of the time, you want to pick up a "convention", like the default conventional_commits and tweak it.
cz_customize forces you to define everything in toml
Edit: Also, a nice to have, is that, by allowing this "override", it allows the convention to evolve more easily, as you can try new things and then move the upstream
And, to make the tweak more straightforward, the base configuration (like the default conventional_commits) should be available in serialized (TOML) format (instead of being hard-coded in the program, as it currently is!), so the relevant fragments can be directly copied and tweaked without further effort.
We can document an example. But we are not changing how it works: conventional_commits is one of the "conventions" that come by default with commitizen, but teams can write their own. The whole idea of commitizen is that you can write your own (in python) and publish the package:
https://commitizen-tools.github.io/commitizen/third-party-commitizen/
The idea of this feature, is that you can override the one you set to your project.
Yet it would be nice if the in-memory representation of those conventions could be exported in serialized (TOML) format, rather than requiring users to reverse-engineer their codebase to figure out their actual definition (an example in the documentation is just a dead fragment without bond to the actual implementation).
reg this issue, should we update the doc to let people know we are deprecating this?
@bearomorphism yep, good idea!
But we are not changing how it works: conventional_commits is one of the "conventions" that come by default with commitizen
This is basically why cz_customize worked the way it did back then. It's a new type of convention that does nothing and expects the user to define what they want. It makes more sense to make it something like cz_empty and allow overriding functionality.
Yet it would be nice if the in-memory representation of those conventions could be exported in serialized (TOML) format, rather than requiring users to reverse-engineer their codebase to figure out their actual definition (an example in the documentation is just a dead fragment without bond to the actual implementation).
We should make it as configurable as possible, if it's easy and maintainable. It wasn't designed this way, maybe because it wasn't easy to serialize them.
@Lee-W Should we remove cz_customize from our pyproject.toml first?
@Lee-W Should we remove
cz_customizefrom ourpyproject.tomlfirst?
not really, we should support it till v5
Yet it would be nice if the in-memory representation of those conventions could be exported in serialized (TOML) format
I think we could have something like cz convention show or cz show (TBD) with a flag --format where you can export the convention set in the config.