fix(table output): sort tags so table output is deterministic - #1207
Conversation
|
Claude finished @dangrondahl's task in 52s —— View job Follow-up review of
|
The flow and environment table printers rendered tags by iterating the tags
map directly, so the order of the rendered pairs changed between runs. Against
a flow tagged app, env and team, `kosli get flow` returned three distinct
orderings across 20 runs.
Tag rendering now goes through one sorted helper, shared by the six places
that had their own copy: get flow, get environment, list flows,
list environments, get repo and get control. Both existing output formats are
preserved, so ordering is the only user-visible change: bracketed pairs for
the flow and environment tables, unbracketed for repo and control.
The helper also guards a missing or non-map tags value, which get environment
asserted unchecked, and formats values with %v rather than %s. Neither is
reachable through the API as it behaves today, which sends "tags": {} for an
untagged resource and string values for tags set via `kosli tag`; both are
kept because the sibling printers already guarded this way.
Every existing assertion on tag output used a single tag or none, which is why
the ordering was never caught. The new tests use three keys.
400f149 to
d4d02be
Compare
Review follow-ups on #1207. formatPlainTags replaces both formatRepoTags and the inline strings.Join in get control, so the unbracketed format has one implementation instead of two plus a wrapper named after one of its callers. sortedTagPairs is now reached only through the two formatters. The sortedTagPairs doc no longer claims the API omits "tags" when there are none — it sends an empty object, as the PR description says — so the guard is described as defensive instead. The same wrong claim is corrected in the test. TestTagRenderingIsDeterministicAcrossPrinters becomes TestTagRenderingIsSortedAcrossPrinters: each subtest renders once, so what it asserts is sorted order, not determinism. All four now pin the full rendering, tab padding included, so a column-width change cannot pass silently. TestFormatRepoTags moves to tableHelpers_test.go as TestFormatPlainTags.
Follow-up review of
|
The comments narrated the bug instead of the constraint: that the released CLI returned three distinct orderings across 20 runs, that get environment used to assert the tags value unchecked, and that the other printers already tolerated both shapes. None of that is useful to a reader a year from now, and it belongs here in the history rather than in the source. What is left states the constraint the code cannot express on its own: map iteration order must not reach table output, an absent tags value must render as "None" rather than panic, and the printer tests assert full renderings so a column-width change cannot pass silently.
kosli-cli 2.43.1 Created-by: HarmonybrewBot Commit-by: HarmonybrewBot Merged-by: HarmonybrewBot Description: Created by `brew bump` --- Created with `brew bump-formula-pr`.<details> <summary>release notes</summary> <pre>- Attestation commands now warn (instead of failing) when a CI-defaulted `--commit` cannot be resolved from the repository, allowing jobs without a checked-out repo to proceed without commit info. - Commands that require commit info (`attest pullrequest`, `attest jira`) now emit a clear error when the commit cannot be resolved, rather than silently proceeding or panicking. - Explicit `--commit` or `--repo-root` flags that cannot be resolved now produce a descriptive error pointing to the correct fix. <!-- Release notes generated using configuration in .github/release.yml at v2.43.1 --> ## What's Changed * fix(k8s): name artifacts by image reference when the runtime reports an image ID by @dangrondahl in kosli-dev/cli#1204 * chore: replace interface{} with any and enforce it via lint by @dangrondahl in kosli-dev/cli#1206 * fix(attest): don't fail when a CI-defaulted --commit has no repository by @mbevc1 in kosli-dev/cli#1202 * fix(table output): sort tags so table output is deterministic by @dangrondahl in kosli-dev/cli#1207 **Full Changelog**: kosli-dev/cli@v2.43.0...v2.43.1 </pre> <p>View the full release notes at <a href="https://github.com/kosli-dev/cli/releases/tag/v2.43.1">https://github.com/kosli-dev/cli/releases/tag/v2.43.1</a>.</p> </details> <hr> See merge request: Harmonybrew/homebrew-core!20579
The flow and environment table printers rendered tags by iterating the tags map directly, so the order of the rendered pairs changed between runs.
Against a flow tagged
app=api,env=prod,team=platform, the released CLI returned three distinct orderings across 20 runs:With this change the same loop returns a single line.
What changed
Tag rendering goes through one sorted helper in
cmd/kosli/tableHelpers.go, shared by the six places that each had their own copy:get flow,get environment,list flows,list environments,get repoandget control(list repossharesget repo's).Both existing output formats are preserved, so ordering is the only user-visible change:
formatTags— bracketed pairs ([app=api], [env=prod]) for the flow and environment tablessortedTagPairs— unbracketed pairs (app=api, env=prod) for repo and controlThe helper additionally guards a missing or non-map
tagsvalue, whichget environmentasserted unchecked, and formats values with%vrather than%s. Neither is reachable through the API as it behaves today — it sends"tags": {}for an untagged resource, and tags set viakosli tagare always strings — but the sibling printers already guarded this way, so the shared helper does too.Every existing assertion on tag output used a single tag or none, which is why the ordering was never caught. The new tests use three keys.
Verification
go build ./...,make vet,make lint(0 issues)go test ./cmd/kosli/ -run 'TestSortedTagPairs|TestFormatTags|TestTagRendering|TestPrintEnvironmentAsTableWithoutTags'app.kosli.com, released binary vs. this build, as aboveNot yet run: the command suites (
GetFlow,ListFlows,GetEnvironment,EnvironmentLs,GetRepo,GetControl,ListControls).GetRepoandGetControlhave golden assertions on tag output, so these want a run before merge.Follow-ups (not in this PR)
Two more clusters of duplication in the table printers:
items/controls/repos)"No X were found", 8 with the page-number variantDeciding whether
[k=v]ork=vwins, and unifying all six sites on one format, is also left out — that's a deliberate output change.Checklist
charts/k8s-reporter/) — not needed