// main.go
package main
import (
"fmt"
"os"
"strings"
"github.com/Bofry/config"
)
func init() {
// set env
{
// NOTE: you can run the following commands in bash
// export ENVIRONMENT=production
// export REDIS_HOST=127.0.0.3:6379
// export REDIS_PASSWORD=1234
// export K8S_REDIS_HOST=demo-kubernetes:6379
// export K8S_REDIS_PASSWORD=p@ssw0rd
// export K8S_REDIS_DB=6
os.Clearenv()
os.Setenv("ENVIRONMENT", "production")
os.Setenv("REDIS_HOST", "127.0.0.3:6379")
os.Setenv("REDIS_PASSWORD", "1234")
os.Setenv("K8S_REDIS_HOST", "demo-kubernetes:6379")
os.Setenv("K8S_REDIS_PASSWORD", "p@ssw0rd")
os.Setenv("K8S_REDIS_DB", "6")
}
// generate .env
{
os.WriteFile(".env", []byte(
strings.Join([]string{
"REDIS_HOST=127.0.0.1:6379",
"REDIS_DB=29",
"TAG=demo,test",
}, "\n")), 0644)
}
// generate .VERSION
{
os.WriteFile(".VERSION", []byte(
strings.Join([]string{
"v1.0.2",
}, "\n")), 0644)
}
// generate config.yaml
{
os.WriteFile("config.yaml", []byte(
strings.Join([]string{
"redisDB: 3",
"redisPoolSize: 10",
"workspace: demo_test",
}, "\n")), 0644)
}
// generate config.staging.yaml
{
os.WriteFile("config.staging.yaml", []byte(
strings.Join([]string{
"redisDB: 9",
"redisPoolSize: 10",
"workspace: demo_stag",
}, "\n")), 0644)
}
// generate config.production.yaml
{
os.WriteFile("config.production.yaml", []byte(
strings.Join([]string{
"redisDB: 12",
"redisPoolSize: 50",
"workspace: demo_prod",
}, "\n")), 0644)
}
}
type DummyConfig struct {
RedisHost string `env:"REDIS_HOST" yaml:"redisHost" arg:"redis-host;the Redis server address and port"`
RedisPassword string `env:"REDIS_PASSWORD" yaml:"redisPassword" arg:"redis-passowrd;the Redis password"`
RedisDB int `env:"REDIS_DB" yaml:"redisDB" arg:"redis-db;the Redis database number"`
RedisPoolSize int `env:"-" yaml:"redisPoolSize"`
Workspace string `env:"-" yaml:"workspace" arg:"workspace;the data workspace"`
Tags []string `env:"TAG"`
Version string `resource:".VERSION"`
}
func main() {
conf := DummyConfig{}
config.NewConfigurationService(&conf).
LoadDotEnv().
LoadEnvironmentVariables("").
LoadEnvironmentVariables("K8S").
LoadYamlFile("config.yaml").
LoadYamlFile("config.${ENVIRONMENT}.yaml").
LoadCommandArguments().
LoadResource("")
fmt.Printf("RedisHost = %q\n", conf.RedisHost)
fmt.Printf("RedisPassword = %q\n", conf.RedisPassword)
fmt.Printf("RedisDB = %d\n", conf.RedisDB)
fmt.Printf("RedisPoolSize = %d\n", conf.RedisPoolSize)
fmt.Printf("Workspace = %q\n", conf.Workspace)
fmt.Printf("Tags = %q\n", conf.Tags)
fmt.Printf("Version = %q\n", conf.Version)
}
Open your terminal and execute the following command:
- Bash
$ go build -o example $ ./example -redis-db=32
- Dos
C:\> go build -o example.exe C:\> example.exe -redis-db=32
You will get:
RedisHost = "demo-kubernetes:6379"
RedisPassword = "p@ssw0rd"
RedisDB = 32
RedisPoolSize = 50
Workspace = "demo_prod"
Tags = ["demo" "test"]
Version = "v1.0.2"
configuration type | struct tag | tag flags | ConfigurationService method | example |
---|---|---|---|---|
environment variables | env |
required | LoadEnvironmentVariables() | env:"CACHE_ADDRESS,required" -or- env:"*CACHE_ADDRESS" |
.env files | env |
required | LoadDotEnv(), LoadDotEnvFile() | env:"CACHE_ADDRESS,required" -or- env:"*CACHE_ADDRESS" |
json files | json |
-- | LoadJsonFile() | json:"LISTEN_PORT" |
yaml files | yaml |
-- | LoadYamlFile() | yaml:"LISTEN_PORT" |
binary reource files | resource |
required | LoadResource() | resource:"VERSION,required" -or- resource:"*VERSION" |
text reource files | resource |
required | LoadResource() | resource:"VERSION,required" -or- resource:"*VERSION" |
command arguments | arg |
-- | LoadCommandArguments() | arg:"SERVER_NAME" -or- arg:"SERVER_NAME;specify server name" |
📝 The
resource:"VERSION,required"
is equivalent toresource:"*VERSION"
, but not equivalent toresource:"*VERSION,required"
. For examples:
tag name flag resource:"VERSION,required"
VERSION required
resource:"*VERSION"
VERSION required
resource:"*VERSION,required"
*VERSION required
resource:"*VERSION,required,_"
*VERSION required
resource:"*VERSION,_"
*VERSION none resource:"VERSION,_"
VERSION none 📝 If you want reserve the start "
*
" in name and keep the setting to optional, to append the blank flag "_
" to tag.📝 The nested struct on tag env, resource, and arg ARE NOT SUPPORTED. And field type can be defined as
bool
,int
,uint
,float
,string
,time.Duration
,time.Time
,url.URL
,net.IP
,[]bool
,[]int
,[]uint
,[]float
,[]string
,[]time.Duration
,[]time.Time
,[]url.URL
,[]net.IP
,bytes.Buffer
,json.RawMessage
, orgit.luolix.top/Bofry/types.RawContent
.
⠿ The following Config structure will import environment variables CACHE_HOST
, CACHE_PASSWORD
, and CACHE_DB
. The tag text env:"CACHE_HOST,required"
use the flag required indicates the environment variable CACHE_HOST
is required. It will get exception if the variable doesn't be assgined.
type Config struct {
CacheHost string `env:"CACHE_HOST,required"`
CachePassword string `env:"CACHE_PASSWORD"`
CacheDB int `env:"CACHE_DB"`
}
The tag form env:"CACHE_HOST,required"
also can be written as env:"*CACHE_HOST"
. Put the symbol "*
" in front of the name is equivalent to appending required
to tag flag part.
type Config struct {
CacheHost string `env:"*CACHE_HOST"`
CachePassword string `env:"CACHE_PASSWORD"`
CacheDB int `env:"CACHE_DB"`
}
⠿ The .env files same as Environment Variables.
📝 The .env file WILL NOT OVERRIDE an environment variable that already exists. To consider .env file to set dev variable or sensible defaults.
⠿ The following Config structure will import content from file VERSION. The tag text resource:"VERSION,required"
use the flag required indicates the file VERSION is required. It will get exception if the file doesn't exist.
type Config struct {
AppVersion string `resource:"VERSION,required"`
}
The tag form resource:"VERSION,required"
also can be written as resource:"*VERSION"
. Put the symbol "*
" in front of the name is equivalent to appending required
to tag flag part.
type Config struct {
AppVersion string `resource:"*VERSION"`
}
📝 The name can compose by any unicode but no space character at the start or end, and no period at the end.
⠿ The following Config structure will import command arguments cache-host
, cache-passowrd
, and cache-db
. The tag text arg:"cache-host;the cache server address and port"
separated by symbol ";
" to two parts. The name part and the usage text part for help.
type Config struct {
CacheHost string `arg:"cache-host;the cache server address and port"`
CachePassword string `arg:"cache-passowrd;the cache server password"`
CacheDB int `arg:"cache-db;the cache database number"`
}
⛔ Don't name arg as
help
.