AT Protocol IPLD-CAR Repository toolkit (CLI)
1package cmd
2
3import (
4 "log"
5 "os"
6 "os/exec"
7 "regexp"
8 "runtime"
9 "strings"
10
11 "github.com/atscan/atr/cli"
12 "github.com/atscan/atr/engine"
13 "github.com/atscan/atr/repo"
14 "github.com/itchyny/gojq"
15 "github.com/jmespath/go-jmespath"
16 jsoniter "github.com/json-iterator/go"
17 "github.com/spf13/cobra"
18)
19
20var (
21 Query string
22 QueryJmes string
23 Type string
24 Raw bool
25 Root string
26 GoBack int
27)
28
29func init() {
30 rootCmd.AddCommand(ShowCmd)
31 ShowCmd.Flags().StringVarP(&Root, "root", "r", "", "Use specific root")
32 ShowCmd.Flags().IntVarP(&GoBack, "back", "b", 0, "Go back (n) commits")
33 ShowCmd.Flags().StringVarP(&Type, "type", "t", "", "Filter by item type")
34 ShowCmd.Flags().StringVarP(&Query, "query", "q", "", "Query results (jq)")
35 ShowCmd.Flags().StringVarP(&QueryJmes, "query-jmes", "x", "", "Query results (jmespath)")
36 ShowCmd.Flags().BoolVar(&Raw, "raw", false, "Do not use colors (faster)")
37}
38
39var ShowCmd = &cobra.Command{
40 Use: "show",
41 Aliases: []string{"s"},
42 Short: "Show repo(s) documents",
43 Long: ``,
44 Run: func(cmd *cobra.Command, args []string) {
45 ctx := cli.Context{
46 WorkingDir: workingDir,
47 Args: args,
48 Raw: Raw,
49 }
50
51 //q := ctx.Args().First()
52 q := Query
53 var query *gojq.Query
54 if q != "" {
55 tq, err := gojq.Parse(q)
56 if err != nil {
57 log.Fatalln("gojq parse error:", err)
58 //return err
59 } else {
60 query = tq
61 }
62 }
63 qq := QueryJmes
64 var queryJmes *jmespath.JMESPath
65 if qq != "" {
66 jc, err := jmespath.Compile(qq)
67 if err != nil {
68 return
69 }
70 queryJmes = jc
71 }
72
73 style := "paraiso-dark"
74 if runtime.GOOS == "darwin" {
75 eo, err := exec.Command("defaults", "read", "-g", "AppleInterfaceStyle").Output()
76 if err != nil {
77 log.Fatal(err)
78 }
79 if strings.Index(string(eo), "Dark") != 0 {
80 style = "paraiso-light"
81 }
82 }
83 hg := cli.Highlight(style)
84
85 walk := func(ss repo.RepoSnapshot, err error) {
86
87 rr := Root
88 if GoBack > 0 {
89 gb, _ := ss.Repo.GetCommitsPath(GoBack)
90 rr = gb[len(gb)-1].String()
91
92 }
93 ss.LoadItems(rr)
94
95 for _, e := range ss.Items {
96 tf := Type
97 if tf != "" {
98 if m := regexp.MustCompile(tf).Match([]byte(e.Path)); !m {
99 continue
100 }
101 }
102
103 out := cli.ObjectOutput{Did: ss.Repo.SignedCommit().Did, Cid: e.Cid.String(), Rkey: e.Path, Body: e.Body}
104
105 if q != "" || qq != "" {
106 json, err := jsoniter.Marshal(out)
107 if err != nil {
108 log.Fatal("jsoniter error:", err)
109 continue
110 }
111 var pv interface{}
112 err = jsoniter.Unmarshal(json, &pv)
113 if err != nil {
114 log.Fatal("jsoniter error:", err)
115 continue
116 }
117 if q != "" {
118 iter := query.Run(interface{}(pv))
119 for {
120 v, ok := iter.Next()
121 if !ok {
122 break
123 }
124 if err, ok := v.(error); ok {
125 log.Fatalln("gojq iter error:", err)
126 continue
127 }
128 if v == nil {
129 continue
130 }
131 out.Match = v
132 }
133 }
134 if qq != "" {
135 r, err := queryJmes.Search(pv)
136 if err != nil {
137 log.Fatalln("jmespath error:", err)
138 }
139 out.Match = r
140 }
141 }
142
143 var ro interface{}
144 if out.Match != nil {
145 ro = out.Match
146 } else {
147 ro = out
148 }
149
150 stat, _ := os.Stdout.Stat()
151 if !Raw && (stat.Mode()&os.ModeCharDevice) != 0 {
152 cli.PrettyPrint(ro, e, ss, hg)
153 } else {
154 cli.Print(ro, e, ss)
155 }
156 }
157 }
158
159 stat, _ := os.Stdin.Stat()
160 if (stat.Mode() & os.ModeCharDevice) == 0 {
161 // data is being piped to stdin
162 engine.WalkStream(&ctx, os.Stdin, walk)
163 } else {
164 //stdin is from a terminal
165 engine.WalkFiles(&ctx, walk)
166 }
167 },
168}