A library to manage application configurations, especially useful for multi-command applications, where each command needs a different subset of configurations.
It leverages Viper for handling configurations, while adding support for:
- marking required configurations within configuration files
- using different subsets of a common configuration for various commands of an application e.g.
Configuration file (config.yaml
):
# all configurations (with default values, if any)
server:
host: localhost
port:
ttl: 30s
# names of required configurations (for a single command application)
required:
main:
server:
host:
port:
Environment:
export SERVER_PORT=80
Code:
package main
import (
"time"
"github.com/zaininfo/comic"
)
type Config struct {
Server Server `mapstructure:"SERVER"`
TTL time.Duration `mapstructure:"TTL"`
}
type Server struct {
Host string `mapstructure:"HOST"`
Port int `mapstructure:"PORT"`
}
func mustLoad() Config {
var cfg Config
comic.MustLoad(&cfg)
return cfg
}
func main() {
// cfg := mustLoad()
}
Please, check Viper documentation for all supported config file types and config data types.
Note that mapstructure
tags are used to unmarshal configuration data.
The following options can be used to change the behavior of Comic.
Name | Default | Description |
---|---|---|
ConfigFileName | config | The name of the configuration file (without extension, but actual file name should have appropriate extension). |
ConfigFilePath | . (working directory) | The path to the configuration file. |
SingleCommandAppName | main | The name used in the required section of the configuration file for a single command application. |
EnvVarNestedKeySeparator | _ | The separator used for referring to nested environment variables. |
New()
- It returns a new instance of Comic with default options.
NewWithOptions(opts Options)
- It returns a new instance of Comic with supplied options.
FromCommandPath(commandPath string)
- It removes the binary name from the supplied command path and returns the rest of it.
Viper()
- It returns the Viper instance in use by Comic, which is unique for package-level exported Comic and all instances of Comic.
MustLoad(cfg interface{})
- It loads configurations from file & environment into
cfg
after verifying all required configurations; it panics on failure.
- It loads configurations from file & environment into
MustLoadForCommand(cfg interface{}, commandName string)
- It loads configurations from file & environment into
cfg
after verifying all required configurations ofcommandName
; it panics on failure.
- It loads configurations from file & environment into
Load(cfg interface{})
- Same as
MustLoad(cfg interface{})
, but returns an error on failure.
- Same as
LoadForCommand(cfg interface{}, commandName string)
- Same as
MustLoadForCommand(cfg interface{}, commandName string)
, but returns an error on failure.
- Same as
The Viper()
& all *Load*()
functions can be called on both package-level exported Comic and an instance of Comic.
Important: the configuration structure passed to any of the *Load*()
functions should be a pointer.
Configuration file (config.yaml
):
# all configurations (with default values, if any)
server:
host: localhost
port:
ttl: 30s
db_connections:
# names of required configurations (for all commands of the application)
required:
api:
server:
host:
port:
db_connections:
indexer:
db_connections:
Environment (api
):
export SERVER_PORT=80
export DB_CONNECTIONS=5
Environment (indexer
):
export DB_CONNECTIONS=5
Code:
package config
import (
"time"
"github.com/zaininfo/comic"
)
type Config struct {
Server Server `mapstructure:"SERVER"`
TTL time.Duration `mapstructure:"TTL"`
DBConnections int `mapstructure:"DB_CONNECTIONS"`
}
type Server struct {
Host string `mapstructure:"HOST"`
Port int `mapstructure:"PORT"`
}
func mustLoad(commandName string) Config {
var cfg Config
comic.MustLoadForCommand(&cfg, commandName)
return cfg
}
func main() {
// apiCfg := mustLoad("api")
// indexerCfg := mustLoad("indexer")
}
Q: What's with it being comical?
A: It's Configuration For Multiple Command Applications.