Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for .properties configuration file #1806

Merged
merged 12 commits into from
May 13, 2022
15 changes: 8 additions & 7 deletions encoding/gjson/gjson.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@ import (
)

const (
ContentTypeJson = `json`
ContentTypeJs = `js`
ContentTypeXml = `xml`
ContentTypeIni = `ini`
ContentTypeYaml = `yaml`
ContentTypeYml = `yml`
ContentTypeToml = `toml`
ContentTypeJson = `json`
ContentTypeJs = `js`
ContentTypeXml = `xml`
ContentTypeIni = `ini`
ContentTypeYaml = `yaml`
ContentTypeYml = `yml`
ContentTypeToml = `toml`
ContentTypeProperties = `properties`
)

const (
Expand Down
28 changes: 28 additions & 0 deletions encoding/gjson/gjson_api_encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package gjson

import (
"github.com/gogf/gf/v2/encoding/gini"
"github.com/gogf/gf/v2/encoding/gproperties"
"github.com/gogf/gf/v2/encoding/gtoml"
"github.com/gogf/gf/v2/encoding/gxml"
"github.com/gogf/gf/v2/encoding/gyaml"
Expand Down Expand Up @@ -197,3 +198,30 @@ func (j *Json) MustToIni() []byte {
func (j *Json) MustToIniString() string {
return string(j.MustToIni())
}

// ========================================================================
// properties
// ========================================================================
// Toproperties json to properties
func (j *Json) ToProperties() ([]byte, error) {
return gproperties.Encode(j.Map())
}

// TopropertiesString properties to string
func (j *Json) ToPropertiesString() (string, error) {
b, e := j.ToProperties()
return string(b), e
}

func (j *Json) MustToProperties() []byte {
result, err := j.ToProperties()
if err != nil {
panic(err)
}
return result
}

// MustTopropertiesString
func (j *Json) MustToPropertiesString() string {
return string(j.MustToProperties())
}
7 changes: 7 additions & 0 deletions encoding/gjson/gjson_api_new_load.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"reflect"

"github.com/gogf/gf/v2/encoding/gini"
"github.com/gogf/gf/v2/encoding/gproperties"
"github.com/gogf/gf/v2/encoding/gtoml"
"github.com/gogf/gf/v2/encoding/gxml"
"github.com/gogf/gf/v2/encoding/gyaml"
Expand Down Expand Up @@ -288,6 +289,10 @@ func doLoadContentWithOptions(data []byte, options Options) (*Json, error) {
if data, err = gini.ToJson(data); err != nil {
return nil, err
}
case ContentTypeProperties:
if data, err = gproperties.ToJson(data); err != nil {
return nil, err
}

default:
err = gerror.NewCodef(
Expand Down Expand Up @@ -335,6 +340,8 @@ func checkDataType(content []byte) string {
(gregex.IsMatch(`[\n\r]*[\s\t\w\-\."]+\s*=\s*".+"`, content) || gregex.IsMatch(`[\n\r]*[\s\t\w\-\."]+\s*=\s*\w+`, content)) {
// Must contain "[xxx]" section.
return ContentTypeIni
} else if gregex.IsMatch(`[\n\r]*[\s\t\w\-\."]+\s*=\s*\w+`, content) {
return ContentTypeProperties
} else {
return ""
}
Expand Down
74 changes: 74 additions & 0 deletions encoding/gproperties/gproperties.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.

// Package gproperties provides accessing and converting for .properties content.
package gproperties

import (
"bufio"
"bytes"
"fmt"
"io/ioutil"
"os"

"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/internal/json"
"github.com/gogf/gf/v2/os/gtime"
"github.com/spf13/viper"
)

// Decode converts properties format to map.
func Decode(data []byte) (res map[string]interface{}, err error) {
res = make(map[string]interface{})
var (
bytesReader = bytes.NewReader(data)
bufioReader = bufio.NewReader(bytesReader)
)
vp := viper.New()
vp.SetConfigType("properties")
if err = vp.ReadConfig(bufioReader); err != nil {
err = gerror.Wrapf(err, `viper ReadConfog failed`)
return nil, err
}
res = vp.AllSettings()
return res, nil
}

// Encode converts map to properties format.
func Encode(data map[string]interface{}) (res []byte, err error) {
var (
//w = new(bytes.Buffer)
vp = viper.New()
tmpFileName = fmt.Sprintf("vp_tmp_config%s", gtime.Now().Format("YmdHis"))
)
vp.SetConfigName(tmpFileName)
vp.SetConfigType("properties")
vp.AddConfigPath(".")
vp.MergeConfigMap(data)
if err = vp.SafeWriteConfig(); err != nil {
err = gerror.Wrapf(err, `viper WriteConfog failed`)
return nil, err
}
tmpFileNameP := tmpFileName + ".properties"
res, err = ioutil.ReadFile(tmpFileNameP)
defer os.Remove(tmpFileNameP)

if err != nil {
err = gerror.Wrapf(err, `Read viper tmp file failed`)
return nil, err
}

return res, nil
}

// ToJson convert .properties format to JSON.
func ToJson(data []byte) (res []byte, err error) {
iniMap, err := Decode(data)
if err != nil {
return nil, err
}
return json.Marshal(iniMap)
}
89 changes: 89 additions & 0 deletions encoding/gproperties/gproperties_z_unit_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.

// Package gproperties provides accessing and converting for properties content.
package gproperties_test

import (
"encoding/json"
"fmt"
"testing"

"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/encoding/gproperties"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/test/gtest"
)

var pStr string = `
# template
data = "/home/www/templates/"
# MySQL
sql.disk.0 = 127.0.0.1:6379,0
sql.cache.0 = 127.0.0.1:6379,1=
sql.cache.1=0
sql.disk.a = 10
`

func TestDecode(t *testing.T) {
gtest.C(t, func(t *gtest.T) {

decodeStr, err := gproperties.Decode(([]byte)(pStr))
if err != nil {
t.Errorf("decode failed. %v", err)
return
}
fmt.Printf("%v\n", decodeStr)
v, _ := json.Marshal(decodeStr)
fmt.Printf("%v\n", string(v))
})
}
func TestEncode(t *testing.T) {
gtest.C(t, func(t *gtest.T) {

encStr, err := gproperties.Encode(map[string]interface{}{
"sql": g.Map{
"userName": "admin",
"password": "123456",
},
"user": "admin",
"no": 123,
})
if err != nil {
t.Errorf("decode failed. %v", err)
return
}
fmt.Printf("%v\n", string(encStr))
})
}

func TestToJson(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
res, err := gproperties.Encode(map[string]interface{}{
"sql": g.Map{
"userName": "admin",
"password": "123456",
},
"user": "admin",
"no": 123,
})
fmt.Print(string(res))
jsonPr, err := gproperties.ToJson(res)
if err != nil {
t.Errorf("ToJson failed. %v", err)
return
}
fmt.Print(string(jsonPr))

p := gjson.New(res)
expectJson, err := p.ToJson()
if err != nil {
t.Errorf("parser ToJson failed. %v", err)
return
}
t.Assert(jsonPr, expectJson)
})
}
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ require (
github.com/gorilla/websocket v1.5.0
github.com/grokify/html-strip-tags-go v0.0.1
github.com/olekukonko/tablewriter v0.0.5
github.com/spf13/viper v1.11.0
go.opentelemetry.io/otel v1.0.0
go.opentelemetry.io/otel/sdk v1.0.0
go.opentelemetry.io/otel/trace v1.0.0
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2
golang.org/x/net v0.0.0-20220412020605-290c469a71a5
golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
)
Loading