repomatic.tabular module

Row type a committed store materializes into.

class repomatic.tabular.RecordT

Row type a committed store materializes into.

alias of TypeVar(‘RecordT’)

repomatic.tabular.render_csv(headers, rows)[source]

Render a header row and its data rows as CSV text.

Newlines are \n on every platform, since the output is committed and a platform-dependent line ending would make the file churn between a Windows and a Unix runner.

Parameters:
Return type:

str

Returns:

The complete CSV document, newline-terminated.

repomatic.tabular.render_markdown_table(headers, rows, align=())[source]

Render a GitHub-flavored Markdown table.

Cells are used as given: a caller wanting a code span, a link or an emoji renders it into the cell first. Nothing is escaped, matching what every report renderer did by hand before this existed: none of them ever feeds a cell carrying a |.

Parameters:
  • headers (Sequence[object]) – Column titles, in order.

  • rows (Iterable[Sequence[object]]) – One sequence of cells per row, in the same order.

  • align (Sequence[str]) – Per-column alignment, left, right or center; an empty entry (or a list shorter than headers) leaves that column on the parser default. Alignment only changes how a renderer justifies the column, so it is worth declaring where it carries meaning, like a numeric column read against its neighbours.

Return type:

str

Returns:

The table’s lines joined with newlines, no trailing newline.

Raises:

KeyError – On an alignment name outside the vocabulary.

repomatic.tabular.read_csv(path)[source]

Read a committed CSV into one mapping per row.

Every cell comes back as a string: CSV carries no types, so a caller wanting a number coerces it. A missing file reads as no rows, which is what a first run sees.

Parameters:

path (Path) – Path to the CSV file.

Return type:

list[dict[str, str]]

Returns:

One mapping per data row, keyed by column name.

Raises:

ValueError – When the file exists but carries no header row. Loud on purpose: a truncated or half-written file must never be silently treated as empty and clobbered by the next write_csv().

repomatic.tabular.load_records(path, from_row, kind, rows=None)[source]

Materialize a committed store through a row parser, loudly.

The committed-dataset counterpart of read_csv(): one row-to-record pass with one failure contract, so every store fails the same way.

Parameters:
  • path (Path) – Path to the CSV store, read when rows is None and named in the failure message either way.

  • from_row (Callable[[Mapping[str, Any]], TypeVar(RecordT)]) – The row parser, typically the record class’s from_row classmethod.

  • kind (str) – What the store holds, opening the failure message.

  • rows (Iterable[Mapping[str, Any]] | None) – Rows already produced by a caller-side fallback read, parsed in place of the file’s.

Return type:

list[TypeVar(RecordT)]

Returns:

The parsed records.

Raises:

ValueError – When the store exists but cannot be parsed. Loud on purpose: a corrupt store must never be silently clobbered by the next write.

repomatic.tabular.write_if_changed(path, content)[source]

Write content to path, leaving an already-matching file alone.

Creates the parent directories when missing. Comparing before writing is what every generator in the package leans on: one that rewrote its output unconditionally would turn each scheduled run into a commit, and a sync job that opens a pull request would open one forever.

Format-neutral despite sitting beside the CSV helpers, because what it encodes is the write rather than the bytes. The SVG charts in repomatic.metric_chart route through it too.

Parameters:
  • path (Path) – File to write.

  • content (str) – The full text the file should hold.

Return type:

bool

Returns:

True when the file was created or its content changed.

repomatic.tabular.write_csv(path, content)[source]

Write rendered CSV to path, leaving an unchanged file alone.

Parameters:
Return type:

bool

Returns:

True when the file content changed.