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
}- 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.
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/configen- 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.
| 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.
| 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")
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: developmentPlease refer to the CONTRIBUTING.md doc.
- 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.
MIT.