Skip to content

Commit ce7ef9f

Browse files
committed
feat: add sample cli and build worrkflow
1 parent 86137f4 commit ce7ef9f

File tree

2 files changed

+202
-0
lines changed

2 files changed

+202
-0
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Release Build
2+
on:
3+
release:
4+
types: [created]
5+
jobs:
6+
releases-matrix:
7+
name: Release Go Binary
8+
runs-on: ubuntu-latest
9+
strategy:
10+
matrix:
11+
goos: [linux, windows, darwin]
12+
goarch: ["386", amd64, arm64]
13+
goversion: ["1.16", "1.17"]
14+
exclude:
15+
- goarch: "386"
16+
goos: darwin
17+
- goarch: "386"
18+
goos: windows
19+
- goarch: arm64
20+
goos: windows
21+
steps:
22+
- uses: actions/checkout@v2
23+
- name: Set BUILD_VERSION env
24+
run: echo "RELEASE_TAG=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV
25+
- uses: wangyoucao577/[email protected]
26+
with:
27+
github_token: ${{ secrets.GITHUB_TOKEN }}
28+
goos: ${{ matrix.goos }}
29+
goarch: ${{ matrix.goarch }}
30+
goversion: ${{ matrix.goversion }}
31+
project_path: "./cmd/"
32+
binary_name: "jsonpath"
33+
ldflags: -X "main.Command=jsonpath" main.Version=${{ env.RELEASE_TAG }}" -X "main.OS=${{ matrix.goos }}" -X main.Arch=${{ matrix.goos }}
34+

cmd/main.go

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"errors"
6+
"flag"
7+
"fmt"
8+
"io/ioutil"
9+
"os"
10+
11+
"github.com/evilmonkeyinc/jsonpath"
12+
)
13+
14+
var (
15+
// Arch build identifier
16+
Arch string = ""
17+
// Command is the expected name of the build
18+
Command string = "jsonpath"
19+
// OS build identifier
20+
OS string = ""
21+
// Version build identifier
22+
Version string = "dev"
23+
24+
errSelectorNotSpecified error = fmt.Errorf("selector not specified. expected -selector option or passed as argument")
25+
errJSONDataNotSpecified error = fmt.Errorf("json data not specified. expected -jsondata, or -input options or passed as argument")
26+
)
27+
28+
const (
29+
cmdHelp string = "help"
30+
cmdVersion string = "version"
31+
)
32+
33+
func main() {
34+
flagset := flag.NewFlagSet("", flag.ContinueOnError)
35+
selectorPtr := flagset.String("selector", "", "a valid JSONPath selector")
36+
jsondataPtr := flagset.String("jsondata", "", "the json data to parse)")
37+
inputPtr := flagset.String("input", "", "optional path to a file that includes the json data to query")
38+
outputPtr := flagset.String("output", "", "optional path to a file that the result ")
39+
40+
if err := flagset.Parse(os.Args[1:]); err != nil {
41+
if !errors.Is(err, flag.ErrHelp) {
42+
outputError(errSelectorNotSpecified)
43+
return
44+
}
45+
printHelp(flagset)
46+
return
47+
}
48+
49+
args := flagset.Args()
50+
firstArg := ""
51+
if len(args) > 0 {
52+
firstArg = args[0]
53+
}
54+
55+
switch firstArg {
56+
case cmdHelp:
57+
printHelp(flagset)
58+
break
59+
case cmdVersion:
60+
fmt.Printf("version %s %s/%s\n", Version, OS, Arch)
61+
break
62+
default:
63+
nextArg := 0
64+
65+
selector := *selectorPtr
66+
if selector == "" && len(args) > nextArg {
67+
selector = args[nextArg]
68+
nextArg++
69+
}
70+
71+
if selector == "" {
72+
outputError(errSelectorNotSpecified)
73+
return
74+
}
75+
76+
compiled, err := jsonpath.Compile(selector)
77+
if err != nil {
78+
outputError(err)
79+
return
80+
}
81+
82+
jsondata := *jsondataPtr
83+
if jsondata == "" && len(args) > nextArg {
84+
jsondata = args[nextArg]
85+
nextArg++
86+
}
87+
88+
if jsondata == "" && *inputPtr != "" {
89+
bytes, err := loadFileContents(*inputPtr)
90+
if err != nil {
91+
outputError(err)
92+
return
93+
}
94+
jsondata = string(bytes)
95+
}
96+
if jsondata == "" {
97+
outputError(errJSONDataNotSpecified)
98+
return
99+
}
100+
101+
result, err := compiled.QueryString(jsondata)
102+
if err != nil {
103+
outputError(err)
104+
return
105+
}
106+
107+
jsonOutput, err := json.Marshal(result)
108+
if err != nil {
109+
outputError(err)
110+
return
111+
}
112+
113+
if *outputPtr != "" {
114+
if err := saveFileContents(*outputPtr, jsonOutput); err != nil {
115+
outputError(err)
116+
}
117+
os.Exit(0)
118+
return
119+
}
120+
121+
fmt.Printf("%s\n", string(jsonOutput))
122+
break
123+
}
124+
os.Exit(0)
125+
}
126+
127+
func printHelp(flagset *flag.FlagSet) {
128+
fmt.Printf("%s is a tool for querying json data using a JSONPath selector\n\n", Command)
129+
fmt.Printf("Usage:\n\n")
130+
fmt.Printf(" %s '[selector]' '[jsondata]'\n", Command)
131+
fmt.Printf("\nExample:\n\n")
132+
fmt.Printf(` %s '$[*].key' '[{"key":"show this"},{"key":"and this"},{"other":"but not this"}]'`+"\n", Command)
133+
fmt.Printf(` > ["show this","and this"]` + "\n")
134+
fmt.Printf("\nOptions:\n\n")
135+
flagset.PrintDefaults()
136+
os.Exit(0)
137+
}
138+
139+
func outputError(err error) {
140+
fmt.Printf("failed: %s\n", err.Error())
141+
os.Exit(1)
142+
}
143+
144+
func loadFileContents(filename string) ([]byte, error) {
145+
jsonFile, err := os.Open(filename)
146+
if err != nil {
147+
return nil, err
148+
}
149+
defer jsonFile.Close()
150+
byteValue, err := ioutil.ReadAll(jsonFile)
151+
if err != nil {
152+
return nil, err
153+
}
154+
return byteValue, nil
155+
}
156+
157+
func saveFileContents(filename string, content []byte) error {
158+
file, err := os.Create(filename)
159+
if err != nil {
160+
return err
161+
}
162+
defer file.Close()
163+
164+
if _, err = file.Write(content); err != nil {
165+
return err
166+
}
167+
return nil
168+
}

0 commit comments

Comments
 (0)