Part of duplicate code analysis: #1006
Summary
Medium-severity duplication where default gateway configuration values (Port, StartupTimeout, ToolTimeout) are assigned in multiple locations across config_core.go and config_stdin.go. This creates maintenance burden when default values need to change.
Duplication Details
Pattern: Repeated Default Value Assignments
- Severity: MEDIUM
- Occurrences: 2+ locations (9+ lines each)
- Locations:
internal/config/config_core.go lines 196-204 (applyDefaults function)
internal/config/config_stdin.go lines 138-143 (convertStdinConfig - initial struct creation)
internal/config/config_stdin.go lines 159-161 (convertStdinConfig - nil gateway case)
Code Sample - config_core.go (lines 196-204):
func applyDefaults(cfg *Config) {
// Apply gateway defaults
if cfg.Gateway.Port == 0 {
cfg.Gateway.Port = DefaultPort
}
if cfg.Gateway.StartupTimeout == 0 {
cfg.Gateway.StartupTimeout = DefaultStartupTimeout
}
if cfg.Gateway.ToolTimeout == 0 {
cfg.Gateway.ToolTimeout = DefaultToolTimeout
}
// ... more defaults
}
Code Sample - config_stdin.go (lines 138-143):
cfg.Gateway = &GatewayConfig{
Port: DefaultPort,
StartupTimeout: DefaultStartupTimeout,
ToolTimeout: DefaultToolTimeout,
}
Code Sample - config_stdin.go (lines 159-161):
if cfg.Gateway == nil {
cfg.Gateway = &GatewayConfig{
Port: DefaultPort,
StartupTimeout: DefaultStartupTimeout,
ToolTimeout: DefaultToolTimeout,
}
}
Impact Analysis
- Maintainability: MEDIUM - Changing a default value requires updates in 3 locations
- Bug Risk: MEDIUM - Easy to miss one location when updating defaults, causing inconsistent behavior
- Code Consistency: Different initialization strategies (zero-check vs struct literal) for same defaults
- Configuration Reliability: Inconsistent defaults could cause subtle bugs in different config loading paths
Refactoring Recommendations
1. Create Unified Default Config Constructor
Recommended implementation:
// Add to internal/config/config_core.go near DefaultPort constants
// NewDefaultGatewayConfig creates a GatewayConfig with all default values applied.
// This ensures consistent defaults across TOML config loading and JSON stdin parsing.
func NewDefaultGatewayConfig() *GatewayConfig {
return &GatewayConfig{
Port: DefaultPort,
StartupTimeout: DefaultStartupTimeout,
ToolTimeout: DefaultToolTimeout,
// Add other gateway defaults as they're added
}
}
Refactored config_core.go applyDefaults (lines 196-204):
func applyDefaults(cfg *Config) {
// If gateway is nil or has zero values, apply defaults
if cfg.Gateway == nil {
cfg.Gateway = NewDefaultGatewayConfig()
return
}
// Apply defaults for individual zero-valued fields
defaults := NewDefaultGatewayConfig()
if cfg.Gateway.Port == 0 {
cfg.Gateway.Port = defaults.Port
}
if cfg.Gateway.StartupTimeout == 0 {
cfg.Gateway.StartupTimeout = defaults.StartupTimeout
}
if cfg.Gateway.ToolTimeout == 0 {
cfg.Gateway.ToolTimeout = defaults.ToolTimeout
}
}
Refactored config_stdin.go (lines 138-143, 159-161):
// Line 138-143: Replace struct literal
cfg.Gateway = NewDefaultGatewayConfig()
// Line 159-161: Replace struct literal
if cfg.Gateway == nil {
cfg.Gateway = NewDefaultGatewayConfig()
}
- Estimated effort: 2-3 hours (create function, refactor 3 locations, verify tests)
- Benefits:
- Single source of truth for all gateway defaults
- Easy to add new default fields in future
- Consistent initialization across config loading paths
- Self-documenting code
- Future-proof against new optional fields
2. Alternative: Use Const Struct Pattern
// Define default values as a reusable struct
var DefaultGatewayConfig = GatewayConfig{
Port: DefaultPort,
StartupTimeout: DefaultStartupTimeout,
ToolTimeout: DefaultToolTimeout,
}
// Usage: Copy defaults
cfg.Gateway = &DefaultGatewayConfig
// or
*cfg.Gateway = DefaultGatewayConfig
Note: This approach requires careful handling to avoid shared pointer issues.
Implementation Checklist
Parent Issue
See parent analysis report: #1006
Related to #1006
Generated by Duplicate Code Detector
Part of duplicate code analysis: #1006
Summary
Medium-severity duplication where default gateway configuration values (Port, StartupTimeout, ToolTimeout) are assigned in multiple locations across
config_core.goandconfig_stdin.go. This creates maintenance burden when default values need to change.Duplication Details
Pattern: Repeated Default Value Assignments
internal/config/config_core.golines 196-204 (applyDefaultsfunction)internal/config/config_stdin.golines 138-143 (convertStdinConfig- initial struct creation)internal/config/config_stdin.golines 159-161 (convertStdinConfig- nil gateway case)Code Sample - config_core.go (lines 196-204):
Code Sample - config_stdin.go (lines 138-143):
Code Sample - config_stdin.go (lines 159-161):
Impact Analysis
Refactoring Recommendations
1. Create Unified Default Config Constructor
Recommended implementation:
Refactored config_core.go applyDefaults (lines 196-204):
Refactored config_stdin.go (lines 138-143, 159-161):
2. Alternative: Use Const Struct Pattern
Note: This approach requires careful handling to avoid shared pointer issues.
Implementation Checklist
NewDefaultGatewayConfig()functionconfig_core.goapplyDefaults()to use constructorconfig_stdin.goconvertStdinConfig()to use constructor (2 locations)Parent Issue
See parent analysis report: #1006
Related to #1006