Conversation
parseTag says it overlays the field's tags over the signature's, but merged
them with append. Tags read through Tag.Get see values[0] and override fine;
the five read through Tag.GetAll -- env, xor, lastwins, and, set -- kept the
signature's value alongside the field's.
So a field that overrode env was still resolved from the signature's variable,
and a field that moved itself to a different xor group stayed in both.
env:"SIG_ENV" on the signature, env:"FIELD_ENV" on the field
before: resolved from $SIG_ENV
after: resolved from $FIELD_ENV only
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2b202890f0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // Prepend field tag values | ||
| items[key] = append(value, items[key]...) | ||
| // A key set on the field replaces the signature's values for that key, rather than adding to them. | ||
| items[key] = value |
There was a problem hiding this comment.
Preserve unrelated signature variables when overriding set
When a Signature() supplies multiple set defaults and the field supplies another set value, replacing the entire slice discards every signature variable, including keys the field did not override. For example, a signature containing set:"a=A" set:"b=B" help:"${a}/${b}/${c}" combined with a field tagged set:"c=C" now makes kong.New fail with undefined variable ${a}. Since set represents a multi-entry variable map, merge this key by variable name with field values winning rather than replacing the whole collection.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
I measured this one and it does not reproduce — set behaves identically before and after the change.
Driving kong.New and reading Tag.Vars off the model, with a signature of set:"a=1" set:"b=2":
master this branch
signature only {a:1 b:2} {a:1 b:2}
signature + field `set:"a=9"` {a:9} {a:9}
signature `set:"a=1"` + field `set:"b=9"` {b:9} {b:9}
So the signature's unrelated set variables are already dropped on master as soon as the field carries any set tag; this patch does not change that either way. If that existing behaviour is itself wrong it is a separate fix, and I am happy to open one — but it is not a regression introduced here.
parseTagmerges the field's struct tags over the onesSignature()supplied. The comment there says what it means to do:Appending only looks like an overlay through
Tag.Get, which returnsvalues[0]. Seventeen of the twenty-two tagshydrateTagreads go throughGet/GetBool/GetRune, soname,help,type,default,group,prefix,envprefix,enum,shortand the rest all override correctly — that is whatTestSignatureFieldTagOverridespins, with its own comment saying "The signature name should NOT work because the field tag overrode it."The other five go through
Tag.GetAll, which returns the whole slice:env,xor,lastwins,and,set. For those the signature's value survives next to the field's.Two things that come out of it, both driven through
kong.New+Parse:A field that overrides
envis still resolved from the signature's variable.A field cannot move itself out of the signature's xor group. With
Acarryingxor:"mygroup"over a signature that saysxor:"siggroup", and aBinsiggroup, kong rejects a command line that should be legal:The change is
items[key] = value.Scope, stated plainly
This makes all five
GetAlltags replace rather than accumulate. I wrote the test forenvand hand-probedxor;lastwins,andandsetchange the same way by construction but I have not exercised them individually.setis aVarsmap, so its visible change is the smallest. If you consider accumulation deliberate for any of these, I am happy to narrow the fix to the ones you want.I also left
parseStructTagItems(tag.go:185-187) alone, where bare tags meet thekong:"..."tag — both sides there belong to the same field, so the override question does not arise.Testing
TestSignatureFieldTagOverridesEnvadded tosignature_test.goin the file's existing style.masterit is the only failure in the package:-signatureEnvFlag("")/+signatureEnvFlag("from-signature").appendfails only the new test. Over-correcting so that any field tag discards the whole signature fails five pre-existing tests (TestSignatureCommand,TestSignatureCommandHelp,TestSignaturePointerReceiver,TestSignaturePointerReceiverHelp,TestSignatureFieldTagOverridesHelp) while the new test passes — so the "help still comes from the signature" side is pinned too.go test ./...andgo test -race ./...pass,gofmtis clean, andgolangci-lintat the pinnedv1.64.5exits 0. I checked the linter was actually running by planting an unused function, which it caught.git log -Sputs theappendat95675de(signature defaults, #581), last touched byb73962b(#602) — nothing has pinned the accumulate behaviour since.AI assistance disclosure: this patch was found and written with Claude Code. Every quoted output above is verbatim from running it against
masterand against this branch.