Skip to content

Commit

Permalink
refmt: add env codec
Browse files Browse the repository at this point in the history
  • Loading branch information
rjeczalik committed Apr 5, 2022
1 parent b6da5b9 commit 208a11d
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 80 deletions.
32 changes: 0 additions & 32 deletions Gopkg.lock

This file was deleted.

38 changes: 0 additions & 38 deletions Gopkg.toml

This file was deleted.

49 changes: 45 additions & 4 deletions format.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"strings"
"text/template"

"github.com/rjeczalik/refmt/object"
"rafal.dev/refmt/object"

"github.com/go-sql-driver/mysql"
"github.com/hashicorp/hcl"
Expand All @@ -27,10 +27,48 @@ var f = &Format{
Type: flag.String("t", "", "Output format type."),
}

var m = map[string]struct {
type envCodec struct {
prefix *string
}

func (c *envCodec) codec() codec {
return codec{
marshal: c.marshal,
unmarshal: c.unmarshal,
}
}

func (c *envCodec) marshal(v interface{}) ([]byte, error) {
m, ok := v.(map[string]interface{})
if !ok {
return nil, errors.New("envCoded: cannot marshal non-object value")
}

envs := object.Flatten(m, "_")

var (
p = *c.prefix
keys = object.Keys(envs)
buf bytes.Buffer
)

for _, k := range keys {
fmt.Fprintf(&buf, "%s%s=%v\n", p, strings.ToUpper(k), envs[k])
}

return buf.Bytes(), nil
}

func (c *envCodec) unmarshal([]byte) (interface{}, error) {
return nil, errors.New("envCodec: not implemented")
}

type codec struct {
marshal func(interface{}) ([]byte, error)
unmarshal func([]byte) (interface{}, error)
}{
}

var m = map[string]codec{
"json": {
marshal: jsonMarshal,
unmarshal: func(p []byte) (v interface{}, _ error) {
Expand Down Expand Up @@ -73,6 +111,9 @@ var m = map[string]struct {
return v, nil
},
},
"env": (&envCodec{
prefix: flag.String("p", "", "Prefix for keys when type is env."),
}).codec(),
}

func typ(file string) string {
Expand All @@ -94,7 +135,7 @@ func typ(file string) string {
}
}

var autoTryOrder = []string{"hcl", "json", "yaml"}
var autoTryOrder = []string{"hcl", "json", "yaml", "env"}

type Format struct {
Type *string // autodetect if nil or empty
Expand Down
15 changes: 9 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
module github.com/rjeczalik/refmt
module rafal.dev/refmt

go 1.18

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-sql-driver/mysql v1.4.0
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce
github.com/kr/pretty v0.1.0 // indirect
github.com/pkg/errors v0.9.1
github.com/savaki/jq v0.0.0-20161209013833-0e6baecebbf8
google.golang.org/appengine v1.2.0 // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0
)

go 1.13
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/kr/pretty v0.1.0 // indirect
google.golang.org/appengine v1.2.0 // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
)
24 changes: 24 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce h1:xdsDDbiBDQTKASoGEZ+pEmF1OnWuu8AQ9I8iNbHNeno=
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/savaki/jq v0.0.0-20161209013833-0e6baecebbf8 h1:ajJQhvqPSQFJJ4aV5mDAMx8F7iFi6Dxfo6y62wymLNs=
github.com/savaki/jq v0.0.0-20161209013833-0e6baecebbf8/go.mod h1:Nw/CCOXNyF5JDd6UpYxBwG5WWZ2FOJ/d5QnXL4KQ6vY=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
google.golang.org/appengine v1.2.0 h1:S0iUepdCWODXRvtE+gcRDd15L+k+k1AiHlMiMjefH24=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0 h1:POO/ycCATvegFmVuPpQzZFJ+pGZeX22Ufu6fibxDVjU=
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
84 changes: 84 additions & 0 deletions object/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package object

import (
"fmt"
"sort"
"strings"
)

Expand Down Expand Up @@ -80,6 +81,64 @@ func Merge(in, out map[string]interface{}) error {
return nil
}

func Flatten(in map[string]interface{}, sep string) map[string]interface{} {
if len(in) == 0 {
return nil
}

root := make(map[string]interface{})

type elm struct {
parent map[string]interface{}
key []string
left []string
}

var (
it elm
k string
queue = []elm{{parent: in, left: Keys(in)}}
)

for len(queue) != 0 {
it, queue = queue[len(queue)-1], queue[:len(queue)-1]
k, it.left = it.left[0], it.left[1:]

key := clone(it.key, k)

if len(it.left) != 0 {
queue = append(queue, it)
}

switch v := it.parent[k].(type) {
case []interface{}:
m := make(map[string]interface{}, len(v))

for i, v := range v {
m[fmt.Sprint(i)] = v
}

queue = append(queue, elm{
parent: m,
key: key,
left: Keys(m),
})
case map[string]interface{}:
queue = append(queue, elm{
parent: v,
key: key,
left: Keys(v),
})
default:
if len(key) != 0 {
root[strings.Join(key, sep)] = v
}
}
}

return root
}

func SetFlatKeyValue(m map[string]interface{}, key, value string) error {
keys := strings.Split(key, ".")
it := m
Expand All @@ -106,3 +165,28 @@ func SetFlatKeyValue(m map[string]interface{}, key, value string) error {

return nil
}

func clone(s []string, vs ...string) []string {
sCopy := make([]string, len(s), len(s)+len(vs))
copy(sCopy, s)

for _, v := range vs {
if v != "" && v != "-" {
sCopy = append(sCopy, v)
}
}

return sCopy
}

func Keys(in map[string]interface{}) []string {
keys := make([]string, 0, len(in))

for k := range in {
keys = append(keys, k)
}

sort.Strings(keys)

return keys
}

0 comments on commit 208a11d

Please sign in to comment.