Skip to content

Commit

Permalink
up: update and modify some parse logic, binding value
Browse files Browse the repository at this point in the history
  • Loading branch information
inhere committed Jul 28, 2022
1 parent 6352dee commit 4b7c771
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 27 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Properties

![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/gookit/properties?style=flat-square)
[![Actions Status](https://github.com/gookit/properties/workflows/action-tests/badge.svg)](https://github.com/gookit/properties/actions)
[![Unit-Tests](https://github.com/gookit/properties/actions/workflows/go.yml/badge.svg)](https://github.com/gookit/properties/actions/workflows/go.yml)
[![GitHub tag (latest SemVer)](https://img.shields.io/github/tag/gookit/properties)](https://github.com/gookit/properties)
[![GoDoc](https://godoc.org/github.com/gookit/properties?status.svg)](https://pkg.go.dev/github.com/gookit/properties/v3)
[![Go Report Card](https://goreportcard.com/badge/github.com/gookit/properties)](https://goreportcard.com/report/github.com/gookit/properties)
Expand Down
2 changes: 1 addition & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Properties

![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/gookit/properties?style=flat-square)
[![Actions Status](https://github.com/gookit/properties/workflows/action-tests/badge.svg)](https://github.com/gookit/properties/actions)
[![Unit-Tests](https://github.com/gookit/properties/actions/workflows/go.yml/badge.svg)](https://github.com/gookit/properties/actions/workflows/go.yml)
[![GitHub tag (latest SemVer)](https://img.shields.io/github/tag/gookit/properties)](https://github.com/gookit/properties)
[![GoDoc](https://godoc.org/github.com/gookit/properties?status.svg)](https://pkg.go.dev/github.com/gookit/properties/v3)
[![Go Report Card](https://goreportcard.com/badge/github.com/gookit/properties)](https://goreportcard.com/report/github.com/gookit/properties)
Expand Down
7 changes: 7 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,10 @@ module github.com/gookit/properties
go 1.18

require github.com/gookit/goutil v0.5.7

require (
github.com/gookit/color v1.5.1 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8=
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
Expand All @@ -27,6 +28,7 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
12 changes: 0 additions & 12 deletions lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,6 @@ func lex(text string) *lexer {
}
}

type tokenItem struct {
kind rune
keys []string

key, val string
comment string
}

func (ti *tokenItem) Valid() bool {
return ti.kind != 0
}

func (l *lexer) parse() error {
r := strings.NewReader(l.text)

Expand Down
120 changes: 111 additions & 9 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,52 @@ import (
"io"
"strings"

"github.com/gookit/goutil/arrutil"
"github.com/gookit/goutil/errorx"
"github.com/gookit/goutil/maputil"
"github.com/gookit/goutil/strutil"
)

// special chars consts
const (
MultiLineValMarkS = "'''"
MultiLineValMarkD = `"""`
MultiLineCmtEnd = "*/"
)

// token consts
const (
TokMLComments = 'C'
TokMLValMarkS = 'm' // multi line value by single quotes: '''
TokMLValMarkD = 'M' // multi line value by double quotes: """
)

type tokenItem struct {
kind rune
// key path string. eg: top.sub.some-key
path string
keys []string

// for multi line value.
values []string
// for multi line comments.
comments []string
}

func (ti *tokenItem) setPath(path string) {
ti.path = path
// TODO check path valid

if strings.ContainsRune(path, '.') {
ti.keys = strings.Split(path, ".")
}
}

// Valid of the token data.
func (ti *tokenItem) Valid() bool {
return ti.kind != 0
}

// Options for config
type Options struct {
// ParseEnv parse ENV var name, default True. eg: "${SHELL}"
Expand Down Expand Up @@ -51,13 +86,6 @@ func NewParser() *Parser {
}
}

// token consts
const (
TokMLComments = 'C'
TokMLValMarkS = 'm' // multi line value by single quotes: '''
TokMLValMarkD = 'M' // multi line value by double quotes: """
)

// Parse text contents
func (p *Parser) Parse(text string) error {
return p.ParseReader(strings.NewReader(text))
Expand All @@ -72,6 +100,9 @@ func (p *Parser) ParseReader(r io.Reader) error {
var line int
var key, val, comments string

// TODO
// var ti tokenItem

for s.Scan() { // split by '\n'
line++

Expand Down Expand Up @@ -187,9 +218,18 @@ func (p *Parser) ParseReader(r io.Reader) error {
if pos := strings.IndexRune(val[1:], '"'); pos > -1 {
val = val[1 : pos+1]
}
} else {
// split inline comments
var comment string
val, comment = splitInlineComment(val)
if len(comment) > 0 {
if len(comments) > 0 {
comments += "\n" + comment
} else {
comments += comment
}
}
}

// TODO inline comments
}

if len(comments) > 0 {
Expand All @@ -203,6 +243,68 @@ func (p *Parser) ParseReader(r io.Reader) error {
return nil
}

// Err last error
func (p *Parser) setValue(ti tokenItem) error {
if !ti.Valid() {
return nil
}

if len(ti.comments) > 0 {
p.comments[ti.path] = strings.Join(ti.comments, "\n")
}

valueString := strings.Join(ti.values, "\n")
p.smap[ti.path] = valueString

// set value by keys
if len(ti.keys) == 1 {
p.Data[ti.path] = valueString
} else {
// mp = buildValueByPath(ti.keys, value)
_, err := maputil.SetByKeys(p.Data, ti.keys, valueString)
if err != nil {
return err
}
}

return p.err
}

// build new value by key paths
// "site.info" -> map[string]map[string]val
func buildValueByPath(paths []string, val interface{}) (newItem map[string]interface{}) {
if len(paths) == 1 {
return map[string]interface{}{paths[0]: val}
}

arrutil.Reverse(paths)

// multi nodes
for _, p := range paths {
if newItem == nil {
newItem = map[string]interface{}{p: val}
} else {
newItem = map[string]interface{}{p: newItem}
}
}
return
}

func splitInlineComment(val string) (string, string) {
if pos := strings.IndexRune(val, '#'); pos > -1 {
return strings.TrimRight(val[0:pos], " "), val[pos:]
}

if pos := strings.Index(val, "//"); pos > -1 {
return strings.TrimRight(val[0:pos], " "), val[pos:]
}

// if pos := strings.Index(val, "/*"); pos > -1 {
// return val[0:pos], val[pos:]
// }
return val, ""
}

// Err last error
func (p *Parser) Err() error {
return p.err
Expand Down
7 changes: 3 additions & 4 deletions parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ top.sub.key2-other = has-char
# comments 2
top.sub.key3 = false
top.sub.key4[0] = abc # comments at end1
top.sub.key4[1] = def /* comments at end2 */
top.sub.key4[2] = def // comments at end3
top.sub.key4[1] = def // comments at end2
## --- comments 3 ---
top.sub.key5[0].f1 = ab
top.sub.key5[1].f2 = de
Expand Down Expand Up @@ -59,7 +58,7 @@ key1 = val2
assert.NoErr(t, err)
smp := p.SMap()
assert.NotEmpty(t, smp)
assert.ContainsKeys(t, smp, []interface{}{"key0", "key1", "top.sub2.mline1"})
assert.ContainsKeys(t, smp, []string{"key0", "key1", "top.sub2.mline1"})
assert.Eq(t, "multi line\nvalue\n", smp.Str("top.sub2.mline1"))

// start and end mark at new line
Expand Down Expand Up @@ -120,7 +119,7 @@ key1 = val2
assert.NoErr(t, err)
smp := p.SMap()
assert.NotEmpty(t, smp)
assert.ContainsKeys(t, smp, []interface{}{"key0", "key1", "top.sub2.mline1"})
assert.ContainsKeys(t, smp, []string{"key0", "key1", "top.sub2.mline1"})
assert.Eq(t, "multi line\nvalue\n", smp.Str("top.sub2.mline1"))

// start and end mark at new line
Expand Down

0 comments on commit 4b7c771

Please sign in to comment.