Skip to content

Commit

Permalink
Add yamlgen/cfggen (bwplotka#79)
Browse files Browse the repository at this point in the history
Signed-off-by: Saswata Mukherjee <[email protected]>
  • Loading branch information
saswatamcode authored Aug 24, 2021
1 parent db5c373 commit d68d51d
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 0 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/charmbracelet/glamour v0.3.0
github.com/efficientgo/tools/core v0.0.0-20210609125236-d73259166f20
github.com/efficientgo/tools/extkingpin v0.0.0-20210609125236-d73259166f20
github.com/fatih/structtag v1.2.0
github.com/felixge/fgprof v0.9.1
github.com/go-kit/kit v0.10.0
github.com/gobwas/glob v0.2.3
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
github.com/evanw/esbuild v0.6.5/go.mod h1:mptxmSXIzBIKKCe4jo9A5SToEd1G+AKZ9JmY85dYRJ0=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
github.com/felixge/fgprof v0.9.1 h1:E6FUJ2Mlv043ipLOCFqo8+cHo9MhQ203E2cdEK/isEs=
github.com/felixge/fgprof v0.9.1/go.mod h1:7/HK6JFtFaARhIljgP2IV8rJLIoHDoOYoUphsnGvqxE=
github.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
Expand Down
65 changes: 65 additions & 0 deletions pkg/yamlgen/cfggen.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) Bartłomiej Płotka @bwplotka
// Licensed under the Apache License 2.0.

// Taken from Thanos project.
//
// Copyright (c) The Thanos Authors.
// Licensed under the Apache License 2.0.

package yamlgen

import (
"io"
"reflect"

"github.com/fatih/structtag"
"github.com/pkg/errors"
"gopkg.in/yaml.v3"
)

func Generate(obj interface{}, w io.Writer) error {
// We forbid omitempty option. This is for simplification for doc generation.
if err := checkForOmitEmptyTagOption(obj); err != nil {
return errors.Wrap(err, "invalid type")
}
return yaml.NewEncoder(w).Encode(obj)
}

func checkForOmitEmptyTagOption(obj interface{}) error {
return checkForOmitEmptyTagOptionRec(reflect.ValueOf(obj))
}

func checkForOmitEmptyTagOptionRec(v reflect.Value) error {
switch v.Kind() {
case reflect.Struct:
for i := 0; i < v.NumField(); i++ {
tags, err := structtag.Parse(string(v.Type().Field(i).Tag))
if err != nil {
return errors.Wrapf(err, "%s: failed to parse tag %q", v.Type().Field(i).Name, v.Type().Field(i).Tag)
}

tag, err := tags.Get("yaml")
if err != nil {
return errors.Wrapf(err, "%s: failed to get tag %q", v.Type().Field(i).Name, v.Type().Field(i).Tag)
}

for _, opts := range tag.Options {
if opts == "omitempty" {
return errors.Errorf("omitempty is forbidden for config, but spotted on field '%s'", v.Type().Field(i).Name)
}
}

if err := checkForOmitEmptyTagOptionRec(v.Field(i)); err != nil {
return errors.Wrapf(err, "%s", v.Type().Field(i).Name)
}
}

case reflect.Ptr:
return errors.New("nil pointers are not allowed in configuration")

case reflect.Interface:
return checkForOmitEmptyTagOptionRec(v.Elem())
}

return nil
}

0 comments on commit d68d51d

Please sign in to comment.