Skip to content

Pin command-reference.md metavar format as a stable contract (docs gate depends on it) #513

Description

@padak

Why

scripts/gen_command_reference.py emits option metavars via Click's make_metavar(), whose output depends on the installed Typer/Click version. This already drifted once: at v0.70.1 the asset showed bare `TEXT` / `INTEGER`; the v0.72.0 release asset shows `<str>` / `<int>`.

A downstream consumer now depends on the shape of that metavar, not just its presence: the connection-docs freshness gate (keboola/connection-docs#1037, PRDCT-556) detects whether an option takes a value by matching /^<.*>$/ on the metavar span. That works today only because 0.72.0 happens to emit the <…> form. If a future dependency bump reverts to bare TEXT, the consumer silently misparses value-taking options — demonstrated: a valid kbagent --config-dir /path project list becomes a false-positive "unknown command", because the unconsumed path is read as the command. The docs build would go red on correct content.

The reference asset is now a published contract (help.keboola.com consumes it). Its column formats should be stable by intent, not by accident of the Typer version.

What

  • Pin the metavar rendering in gen_command_reference.py to a documented, stable convention (e.g. always <lowercase-type> for value-taking options, empty for flags), independent of the installed Click's make_metavar() default.
  • Add a test in tests/test_gen_command_reference.py asserting the metavar format (e.g. every value-taking option's metavar matches ^<[a-z0-9|]+>$, flags have none), so a Typer/Click bump that changes make_metavar() fails CI here instead of silently breaking the docs gate downstream.
  • Document the column contract in the file header (the connection-docs checker parses | \--flag` `` | required | help |`).

Consumer

keboola/connection-docs#1037 — I've recommended a defensive one-liner on their checker (accept <str> | TEXT | [a|b]) as the immediate mitigation, but the durable fix is pinning the format at the source here so the contract can't drift under a dependency upgrade.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions