Skip to content

Commit 1d5fbd5

Browse files
author
mfarah
committed
Use cobra for cli for nicer cli-ness
1 parent 1605938 commit 1d5fbd5

File tree

3 files changed

+70
-63
lines changed

3 files changed

+70
-63
lines changed

README.md

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ go get github.com/mikefarah/yaml
1212

1313
## Read examples
1414
```
15-
yaml <yaml file> <path>
15+
yaml r <yaml file> <path>
1616
```
1717

1818
### Basic
@@ -23,14 +23,14 @@ b:
2323
```
2424
then
2525
```bash
26-
yaml sample.yaml b.c
26+
yaml r sample.yaml b.c
2727
```
2828
will output the value of '2'.
2929

3030
### Reading from STDIN
3131
Given a sample.yaml file of:
3232
```bash
33-
cat sample.yaml | yaml - b.c
33+
cat sample.yaml | yaml r - b.c
3434
```
3535
will output the value of '2'.
3636

@@ -46,7 +46,7 @@ bob:
4646
```
4747
then
4848
```bash
49-
yaml sample.yaml bob.*.cats
49+
yaml r sample.yaml bob.*.cats
5050
```
5151
will output
5252
```yaml
@@ -62,7 +62,7 @@ b.x:
6262
```
6363
then
6464
```bash
65-
yaml sample.yaml \"b.x\".c
65+
yaml r sample.yaml \"b.x\".c
6666
```
6767
will output the value of '2'.
6868

@@ -79,7 +79,7 @@ b:
7979
```
8080
then
8181
```
82-
yaml sample.yaml b.e[1].name
82+
yaml r sample.yaml b.e[1].name
8383
```
8484
will output 'sam'
8585

@@ -95,7 +95,7 @@ b:
9595
```
9696
then
9797
```
98-
yaml sample.yaml b.e[*].name
98+
yaml r sample.yaml b.e[*].name
9999
```
100100
will output:
101101
```
@@ -121,7 +121,6 @@ b:
121121
c: cat
122122
```
123123
124-
125124
### Updating yaml in-place
126125
Given a sample.yaml file of:
127126
```yaml
@@ -130,6 +129,6 @@ b:
130129
```
131130
then
132131
```bash
133-
yaml wi sample.yaml b.c cat
132+
yaml w -i sample.yaml b.c cat
134133
```
135134
will update the sample.yaml file so that the value of 'c' is cat.

precheckin.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ go test
66

77
# acceptance test
88
go build
9-
X=$(./yaml sample.yaml b.c)
9+
X=$(./yaml r sample.yaml b.c)
1010

1111
if [ $X != 2 ]
1212
then

yaml.go

Lines changed: 61 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package main
22

33
import (
44
"fmt"
5-
"github.com/codegangsta/cli"
5+
"github.com/spf13/cobra"
66
"gopkg.in/yaml.v2"
77
"io/ioutil"
88
"log"
@@ -11,74 +11,79 @@ import (
1111
"strings"
1212
)
1313

14+
var trimOutput = true
15+
var writeInplace = false
16+
1417
func main() {
15-
app := cli.NewApp()
16-
app.Name = "yaml"
17-
app.Usage = "command line tool for reading and writing yaml"
18-
app.Commands = []cli.Command{
19-
{
20-
Name: "read",
21-
Aliases: []string{"r"},
22-
Usage: "read <filename> <path>\n\te.g.: yaml read sample.yaml a.b.c\n\t(default) reads a property from a given yaml file\n",
23-
Action: readProperty,
24-
},
25-
{
26-
Name: "write",
27-
Aliases: []string{"w"},
28-
Usage: "write <filename> <path> <value>\n\te.g.: yaml write sample.yaml a.b.c 5\n\tupdates a property from a given yaml file, outputs to stdout\n",
29-
Action: writeProperty,
30-
},
31-
{
32-
Name: "write-inplace",
33-
Aliases: []string{"wi"},
34-
Usage: "wi <filename> <path> <value>\n\te.g.: yaml wi sample.yaml a.b.c 5\n\tupdates a property from a given yaml file and saves it to the given filename (sample.yaml)\n",
35-
Action: writePropertyInPlace,
36-
},
18+
var cmdRead = &cobra.Command{
19+
Use: "read [yaml_file] [path]",
20+
Aliases: []string{"r"},
21+
Short: "yaml r sample.yaml a.b.c",
22+
Example: `
23+
yaml read things.yaml a.b.c
24+
yaml r - a.b.c (reads from stdin)
25+
yaml r things.yaml a.*.c
26+
yaml r things.yaml a.array[0].blah
27+
yaml r things.yaml a.array[*].blah
28+
`,
29+
Long: "Outputs the value of the given path in the yaml file to STDOUT",
30+
Run: readProperty,
3731
}
38-
app.Action = readProperty
39-
app.Run(os.Args)
40-
}
4132

42-
func readProperty(c *cli.Context) {
33+
var cmdWrite = &cobra.Command{
34+
Use: "write [yaml_file] [path] [value]",
35+
Aliases: []string{"w"},
36+
Short: "yaml w [--inplace/-i] sample.yaml a.b.c newValueForC",
37+
Example: `
38+
yaml write things.yaml a.b.c cat
39+
yaml write --inplace things.yaml a.b.c cat
40+
yaml w -i things.yaml a.b.c cat
41+
`,
42+
Long: `Updates the yaml file w.r.t the given path and value.
43+
Outputs to STDOUT unless the inplace flag is used, in which case the file is updated instead.`,
44+
Run: writeProperty,
45+
}
46+
cmdWrite.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the yaml file inplace")
47+
48+
var rootCmd = &cobra.Command{Use: "yaml"}
49+
rootCmd.PersistentFlags().BoolVarP(&trimOutput, "trim", "t", true, "trim yaml output")
50+
rootCmd.AddCommand(cmdRead, cmdWrite)
51+
rootCmd.Execute()
52+
}
4353

54+
func readProperty(cmd *cobra.Command, args []string) {
4455
var parsedData map[interface{}]interface{}
4556

46-
readYaml(c, &parsedData)
57+
readYaml(args, &parsedData)
4758

48-
if len(c.Args()) == 1 {
59+
if len(args) == 1 {
4960
printYaml(parsedData)
5061
os.Exit(0)
5162
}
5263

53-
var paths = parsePath(c.Args()[1])
64+
var paths = parsePath(args[1])
5465

5566
printYaml(readMap(parsedData, paths[0], paths[1:len(paths)]))
5667
}
5768

58-
func writeProperty(c *cli.Context) {
59-
printYaml(updateProperty(c))
60-
}
61-
62-
func writePropertyInPlace(c *cli.Context) {
63-
updatedYaml := updateProperty(c)
64-
ioutil.WriteFile(c.Args()[0], []byte(updatedYaml), 0644)
65-
}
66-
67-
func updateProperty(c *cli.Context) string {
68-
var parsedData map[interface{}]interface{}
69-
readYaml(c, &parsedData)
70-
71-
if len(c.Args()) < 3 {
69+
func writeProperty(cmd *cobra.Command, args []string) {
70+
if len(args) < 3 {
7271
log.Fatalf("Must provide <filename> <path_to_update> <value>")
7372
}
7473

75-
var paths = parsePath(c.Args()[1])
74+
var parsedData map[interface{}]interface{}
75+
readYaml(args, &parsedData)
7676

77-
write(parsedData, paths[0], paths[1:len(paths)], getValue(c.Args()[2]))
77+
var paths = parsePath(args[1])
7878

79-
return yamlToString(parsedData)
80-
}
79+
write(parsedData, paths[0], paths[1:len(paths)], getValue(args[2]))
8180

81+
if writeInplace {
82+
ioutil.WriteFile(args[0], []byte(yamlToString(parsedData)), 0644)
83+
} else {
84+
printYaml(parsedData)
85+
}
86+
}
8287
func getValue(argument string) interface{} {
8388
var value, err interface{}
8489
var inQuotes = argument[0] == '"'
@@ -108,19 +113,22 @@ func yamlToString(context interface{}) string {
108113
outStr := string(out)
109114
// trim the trailing new line as it's easier for a script to add
110115
// it in if required than to remove it
111-
return strings.Trim(outStr, "\n ")
116+
if trimOutput {
117+
return strings.Trim(outStr, "\n ")
118+
}
119+
return outStr
112120
}
113121

114-
func readYaml(c *cli.Context, parsedData *map[interface{}]interface{}) {
115-
if len(c.Args()) == 0 {
122+
func readYaml(args []string, parsedData *map[interface{}]interface{}) {
123+
if len(args) == 0 {
116124
log.Fatalf("Must provide filename")
117125
}
118126

119127
var rawData []byte
120-
if c.Args()[0] == "-" {
128+
if args[0] == "-" {
121129
rawData = readStdin()
122130
} else {
123-
rawData = readFile(c.Args()[0])
131+
rawData = readFile(args[0])
124132
}
125133

126134
err := yaml.Unmarshal([]byte(rawData), &parsedData)

0 commit comments

Comments
 (0)