Skip to content

Commit

Permalink
Init.
Browse files Browse the repository at this point in the history
  • Loading branch information
onrik committed Oct 20, 2022
1 parent 5ec2298 commit 73a79b9
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 0 deletions.
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,27 @@
# yaconf
Golang yaml config reader

```golang
package main

import (
"log"

"github.com/onrik/yaconf"
)

type Config struct {
LogFile string `yaml:"log_file" yaconf:"required"`
}

func main() {
config := Config{}
err := yaconf.Read("config.yml", &config)
if err != nil {
log.Println(err)
return
}

log.Printf("%+v\n", config)
}
```
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module github.com/onrik/yaconf

go 1.19

require gopkg.in/yaml.v3 v3.0.1
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
85 changes: 85 additions & 0 deletions yaconf.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package yaconf

import (
"fmt"
"os"
"reflect"
"strings"

"gopkg.in/yaml.v3"
)

type validator interface {
Validate() error
}

func addPrefix(prefix, name string) string {
if prefix == "" {
return name
}

return fmt.Sprintf("%s.%s", prefix, name)
}

func validate(config interface{}, prefix string) []string {
t := reflect.TypeOf(config)
v := reflect.ValueOf(config)
if t.Kind() == reflect.Ptr {
t = t.Elem()
v = v.Elem()
}

errors := []string{}
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
name := f.Tag.Get("yaml")
if name == "" {
name = f.Name
}

if f.Tag.Get("yaconf") == "required" && v.Field(i).IsZero() {
errors = append(errors, fmt.Sprintf("%s is required", addPrefix(prefix, name)))
continue
}

if f.Type.Kind() == reflect.Struct {
errors = append(errors, validate(v.Field(i).Interface(), addPrefix(prefix, name))...)
continue
}

if f.Type.Kind() == reflect.Ptr {
if f.Type.Elem().Kind() == reflect.Struct {
if v.Field(i).IsNil() {
v.Field(i).Set(reflect.New(f.Type.Elem()))
}
errors = append(errors, validate(v.Field(i).Elem().Interface(), addPrefix(prefix, name))...)
}
}

}
return errors
}

// Read config from file
func Read(filename string, config interface{}) error {
data, err := os.ReadFile(filename)
if err != nil {
return err
}

err = yaml.Unmarshal(data, config)
if err != nil {
return err
}

errors := validate(config, "")
if len(errors) > 0 {
return fmt.Errorf(strings.Join(errors, ", "))
}

if v, ok := config.(validator); ok {
return v.Validate()
}

return nil
}

0 comments on commit 73a79b9

Please sign in to comment.