kukymbr/configen
The go:generate tool to create YAML, .env and go read-only getter files from the golang struct.
configen
The configen is a config files generator for the Golang, converting this:
package readme
type config struct {
InstanceID int `env:"INSTANCE_ID" default:"1" yaml:"instance_id"`
// App is an application common settings.
App struct {
Env string `env:"ENV" default:"development" yaml:"env"`
Namespace string `env:"NAMESPACE" default:"unknown" yaml:"namespace"`
Domain string `env:"DOMAIN" yaml:"domain"`
} `envPrefix:"APP_" yaml:"app"`
// Logger is a logging setup values.
Logger struct {
Level string `env:"LEVEL" default:"debug" yaml:"level"`
} `envPrefix:"LOG_" yaml:"logger"`
}into this:
instance_id: 1
# App is an application common settings.
app:
env: development
namespace: unknown
domain: ""
# Logger is a logging setup values.
logger:
level: debugand this:
INSTANCE_ID=1
APP_ENV=development
APP_NAMESPACE=unknown
APP_DOMAIN=
LOG_LEVEL=debugAlso, the configen is able to generate a new go struct with read-only getters of the config value.
See the example of generated struct
package readme
type Config struct {
instanceID int
app struct {
env string
namespace string
domain string
}
logger struct {
level string
}
origin any
}
func (c Config) InstanceID() int {
return c.instanceID
}
// App is an application common settings.
func (c Config) App() struct {
env string
namespace string
domain string
} {
return c.app
}
// Logger is a logging setup values.
func (c Config) Logger() struct {
level string
} {
return c.logger
}
// NewConfig is a constructor converting config into the Config.
func NewConfig(dto config) Config {
return Config{
instanceID: dto.InstanceID,
app: struct {
env string
namespace string
domain string
}{
env: dto.App.Env,
namespace: dto.App.Namespace,
domain: dto.App.Domain,
},
logger: struct {
level string
}{
level: dto.Logger.Level,
},
origin: dto,
}
}
type ConfigAppProvider struct {
env string
namespace string
domain string
origin any
}
func (c ConfigAppProvider) Env() string {
return c.env
}
func (c ConfigAppProvider) Namespace() string {
return c.namespace
}
func (c ConfigAppProvider) Domain() string {
return c.domain
}
type ConfigLoggerProvider struct {
level string
origin any
}
func (c ConfigLoggerProvider) Level() string {
return c.level
}Why?
- To simplify the creation of config files, obviously;
- and to easily keep up to date an example config files when the config structure has changed;
- to see all the available config values in one place;
- to hide config values behind the read-only struct.
Installation
The go 1.24 is a minimal requirement for the configen.
The go tool is a preferred way to install:
go get -tool github.com/kukymbr/configen/cmd/configenUsage
- Create the structure you want to generate files from, e.g.
Config; - set the structure tags (see the available in the table below),
- add the
//go:generatedirective (rungo tool configen --helpfor available flags):package config //go:generate go tool configen --struct=Config --yaml=true --env=true
- run the
go generatecommand:go generate ./...
- enjoy the generated files.
Supported struct tags
| Tag | Value |
|---|---|
yaml |
key for the value in YAML file, or - to skip |
env |
key for the value in dotenv file, fields without this tag are not added to env file |
envPrefix |
prefix for sub-structs in dotenv file |
default |
default value to write to config files, prioritized for YAML |
envDefault |
default value to write to config files, prioritized for env |
example |
default value to write to config files, general use (to use with swaggo for example) |
See the example directory for usage and generated code example.
Command arguments to generate things
| Argument | Required | Value |
|---|---|---|
--struct=<StructName> |
✅ | Name of the struct to generate config from |
--source=<dir> |
Directory of the source go files (default .) |
|
--yaml=<filepath/true> |
Path to YAML config file, set true to enable with default path |
|
--yaml-tag=<tag> |
Tag name for a YAML field names (default yaml) |
|
--env=<filepath/true> |
Path to dotenv config file, set true to enable with default path |
|
--env-tag=<tag> |
Tag name for a dotenv variables names (default env) |
|
--env-prefix-tag=<tag> |
Tag name for a dotenv subs-struct variables prefixes (default envPrefix) |
|
--go=<filepath/true> |
Path to Golang config getter file, set true to enable with default path |
|
--go-pkg=<package> |
Target package name (default is equal to source package) | |
--go-struct=<StructName> |
Target struct name (default is exported variant of incoming struct name) | |
--value-tag=<tag> |
Custom tag name for default values |
The configen --help output
Usage:
configen [flags]
Flags:
--env string Path to dotenv config file, set 'true' to enable with default path
--env-prefix-tag string Tag name for a dotenv variable prefixes (default "envPrefix")
--env-tag string Tag name for a dotenv variables names (default "env")
--go string Path to Golang config getter file, set 'true' to enable with default path
--go-pkg string Target package name
--go-struct string Target struct name (default is exported variant of incoming struct name)
-h, --help help for configen
-s, --silent Silent mode
--source string Directory of the source go files (default ".")
--struct string Name of the struct to generate config from
--value-tag string Tag name for a default value, prepends the default lookup if given
-v, --version version for configen
--yaml string Path to YAML config file, set 'true' to enable with default path
--yaml-tag string Tag name for a YAML field names (default "yaml")
Generating multiple versions from one struct
Sometimes you need to generate multiple versions of the config file, for example, for different environments.
To do this, you can use the --value-tag flag to specify a custom tag name for default values.
For example, to generate two YAMLs for production and local environments:
package config
//go:generate go run ../../cmd/configen/main.go --source=. --struct=MultiConfig --yaml=production.yaml
//go:generate go run ../../cmd/configen/main.go --source=. --struct=MultiConfig --yaml=local.yaml --yaml-tag=local --value-tag=localDefault
type MultiConfig struct {
Env string `yaml:"env" default:"production" local:"env" localDefault:"development"`
ProductionOnlyValue string `yaml:"production_only_value" local:"-" default:"very productional value"`
}This will give you two YAML files with different keys presence and values:
# production.yaml
env: production
production_only_value: very productional value# local.yaml
env: developmentContributing
Please refer to the CONTRIBUTING.md doc.
TODO
- Add an empty value check in go generator (for basic types), for example:
func NewAppConfig(dto appConfig) AppConfig { if dto.env == "" { dto.env = "development" } return AppConfig{ env: dto.Env, } }
- Make an option to include/exclude origin in generated structs.
License
MIT.