Skip to content

Conversation

@karngyan
Copy link
Member

Add getter mode for runtime environment variable overrides

This PR introduces a new "getter mode" generation option that provides runtime environment variable overrides as an alternative to the existing "static mode" where values are baked at build time.

Changes

  • Add --mode flag to CLI (static or getter)
  • Add Mode field to GenerateOptions
  • Implement getter method generation that checks environment variables at runtime before returning default values
  • Generate struct types with getter methods instead of struct fields
  • Update documentation with getter mode examples and usage
  • Add example getter_config package demonstrating the new mode

Usage

cfgx generate --in config.toml --out config.go --mode getter

In getter mode, the generated code returns runtime environment variable values when present, falling back to TOML defaults otherwise.

Copilot AI review requested due to automatic review settings October 28, 2025 17:12
@github-actions
Copy link

📊 Code Coverage Report

total:									(statements)			56.7%
Coverage by file
github.com/gomantics/cfgx/cfgx.go:88:					GenerateFromFile		78.9%
github.com/gomantics/cfgx/cfgx.go:180:					Generate			100.0%
github.com/gomantics/cfgx/cfgx.go:197:					GenerateWithOptions		62.5%
github.com/gomantics/cfgx/cmd/cfgx/main.go:31:				main				0.0%
github.com/gomantics/cfgx/cmd/cfgx/main.go:39:				parseFileSize			0.0%
github.com/gomantics/cfgx/cmd/cfgx/main.go:147:				init				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:33:		Logging				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:37:		File				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:44:		Format				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:51:		Level				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:58:		Rotation			0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:62:		Compress			0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:71:		MaxAge				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:80:		MaxSize				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:89:		Name				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:96:		Version				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:103:		Enabled				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:112:		MaxEntries			0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:121:		Outputs				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:128:		Redis				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:132:		Addr				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:139:		Db				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:148:		Password			0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:155:		Ttl				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:164:		ConnMaxLifetime			0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:173:		Dsn				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:180:		MaxIdleConns			0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:189:		MaxOpenConns			0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:198:		Pool				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:202:		Enabled				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:211:		MaxSize				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:220:		MinSize				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:229:		Methods				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:236:		Path				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:243:		RateLimit			0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:252:		Enabled				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:261:		Name				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:268:		Priority			0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:277:		Addr				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:284:		Cert				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:332:		Debug				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:341:		IdleTimeout			0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:350:		MaxHeaderBytes			0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:359:		ReadTimeout			0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:368:		ShutdownTimeout			0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:377:		Timeout				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:386:		WriteTimeout			0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:395:		AllowedOrigins			0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:402:		Features			0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:409:		Name				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:416:		Ports				0.0%
github.com/gomantics/cfgx/example/getter_config/config.go:423:		Weights				0.0%
github.com/gomantics/cfgx/internal/envoverride/envoverride.go:13:	Apply				50.0%
github.com/gomantics/cfgx/internal/envoverride/envoverride.go:40:	applyNested			88.2%
github.com/gomantics/cfgx/internal/envoverride/envoverride.go:79:	convertValue			93.3%
github.com/gomantics/cfgx/internal/envoverride/envoverride.go:111:	convertArray			88.9%
github.com/gomantics/cfgx/internal/generator/file_handler.go:11:	isFileReference			100.0%
github.com/gomantics/cfgx/internal/generator/file_handler.go:18:	loadFileContent			81.2%
github.com/gomantics/cfgx/internal/generator/generator.go:26:		WithPackageName			100.0%
github.com/gomantics/cfgx/internal/generator/generator.go:33:		WithEnvOverride			0.0%
github.com/gomantics/cfgx/internal/generator/generator.go:40:		WithInputDir			100.0%
github.com/gomantics/cfgx/internal/generator/generator.go:47:		WithMaxFileSize			100.0%
github.com/gomantics/cfgx/internal/generator/generator.go:54:		WithMode			100.0%
github.com/gomantics/cfgx/internal/generator/generator.go:61:		New				100.0%
github.com/gomantics/cfgx/internal/generator/generator.go:77:		stripSuffix			40.0%
github.com/gomantics/cfgx/internal/generator/generator.go:88:		writeGetterImports		100.0%
github.com/gomantics/cfgx/internal/generator/generator.go:109:		needsStrconvImport		100.0%
github.com/gomantics/cfgx/internal/generator/generator.go:119:		checkStrconvNeeded		69.2%
github.com/gomantics/cfgx/internal/generator/generator.go:148:		Generate			86.4%
github.com/gomantics/cfgx/internal/generator/struct_gen.go:24:		generateStructsAndVars		63.8%
github.com/gomantics/cfgx/internal/generator/struct_gen.go:128:		collectNestedStructs		57.1%
github.com/gomantics/cfgx/internal/generator/struct_gen.go:166:		generateStruct			89.5%
github.com/gomantics/cfgx/internal/generator/struct_gen.go:208:		generateStructInit		85.2%
github.com/gomantics/cfgx/internal/generator/struct_gen.go:272:		writeArrayOfTablesInit		58.8%
github.com/gomantics/cfgx/internal/generator/struct_gen.go:317:		writeArrayOfStructs		0.0%
github.com/gomantics/cfgx/internal/generator/struct_gen.go:374:		generateStructsAndGetters	71.8%
github.com/gomantics/cfgx/internal/generator/struct_gen.go:442:		collectNestedStructsForGetters	57.1%
github.com/gomantics/cfgx/internal/generator/struct_gen.go:471:		generateGetterMethods		62.8%
github.com/gomantics/cfgx/internal/generator/struct_gen.go:547:		generateGetterMethod		91.7%
github.com/gomantics/cfgx/internal/generator/struct_gen.go:609:		envVarName			100.0%
github.com/gomantics/cfgx/internal/generator/validation.go:10:		validateFileReferences		100.0%
github.com/gomantics/cfgx/internal/generator/validation.go:20:		validateFileReferencesValue	84.6%
github.com/gomantics/cfgx/internal/generator/validation.go:51:		needsTimeImport			100.0%
github.com/gomantics/cfgx/internal/generator/validation.go:60:		needsTimeImportValue		88.9%
github.com/gomantics/cfgx/internal/generator/validation.go:82:		isDurationString		100.0%
github.com/gomantics/cfgx/internal/generator/value_writer.go:17:	toGoType			94.1%
github.com/gomantics/cfgx/internal/generator/value_writer.go:61:	writeValue			100.0%
github.com/gomantics/cfgx/internal/generator/value_writer.go:66:	writeValueWithIndent		76.5%
github.com/gomantics/cfgx/internal/generator/value_writer.go:105:	writeByteArrayLiteral		88.2%
github.com/gomantics/cfgx/internal/generator/value_writer.go:141:	writeDurationLiteral		80.0%
github.com/gomantics/cfgx/internal/generator/value_writer.go:197:	writeArray			80.0%
github.com/gomantics/cfgx/internal/pkgutil/pkgutil.go:11:		InferName			63.6%
total:									(statements)			56.7%

@karngyan karngyan merged commit 53425db into main Oct 28, 2025
6 checks passed
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces a new "getter mode" that generates runtime-configurable code as an alternative to the existing "static mode" where values are baked at build time. The getter mode generates empty structs with getter methods that check environment variables at runtime before returning TOML defaults, making it ideal for containerized deployments and open-source projects.

Key Changes

  • Added --mode CLI flag supporting "static" (default) and "getter" modes
  • Implemented getter method generation with runtime environment variable checking and type-safe parsing
  • Generated comprehensive documentation and examples for both modes

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
readme.md Documents getter mode usage, examples, and comparison with static mode
internal/generator/struct_gen.go Implements getter method generation with env var overrides and type conversions
internal/generator/generator_test.go Adds comprehensive tests for getter mode functionality
internal/generator/generator.go Adds mode support and getter-specific import generation
example/getter_config/config.go Example generated code demonstrating getter mode output
example/gen.go Adds getter mode to go:generate directives
cmd/cfgx/main.go Adds --mode flag validation and passes mode to generator
cfgx.go Updates GenerateOptions and function signatures to support mode
Makefile Adds generate-example target

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +612 to +613
section = strings.TrimSuffix(section, "Config")
section = strings.TrimSuffix(section, "Item")
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lines 611-612 are redundant since stripSuffix() already removes 'Config' and 'Item' suffixes. These duplicate trimming operations should be removed.

Suggested change
section = strings.TrimSuffix(section, "Config")
section = strings.TrimSuffix(section, "Item")

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants