repomatic.templating module¶

Load and render the markdown templates of repomatic/templates/.

A template is a markdown body with optional YAML frontmatter. The body uses string.Template placeholders ($variable), which leave markdown braces like [tool.repomatic] alone. The frontmatter carries what an operation needs besides the body: the args the body takes, and, for a template that fronts a pull request, its title, commit_message, labels, draft state and docs link.

PrTemplate parses a template once and answers every question about it. render_template() renders one or more templates into one document, with the attribution footer.

Note

A template is also read from a Path. Downstream repos ship project-specific templates and feed them through repomatic pr-sync –template-file path/to/template.md``(with one or more`–template-arg KEY=VALUE` entries to fill the placeholders) without forking repomatic. Such a template sets footer: false in its frontmatter: the metadata block of a pull request body already carries the attribution footer.

repomatic.templating.TEMPLATE_PACKAGE = 'repomatic.templates'¶

The package holding the bundled templates.

repomatic.templating.TEMPLATE_SUFFIXES = ('.md.noformat', '.md')¶

Extensions of a template file, in lookup order.

.md.noformat hides a template from mdformat, whose list parser reads a placeholder at the head of a list line ($rerun_entry- **Ref**) as literal text and breaks the list. pr-metadata.md.noformat is the canonical example.

repomatic.templating.FOOTER_TEMPLATE = 'generated-footer'¶

The template holding the attribution footer render_template() appends.

repomatic.templating.footer_opted_out(meta)[source]¶

Whether a template’s frontmatter opts out of the attribution footer.

A template opts out with footer: false. Both the boolean and the quoted string are honored: the frontmatter is YAML, so a bare false parses as a boolean, but a downstream template may well have quoted it, and the two spellings mean the same thing to whoever wrote them. An absent field keeps the footer. repomatic.lint_repo.workflows.check_pr_templates() applies the same rule, so it never flags a spelling the renderer honors.

Parameters:

meta (Mapping[str, object]) – Parsed frontmatter of one template.

Return type:

bool

Returns:

True when the template drops the footer.

repomatic.templating.template_stem(filename)[source]¶

Return a template’s name, shorn of its .md or .md.noformat extension.

The one place that knows how template filenames decompose: .md.noformat files are renamed .md files hidden from mdformat (see TEMPLATE_SUFFIXES), so both extensions strip down to the same name.

Parameters:

filename (str) – A template file’s basename.

Return type:

str

Returns:

The name with neither extension.

repomatic.templating.get_template_names()[source]¶

Discover all available template names from the templates package.

Return type:

list[str]

Returns:

Sorted list of template names (without extension).

class repomatic.templating.PrTemplate(name, meta, body)[source]¶

Bases: object

One template, parsed once: its frontmatter and its body.

Every question about a template reads the same parse: the bundled ones are loaded once per process by load(), and one pull request sync asks a template for its title, commit message, labels, draft state, docs link and body.

name: str¶

The template’s name: the bundled name, or the stem of an external file.

Also the default branch of the pull request it fronts, and the label of the documentation link in its metadata block.

meta: Mapping[str, object]¶

The parsed frontmatter, read-only.

body: str¶

The markdown body, with mdformat’s $ escapes undone.

classmethod load(ref)[source]¶

Load a template by bundled name or by filesystem path.

A str (like "bump-version") names a bundled template, looked up under each of TEMPLATE_SUFFIXES in turn and cached for the process. A Path is read from disk on every call, so a downstream repo iterating on its own template sees each edit.

Parameters:

ref (str | Path) – Template name without extension, or a template file path.

Raises:

FileNotFoundError – If neither resource nor file exists.

Return type:

PrTemplate

property args: tuple[str, ...]¶

The placeholder names the frontmatter args field declares.

property labels: tuple[str, ...]¶

The labels the template’s pull request carries.

Read from the labels: frontmatter key, accepting a YAML list or a single string. The template is the one place that knows which operation it fronts, so its labels live beside its title and commit message rather than in every workflow step that opens the pull request.

property draft: bool¶

Whether the template’s pull request is held in draft.

Both the YAML boolean and its quoted spelling are honored, mirroring footer_opted_out().

property docs_url: str¶

The template’s documentation deep link, empty when it declares none.

A pull request template carries a docs: field pointing at its job’s section of the hosted workflows reference, surfaced as the Documentation entry of the metadata block.

Whether rendering appends the attribution footer.

See footer_opted_out() for the frontmatter that drops it.

title(**kwargs)[source]¶

Render the frontmatter title, empty when the template has none.

Parameters:

kwargs (str | None) – Variables to substitute into the title.

Return type:

str

commit_message(**kwargs)[source]¶

Render the frontmatter commit_message, falling back to the title.

Empty when the template defines neither: a template without them only renders a body.

Parameters:

kwargs (str | None) – Variables to substitute into the commit message.

Return type:

str

render_body(**kwargs)[source]¶

Render the body alone, stripped, without the attribution footer.

Parameters:

kwargs (str | None) – Variables to substitute into the body.

Return type:

str

repomatic.templating.render_template(*refs, **kwargs)[source]¶

Load and render one or more templates with variable substitution.

When several templates are given, each is rendered and joined with a blank line. The generated-footer attribution is appended once at the end if any of the templates wants it (see PrTemplate.wants_footer).

Consecutive blank lines left by empty variables are collapsed to a single blank line.

Note

The footer’s version is __version__ as read from the working tree, which makes it cosmetically wrong on the version-machinery PRs. That is accepted rather than fixed. Upstream runs the CLI from its own checkout (local_cli_invocation()), and both the bump-version and prepare-release jobs rewrite __version__ with bump-my-version before this renders, so each of those bodies advertises the version its own PR produces (the minor or major bump target, or the post-release patch bump) instead of the identical code that rendered it. Both fixes cost more than the tag is worth: rendering the body before the bump means splitting pr-body back out of pr-sync, and feeding the pre-bump version in means a CLI option that exists only to work around step ordering. Downstream never sees it, since a frozen workflow runs uvx 'repomatic==X.Y.Z' and takes its version from the installed distribution.

Parameters:
  • refs (str | Path | PrTemplate) – Template names (without extension), template file paths, or templates already loaded.

  • kwargs (str | None) – Variables to substitute into all templates.

Return type:

str

Returns:

The rendered markdown string.