René's URL Explorer Experiment


Title: feat(init): discover third-party version providers via entry points by bearomorphism · Pull Request #1971 · commitizen-tools/commitizen · GitHub

Open Graph Title: feat(init): discover third-party version providers via entry points by bearomorphism · Pull Request #1971 · commitizen-tools/commitizen

X Title: feat(init): discover third-party version providers via entry points by bearomorphism · Pull Request #1971 · commitizen-tools/commitizen

Description: Description Closes #1258. Why cz init interactively asks the user to pick a version_provider. The picker's options were hard-coded to the eight built-in providers (commitizen, cargo, composer, npm, pep621, poetry, uv, scm), even though commitizen already supports third-party providers via the commitizen.provider entry-point group at runtime (commitizen/providers/__init__.py:get_provider). The mismatch meant a user who installed e.g. commitizen-deno-provider had to either know the provider name from memory and hand-edit the config, or skip cz init entirely. The original reporter offered the implementation sketch. What changed File Change commitizen/commands/init.py _VERSION_PROVIDER_CHOICES (a tuple of questionary.Choice) is replaced by _BUILTIN_VERSION_PROVIDER_OPTIONS (data-only) and a new _construct_version_provider_choices() helper that builds the picker list at call time. _ask_version_provider() now invokes that helper. tests/commands/test_init_command.py Three new tests: built-ins-only, third-party-discovered, duplicate-third-party-deduped. docs/config/version_provider.md One-paragraph note in the "Custom Provider Plugins" section explaining that cz init now surfaces the plugin once installed. How it works Built-ins still come first, with curated descriptions. The _BUILTIN_VERSION_PROVIDER_OPTIONS tuple keeps the human-readable labels (e.g. "pep621: Get and set version from pyproject.toml:project.version field") instead of falling back to a generic suffix. Third-party providers are discovered, never loaded. Only ep.name is read; ep.load() is not called, so installing a malicious cz_* plugin can't execute its module just because the user opened cz init. Two layers of dedup, both necessary: The eight built-ins are themselves registered under [project.entry-points."commitizen.provider"] in pyproject.toml:73-81. A naive listing would yield each one twice. We seed seen_names with the built-in set and skip any entry-point name already in it. Two distributions can register a third-party provider under the same name (e.g. two unrelated forks both publishing cz_jira). After the first occurrence is added we mark the name seen and skip the rest. We deliberately don't try to merge the duplicates: commitizen.providers.get_provider() raises VersionProviderUnknown when more than one entry point matches, so the user picking the duplicated name gets a clear error instead of the picker silently choosing whichever distribution loaded first. No registry caching. Each cz init invocation re-reads the entry-point group, so a provider installed mid-shell-session is picked up immediately. Backward compatibility Users without any third-party plugin see exactly the same picker as v4.15.1 (same eight built-ins, same order, same titles). The function signature change is internal (_VERSION_PROVIDER_CHOICES was a leading-underscore module global, never exported). Checklist I have read the contributing guidelines Was generative AI tooling used to co-author this PR? Yes (please specify the tool below) Generated-by: Claude following the guidelines Code Changes Add test cases to all the changes you introduce (3 new tests, see the targeted commands below) Run uv run poe all locally to ensure this change passes linter check and tests (poe lint clean; 33/33 init tests pass) Manually test the changes (see "Steps to Test" below) Update the documentation for the changes Documentation Changes Added a paragraph about auto-discovery to docs/config/version_provider.md Run uv run poe doc locally to ensure the documentation pages render correctly Check and fix any broken links (internal or external) Expected Behavior Scenario Outcome cz init with no third-party providers installed Same eight built-in choices, same order, same descriptions as before. cz init with a third-party plugin installed (e.g. commitizen-deno-provider exposing commitizen.provider -> deno) The eight built-ins appear first, then deno: third-party version provider. Selecting it writes version_provider = "deno" to pyproject.toml. Two installed distributions both register commitizen.provider -> dup dup appears once in the picker. Selecting it surfaces the existing VersionProviderUnknown error from get_provider() so the conflict is loud, not silent. Steps to Test This Pull Request git fetch fork feat/1258-init-discover-providers git checkout fork/feat/1258-init-discover-providers # 1. Built-ins-only test (no plugins installed): all eight present, none labelled third-party. uv run pytest tests/commands/test_init_command.py::test_construct_version_provider_choices_includes_builtins -v # 2. Third-party-discovered test: a fake EntryPoint("my-third-party") is patched in. uv run pytest tests/commands/test_init_command.py::test_construct_version_provider_choices_discovers_third_party -v # 3. Duplicate-third-party-deduped test: two EntryPoint(name="duplicated") -> only one choice. uv run pytest tests/commands/test_init_command.py::test_construct_version_provider_choices_dedupes_duplicate_third_party -v # 4. Full init suite (32 pre-existing + 1 new dedup test). uv run pytest tests/commands/test_init_command.py -q # expected: 33 passed Additional Context Surfaced while triaging open issues in #1965. The implementation follows the original reporter's sketch but uses a single discover-on-call function and dedupes against the built-in list rather than building a separate registry. The duplicate-name handling was added in fixup commit 1bad9047 after a GitHub Copilot review pass flagged it as a potential UX gap.

Open Graph Description: Description Closes #1258. Why cz init interactively asks the user to pick a version_provider. The picker's options were hard-coded to the eight built-in providers (commitizen, cargo, composer, ...

X Description: Description Closes #1258. Why cz init interactively asks the user to pick a version_provider. The picker's options were hard-coded to the eight built-in providers (commitizen, cargo, compos...

Opengraph URL: https://github.com/commitizen-tools/commitizen/pull/1971

X: @github

direct link

Domain: github.com

route-pattern/:user_id/:repository/pull/:id/files(.:format)
route-controllerpull_requests
route-actionfiles
fetch-noncev2:b64a2d99-d699-808c-5de3-d85db75a2209
current-catalog-service-hashae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b
request-id9E24:38592C:F61FEC:16725E9:6A4E354A
html-safe-nonceed37ad416927b33f8843ee9af4a66167e0745948ed4b767faa088c1f04cccd76
visitor-payloadeyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI5RTI0OjM4NTkyQzpGNjFGRUM6MTY3MjVFOTo2QTRFMzU0QSIsInZpc2l0b3JfaWQiOiIyNjIyOTI1NTEyODU5NTk2MTA2IiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0=
visitor-hmacb8e48fd6177806a65ccc45f73aa796b05da8cc9424900882e33f9d8e906601d8
hovercard-subject-tagpull_request:3654708065
github-keyboard-shortcutsrepository,pull-request-list,pull-request-conversation,pull-request-files-changed,copilot
google-site-verificationApib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I
octolytics-urlhttps://collector.github.com/github/collect
analytics-location///pull_requests/show/files
fb:app_id1401488693436528
apple-itunes-appapp-id=1477376905, app-argument=https://github.com/commitizen-tools/commitizen/pull/1971/files
twitter:imagehttps://avatars.githubusercontent.com/u/26526132?s=400&v=4
twitter:cardsummary_large_image
og:imagehttps://avatars.githubusercontent.com/u/26526132?s=400&v=4
og:image:altDescription Closes #1258. Why cz init interactively asks the user to pick a version_provider. The picker's options were hard-coded to the eight built-in providers (commitizen, cargo, composer, ...
og:site_nameGitHub
og:typeobject
hostnamegithub.com
expected-hostnamegithub.com
None030096ee0db095447bfe77409d33bfac127ca7128299c58deef27c52eaa1b1f0
turbo-cache-controlno-preview
diff-viewunified
go-importgithub.com/commitizen-tools/commitizen git https://github.com/commitizen-tools/commitizen.git
octolytics-dimension-user_id62252524
octolytics-dimension-user_logincommitizen-tools
octolytics-dimension-repository_id106127589
octolytics-dimension-repository_nwocommitizen-tools/commitizen
octolytics-dimension-repository_publictrue
octolytics-dimension-repository_is_forkfalse
octolytics-dimension-repository_network_root_id106127589
octolytics-dimension-repository_network_root_nwocommitizen-tools/commitizen
turbo-body-classeslogged-out env-production page-responsive full-width
disable-turbotrue
browser-stats-urlhttps://api.github.com/_private/browser/stats
browser-errors-urlhttps://api.github.com/_private/browser/errors
release42a6d378d7587a44c93aca255096cd66b7c8eb2d
ui-targetfull
theme-color#1e2327
color-schemelight dark

Links:

Skip to contenthttps://github.com/commitizen-tools/commitizen/pull/1971/files#start-of-content
https://github.com/
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fcommitizen-tools%2Fcommitizen%2Fpull%2F1971%2Ffiles
GitHub CopilotWrite better code with AIhttps://github.com/features/copilot
GitHub Copilot appDirect agents from issue to mergehttps://github.com/features/ai/github-app
MCP RegistryNewIntegrate external toolshttps://github.com/mcp
ActionsAutomate any workflowhttps://github.com/features/actions
CodespacesInstant dev environmentshttps://github.com/features/codespaces
IssuesPlan and track workhttps://github.com/features/issues
Code ReviewManage code changeshttps://github.com/features/code-review
GitHub Advanced SecurityFind and fix vulnerabilitieshttps://github.com/security/advanced-security
Code securitySecure your code as you buildhttps://github.com/security/advanced-security/code-security
Secret protectionStop leaks before they starthttps://github.com/security/advanced-security/secret-protection
Why GitHubhttps://github.com/why-github
Documentationhttps://docs.github.com
Bloghttps://github.blog
Changeloghttps://github.blog/changelog
Marketplacehttps://github.com/marketplace
View all featureshttps://github.com/features
Enterpriseshttps://github.com/enterprise
Small and medium teamshttps://github.com/team
Startupshttps://github.com/enterprise/startups
Nonprofitshttps://github.com/solutions/industry/nonprofits
App Modernizationhttps://github.com/solutions/use-case/app-modernization
DevSecOpshttps://github.com/solutions/use-case/devsecops
DevOpshttps://github.com/solutions/use-case/devops
CI/CDhttps://github.com/solutions/use-case/ci-cd
View all use caseshttps://github.com/solutions/use-case
Healthcarehttps://github.com/solutions/industry/healthcare
Financial serviceshttps://github.com/solutions/industry/financial-services
Manufacturinghttps://github.com/solutions/industry/manufacturing
Governmenthttps://github.com/solutions/industry/government
View all industrieshttps://github.com/solutions/industry
View all solutionshttps://github.com/solutions
AIhttps://github.com/resources/articles?topic=ai
Software Developmenthttps://github.com/resources/articles?topic=software-development
DevOpshttps://github.com/resources/articles?topic=devops
Securityhttps://github.com/resources/articles?topic=security
View all topicshttps://github.com/resources/articles
Customer storieshttps://github.com/customer-stories
Events & webinarshttps://github.com/resources/events
Ebooks & reportshttps://github.com/resources/whitepapers
Business insightshttps://github.com/solutions/executive-insights
GitHub Skillshttps://skills.github.com
Documentationhttps://docs.github.com
Customer supporthttps://support.github.com
Community forumhttps://github.com/orgs/community/discussions
Trust centerhttps://github.com/trust-center
Partnershttps://github.com/partners
View all resourceshttps://github.com/resources
GitHub SponsorsFund open source developershttps://github.com/sponsors
Security Labhttps://securitylab.github.com
Maintainer Communityhttps://maintainers.github.com
Acceleratorhttps://github.com/accelerator
GitHub Starshttps://stars.github.com
Archive Programhttps://archiveprogram.github.com
Topicshttps://github.com/topics
Trendinghttps://github.com/trending
Collectionshttps://github.com/collections
Enterprise platformAI-powered developer platformhttps://github.com/enterprise
GitHub Advanced SecurityEnterprise-grade security featureshttps://github.com/security/advanced-security
Copilot for BusinessEnterprise-grade AI featureshttps://github.com/features/copilot/copilot-business
Premium SupportEnterprise-grade 24/7 supporthttps://github.com/premium-support
Pricinghttps://github.com/pricing
Search syntax tipshttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
documentationhttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fcommitizen-tools%2Fcommitizen%2Fpull%2F1971%2Ffiles
Sign up https://github.com/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fpull_requests%2Fshow%2Ffiles&source=header-repo&source_repo=commitizen-tools%2Fcommitizen
Reloadhttps://github.com/commitizen-tools/commitizen/pull/1971/files
Reloadhttps://github.com/commitizen-tools/commitizen/pull/1971/files
Reloadhttps://github.com/commitizen-tools/commitizen/pull/1971/files
Please reload this pagehttps://github.com/commitizen-tools/commitizen/pull/1971/files
commitizen-tools https://github.com/commitizen-tools
commitizenhttps://github.com/commitizen-tools/commitizen
Please reload this pagehttps://github.com/commitizen-tools/commitizen/pull/1971/files
Notifications https://github.com/login?return_to=%2Fcommitizen-tools%2Fcommitizen
Fork 344 https://github.com/login?return_to=%2Fcommitizen-tools%2Fcommitizen
Star 3.5k https://github.com/login?return_to=%2Fcommitizen-tools%2Fcommitizen
Code https://github.com/commitizen-tools/commitizen
Issues 116 https://github.com/commitizen-tools/commitizen/issues
Pull requests 45 https://github.com/commitizen-tools/commitizen/pulls
Discussions https://github.com/commitizen-tools/commitizen/discussions
Actions https://github.com/commitizen-tools/commitizen/actions
Projects https://github.com/commitizen-tools/commitizen/projects
Security and quality 0 https://github.com/commitizen-tools/commitizen/security
Insights https://github.com/commitizen-tools/commitizen/pulse
Code https://github.com/commitizen-tools/commitizen
Issues https://github.com/commitizen-tools/commitizen/issues
Pull requests https://github.com/commitizen-tools/commitizen/pulls
Discussions https://github.com/commitizen-tools/commitizen/discussions
Actions https://github.com/commitizen-tools/commitizen/actions
Projects https://github.com/commitizen-tools/commitizen/projects
Security and quality https://github.com/commitizen-tools/commitizen/security
Insights https://github.com/commitizen-tools/commitizen/pulse
Sign up for GitHub https://github.com/signup?return_to=%2Fcommitizen-tools%2Fcommitizen%2Fissues%2Fnew%2Fchoose
terms of servicehttps://docs.github.com/terms
privacy statementhttps://docs.github.com/privacy
Sign inhttps://github.com/login?return_to=%2Fcommitizen-tools%2Fcommitizen%2Fissues%2Fnew%2Fchoose
bearomorphismhttps://github.com/bearomorphism
commitizen-tools:masterhttps://github.com/commitizen-tools/commitizen/tree/master
bearomorphism:feat/1258-init-discover-providershttps://github.com/bearomorphism/commitizen/tree/feat/1258-init-discover-providers
Conversation 5 https://github.com/commitizen-tools/commitizen/pull/1971
Commits 2 https://github.com/commitizen-tools/commitizen/pull/1971/commits
Checks 20 https://github.com/commitizen-tools/commitizen/pull/1971/checks
Files changed https://github.com/commitizen-tools/commitizen/pull/1971/files
Please reload this pagehttps://github.com/commitizen-tools/commitizen/pull/1971/files
feat(init): discover third-party version providers via entry points https://github.com/commitizen-tools/commitizen/pull/1971/files#top
Show all changes 2 commits https://github.com/commitizen-tools/commitizen/pull/1971/files
e4dcc5b feat(init): discover third-party version providers via entry points bearomorphism May 9, 2026 https://github.com/commitizen-tools/commitizen/pull/1971/commits/e4dcc5b34f9e37a09d632c0349ae8556761a111b
1bad904 fix(init): dedupe duplicate third-party provider names bearomorphism May 9, 2026 https://github.com/commitizen-tools/commitizen/pull/1971/commits/1bad9047d9558cad4658493a7c91ad5ad52609b4
Clear filters https://github.com/commitizen-tools/commitizen/pull/1971/files
Please reload this pagehttps://github.com/commitizen-tools/commitizen/pull/1971/files
Please reload this pagehttps://github.com/commitizen-tools/commitizen/pull/1971/files
init.py https://github.com/commitizen-tools/commitizen/pull/1971/files#diff-43bdf96da59e2edd79c3797ccaf86dda6495266c02768cb045502851ebb047e8
version_provider.md https://github.com/commitizen-tools/commitizen/pull/1971/files#diff-858ceb91db24e8cbfb35247d2f5afee31ffefc22fa871e13758efd11e530ebb6
test_init_command.py https://github.com/commitizen-tools/commitizen/pull/1971/files#diff-759a8a6bf7feb1609205e246cb3677d685be1cc8c1bad4bd558e22694ed56002
commitizen/commands/init.pyhttps://github.com/commitizen-tools/commitizen/pull/1971/files#diff-43bdf96da59e2edd79c3797ccaf86dda6495266c02768cb045502851ebb047e8
View file https://github.com/bearomorphism/commitizen/blob/1bad9047d9558cad4658493a7c91ad5ad52609b4/commitizen/commands/init.py
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/commitizen-tools/commitizen/pull/1971/{{ revealButtonHref }}
https://github.com/commitizen-tools/commitizen/pull/1971/files#diff-43bdf96da59e2edd79c3797ccaf86dda6495266c02768cb045502851ebb047e8
https://github.com/commitizen-tools/commitizen/pull/1971/files#diff-43bdf96da59e2edd79c3797ccaf86dda6495266c02768cb045502851ebb047e8
https://github.com/commitizen-tools/commitizen/pull/1971/files#diff-43bdf96da59e2edd79c3797ccaf86dda6495266c02768cb045502851ebb047e8
https://github.com/commitizen-tools/commitizen/pull/1971/files#diff-43bdf96da59e2edd79c3797ccaf86dda6495266c02768cb045502851ebb047e8
https://github.com/commitizen-tools/commitizen/pull/1971/files#diff-43bdf96da59e2edd79c3797ccaf86dda6495266c02768cb045502851ebb047e8
docs/config/version_provider.mdhttps://github.com/commitizen-tools/commitizen/pull/1971/files#diff-858ceb91db24e8cbfb35247d2f5afee31ffefc22fa871e13758efd11e530ebb6
View file https://github.com/bearomorphism/commitizen/blob/1bad9047d9558cad4658493a7c91ad5ad52609b4/docs/config/version_provider.md
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/commitizen-tools/commitizen/pull/1971/{{ revealButtonHref }}
https://github.com/commitizen-tools/commitizen/pull/1971/files#diff-858ceb91db24e8cbfb35247d2f5afee31ffefc22fa871e13758efd11e530ebb6
https://github.com/commitizen-tools/commitizen/pull/1971/files#diff-858ceb91db24e8cbfb35247d2f5afee31ffefc22fa871e13758efd11e530ebb6
tests/commands/test_init_command.pyhttps://github.com/commitizen-tools/commitizen/pull/1971/files#diff-759a8a6bf7feb1609205e246cb3677d685be1cc8c1bad4bd558e22694ed56002
View file https://github.com/bearomorphism/commitizen/blob/1bad9047d9558cad4658493a7c91ad5ad52609b4/tests/commands/test_init_command.py
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/commitizen-tools/commitizen/pull/1971/{{ revealButtonHref }}
https://github.com/commitizen-tools/commitizen/pull/1971/files#diff-759a8a6bf7feb1609205e246cb3677d685be1cc8c1bad4bd558e22694ed56002
https://github.com/commitizen-tools/commitizen/pull/1971/files#diff-759a8a6bf7feb1609205e246cb3677d685be1cc8c1bad4bd558e22694ed56002
Please reload this pagehttps://github.com/commitizen-tools/commitizen/pull/1971/files
https://github.com
Termshttps://docs.github.com/site-policy/github-terms/github-terms-of-service
Privacyhttps://docs.github.com/site-policy/privacy-policies/github-privacy-statement
Securityhttps://github.com/security
Statushttps://www.githubstatus.com/
Communityhttps://github.community/
Docshttps://docs.github.com/
Contacthttps://support.github.com?tags=dotcom-footer

Viewport: width=device-width


URLs of crawlers that visited me.