Documentation
¶
Overview ¶
Package xcfg 通用的配置解析组件,已默认内置支持 .json 和 .xml 格式的配置文件
1. 支持的文件格式 ¶
默认内置支持 .json 和 .xml 格式, 支持使用 WithParser 和 MustWithParser 注册新的解析器。
2. 配置文件路径 ¶
在使用 Parse 方法解析配置文件或者使用 Exists 判断文件是否存在时,传入的配置文件路径( path 参数) 可以是绝对路径,也可以是相对于配置文件根目录 ( 读取自 xattr.ConfDir() ) 的相对路径。 同时,文件后缀是可选的,当查找文件不存在时,会添加上支持的后缀依次去判断, 如 Exists("app.toml") 会补充为完整路径 {ConfDir}/app.json、{ConfDir}/app.xml 等去判断。
3. Hooks ¶
Hook 功能会在解析配置内容时自动运行。目前内置如下几个功能:
1. 读取环境变量的值
在配置内容中使用 {env.变量名} 或者 {env.变量名|默认值}。 变量名应该是有效的环境变量名称。 环境变量的值会使用 os.Getenv( 变量名 ) 方法读取,若环境变量不存在,会返回空字符串。 如 user.json:
{"name":"{env.userName}","age":{env.age|18}}
若有环境变量值( export userName=hello ),在解析前,配置内容会被替换为:
{"name":"hello","age":18}
2. 读取 xattr 属性的值
在配置内容中使用 {xattr.属性名},可读取到 xattr 的属性值,支持的属性名仅限如下:
RootDir : 应用根目录地址,如 /home/work/myapp IDC : 应用所属机房, 如 online DataDir : 应用数据目录地址,如 /home/work/myapp/data ConfDir : 应用配置目录地址, 如 /home/work/myapp/conf TempDir : 应用临时文件目录地址, 如 /home/work/myapp/temp LogDir : 应用日志文件目录地址, 如 /home/work/myapp/log RunMode : 应用运行模式,如 product
3. Go Template 语法
该功能默认未启用,需要在配置文件的头部添加如何内容以启用该功能:
# hook.template Enable=true
以下是一个例子 ( server.toml ):
# hook.template Enable=true Port = {env.Port1} {{ include "sub1/*.toml" }} {{ include "sub2/z.toml" }}
template 语法详见 https://pkg.go.dev/text/template 。 默认内置如下自定义函数:
include : 包含指定的文件,如 include "sub2/z.toml",include "sub1/*.toml" env : 读取环境变量的值,如 env "userName" contains : 即 strings.Contains,如 contains "hello" "h" prefix : 即 strings.HasPrefix,如 contains "hello" "h" suffix : 即 strings.HasSuffix,如 contains "hello" "o"
4. 数据校验( Validator ) ¶
使用 Parser、ParseBytes 解析配置后,得的的结果可能是非预期的,如必填字段为空或者格式错误。
如典型的解析配置然后校验的逻辑为:
if err := xcfg.Parse("abc.json", &info); err != nil { return err } // 下面是校验逻辑 if info.A == "" { return fmt.Errorf("required field A is empty") }
若 info 的 struct 对象实现了 AutoChecker 接口,则在调用 Parse 解析配置内容之后,会自动调用校验逻辑。
type AutoChecker interface { AutoCheck() error }
即让 info 的 struct 定义为:
type Info struct { A string } func (in *Info)AutoCheck() error{ if in==nil || in.A==""{ return fmt.Errorf("invalid info") } return nil }
除此之外,还可以使用 Validator 实现自动校验,使用的前提是给 DefaultValidator 赋值。 如可以使用 github.com/go-playground/validator/v10 来初始化 DefaultValidator。
type Info struct { A string `validator:"required"` // A 字段必填,不能为空 }
具体顺序为:
- Validator
- AutoChecker
Index ¶
- func Exists(path string) bool
- func MustParse(path string, obj any)
- func MustParseBytes(ext string, content []byte, obj any)
- func MustWithDecoder(ext string, fn xcodec.Decoder)
- func MustWithHook(hooks ...Hook)
- func Parse(path string, obj any) error
- func ParseBytes(ext string, content []byte, obj any) error
- func WithDecoder(ext string, fn xcodec.Decoder) error
- func WithHook(hooks ...Hook) error
- type Configure
- func (c *Configure) Clone() *Configure
- func (c *Configure) CloneWithContext(ctx context.Context) *Configure
- func (c *Configure) CloneWithHook(hooks ...Hook) *Configure
- func (c *Configure) Exists(path string) bool
- func (c *Configure) MusWithHook(hooks ...Hook)
- func (c *Configure) MustWithDecoder(ext string, fn xcodec.Decoder)
- func (c *Configure) Parse(path string, obj any) error
- func (c *Configure) ParseBytes(ext string, content []byte, obj any) error
- func (c *Configure) WithDecoder(ext string, fn xcodec.Decoder) error
- func (c *Configure) WithHook(hooks ...Hook) error
- type Hook
- type HookParam
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Exists ¶
Exists 判断配置文件是否存在
path: 配置文件路径,可以是绝对路径,也可以是相对于 ConfDir 的相对路径。 文件后缀是可选的,当查找文件不存在时,会添加上支持的后缀依次去判断。 如 Exists("app.toml") 会补充为 完整路径 {ConfDir}/app.json、{ConfDir}/app.xml 等去判断
Example ¶
package main import ( "fmt" "github.com/xanygo/anygo/xcfg" ) func main() { // 配置文件 {ConfDir}/abc.json 存在: fmt.Println(xcfg.Exists("abc")) // true fmt.Println(xcfg.Exists("abc.json")) // true // 配置文件 {ConfDir}/not-found.json 不存在: fmt.Println(xcfg.Exists("not-found")) // false fmt.Println(xcfg.Exists("not-found.json")) // false }
Output: true true false false
func MustParse ¶
MustParse 调用 Parse,若返回 err != nil 则 panic
Example ¶
package main import ( "fmt" "github.com/xanygo/anygo/xcfg" ) func main() { type Info struct { A string } var info Info // 解析 配置文件 {ConfDir}/abc.json,若失败会 panic xcfg.MustParse("abc.json", &info) fmt.Printf("info.A = %q\n", info.A) }
Output: info.A = "bb"
func MustParseBytes ¶
MustParseBytes 调用 ParseBytes,若返回 err!=ni 则 panic
Example ¶
package main import ( "fmt" "github.com/xanygo/anygo/xcfg" ) func main() { type User struct { Name string Age int } content := []byte(`{"Name":"Hello","age":18}`) var user *User xcfg.MustParseBytes(".json", content, &user) // 解析失败会 panic fmt.Println("Name=", user.Name) fmt.Println("Age=", user.Age) }
Output: Name= Hello Age= 18
func MustWithDecoder ¶
MustWithDecoder 注册一个解析器,若返回的 err!=nil 则 panic
func Parse ¶
Parse 解析配置,配置文件默认认为在 conf/ 目录下, 如 有 conf/abc.toml ,则 path = "abc.toml"
Example ¶
package main import ( "fmt" "log" "github.com/xanygo/anygo/xcfg" ) func main() { type Info struct { A string } var info Info // 解析 配置文件 {ConfDir}/abc.json if err := xcfg.Parse("abc.json", &info); err != nil { log.Println(err.Error()) } fmt.Printf("info.A = %q\n", info.A) }
Output: info.A = "bb"
func ParseBytes ¶
ParseBytes 解析 bytes 内容的配置 ext: 文件后缀,如.json、.toml
Example ¶
package main import ( "fmt" "log" "github.com/xanygo/anygo/xcfg" ) func main() { type User struct { Name string Age int } content := []byte(`{"Name":"Hello","age":18}`) var user *User if err := xcfg.ParseBytes(".json", content, &user); err != nil { log.Fatalln("ParseBytes with error:", err) } fmt.Println("Name=", user.Name) fmt.Println("Age=", user.Age) }
Output: Name= Hello Age= 18
Types ¶
type Configure ¶
type Configure struct { // Dir 配置的根目录,可选,当为空时,会使用 xattr.ConfDir() Dir string // contains filtered or unexported fields }
func CloneWithContext ¶
CloneWithContext (全局)返回新的对象,并设置新的 ctx
func SetDefault ¶
func (*Configure) CloneWithContext ¶
func (*Configure) CloneWithHook ¶
func (*Configure) MusWithHook ¶
MusWithHook 注册新的 Hook, 若出现重名等异常情况会 panic