Skip to content

Instantly share code, notes, and snippets.

@klingtnet
Last active August 20, 2020 06:00
Show Gist options
  • Save klingtnet/734fbd76d707ac7481bf7cad48d4dd83 to your computer and use it in GitHub Desktop.
Save klingtnet/734fbd76d707ac7481bf7cad48d4dd83 to your computer and use it in GitHub Desktop.
How to properly parts of an unknown YAML file in Go
package main
import (
"fmt"
"log"
"os"
"strings"
"gopkg.in/yaml.v2"
)
type DependencyDefinition struct {
Platform []string `yaml:"plaform"`
Type string `yaml:"type"`
RequiredForStartup bool `yaml:"required-for-startup"`
}
func run() (err error) {
f, err := os.Open("test.yaml")
if err != nil {
return
}
defer f.Close()
configYAML := make(map[string]interface{})
err = yaml.NewDecoder(f).Decode(&configYAML)
if err != nil {
return
}
var metaKey string
for k := range configYAML {
if strings.HasSuffix(k, "::meta") {
metaKey = k
break
}
}
if metaKey == "" {
err = fmt.Errorf("meta key not found")
return
}
metaTree, ok := configYAML[metaKey].(map[interface{}]interface{})
if !ok {
err = fmt.Errorf("meta is in bad format")
return
}
depTree, ok := metaTree["dependencies"]
if !ok {
err = fmt.Errorf("no dependencies key in %q section", metaKey)
return
}
// Here is the important part.
// First, try to marshal the subtree of type interface{} into your desired struct.
bs, err := yaml.Marshal(depTree)
if err != nil {
return
}
// Second, just Unmarshal as usual, without the need for interface{} or reflect magic.
var deps map[string]DependencyDefinition
err = yaml.Unmarshal(bs, &deps)
if err != nil {
return
}
// process deps ...
return
}
func main() {
err := run()
if err != nil {
log.Fatal(err)
}
}
app::something: "foo"
# expect a lot of junk here
app::meta:
sla: "1"
business_unit: "Something"
contact: "[email protected]"
dependencies:
some-service:
platform:
- us-east
- eu-central
mysql-some-service:
type: database
required-for-startup: true
an-external-service:
type: external
some-other-service:
app::more_stuff: 1
# expect more junk here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment