1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-11-17 18:06:15 -05:00
v2fly/infra/conf/merge/merge.go
Jebbs ff59bd37ce
v5: New multi-json loader (#451)
* scalable commands column

* new multi-json loader
For both internal & external json loader

This commit also:
* applies -confdir to other formats, e.g. "yaml" in the future
* multiple assign of -confdir is accepted
* add flag to load confdir recursively
* config loader can have alias name
* json loader also accepts .jsonc
* add merge command
* add help topics for json merge, format loader
* format loaders don't panic

* apply lint style

* add merge test

* merge same tag in array, solve v2fly/discussion#97

* apply lint style

* merge code optimize

* fix merge cmdarg.Arg

* update cmd description

* improve merge logic
* fix zero value overwrite
* fix "null" lost after array merge

* code optimize

* fix merged slices not sorted

* code optimize

* add package doc

* fix a typo
2020-11-28 22:06:03 +08:00

99 lines
2.1 KiB
Go

// Copyright 2020 Jebbs. All rights reserved.
// Use of this source code is governed by MIT
// license that can be found in the LICENSE file.
/*
Package merge provides the capbility to merge multiple
JSON files or contents into one output.
Merge Rules:
- Simple values (string, number, boolean) are overwritten, others are merged
- Elements with same "tag" (or "_tag") in an array will be merged
- Add "_priority" property to array elements will help sort the
*/
package merge
import (
"bytes"
"encoding/json"
)
// FilesToJSON merges multiple jsons files into one json, accepts remote url, or local file path
func FilesToJSON(args []string) ([]byte, error) {
m, err := FilesToMap(args)
if err != nil {
return nil, err
}
return json.Marshal(m)
}
// BytesToJSON merges multiple json contents into one json.
func BytesToJSON(args [][]byte) ([]byte, error) {
m, err := BytesToMap(args)
if err != nil {
return nil, err
}
return json.Marshal(m)
}
// FilesToMap merges multiple json files into one map, accepts remote url, or local file path
func FilesToMap(args []string) (m map[string]interface{}, err error) {
m, err = loadFiles(args)
if err != nil {
return nil, err
}
err = applyRules(m)
if err != nil {
return nil, err
}
return m, nil
}
// BytesToMap merges multiple json contents into one map.
func BytesToMap(args [][]byte) (m map[string]interface{}, err error) {
m, err = loadBytes(args)
if err != nil {
return nil, err
}
err = applyRules(m)
if err != nil {
return nil, err
}
return m, nil
}
func loadFiles(args []string) (map[string]interface{}, error) {
conf := make(map[string]interface{})
for _, arg := range args {
r, err := loadArg(arg)
if err != nil {
return nil, err
}
m, err := decode(r)
if err != nil {
return nil, err
}
if err = mergeMaps(conf, m); err != nil {
return nil, err
}
}
return conf, nil
}
func loadBytes(args [][]byte) (map[string]interface{}, error) {
conf := make(map[string]interface{})
for _, arg := range args {
r := bytes.NewReader(arg)
m, err := decode(r)
if err != nil {
return nil, err
}
if err = mergeMaps(conf, m); err != nil {
return nil, err
}
}
return conf, nil
}