Skip to content

Commit d68d51d

Browse files
authored
Add yamlgen/cfggen (#79)
Signed-off-by: Saswata Mukherjee <saswataminsta@yahoo.com>
1 parent db5c373 commit d68d51d

3 files changed

Lines changed: 68 additions & 0 deletions

File tree

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ require (
88
github.com/charmbracelet/glamour v0.3.0
99
github.com/efficientgo/tools/core v0.0.0-20210609125236-d73259166f20
1010
github.com/efficientgo/tools/extkingpin v0.0.0-20210609125236-d73259166f20
11+
github.com/fatih/structtag v1.2.0
1112
github.com/felixge/fgprof v0.9.1
1213
github.com/go-kit/kit v0.10.0
1314
github.com/gobwas/glob v0.2.3

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
193193
github.com/evanw/esbuild v0.6.5/go.mod h1:mptxmSXIzBIKKCe4jo9A5SToEd1G+AKZ9JmY85dYRJ0=
194194
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
195195
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
196+
github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=
197+
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
196198
github.com/felixge/fgprof v0.9.1 h1:E6FUJ2Mlv043ipLOCFqo8+cHo9MhQ203E2cdEK/isEs=
197199
github.com/felixge/fgprof v0.9.1/go.mod h1:7/HK6JFtFaARhIljgP2IV8rJLIoHDoOYoUphsnGvqxE=
198200
github.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=

pkg/yamlgen/cfggen.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright (c) Bartłomiej Płotka @bwplotka
2+
// Licensed under the Apache License 2.0.
3+
4+
// Taken from Thanos project.
5+
//
6+
// Copyright (c) The Thanos Authors.
7+
// Licensed under the Apache License 2.0.
8+
9+
package yamlgen
10+
11+
import (
12+
"io"
13+
"reflect"
14+
15+
"github.com/fatih/structtag"
16+
"github.com/pkg/errors"
17+
"gopkg.in/yaml.v3"
18+
)
19+
20+
func Generate(obj interface{}, w io.Writer) error {
21+
// We forbid omitempty option. This is for simplification for doc generation.
22+
if err := checkForOmitEmptyTagOption(obj); err != nil {
23+
return errors.Wrap(err, "invalid type")
24+
}
25+
return yaml.NewEncoder(w).Encode(obj)
26+
}
27+
28+
func checkForOmitEmptyTagOption(obj interface{}) error {
29+
return checkForOmitEmptyTagOptionRec(reflect.ValueOf(obj))
30+
}
31+
32+
func checkForOmitEmptyTagOptionRec(v reflect.Value) error {
33+
switch v.Kind() {
34+
case reflect.Struct:
35+
for i := 0; i < v.NumField(); i++ {
36+
tags, err := structtag.Parse(string(v.Type().Field(i).Tag))
37+
if err != nil {
38+
return errors.Wrapf(err, "%s: failed to parse tag %q", v.Type().Field(i).Name, v.Type().Field(i).Tag)
39+
}
40+
41+
tag, err := tags.Get("yaml")
42+
if err != nil {
43+
return errors.Wrapf(err, "%s: failed to get tag %q", v.Type().Field(i).Name, v.Type().Field(i).Tag)
44+
}
45+
46+
for _, opts := range tag.Options {
47+
if opts == "omitempty" {
48+
return errors.Errorf("omitempty is forbidden for config, but spotted on field '%s'", v.Type().Field(i).Name)
49+
}
50+
}
51+
52+
if err := checkForOmitEmptyTagOptionRec(v.Field(i)); err != nil {
53+
return errors.Wrapf(err, "%s", v.Type().Field(i).Name)
54+
}
55+
}
56+
57+
case reflect.Ptr:
58+
return errors.New("nil pointers are not allowed in configuration")
59+
60+
case reflect.Interface:
61+
return checkForOmitEmptyTagOptionRec(v.Elem())
62+
}
63+
64+
return nil
65+
}

0 commit comments

Comments
 (0)