-
Notifications
You must be signed in to change notification settings - Fork 1
/
hydrator.go
101 lines (88 loc) · 2.38 KB
/
hydrator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package main
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"html/template"
"io/ioutil"
"log"
"path"
"strings"
"time"
)
// The usage of variable length args is to prevent
// missing fields from breaking the templates
func formatAsDollars(valueInCents ...int) (string, error) {
if len(valueInCents) != 1 {
return "$0", nil
}
dollars := valueInCents[0] / 100
cents := valueInCents[0] % 100
return fmt.Sprintf("$%d.%2d", dollars, cents), nil
}
func formatAsDate(t ...string) string {
if len(t) != 1 {
return ""
}
// Mon Jan 2 15:04:05 MST 2006
d, _ := time.Parse("2/1/2006", t[0])
// log.Println(err)
year, month, day := d.Date()
return fmt.Sprintf("%d/%d/%d", day, month, year)
}
func titleCase(input ...string) string {
if len(input) != 1 {
return ""
}
return strings.Title(strings.ToLower(input[0]))
}
// UnstructuredJSON is a simple cover for map[string]interface{}
type UnstructuredJSON map[string]interface{}
var (
tpl = flag.String("t", "./transform.tmpl", "the template to use to transform the data")
src = flag.String("s", "./source.json", "source JSON")
out = flag.String("w", "", "Specifies an output file if present")
)
func main() {
flag.Parse()
filebytes, err := ioutil.ReadFile(*src)
if err != nil {
log.Fatalln("Couldn't open file '", *src, "' -", err)
return
}
jsonBlob := UnstructuredJSON{}
json.Unmarshal(filebytes, &jsonBlob)
// Wire up our FuncMap
// TODO: Dynamically load these using plugins!
fmap := template.FuncMap{
"formatAsDollars": formatAsDollars,
"formatAsDate": formatAsDate,
"titleCase": titleCase,
}
t := template.Must(template.New(path.Base(*tpl)).Funcs(fmap).ParseFiles(*tpl))
// Exexute the template, on our source.json and output to a holding buffer
outputBuffer := bytes.NewBuffer(nil)
err = t.Execute(outputBuffer, jsonBlob)
if err != nil {
log.Fatalln("Execute:", err)
}
// Cleanup the JSON
tmp := UnstructuredJSON{}
err = json.Unmarshal(outputBuffer.Bytes(), &tmp)
if err != nil {
log.Fatalln("Unmarshal:", err, "-", outputBuffer.String())
}
indentedBytes, err := json.MarshalIndent(tmp, "", " ")
if err != nil {
log.Fatalln("MarshalIndent:", err)
}
// It's lumpy to marshal and unmarshal but it does make it pretty
if *out != "" {
if err = ioutil.WriteFile(*out, indentedBytes, 0644); err != nil {
log.Fatalln("WriteFile:", err)
}
} else {
fmt.Printf("%s\n", string(indentedBytes))
}
}