repo mirror list: split column key from display header · Entire
repo mirror list: split column key from display header
8a8c30b→main·
gtrrz-victor·1w ago·2 files·+50 added/-48 removed
Replace the parseSortColumn parenthetical-stripping (regexp + sortKeyOf) with a column{key, header} struct: key is the canonical --sort/match name, header is the table text. They differ only where the header adds a display hint the key shouldn't (NAME -> "NAME (owner/repo)"), so --sort matching is a plain equality on key with no header parsing.
--sort now takes the key ("name"); the full display form is no longer a second accepted spelling (it never needed to be — it was only a workaround for overloading one string for both jobs).
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Sessions
01KX0MWF385YSK197X1BWAJ6CJView transcript
[?
Rename Repo Column to Name for ConsistencyClaude Code·1 step](/content/gh/entireio/cli/session/dec0d061-ea6a-4326-b5dd-6ba25b48eed6#timeline-01KX0MWF385YSK197X1BWAJ6CJ/index.html)
Changes
2
cmd/entire/cli
Mrepo_mirror.go+47/-45
Mrepo_mirror_test.go+3/-3
17 unmodified lines
// Column header names, the single source of truth for both the table headers
// (mirrorColumns/availableMirrorColumns) and the --sort key switches. parseSort-
// Column returns the canonical header it matched, so the sort switches compare
// against these constants directly. The NAME header carries an inline
// "(owner/repo)" hint spelling out what the cell holds; parseSortColumn accepts
// the header with that trailing parenthetical stripped, so `--sort name` works.
const (
colName = "NAME (owner/repo)"
colCloneURL = "CLONE URL"
colPrivate = "PRIVATE"
colAccess = "ACCESS"
colStatus = "STATUS"
)
// column is a table column with two separable identities: key is the canonical
// name a caller types for --sort (and the value parseSortColumn returns, so the
// sort switches compare against these constants directly); header is the text
// shown in the table. They differ only where the header carries a display hint
// the sort key shouldn't — e.g. NAME's inline "(owner/repo)" — which keeps
// --sort matching a simple equality on key with no header parsing.
type column struct {
key string
header string
}
var (
colName = column{key: "NAME", header: "NAME (owner/repo)"}
colCloneURL = column{key: "CLONE URL", header: "CLONE URL"}
colPrivate = column{key: "PRIVATE", header: "PRIVATE"}
colAccess = column{key: "ACCESS", header: "ACCESS"}
colStatus = column{key: "STATUS", header: "STATUS"}
)
// columnHeaders is the display-header view of a column set, for the table/field
// renderers (runCoreList/runCoreObject) which take plain header strings.
func columnHeaders(cols []column) []string {
h := make([]string, len(cols))
for i, c := range cols {
h[i] = c.header
}
return h
}
// mirrorColumns is the human table/field view of a mirror: the scannable
// owner/repo name, the clone URL you'd copy, and whether the upstream is
// private. Owner, provider, and cluster aren't columns of their own — they're
// model's internal ids are dropped. The clone URL is synthesized from the
// mirror's coords (the form `git clone` accepts), since the list API doesn't
// return it.
var mirrorColumns = []column{colName, colCloneURL, colPrivate}
// mirrorPrivate renders the PRIVATE column ("yes"/"no"), shared by the table
// row and the --sort private key so both agree on the cell value.
func availableMirrorRow(m coreapi.AvailableMirror) []string {
return []string{m.Owner + "/" + m.Repo, string(m.Access), string(m.Status)}
}
// sortKeyOf returns the header with its trailing parenthetical hint removed,
// i.e. the short name accepted by --sort ("NAME (owner/repo)" -> "NAME").
func sortKeyOf(header string) string {
return parenHint.ReplaceAllString(header, "")
}
// parseSortColumn resolves a --sort spec to the canonical column header it
// names (one of the columns entries) and a direction. It trims first, then
// reads the '-' prefix, so leading/trailing whitespace is handled identically
// on every path (the direction and the column name never disagree). An empty
// spec selects the first column. A spec matches a column by its full header or
// by the header with its trailing parenthetical hint stripped, so both
// `--sort "name (owner/repo)"` and the friendly `--sort name` resolve. An
// unknown name errors naming the valid (short) columns. Returning the matched
// header lets callers switch on the col* constants directly.
func parseSortColumn(spec string, columns []column) (col column, desc bool, err error) {
spec = strings.TrimSpace(spec)
desc = strings.HasPrefix(spec, "-")
name := strings.TrimSpace(strings.TrimPrefix(spec, "-"))
if name == "" {
return columns[0], desc, nil
}
for _, h := range columns {
if strings.EqualFold(h.key, name) {
return h, desc, nil
}
}
valid := make([]string, len(columns))
for i, h := range columns {
valid[i] = strings.ToLower(h.key)
}
return column{}, false, fmt.Errorf("unknown sort column %q; valid columns: %s", name, strings.Join(valid, ", "))
}