...
1
17 package main
18
19 import (
20 "flag"
21 "fmt"
22 "io/ioutil"
23 "os"
24 )
25
26 import (
27 "encoding/json"
28
29 "github.com/jmespath/go-jmespath"
30 )
31
32 func errMsg(msg string, a ...interface{}) int {
33 fmt.Fprintf(os.Stderr, msg, a...)
34 fmt.Fprintln(os.Stderr)
35 return 1
36 }
37
38 func run() int {
39
40 astOnly := flag.Bool("ast", false, "Print the AST for the input expression and exit.")
41 inputFile := flag.String("input", "", "Filename containing JSON data to search. If not provided, data is read from stdin.")
42
43 flag.Parse()
44 args := flag.Args()
45 if len(args) != 1 {
46 fmt.Fprintf(os.Stderr, "Usage:\n\n")
47 flag.PrintDefaults()
48 return errMsg("\nError: expected a single argument (the JMESPath expression).")
49 }
50
51 expression := args[0]
52 parser := jmespath.NewParser()
53 parsed, err := parser.Parse(expression)
54 if err != nil {
55 if syntaxError, ok := err.(jmespath.SyntaxError); ok {
56 return errMsg("%s\n%s\n", syntaxError, syntaxError.HighlightLocation())
57 }
58 return errMsg("%s", err)
59 }
60 if *astOnly {
61 fmt.Println("")
62 fmt.Printf("%s\n", parsed)
63 return 0
64 }
65
66 var inputData []byte
67 if *inputFile != "" {
68 inputData, err = ioutil.ReadFile(*inputFile)
69 if err != nil {
70 return errMsg("Error loading file %s: %s", *inputFile, err)
71 }
72 } else {
73
74
75 inputData, err = ioutil.ReadAll(os.Stdin)
76 if err != nil {
77 return errMsg("Error reading from stdin: %s", err)
78 }
79 }
80 var data interface{}
81 if err := json.Unmarshal(inputData, &data); err != nil {
82 return errMsg("Invalid input JSON: %s", err)
83 }
84 result, err := jmespath.Search(expression, data)
85 if err != nil {
86 return errMsg("Error executing expression: %s", err)
87 }
88 toJSON, err := json.MarshalIndent(result, "", " ")
89 if err != nil {
90 return errMsg("Error serializing result to JSON: %s", err)
91 }
92 fmt.Println(string(toJSON))
93 return 0
94 }
95
96 func main() {
97 os.Exit(run())
98 }
99
View as plain text