Plan: Fix config library issues (priority order) #3
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
residual/config#3
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Plan: Fix config library issues (priority order)
Fix order
optional→omitempty, integration status) — tier-0-trivialFix details
1. InitWithTemplate error swallowing (
core/load.go:61-82)Problem: Returns
(cfg, nil)even when template rendering, dir creation, or file writing fails.Fix: Return errors from the template-writing block. The cascade load before it still runs (errors from
System/Userare intentionally ignored for missing files), but template writing failures are returned.Files:
core/load.goTests: Add test that triggers template write error (read-only dir or bad template), verify error is returned.
Closes: Forgejo #1
2. Add float support to
setFromString+coerceDefaultProblem:
setFromString(load.go) andcoerceDefault(write.go) don't handlereflect.Float32/Float64. Fields withdefault:"3.14"silently get no default.Fix in
core/load.gosetFromString:Fix in
core/write.gocoerceDefault:Fix in
core/env.gocoerceAndSet:Files:
core/load.go,core/write.go,core/env.goTests: Add float fields to test structs; test
default:"3.14", env varPREFIX__FLOAT_FIELD=2.718, and write round-trip.3. Fix stale docs
Files:
README.mdline 27:optional→omitemptydocs/residual-overview.mdline 16:optional→omitemptydocs/residual-overview.mdlines 7, 23: Update integration status ("integrated into core/ viaconfig/import path")4. structToMap omitempty propagation (design decision)
Problem:
structToMapalways writes all nested fields including zero-value ones withomitempty. Theomitemptyhint only works at the top level viabuildMarshalOutput.Question for user: Should
structToMapalso skip zero-value fields that haveomitempty? This would mean nested struct sections could have fewer keys in TOML. Or is "always write all nested fields" the intended behavior?If yes: Add
omitemptycheck tostructToMap— skip fields wheref.OmitEmpty && field.IsZero() && f.Default == "".If no: Document that
omitemptyonly applies at the top level.5. RenderTemplate missing key handling (design decision)
Problem: Missing placeholder keys render as literal
<not found>in the config file.Options:
<not found>but log a warning → permissive, useful for templates with optional sectionsRecommendation: Option A — return an error. A template that references a non-existent key is a bug. The caller can catch and handle it.
6. MergeWithRules wildcard matching for nested fields (design decision)
Problem:
resolveFieldModereceivesf.Namewhich is the leaf conf tag name (e.g."host"), not a dotted path. Patterns like"database.*"can never match because there's no path context.Options:
MergeWithRulesisn't used in production yet, and the wildcard feature is untested in real use. Document the limitation.resolveFieldMode. RequiresinspectFieldsFromTypeto include parent path context, or the caller to build it.Recommendation: Option A for now. The feature is experimental, not used in production, and fixing it properly requires restructuring how field metadata is passed through the merge pipeline.
7. write.go dir permissions umask
Problem:
os.MkdirAll(filepath.Dir(path), 0o700)ignores umask.Fix: Use
0o777and let umask do its job, or useos.MkdirAllwith a mode that respects the process umask. The current0o700is overly restrictive on shared systems.Files:
core/write.goline 50Verification
After all fixes:
Commit strategy
One commit per fix (logical atomicity), or group:
core/code fixes)Design decisions (confirmed by user)
Fix 4 — structToMap omitempty propagation
Decision: Fix it. omitempty should function like it does in other parsers — when writing, zero-value fields with omitempty are omitted from the output. This applies at all nesting levels, not just top-level. When reading, parsers should not error on missing values (already handled by the shadow type decoder).
Fix 5 — RenderTemplate missing keys
Decision: Option A — return error. If a template references a key that doesn't exist in the config struct, that's a bug. Return an error. The caller can handle it.
Fix 6 — MergeWithRules wildcard matching
Decision: Skip for now. Noted as a backburner item.
MergeWithRulesisn't used in production yet, and the wildcard feature is untested in real use. Document the limitation.Implementation order
Implementation complete
All 7 fixes implemented and verified:
reflect.Float32/Float64tosetFromString,coerceDefault, andcoerceAndSet.optional→omitemptyin README and overview; updated integration status.omitempty:"true"are now skipped when zero and no default.0o700→0o777to respect umask.Tests added
TestInitWithTemplate,TestInitWithTemplateBadTemplate,TestInitWithTemplateExistingFile,TestInitWithTemplateReadOnlyDirTestDefaultsFloat,TestLoadFloat,TestEnvFloat,TestWriteFloat,TestWriteFloatWithDefaultTestWriteNestedOmitEmpty,TestWriteNestedOmitEmptyNonZeroVerification
Status Update — 2026-09-20
The original 7 items from this plan are all implemented and verified (per comment above). However, a full production-readiness audit on 2026-09-20 identified additional gaps. These are now tracked as separate issues:
New issues created
Original items — completion status
This issue can be closed once all new issues (#4-#10) are resolved.