1- //
21// jsonjoin is a command line tool that takes two JSON documents and combined
32// them into one depending on the options
43//
54// @author R. S. Doiel, <[email protected] > 6- //
75package main
86
97import (
10- "encoding/json"
118 "flag"
129 "fmt"
1310 "io/ioutil"
@@ -20,23 +17,28 @@ import (
2017)
2118
2219var (
23- helpText = `---
24- title: "json2toml (1) user manual"
25- author: "R. S. Doiel"
26- pubDate: 2013-01-06
27- ---
20+ helpText = `%{app_name}(1) irdmtools user manual | version {version} {release_hash}
21+ % R. S. Doiel
22+ % {release_date}
2823
2924# NAME
3025
31- json2toml
26+ {app_name}
3227
3328# SYNOPSIS
3429
35- json2toml [OPTIONS] [ JSON_FILENAME] [TOML_FILENAME ]
30+ {app_name} [OPTIONS] JSON_FILENAME [JSON_FILENAME ... ]
3631
3732# DESCRIPTION
3833
39- json2toml is a tool that converts JSON objects into TOML output.
34+ {app_name} joins one or more JSON objects. By default the
35+ objects are each assigned to an attribute corresponding with their
36+ filenames minus the ".json" extension. If the object is read from
37+ standard input then "_" is used as it's attribute name.
38+
39+ If you use the update or overwrite options you will create a merged
40+ object. The update option keeps the attribute value first encountered
41+ and overwrite takes the last attribute value encountered.
4042
4143# OPTIONS
4244
@@ -61,20 +63,44 @@ display version
6163-quiet
6264: suppress error messages
6365
66+ -create
67+ : Create a root object placing each joined objects under their own attribute
68+
69+ -update
70+ : update first object with the second object, ignore existing attributes
71+
72+ -overwrite
73+ : update first object with the second object, overwriting existing attributes
6474
6575# EXAMPLES
6676
67- These would get the file named "my.json" and save it as my.toml
77+ This is an example of take "my1.json" and "my2.json"
78+ render "my.json"
79+
80+ ~~~
81+ jsonjoin my1.json my2.json >my.json
82+ ~~~
83+
84+ my.json would have two attributes, "my1" and "my2" each
85+ with their complete attributes.
6886
87+ Using the update option you can merge my1.json with any additional attribute
88+ values found in m2.json.
89+
90+ ~~~
91+ jsonjoin -update my1.json my2.json >my.json
6992~~~
70- json2toml my.json > my.toml
7193
72- json2toml my.json my.toml
94+ Using the overwrite option you can merge my1.json with my2.json accepted
95+ as replacement values.
7396
74- cat my.json | json2toml -i - > my.toml
97+ ~~~
98+ jsonjoin -overwrite my1.json my2.json >my.json
7599~~~
76100
77- json2toml 1.2.1
101+
102+
103+
78104
79105
80106`
@@ -84,7 +110,7 @@ json2toml 1.2.1
84110 showLicense bool
85111 showVersion bool
86112 showExamples bool
87- inputFName string
113+ pretty bool
88114 outputFName string
89115 generateMarkdown bool
90116 generateManPage bool
@@ -98,10 +124,6 @@ json2toml 1.2.1
98124 createRoot bool
99125)
100126
101- func fmtTxt (src string , appName string , version string ) string {
102- return strings .ReplaceAll (strings .ReplaceAll (src , "{app_name}" , appName ), "{version}" , version )
103- }
104-
105127func main () {
106128 appName := path .Base (os .Args [0 ])
107129
@@ -110,16 +132,16 @@ func main() {
110132 flag .BoolVar (& showLicense , "license" , false , "display license" )
111133 flag .BoolVar (& showVersion , "version" , false , "display version" )
112134
113- flag .StringVar (& inputFName , "i" , "" , "input filename (for root object)" )
114- flag .StringVar (& inputFName , "input" , "" , "input filename (for root object)" )
115135 flag .StringVar (& outputFName , "o" , "" , "output filename" )
116136 flag .StringVar (& outputFName , "output" , "" , "output filename" )
117137 flag .BoolVar (& quiet , "quiet" , false , "suppress error messages" )
118138 flag .BoolVar (& newLine , "nl" , false , "if true add a trailing newline" )
119139 flag .BoolVar (& newLine , "newline" , false , "if true add a trailing newline" )
140+ flag .BoolVar (& pretty , "p" , false , "pretty print json" )
141+ flag .BoolVar (& pretty , "pretty" , false , "pretty print json" )
120142
121143 // Application Specific Options
122- flag .BoolVar (& createRoot , "create" , false , "create an empty root object, {} " )
144+ flag .BoolVar (& createRoot , "create" , false , "for each object joined each under their own attribute. " )
123145 flag .BoolVar (& update , "update" , false , "copy new key/values pairs into root object" )
124146 flag .BoolVar (& overwrite , "overwrite" , false , "copy all key/values into root object" )
125147
@@ -134,35 +156,17 @@ func main() {
134156 out := os .Stdout
135157 eout := os .Stderr
136158
137- if inputFName != "" && inputFName != "-" {
138- in , err = os .Open (inputFName )
139- if err != nil {
140- fmt .Fprintln (eout ,err )
141- os .Exit (1 )
142- }
143- defer in .Close ()
144- }
145-
146- if outputFName != "" && outputFName != "-" {
147- out , err = os .Create (outputFName )
148- if err != nil {
149- fmt .Fprintln (eout , err )
150- os .Exit (1 )
151- }
152- defer out .Close ()
153- }
154-
155159 // Process options
156160 if showHelp {
157- fmt .Fprintf (out , "%s\n " , fmtTxt (helpText , appName , datatools .Version ))
161+ fmt .Fprintf (out , "%s\n " , datatools . FmtHelp (helpText , appName , datatools .Version , datatools . ReleaseDate , datatools . ReleaseHash ))
158162 os .Exit (0 )
159163 }
160164 if showLicense {
161165 fmt .Fprintf (out , "%s\n " , datatools .LicenseText )
162166 os .Exit (0 )
163167 }
164168 if showVersion {
165- fmt .Fprintf (out , "%s %s\n " , appName , datatools .Version )
169+ fmt .Fprintf (out , "%s %s %s \n " , appName , datatools .Version , datatools . ReleaseHash )
166170 os .Exit (0 )
167171 }
168172 if newLine {
@@ -180,27 +184,18 @@ func main() {
180184 outObject := map [string ]interface {}{}
181185 newObject := map [string ]interface {}{}
182186
183- // READ in the JSON document if present on standard in or specified with -i.
184- if createRoot == false {
185- buf , err := ioutil .ReadAll (in )
186- if err != nil {
187- fmt .Fprintln (eout , err )
188- os .Exit (1 )
189- }
190- err = json .Unmarshal (buf , & outObject )
191- if err != nil {
192- fmt .Fprintln (eout , err )
193- os .Exit (1 )
194- }
195- }
196-
197187 for _ , arg := range args {
198- src , err := ioutil .ReadFile (arg )
199- if err != nil {
200- fmt .Fprintln (eout , err )
201- os .Exit (1 )
188+ var src []byte
189+ if arg != "" && arg != "-" {
190+ src , err = ioutil .ReadFile (arg )
191+ if err != nil {
192+ fmt .Fprintln (eout , err )
193+ os .Exit (1 )
194+ }
195+ } else {
196+ src , err = ioutil .ReadAll (in )
202197 }
203- err = json . Unmarshal (src , & newObject )
198+ err = datatools . JSONUnmarshal (src , & newObject )
204199 if err != nil {
205200 fmt .Fprintln (eout , err )
206201 os .Exit (1 )
@@ -218,11 +213,22 @@ func main() {
218213 }
219214 default :
220215 key := strings .TrimSuffix (path .Base (arg ), ".json" )
216+ if key == "" {
217+ key = "_"
218+ }
221219 outObject [key ] = newObject
222220 }
223221 }
224222
225- src , err := json .Marshal (outObject )
223+ var (
224+ src []byte
225+ )
226+
227+ if pretty {
228+ src , err = datatools .JSONMarshalIndent (outObject , "" , " " )
229+ } else {
230+ src , err = datatools .JSONMarshal (outObject )
231+ }
226232 if err != nil {
227233 fmt .Fprintln (eout , err )
228234 os .Exit (1 )
0 commit comments