Skip to content

Commit

Permalink
Merge branch 'main' into add_doc
Browse files Browse the repository at this point in the history
  • Loading branch information
TimurIskandarov authored and Тимур Искандаров committed Jul 19, 2024
2 parents 455c15b + ea1f4e0 commit a64358a
Show file tree
Hide file tree
Showing 17 changed files with 191 additions and 139 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.20'
go-version: '1.21'

- name: Build
run: go build -v ./...
Expand Down
3 changes: 2 additions & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ package main
import (
"fmt"
"github.com/google/uuid"
"tinyconf"
"github.com/insei/tinyconf"
"tinyconf/drivers/env"
"tinyconf/drivers/tag"
"tinyconf/drivers/yaml"
Expand Down Expand Up @@ -91,6 +91,7 @@ func main() {
if err != nil {
panic(err)
}
fmt.Println(config.GenDoc("yaml"))
err = config.Parse(&c)
if err != nil {
panic(err)
Expand Down
41 changes: 19 additions & 22 deletions drivers/env/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ package env
import (
"cmp"
"fmt"
"github.com/insei/cast"
"github.com/insei/fmap/v3"
"github.com/insei/tinyconf"
"os"
"reflect"
"slices"
"strings"

"github.com/insei/cast"
"github.com/insei/fmap/v3"
"github.com/insei/tinyconf"
)

type envDriver struct {
Expand Down Expand Up @@ -41,19 +42,17 @@ type field struct {
tag reflect.StructTag
}

func (f field) getTag(tag string) string {
if tagValue, ok := f.tag.Lookup(tag); ok {
return fmt.Sprintf("#%s\n%s:\n", f.tag.Get("doc"), tagValue)
func (f field) genDoc(driver string) string {
if tagDriver, ok := f.tag.Lookup(driver); ok {
tagDoc := f.tag.Get("doc")
return fmt.Sprintf("#%s\n#%s=\n\n", tagDoc, tagDriver)
}
return ""
}

func (d envDriver) getUniqueFields(storages []fmap.Storage) []field {
var fields []field
for _, storage := range storages {
if storage == nil {
continue
}
for _, path := range storage.GetAllPaths() {
member := field{path: path, tag: storage.MustFind(path).GetTag()}
if slices.Contains(fields, member) {
Expand All @@ -67,38 +66,37 @@ func (d envDriver) getUniqueFields(storages []fmap.Storage) []field {

func (d envDriver) getRootMap(fields []field) map[string]string {
roots := map[string]string{}
var keyPath string
var rootPath string
for _, field := range fields {
docField := field.genDoc(d.name)
depth := strings.Count(field.path, ".")
if depth == 0 {
keyPath = field.path
roots[keyPath] = field.getTag(d.name)
rootPath = field.path
roots[rootPath] = docField
continue
}

if strings.HasPrefix(field.path, keyPath) {
docTag := field.getTag(d.name)
if strings.Contains(roots[keyPath], docTag) {
if strings.HasPrefix(field.path, rootPath) {
if strings.Contains(roots[rootPath], field.tag.Get(d.name)) {
continue
}
roots[keyPath] += docTag
roots[rootPath] += docField
}
}
return roots
}

func (d envDriver) Doc(storages ...fmap.Storage) string {
fields := d.getUniqueFields(storages)
func (d envDriver) GenDoc(storages ...fmap.Storage) string {
uniqueFields := d.getUniqueFields(storages)

sortedFields := slices.Clone(fields)
sortedFields := slices.Clone(uniqueFields)
slices.SortStableFunc(sortedFields, func(i, j field) int {
return cmp.Compare(i.path, j.path)
})

roots := d.getRootMap(sortedFields)

var doc string
for _, field := range fields {
for _, field := range uniqueFields {
depth := strings.Count(field.path, ".")
if depth != 0 {
continue
Expand All @@ -107,7 +105,6 @@ func (d envDriver) Doc(storages ...fmap.Storage) string {
doc += roots[field.path]
}

fmt.Println(doc)
return doc
}

Expand Down
32 changes: 19 additions & 13 deletions drivers/env/env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,21 +88,21 @@ func Test_envDriver_GetValue(t *testing.T) {
}
}

func TestEnvDriver_Doc(t *testing.T) {
func TestEnvDriver_GenDoc(t *testing.T) {
type TestingFirstStruct struct {
Service struct {
Name string `env:"SERVICE_NAME" doc:"service name"`
}
HTTP struct {
Auth struct {
Alg string `env:"HTTP_AUTH_ALG" doc:"http authentication algorithm"`
Issuer string `env:"HTTP_AUTH_ISSUER" doc:"http authentication issuer"`
Alg string `env:"HTTP_AUTH_ALG"`
Issuer string `env:"HTTP_AUTH_ISSUER" doc:""`
}
}
}
type TestingSecondStruct struct {
Service struct {
ServiceName string `env:"SERVICE_NAME" doc:"service name"`
ServiceName string `env:"SERVICE_NAME" doc:"service name 27"`
}
Something uint `env:"SOMETHING" doc:"something"`
}
Expand All @@ -127,24 +127,30 @@ func TestEnvDriver_Doc(t *testing.T) {
"test map": {
in: storages,
out: `#service name
SERVICE_NAME:
#http authentication algorithm
HTTP_AUTH_ALG:
#http authentication issuer
HTTP_AUTH_ISSUER:
#SERVICE_NAME=
#
#HTTP_AUTH_ALG=
#
#HTTP_AUTH_ISSUER=
#http protocol host
HTTP_HOST:
#HTTP_HOST=
#http protocol port
HTTP_PORT:
#HTTP_PORT=
#something
SOMETHING:
#SOMETHING=
`,
},
}

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
out := driver.Doc(tc.in...)
out := driver.GenDoc(tc.in...)
assert.Equal(t, tc.out, out)
})
}
Expand Down
13 changes: 2 additions & 11 deletions drivers/tag/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package tag

import (
"fmt"

"github.com/insei/cast"
"github.com/insei/fmap/v3"
"github.com/insei/tinyconf"
Expand Down Expand Up @@ -32,16 +31,8 @@ func (d defaultTagDriver) GetName() string {
return d.name
}

func (d defaultTagDriver) Doc(storage fmap.Storage) string {
doc := ""
for _, path := range storage.GetAllPaths() {
tags := storage.MustFind(path).GetTag()
if tag, ok := tags.Lookup(d.name); ok {
doc += fmt.Sprintf("#%s\n%s=", tags.Get("doc"), tag)
}
}
fmt.Println(doc)
return doc
func (d defaultTagDriver) GenDoc(storages ...fmap.Storage) string {
return ""
}

func New(tagName string) (tinyconf.Driver, error) {
Expand Down
22 changes: 0 additions & 22 deletions drivers/tag/tag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,28 +119,6 @@ func TestDefaultTagDriver_GetName(t *testing.T) {
}
}

func TestDefaultTagDriver_Doc(t *testing.T) {
type TestingStruct struct {
Test string `tag:"TEST" doc:"Test tag"`
}
driver := defaultTagDriver{name: "tag"}
storage, _ := fmap.Get[TestingStruct]()

tests := map[string]struct {
in fmap.Storage
out string
}{
"test map": {in: storage, out: "#Test tag\n#TEST="},
}

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
out := driver.Doc(tc.in)
assert.Equal(t, tc.out, out)
})
}
}

func TestNew(t *testing.T) {
testCases := []struct {
name string
Expand Down
2 changes: 1 addition & 1 deletion drivers/yaml/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"fmt"
"io"
"os"

"github.com/insei/tinyconf"
"gopkg.in/yaml.v3"
)
Expand Down
73 changes: 36 additions & 37 deletions drivers/yaml/yaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,32 @@ type field struct {
tag reflect.StructTag
}

func (f field) genDoc(driver string, depth int) string {
var offset strings.Builder
for i := 0; i < depth; i++ {
offset.WriteRune('\t')
}
offset.WriteRune('#')
tagDriver := offset.String() + f.tag.Get(driver)
tagDoc := offset.String() + f.tag.Get("doc")
offset.Reset()
return fmt.Sprintf("%s\n%s:\n", tagDoc, tagDriver)
}

func (d *yamlDriver) getUniqueFields(storages []fmap.Storage) []field {
var fields []field
for _, storage := range storages {
if storage == nil {
continue
}
for _, path := range storage.GetAllPaths() {
member := field{path: path, tag: storage.MustFind(path).GetTag()}
if slices.Contains(fields, member) {
tagDriver, ok := member.tag.Lookup(d.name)
if !ok {
continue
}
if slices.ContainsFunc(fields, func(item field) bool {
matchPath := item.path == member.path
matchTagDriver := tagDriver == item.tag.Get(d.name)
return matchPath && matchTagDriver
}) {
continue
}
fields = append(fields, member)
Expand All @@ -101,65 +118,47 @@ func (d *yamlDriver) getUniqueFields(storages []fmap.Storage) []field {

func (d *yamlDriver) getRootMap(fields []field) map[string]string {
roots := map[string]string{}
var offset strings.Builder
var keyPath, keyTag string

var root struct {
path, tag string
}
for _, field := range fields {
depth := strings.Count(field.path, ".")
if depth == 0 {
if tagValue, ok := field.tag.Lookup(d.name); ok {
keyPath, keyTag = field.path, tagValue
roots[keyTag] = ""
}
root = struct{ path, tag string }{path: field.path, tag: field.tag.Get(d.name)}
roots[root.tag] = ""
continue
}

if strings.HasPrefix(field.path, keyPath) {
var path string
for i := 0; i < depth; i++ {
offset.WriteRune('\t')
}
if tagValue, ok := field.tag.Lookup(d.name); ok {
remark := offset.String() + "#" + field.tag.Get("doc")
tagValue = offset.String() + tagValue
path = fmt.Sprintf("%s\n%s:\n", remark, tagValue)
roots[keyTag] += path
}
offset.Reset()
if strings.HasPrefix(field.path, root.path) {
roots[root.tag] += field.genDoc(d.name, depth)
}
}

return roots
}

func (d *yamlDriver) Doc(storages ...fmap.Storage) string {
fields := d.getUniqueFields(storages)
func (d *yamlDriver) GenDoc(storages ...fmap.Storage) string {
uniqueFields := d.getUniqueFields(storages)

sortedFields := slices.Clone(fields)
sortedFields := slices.Clone(uniqueFields)
slices.SortStableFunc(sortedFields, func(i, j field) int {
return cmp.Compare(i.path, j.path)
})

roots := d.getRootMap(sortedFields)

var doc string
for _, field := range fields {
for _, field := range uniqueFields {
depth := strings.Count(field.path, ".")
if depth != 0 {
continue
}

tagValue, ok := field.tag.Lookup(d.name)
if !ok {
continue
}

if v, ok := roots[tagValue]; ok {
doc += fmt.Sprintf("#%s\n%s:\n%s", field.tag.Get("doc"), tagValue, v)
tagRootDriver := field.tag.Get(d.name)
if nestedDoc, ok := roots[tagRootDriver]; ok {
rootFieldDoc := field.genDoc(d.name, 0)
doc += rootFieldDoc + nestedDoc
}
}

fmt.Println(doc)
return doc
}

Expand Down
Loading

0 comments on commit a64358a

Please sign in to comment.