fix(config): reject bare and null forms of unsupported sections#44
fix(config): reject bare and null forms of unsupported sections#44shreemaan-abhishek wants to merge 1 commit into
Conversation
Closes #33. The previous `cfg.<Section> != nil` checks only rejected explicitly-empty sections (`upstreams: []`). YAML like `upstreams:` (bare key, no value) and `upstreams: null` unmarshalled to a nil slice and slipped past, even though the user had clearly declared an unsupported section. - Add `markPresentUnsupportedSections` in configutil: a two-pass parse over the raw input (`map[string]json.RawMessage` for JSON, `map[string]yaml.Node` for YAML) that flips the four unsupported section fields from nil to a non-nil empty slice when the key is present, regardless of its value shape. - Route `config validate` through `configutil.ReadConfigFile` so it inherits the same key-presence detection that diff/sync already use. Drops validate's now-duplicate file-reading code. - Extend `TestConfigValidate_EmptyUnsupportedSections` with 12 subtests covering empty-list, bare, and null shapes for all four sections, plus 2 JSON-null variants. All pass.
📝 WalkthroughWalkthroughThe PR extends config validation to detect bare keys and null values for unsupported top-level sections. ChangesUnsupported section bare/null key-presence detection
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 6✅ Passed checks (6 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
pkg/cmd/config/validate/validate_test.go (1)
375-376:⚠️ Potential issue | 🟠 Major | ⚡ Quick winJSON-null subtests are currently written as
.yaml, so they may miss the JSON code path.
json_*cases should use a.jsonfilename; otherwise they can still parse as YAML and give false confidence for JSON-specific normalization.Suggested fix
t.Run(tc.name, func(t *testing.T) { ios, _, _, _ := iostreams.Test() - filePath := filepath.Join(t.TempDir(), "config.yaml") + ext := ".yaml" + if strings.HasPrefix(tc.name, "json_") { + ext = ".json" + } + filePath := filepath.Join(t.TempDir(), "config"+ext) require.NoError(t, os.WriteFile(filePath, []byte(tc.body), 0o644))import ( "net/http" "os" "path/filepath" + "strings" "testing"As per coding guidelines,
**/*.go: Write tests for every code change.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/cmd/config/validate/validate_test.go` around lines 375 - 376, The JSON-specific subtests (named like "json_*") are writing test fixtures to a .yaml path which allows YAML parsing to succeed and skips the JSON code path; update the test so when tc.name or the test case indicates JSON (e.g., json_* cases) you create the temp file with a .json extension instead of .yaml by adjusting filePath (the filepath.Join(t.TempDir(), "...") call) so it uses ".json" for JSON cases, ensuring the test writes tc.body to that .json file and exercises the JSON parsing/normalization path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@pkg/cmd/config/validate/validate_test.go`:
- Around line 375-376: The JSON-specific subtests (named like "json_*") are
writing test fixtures to a .yaml path which allows YAML parsing to succeed and
skips the JSON code path; update the test so when tc.name or the test case
indicates JSON (e.g., json_* cases) you create the temp file with a .json
extension instead of .yaml by adjusting filePath (the filepath.Join(t.TempDir(),
"...") call) so it uses ".json" for JSON cases, ensuring the test writes tc.body
to that .json file and exercises the JSON parsing/normalization path.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: d149dcd0-07f7-417a-89a2-6e7686e8ddef
📒 Files selected for processing (3)
pkg/cmd/config/configutil/configutil.gopkg/cmd/config/validate/validate.gopkg/cmd/config/validate/validate_test.go
There was a problem hiding this comment.
Pull request overview
This PR hardens declarative config validation so that key presence for unsupported top-level sections is detected consistently across YAML and JSON, including “bare key” (upstreams:) and explicit null forms that previously unmarshalled to nil and slipped past validation. It also aligns config validate with the existing configutil.ReadConfigFile parsing path used by other config commands.
Changes:
- Add a raw key-presence pass in
configutil.ReadConfigFileto normalize declared-but-empty unsupported sections into non-nilempty slices. - Route
config validatethroughconfigutil.ReadConfigFile(removing duplicate file reading / JSON-vs-YAML parsing code). - Expand validation tests to cover
[], bare, andnullshapes (plus JSONnullcases) for unsupported sections.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| pkg/cmd/config/validate/validate.go | Switches validate to use configutil.ReadConfigFile, ensuring bare/null unsupported sections are detected. |
| pkg/cmd/config/validate/validate_test.go | Extends TestConfigValidate_EmptyUnsupportedSections with additional YAML/JSON cases for bare and null forms. |
| pkg/cmd/config/configutil/configutil.go | Adds markPresentUnsupportedSections two-pass parsing to treat declared unsupported sections as present even when unmarshalling yields nil. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
Closes #33.
The previous
cfg.<Section> != nilchecks only rejected explicitly-empty sections (upstreams: []). YAML likeupstreams:(bare key, no value) andupstreams: nullunmarshalled to a nil slice and slipped past, even though the user had clearly declared an unsupported section.Changes
configutil.markPresentUnsupportedSections: a two-pass parse over the raw input (map[string]json.RawMessagefor JSON,map[string]yaml.Nodefor YAML) that flips the four unsupported section fields (upstreams/consumer_groups/plugin_configs/service_templates) from nil to a non-nil empty slice when the key is present, regardless of value shape.config validatethroughconfigutil.ReadConfigFileso it inherits the same key-presence detection that diff/sync already use. Drops validate's now-duplicate file-reading code (bytes/encoding/json/os/gopkg.in/yaml.v3imports go with it).TestConfigValidate_EmptyUnsupportedSectionsis extended with 14 subtests covering empty-list / bare / null shapes for all four sections, plus JSON-null variants. All pass:Test plan
go build,go vet, fullgo test ./...green locally.TestConfigValidate_EmptyUnsupportedSectionsall pass.Why this isn't merged with PR #43
Kept scope-tight on PR #43 (
json.RawMessageexporter audit + CI verbosity). This change is config-validation hardening, a different concern with its own test surface.Closes #33. Part of #22.
Summary by CodeRabbit
Bug Fixes