repomatic.cli.main module¶
The repomatic command-line group and its shared plumbing.
Commands live in the per-section cli_* sibling modules and register onto
the group defined here; the bottom of this module imports them for that side
effect. What stays here is everything they share: the group, its help
sections, the reusable option declarations, the parameter types, and the
small helpers command bodies lean on.
- repomatic.cli.main.deprecated_alias(name, command, *, replacement, removed_in)[source]¶
Build a hidden alias for a renamed command, warning on each run.
The alias shares the renamed command’s parameters, so both spellings parse the same command line; it only swaps the callback for one that logs the deprecation first. The copy is shallow, which is safe here: a Click command holds no state between invocations.
- Parameters:
- Return type:
- Returns:
The alias, ready to register on the group.
- repomatic.cli.main.exit_if_disabled(ctx, enabled, key)[source]¶
Exit successfully when a
[tool.repomatic]feature flag is off.The shared guard of every sync command: a disabled feature is a normal, configured state, so the command logs the flag and exits
0instead of failing the workflow that invoked it.
- repomatic.cli.main.log_output_target(subject, output)[source]¶
Log where a command is about to write subject.
Every command that honors an
--outputpath narrates the destination the same way, distinguishing the stdout case (-) so the log names the stream instead of a literal dash.
- class repomatic.cli.main.ComponentSelector[source]¶
Bases:
ParamTypeAccepts bare component names or qualified
component/fileselectors.Bare names (e.g.,
skills) select an entire component. Qualified entries (e.g.,skills/repomatic-topics) select a single file within a component. Validation delegates toparse_component_entries(), the same code path theexcludeandincludeconfig options go through, so the CLI and config agree on syntax and error messages.- get_metavar(param, ctx)[source]¶
Returns the metavar default for this param if it provides one.
- Return type:
- convert(value, param, ctx)[source]¶
Check that value names a component, or one file of a component.
- Return type:
- Returns:
The selector, unchanged.
- Raises:
click.BadParameter – The selector names neither.
- shell_complete(ctx, param, incomplete)[source]¶
Return a list of
CompletionItemobjects for the incomplete value. Most types do not provide completions, but some do, and this allows custom types to provide custom completions as well.- Parameters:
Added in version 8.0.
- Return type:
- repomatic.cli.main.AXIS_HEADER_LABELS = {'os': 'OS', 'python-version': 'Python', 'state': 'State'}¶
Display names for the job keys
show-test-matrixheads a row or column with.A key absent from here heads its column under the raw name a matrix declares it as, which is also how a caller names it on the command line.
- repomatic.cli.main.UNIVERSAL_AXIS_KEYS = ('os', 'python-version', 'state')¶
The job keys every test matrix carries, whatever a project configures.
The base cross-product declares the first two and the state include stamps the third, so no
[tool.repomatic.test-matrix]directive can leave a matrix without them. That makes them the safe answer when the real matrix cannot be read at all, which is the only timeMatrixAxisneeds one.
- repomatic.cli.main.JOB_COUNT_MARK = '×'¶
Introduces the job count of a cell standing for more than one job.
A cell collapses every job at its intersection, so a matrix varying on a third axis renders five jobs exactly like one. The mark is the East Asian Ambiguous U+00D7, like the
—placeholder the grid already uses: a terminal drawing ambiguous characters double-width misaligns both alike, and neither before the other.
- repomatic.cli.main.TEST_MATRIX_STATE_DISPLAY = {'stable': '✅ stable', 'unstable': '⁉️ unstable'}¶
Emoji-decorated labels for job states in the
show-test-matrixgrid.The same two glyphs the workflow templates stamp onto each matrix job’s name, and that
repomatic.github.ci_status.JobStatus.required()reads back off it, so the grid and the CI verdict cannot come to disagree about which mark means “allowed to fail”.
- repomatic.cli.main.matrix_axis_keys(matrix)[source]¶
Every job key one matrix carries, sorted.
Read off the solved job stream rather than off the declared axes, so a key only an
includedirective contributes is listed and one whose directive everyexcludecancelled is not. That makes the listing exactly the set an axis can pivot on: anything outside it yields an empty grid.
- class repomatic.cli.main.LazyChoice[source]¶
Bases:
ChoiceA
Choicewhose accepted values are the project’s, read at render time.A
Choicedeclared at import can only carry what every repository has in common, which for most of these options is nothing: the dependency groups, the workflow files and the matrix axes are all the project’s own. Resolving them when Click renders the help (or a completion list) is what lets the option name them, and keeps the lookup out of every other command’s startup.Two rules make that safe to do mid-render:
Nothing may fail or speak. A traceback replaces the text the reader asked for, and a warning prepends noise to it, so
resolveruns with logging off and any exception degrades to no values at all.No values means “cannot tell”, not “nothing is valid”. An empty
Choicerefuses every value including the option’s own default, so a project this type cannot read would take the whole command down with it. The type accepts anything instead, and renders the plain metavar itsnamegives rather than an empty[].
A subclass that knows a floor its project cannot go below declares it as
fallback, and never reaches the pass-through above.- fallback: tuple[str, ...] = ()¶
Values to offer when
resolvefinds none. Empty means accept anything.
- class repomatic.cli.main.MatrixAxis[source]¶
Bases:
LazyChoiceA job key naming one axis of the
show-test-matrixgrid.A
Choicerather than a bare type, so the accepted keys reach the reader through Click’s own[a|b|c]metavar and click-extra’s choice styling, and the shell completes them: a hand-written help line would render none of that. Its values are read at render time rather than declared at import, because they are the project’s own. A repository varying its matrix on aclick-versioncan pivot on it, and that is exactly the axis a fixed list would omit.The listing is the full matrix’s, the superset:
variationsandfull-includerows reach it alone, while every other directive reaches both matrices. Which one the caller names is not parsed yet when a type converts, soshow-test-matrixre-checks the axis against the matrix they did name, and refuses the few keysprdrops.
- class repomatic.cli.main.WorkflowFile[source]¶
Bases:
LazyChoiceA workflow file name, as
.github/workflows/spells it.Both commands taking one read the current repository’s own CI, so the checkout is the authority on what may be named. Every file counts, not just the ones
monitored_workflows()watches by default: a schedule-only workflow has runs worth reading too.
- class repomatic.cli.main.DependencyGroup[source]¶
Bases:
LazyChoiceA group declared in the project’s
[dependency-groups].uvrefuses an undeclared group, so the set is closed and naming one it does not hold is always a typo.
- class repomatic.cli.main.ProjectExtra[source]¶
Bases:
LazyChoiceAn extra declared in the project’s
[project.optional-dependencies].
- repomatic.cli.main.matrix_axis_sort_key(axis, matrix_name)[source]¶
Canonical ordering for one grid axis, or
Noneto keep job order.Keyed on which axis it is rather than on which side of the grid it landed: a transposed grid earns the runner order its columns get by default, and reads as arbitrarily shuffled without it. An axis the test matrix does not define an order for (a
click-version) keeps the order the job stream presents it in, which is the matrix author’s own.
- repomatic.cli.main.state_label(state, emoji=True)[source]¶
Label one job state, glyph-decorated unless
emojisays otherwise.A state the matrix carries but this CLI has no label for renders as itself, so a new one shows up in the grid rather than vanishing from it.
- Return type:
- repomatic.cli.main.flat_matrix_table(jobs, leading=(), emoji=True)[source]¶
Lay a solved job stream out as one row per job, one column per key.
A grid has two axes and collapses every other one into its cells, which is what a matrix varying on a third loses. Here each key is a column instead, so nothing collapses and the table is the job list CI will run.
Columns are collected across the whole stream, since a job may carry a key its neighbour does not (the
python-labelonly a prerelease needs), and the state lands last as the outcome the other columns explain. A job missing a key renders empty there rather than shifting its row.- Parameters:
jobs (
Sequence[Mapping[str,str]]) – The solved job stream, already in the order to render.leading (
Sequence[str]) – Keys to column first, in this order, before the ones the stream contributes. A listing sorted on an axis reads as unsorted with that axis buried in the middle, so the caller leads with the axes it ordered by. A key no job carries is skipped rather than columned empty.emoji (
bool) – Label the state with its glyph rather than its bare word.
- Return type:
- Returns:
A
(headers, rows)pair, in the orderprint_tabletakes them the other way round.
- repomatic.cli.main.format_matrix_cell(cell, tally, emoji=True)[source]¶
Render one
show-test-matrixcell from the jobs that landed in it.Every state is labelled on its own. A cell holds more than one when the matrix carries an axis beyond its two (a
click-versionvariation, say): both jobs land on the same intersection, and a label looked up for the joined string would match nothing and leave that cell the only bare one in its column.A state carrying several jobs also states how many, since the grid gives a reader no other way to tell five stable jobs from one.
- Parameters:
cell (
str) – The cellpivot()rendered, returned untouched when no job occupies the intersection: the placeholder for an empty one is that method’s to choose.tally (
Counter[str] |None) – That intersection’s job count per state, orNonewhere the matrix puts no job at all.emoji (
bool) – Label each state with its glyph rather than its bare word. A count is not decoration, and shows either way.
- Return type: