Skip to content

Commit 6dda294

Browse files
docs(agents): fix incorrect playbook examples
Validation against the actual source code surfaced three inaccuracies: * add-version-provider.md: `composer_provider.py` was labelled `JSON file with non-standard layout`, but it is actually the simplest `JsonProvider` (just `filename` and `indent`). Replace with `npm_provider.py` for the non-standard layout / multi-file case, and re-introduce composer as the simplest-case example. * add-changelog-format.md: pointed agents at `restructuredtext.py` as an example of overriding only `parse_version_from_title` + `parse_title_level`. RST actually overrides `get_metadata_from_file` because its titles span multiple lines. Re-route the line-anchored example to `markdown.py` / `asciidoc.py` / `textile.py` and keep RST as the multi-line example. Add the multi-line escape hatch to Step 2 and clarify that the template extension comes from the class attribute, not the format name. * architecture.md: claimed entry points are loaded `lazily`. Only providers are looked up at call time; `KNOWN_CHANGELOG_FORMATS` is populated at module import time. Drop the misleading qualifier. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent ac589a8 commit 6dda294

3 files changed

Lines changed: 12 additions & 9 deletions

File tree

docs/contributing/agents/playbooks/add-changelog-format.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,23 @@ Architectural context: [Architecture § Extension points](../../architecture.md#
1313
## Read first
1414

1515
- `commitizen/changelog_formats/__init__.py``ChangelogFormat` Protocol, entry-point group `commitizen.changelog_format`, `KNOWN_CHANGELOG_FORMATS` registry, `_guess_changelog_format` extension-based fallback.
16-
- `commitizen/changelog_formats/base.py:BaseFormat`abstract implementation; you only need to override `parse_version_from_title` and `parse_title_level`.
16+
- `commitizen/changelog_formats/base.py:BaseFormat`provides a default `get_metadata_from_file` that walks the file once for **line-anchored** titles. You override `parse_version_from_title` and `parse_title_level` to fit your markup.
1717
- A close-match existing format:
18-
- Heading-prefix-based: `commitizen/changelog_formats/markdown.py` (uses `#`, `##` prefixes).
19-
- Underline-based: `commitizen/changelog_formats/restructuredtext.py` (uses `===`, `---` lines).
20-
- `commitizen/templates/` — Jinja2 templates named `CHANGELOG.<ext>.j2` control rendering.
18+
- Line-anchored heading prefix (`#`, `=`, `h1.`): `commitizen/changelog_formats/markdown.py`, `asciidoc.py`, or `textile.py` — each overrides only the two `parse_*` methods.
19+
- Multi-line titles (overline/underline, as in reStructuredText): `commitizen/changelog_formats/restructuredtext.py` — overrides `get_metadata_from_file` directly because the base class assumes one-line titles.
20+
- `commitizen/templates/` — Jinja2 templates named `CHANGELOG.<ext>.j2` (e.g. `CHANGELOG.md.j2`, `CHANGELOG.rst.j2`, `CHANGELOG.adoc.j2`); the file extension comes from the `extension` class attribute, not the format name.
2121
- `tests/test_changelog_format_<name>.py` — every format has parity tests; copy the closest one.
2222

2323
## Steps
2424

2525
1. **Create the format module** at `commitizen/changelog_formats/<name>.py`. Subclass `BaseFormat`. Set the class attributes:
2626
- `extension: ClassVar[str]` — primary file extension (no dot).
2727
- `alternative_extensions: ClassVar[set[str]]` — other accepted extensions for the same format.
28-
2. **Implement two methods**:
28+
2. **Implement two methods** for line-anchored formats:
2929
- `parse_version_from_title(line: str) -> VersionTag | None` — given one line, return a `VersionTag` if the line is a release heading.
3030
- `parse_title_level(line: str) -> int | None` — return the heading level (1, 2, 3, ...) if the line is a heading. The base class `BaseFormat.get_metadata_from_file` walks the file once and calls both methods per line.
31+
32+
If your format's titles span multiple lines (overline/title/underline, as in reStructuredText), override `get_metadata_from_file` directly instead — see `RestructuredText` for the algorithm.
3133
3. **Add the Jinja2 template** at `commitizen/templates/CHANGELOG.<ext>.j2`. Mirror the structure of `CHANGELOG.md.j2` — same blocks, different markup. Make sure the loops over `tree`, `entries`, and `change_type` match.
3234
4. **Register the built-in** in `pyproject.toml` under `[project.entry-points."commitizen.changelog_format"]`:
3335

docs/contributing/agents/playbooks/add-version-provider.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ Architectural context: [Architecture § Extension points](../../architecture.md#
1515
- `commitizen/providers/__init__.py` — registration helper `get_provider`, entry-point group `commitizen.provider`, default provider name.
1616
- `commitizen/providers/base_provider.py``VersionProvider`, `FileProvider`, `JsonProvider`, `TomlProvider` base classes.
1717
- An existing provider that resembles your target:
18-
- JSON file with non-standard layout: `commitizen/providers/composer_provider.py`
19-
- TOML file with multi-file updates: `commitizen/providers/uv_provider.py`
20-
- SCM tag-based, no file write: `commitizen/providers/scm_provider.py`
18+
- Simplest JSON case (single file, top-level `version` key): `commitizen/providers/composer_provider.py` — only sets `filename` and `indent`.
19+
- JSON with multi-file updates (package + lockfile + shrinkwrap): `commitizen/providers/npm_provider.py` — overrides `get_version`/`set_version`.
20+
- TOML with multi-file updates (`pyproject.toml` + `uv.lock`): `commitizen/providers/uv_provider.py`.
21+
- SCM tag-based, no file write: `commitizen/providers/scm_provider.py`.
2122
- Test for the closest existing provider: `tests/providers/test_<name>_provider.py`.
2223
- `commitizen/config/base_config.py:BaseConfig` — what your provider's `__init__(config)` will receive.
2324

docs/contributing/architecture.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Commitizen is plugin-friendly. Four kinds of extensions can be registered by ext
3737
| Version scheme | `commitizen.scheme` | `pep440`, `semver`, `semver2` | `commitizen/version_schemes.py:VersionProtocol` |
3838
| Changelog format | `commitizen.changelog_format` | `markdown`, `asciidoc`, `textile`, `restructuredtext` | `commitizen/changelog_formats/base.py:BaseFormat` |
3939

40-
Each kind is loaded lazily via `importlib.metadata.entry_points(...)`. To add a new built-in implementation you register it in `pyproject.toml` under the appropriate `[project.entry-points."..."]` table.
40+
Each kind is registered as a Python entry point and resolved through `importlib.metadata.entry_points(...)`. To add a new built-in implementation you register it in `pyproject.toml` under the appropriate `[project.entry-points."..."]` table.
4141

4242
End-user documentation for these extension points lives elsewhere — see [Version Provider](../config/version_provider.md), [Customized Python Class](../customization/python_class.md), and [Changelog Template](../customization/changelog_template.md). This page focuses on where the source lives and how it is wired together.
4343

0 commit comments

Comments
 (0)