• Stars
    star
    471
  • Rank 93,216 (Top 2 %)
  • Language
    Go
  • License
    MIT License
  • Created over 6 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

📝 Go configuration manage(load,get,set,export). support JSON, YAML, TOML, Properties, INI, HCL, ENV and Flags. Multi file load, data override merge, parse ENV var. Go应用配置加载管理,支持多种格式,多文件加载,远程文件加载,支持数据合并,解析环境变量名

Config

GitHub go.mod Go version Codacy Badge Build Status Actions Status Coverage Status Go Report Card Go Reference

config - Simple, full-featured Go application configuration management tool library.

中文说明

Features

  • Support multi format: JSON(default), JSON5, INI, Properties, YAML, TOML, HCL, ENV, Flags
    • JSON content support comments. will auto clear comments
    • Other drivers are used on demand, not used will not be loaded into the application.
      • Possibility to add custom driver for your specific format
  • Support multi-file and multi-data loading
  • Support for loading configuration from system ENV
  • Support for loading configuration data from remote URLs
  • Support for setting configuration data from command line(flags)
  • Support listen and fire events on config data changed.
    • allow events: set.value, set.data, load.data, clean.data, reload.data
  • Support data overlay and merge, automatically load by key when loading multiple copies of data
  • Support for binding all or part of the configuration data to the structure
    • Support init default value by struct tag default:"def_value"
    • Support init default value from ENV default:"${APP_ENV | dev}"
  • Support get sub value by key-path, like map.key arr.2
  • Support parse ENV name and allow with default value. like envKey: ${SHELL|/bin/bash} -> envKey: /bin/zsh
  • Generic API: Get Int Uint Int64 Float String Bool Ints IntMap Strings StringMap ...
  • Complete unit test(code coverage > 95%)

Only use INI

If you just want to use INI for simple config management, recommended use gookit/ini

Load dotenv file

On gookit/ini: Provide a sub-package dotenv that supports importing data from files (eg .env) to ENV

go get github.com/gookit/ini/v2/dotenv

GoDoc

Install

go get github.com/gookit/config/v2

Usage

Here using the yaml format as an example(testdata/yml_other.yml):

name: app2
debug: false
baseKey: value2
shell: ${SHELL}
envKey1: ${NotExist|defValue}

map1:
    key: val2
    key2: val20

arr1:
    - val1
    - val21

Load data

examples code please see _examples/yaml.go:

package main

import (
    "github.com/gookit/config/v2"
    "github.com/gookit/config/v2/yaml"
)

// go run ./examples/yaml.go
func main() {
	// config.ParseEnv: will parse env var in string value. eg: shell: ${SHELL}
	config.WithOptions(config.ParseEnv)

	// add driver for support yaml content
	config.AddDriver(yaml.Driver)

	err := config.LoadFiles("testdata/yml_base.yml")
	if err != nil {
		panic(err)
	}

	// load more files
	err = config.LoadFiles("testdata/yml_other.yml")
	// can also load multi at once
	// err := config.LoadFiles("testdata/yml_base.yml", "testdata/yml_other.yml")
	if err != nil {
		panic(err)
	}

	// fmt.Printf("config data: \n %#v\n", config.Data())
}

Usage tips:

  • More extra options can be added using WithOptions(). For example: ParseEnv, ParseDefault
  • You can use AddDriver() to add the required format driver (json is loaded by default, no need to add)
  • The configuration data can then be loaded using LoadFiles() LoadStrings() etc.
    • You can pass in multiple files or call multiple times
    • Data loaded multiple times will be automatically merged by key

Bind Structure

Note: The default binding mapping tag of a structure is mapstructure, which can be changed by setting the decoder's option options.DecoderConfig.TagName

type User struct {
    Age  int  `mapstructure:"age"`
    Key  string `mapstructure:"key"`
    UserName  string `mapstructure:"user_name"`
    Tags []int  `mapstructure:"tags"`
}

user := User{}
err = config.BindStruct("user", &user)

fmt.Println(user.UserName) // inhere

Change struct tag name

config.WithOptions(func(opt *Options) {
    options.DecoderConfig.TagName = "config"
})

// use custom tag name.
type User struct {
  Age  int  `config:"age"`
  Key  string `config:"key"`
  UserName  string `config:"user_name"`
  Tags []int  `config:"tags"`
}

user := User{}
err = config.Decode(&user)

Can bind all config data to a struct:

config.Decode(&myConf)
// can also
config.BindStruct("", &myConf)

config.MapOnExists like BindStruct,but map binding only if key exists

Direct read data

  • Get integer
age := config.Int("age")
fmt.Print(age) // 100
  • Get bool
val := config.Bool("debug")
fmt.Print(val) // true
  • Get string
name := config.String("name")
fmt.Print(name) // inhere
  • Get strings(slice)
arr1 := config.Strings("arr1")
fmt.Printf("%#v", arr1) // []string{"val1", "val21"}
  • Get string map
val := config.StringMap("map1")
fmt.Printf("%#v",val) // map[string]string{"key":"val2", "key2":"val20"}
  • Value contains ENV var
value := config.String("shell")
fmt.Print(value) // "/bin/zsh"
  • Get value by key path
// from array
value := config.String("arr1.0")
fmt.Print(value) // "val1"

// from map
value := config.String("map1.key")
fmt.Print(value) // "val2"
  • Setting new value
// set value
config.Set("name", "new name")
name = config.String("name")
fmt.Print(name) // "new name"

Load from flags

Support simple flags parameter parsing, loading

// flags like: --name inhere --env dev --age 99 --debug

// load flag info
keys := []string{"name", "env", "age:int" "debug:bool"}
err := config.LoadFlags(keys)

// read
config.String("name") // "inhere"
config.String("env") // "dev"
config.Int("age") // 99
config.Bool("debug") // true

Load from ENV

// os env: APP_NAME=config APP_DEBUG=true
// load ENV info
config.LoadOSEnvs(map[string]string{"APP_NAME": "app_name", "APP_DEBUG": "app_debug"})

// read
config.Bool("app_debug") // true
config.String("app_name") // "config"

New config instance

You can create custom config instance

// create new instance, will auto register JSON driver
myConf := config.New("my-conf")

// create empty instance
myConf := config.NewEmpty("my-conf")

// create and with some options
myConf := config.NewWithOptions("my-conf", config.ParseEnv, config.ReadOnly)

Listen config change

Now, you can add a hook func for listen config data change. then, you can do something like: write data to file

Add hook func on create config:

hookFn := func(event string, c *Config) {
    fmt.Println("fire the:", event)
}

c := NewWithOptions("test", config.WithHookFunc(hookFn))
// for global config
config.WithOptions(config.WithHookFunc(hookFn))

After that, when calling LoadXXX, Set, SetData, ClearData methods, it will output:

fire the: load.data
fire the: set.value
fire the: set.data
fire the: clean.data

Watch loaded config files

To listen for changes to loaded config files, and reload the config when it changes, you need to use the https://github.com/fsnotify/fsnotify library. For usage, please refer to the example ./_example/watch_file.go

Also, you need to listen to the reload.data event:

config.WithOptions(config.WithHookFunc(func(event string, c *config.Config) {
    if event == config.OnReloadData {
        fmt.Println("config reloaded, you can do something ....")
    }
}))

When the configuration changes, you can do related things, for example: rebind the configuration to your struct.

Dump config data

Can use config.DumpTo() export the configuration data to the specified writer, such as: buffer,file

Dump to JSON file

buf := new(bytes.Buffer)

_, err := config.DumpTo(buf, config.JSON)
ioutil.WriteFile("my-config.json", buf.Bytes(), 0755)

Dump pretty JSON

You can set the default var JSONMarshalIndent or custom a new JSON driver.

config.JSONMarshalIndent = "    "

Dump to YAML file

_, err := config.DumpTo(buf, config.YAML)
ioutil.WriteFile("my-config.yaml", buf.Bytes(), 0755)

Available options

// Options config options
type Options struct {
	// parse env in string value. like: "${EnvName}" "${EnvName|default}"
	ParseEnv bool
    // ParseTime parses a duration string to time.Duration
    // eg: 10s, 2m
    ParseTime bool
	// config is readonly. default is False
	Readonly bool
	// enable config data cache. default is False
	EnableCache bool
	// parse key, allow find value by key path. default is True eg: 'key.sub' will find `map[key]sub`
	ParseKey bool
	// the delimiter char for split key path, if `FindByPath=true`. default is '.'
	Delimiter byte
	// default write format
	DumpFormat string
	// default input format
	ReadFormat string
	// DecoderConfig setting for binding data to struct
	DecoderConfig *mapstructure.DecoderConfig
	// HookFunc on data changed.
	HookFunc HookFunc
	// ParseDefault tag on binding data to struct. tag: default
	ParseDefault bool
}

Examples for set options:

config.WithOptions(config.WithTagName("mytag"))
config.WithOptions(func(opt *Options) {
    opt.SetTagNames("config")
})

Options: Parse default

Support parse default value by struct tag default

// add option: config.ParseDefault
c := config.New("test").WithOptions(config.ParseDefault)

// only set name
c.SetData(map[string]any{
    "name": "inhere",
})

// age load from default tag
type User struct {
    Age  int `default:"30"`
    Name string
    Tags []int
}

user := &User{}
goutil.MustOk(c.Decode(user))
dump.Println(user)

Output:

&config_test.User {
  Age: int(30),
  Name: string("inhere"), #len=6
  Tags: []int [ #len=0
  ],
},

API Methods Refer

Load Config

  • LoadOSEnvs(nameToKeyMap map[string]string) Load data from os ENV
  • LoadData(dataSource ...any) (err error) Load from struts or maps
  • LoadFlags(keys []string) (err error) Load from CLI flags
  • LoadExists(sourceFiles ...string) (err error)
  • LoadFiles(sourceFiles ...string) (err error)
  • LoadFromDir(dirPath, format string) (err error) Load custom format files from the given directory, the file name will be used as the key
  • LoadRemote(format, url string) (err error)
  • LoadSources(format string, src []byte, more ...[]byte) (err error)
  • LoadStrings(format string, str string, more ...string) (err error)
  • LoadFilesByFormat(format string, sourceFiles ...string) (err error)
  • LoadExistsByFormat(format string, sourceFiles ...string) error

Getting Values

  • Bool(key string, defVal ...bool) bool
  • Int(key string, defVal ...int) int
  • Uint(key string, defVal ...uint) uint
  • Int64(key string, defVal ...int64) int64
  • Ints(key string) (arr []int)
  • IntMap(key string) (mp map[string]int)
  • Float(key string, defVal ...float64) float64
  • String(key string, defVal ...string) string
  • Strings(key string) (arr []string)
  • SubDataMap(key string) maputi.Data
  • StringMap(key string) (mp map[string]string)
  • Get(key string, findByPath ...bool) (value any)

Mapping data to struct:

  • Decode(dst any) error
  • BindStruct(key string, dst any) error
  • MapOnExists(key string, dst any) error

Setting Values

  • Set(key string, val any, setByPath ...bool) (err error)

Useful Methods

  • Getenv(name string, defVal ...string) (val string)
  • AddDriver(driver Driver)
  • Data() map[string]any
  • SetData(data map[string]any) set data to override the Config.Data
  • Exists(key string, findByPath ...bool) bool
  • DumpTo(out io.Writer, format string) (n int64, err error)

Run Tests

go test -cover
// contains all sub-folder
go test -cover ./...

Projects using config

Check out these projects, which use https://github.com/gookit/config :

Gookit packages

  • gookit/ini Go config management, use INI files
  • gookit/rux Simple and fast request router for golang HTTP
  • gookit/gcli build CLI application, tool library, running CLI commands
  • gookit/event Lightweight event manager and dispatcher implements by Go
  • gookit/cache Generic cache use and cache manager for golang. support File, Memory, Redis, Memcached.
  • gookit/config Go config management. support JSON, YAML, TOML, INI, HCL, ENV and Flags
  • gookit/color A command-line color library with true color support, universal API methods and Windows support
  • gookit/filter Provide filtering, sanitizing, and conversion of golang data
  • gookit/validate Use for data validation and filtering. support Map, Struct, Form data
  • gookit/goutil Some utils for the Go: string, array/slice, map, format, cli, env, filesystem, test and more
  • More, please see https://github.com/gookit

See also

License

MIT

More Repositories

1

goutil

💪 Helper Utils(700+): int, byte, string, array/slice, map, struct, dump, convert/format, error, web/http, cli/flag, OS/ENV, filesystem, system, test/assert, time and more. Go 常用的一些工具函数:数字,字符串,数组,Map,结构体,反射,文本,文件,错误,时间日期,特殊处理,格式化,常用信息获取等等
Go
1,480
star
2

color

🎨 Terminal color rendering library, support 8/16 colors, 256 colors, RGB color rendering output, support Print/Sprintf methods, compatible with Windows. GO CLI 控制台颜色渲染工具库,支持16色,256色,RGB色彩渲染输出,使用类似于 Print/Sprintf,兼容并支持 Windows 环境的色彩渲染
Go
1,342
star
3

validate

⚔ Go package for data validation and filtering. support Map, Struct, Form data. Go通用的数据验证与过滤库,使用简单,内置大部分常用验证、过滤器,支持自定义验证器、自定义消息、字段翻译。
Go
904
star
4

event

📢 Lightweight event manager and dispatcher implements by Go. Go实现的轻量级的事件管理、调度程序库, 支持设置监听器的优先级, 支持使用通配符来进行一组事件的监听
Go
395
star
5

gcli

🖥 Go CLI application, tool library, running CLI commands, support console color, user interaction, progress display, data formatting display, generate bash/zsh completion add more features. Go的命令行应用,工具库,运行CLI命令,支持命令行色彩,用户交互,进度显示,数据格式化显示,生成bash/zsh命令补全脚本
Go
314
star
6

slog

📑 Lightweight, configurable, extensible logging library written in Go. Support multi level, multi outputs and built-in multi file logger, buffers, clean, rotate-file handling.一个易于使用的,轻量级、可配置、可扩展的日志库。支持多个级别,输出到多文件;内置文件日志处理、自动切割、清理、压缩等增强功能
Go
266
star
7

cache

🗃 Generic cache use and cache manage. Provide a unified usage API by packaging various commonly used drivers. Support File, Memory, Redis, Memcached and more. Go 通用的缓存使用库,通过包装各种常用的驱动,来提供统一的使用API,便于使用。
Go
166
star
8

filter

⏳ Provide filtering, sanitizing, and conversion of Golang data. 提供对Golang数据的过滤,净化,转换。
Go
131
star
9

rux

⚡ Rux is an simple and fast web framework. support route group, param route binding, middleware, compatible http.Handler interface. 简单且快速的 Go api/web 框架,支持路由分组,路由参数绑定,中间件,兼容 http.Handler 接口
Go
91
star
10

ini

📝 Go INI config management. support multi file load, data override merge. parse ENV variable, parse variable reference. Dotenv file parse and loader. INI配置读取管理,支持多文件加载,数据覆盖合并, 解析ENV变量, 解析变量引用。DotEnv 解析加载
Go
73
star
11

gitw

🛠 Git command wrapper, git emojis, generate changelog, get repo, branch, remote information and some git command tools. Git 命令包装器,生成 git 变更记录日志,获取 repo,branch,remote 信息和一些 git 命令工具。
Go
26
star
12

i18n

🏳️An simple i18n messages manage implement, use INI files. 使用INI格式文件,实现的简单方便的语言加载与管理
Go
16
star
13

properties

📝 Java Properties format contents parse, marshal and unmarshal library. Java Properties 格式内容的解析器,编码解码库
Go
8
star
14

nako

A lightweight go web framework.
Go
5
star
15

greq

🛠 greq is a simple http client request builder and sender.
Go
5
star
16

di

Lightweight dependency injection container implements by Go
Go
4
star
17

easytpl

A simple view renderer based on the `html/template`, but much simpler to use. support layout rendering, including templates. 简单的视图渲染工具包,基于原生的 html/template 包,支持布局文件渲染,支持加载多目录,多文件,渲染字符串模板等。
Go
4
star
18

gsr

Go Standards Recommendations - common interfaces. e.g: cache, logger. Golang 一些通用的接口定义
Go
3
star
19

lako

A lightweight go web framework.
Go
3
star
20

webproxy

Go
2
star
21

gookit.github.io

Some useful libs for the Golang: router, DI, log, config, cache, event, validate, filter, CLI, i18n, respond-data, view-render
HTML
2
star
22

chain

A simple HTTP middleware chain implement. 一个简单的HTTP中间件chain实现。
Go
2
star
23

respond

respond Text, HTML, XML, JSON, JSONP data to http.ResponseWriter. 响应不同格式的数据到HTTP客户端
Go
2
star
24

rux-middles

1
star
25

golib

go lib projects
Go
1
star
26

.github

.github common template files for the organization
1
star