Skip to content

[duplicate-code] Duplicate Code Pattern: Trivial getDefault*() Env-Var Wrapper Functions #2364

@github-actions

Description

@github-actions

Part of duplicate code analysis: #2361

Summary

internal/cmd/flags_difc.go and internal/cmd/flags_logging.go together contain 9 trivial one-to-two-line getDefault*() functions that each wrap a single os.Getenv() or envutil.Get*() call. While each function is individually small, the pattern is repeated identically across both files and could be consolidated with a shared helper.

Duplication Details

Pattern: Single-Expression getDefault*() Wrappers

  • Severity: Medium
  • Occurrences: 9 near-identical functions (5 in flags_difc.go, 4 in flags_logging.go)
  • Locations:
    • internal/cmd/flags_difc.go lines 63–85:
      func getDefaultDIFCSinkServerIDs() string {
          return os.Getenv("MCP_GATEWAY_GUARDS_SINK_SERVER_IDS")
      }
      func getDefaultGuardPolicyJSON() string {
          return os.Getenv("MCP_GATEWAY_GUARD_POLICY_JSON")
      }
      func getDefaultAllowOnlyScopeOwner() string {
          return os.Getenv("MCP_GATEWAY_ALLOWONLY_SCOPE_OWNER")
      }
      func getDefaultAllowOnlyScopeRepo() string {
          return os.Getenv("MCP_GATEWAY_ALLOWONLY_SCOPE_REPO")
      }
      func getDefaultAllowOnlyMinIntegrity() string {
          return os.Getenv("MCP_GATEWAY_ALLOWONLY_MIN_INTEGRITY")
      }
    • internal/cmd/flags_logging.go lines 35–55:
      func getDefaultLogDir() string {
          return envutil.GetEnvString("MCP_GATEWAY_LOG_DIR", config.DefaultLogDir)
      }
      func getDefaultPayloadDir() string {
          return envutil.GetEnvString("MCP_GATEWAY_PAYLOAD_DIR", config.DefaultPayloadDir)
      }
      func getDefaultPayloadPathPrefix() string {
          return envutil.GetEnvString("MCP_GATEWAY_PAYLOAD_PATH_PREFIX", defaultPayloadPathPrefix)
      }
      func getDefaultPayloadSizeThreshold() int {
          return envutil.GetEnvInt("MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD", config.DefaultPayloadSizeThreshold)
      }

Impact Analysis

  • Maintainability: Adding new flags requires adding new one-liner functions; pattern is repetitive
  • Bug Risk: Low — each function is trivial and clearly correct
  • Code Bloat: ~27 lines of boilerplate for 9 functions that could be replaced by direct os.Getenv() calls at the call site, or by a shared helper

Refactoring Recommendations

  1. Inline trivial getters directly at the flag registration call site (since they are only called once):

    // Before
    cmd.Flags().StringVar(&difcSinkServerIDs, "guards-sink-server-ids", getDefaultDIFCSinkServerIDs(), "...")
    
    // After
    cmd.Flags().StringVar(&difcSinkServerIDs, "guards-sink-server-ids", os.Getenv("MCP_GATEWAY_GUARDS_SINK_SERVER_IDS"), "...")
    • Applicable to the 5 trivial os.Getenv() wrappers in flags_difc.go
    • Estimated effort: 15 minutes
    • Benefits: Removes 15+ lines of boilerplate; env var name is visible at the registration site
  2. Alternative: Keep as named functions (acceptable if the team values named functions for documentation purposes — they make the flag default source explicit in the code).

    Note: getDefaultDIFCMode() (lines 41–51) is intentionally more complex with validation logic — it should remain as a named function regardless.

Implementation Checklist

  • Decide: inline or keep named getters (team preference)
  • If inlining: replace 5 trivial os.Getenv() wrappers in flags_difc.go
  • If inlining: verify call sites are updated
  • Run make test to verify no regressions

Parent Issue

See parent analysis report: #2361
Related to #2361

Generated by Duplicate Code Detector ·

Warning

⚠️ Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • proxy.golang.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "proxy.golang.org"

See Network Configuration for more information.

  • expires on Mar 30, 2026, 3:05 AM UTC

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions