1
1
package main
2
2
3
3
import (
4
+ "cmp"
4
5
"context"
5
6
"crypto/tls"
7
+ "encoding/json"
6
8
"fmt"
9
+ "log/slog"
7
10
"net"
8
11
"net/http"
9
12
"slices"
13
+ "strings"
10
14
11
15
"connectrpc.com/connect"
12
16
"github.com/brianvoe/gofakeit/v7"
13
17
stubsv1 "github.com/sudorandom/fauxrpc/private/proto/gen/stubs/v1"
14
18
"github.com/sudorandom/fauxrpc/private/proto/gen/stubs/v1/stubsv1connect"
15
19
"golang.org/x/net/http2"
16
- "google.golang.org/protobuf/encoding/protojson"
17
20
)
18
21
19
22
type StubCmd struct {
20
- Add StubAddCmd `cmd:"" help:"Adds a new stub response by method or type"`
21
- List StubListCmd `cmd:"" help:"List all registered mocks"`
23
+ Add StubAddCmd `cmd:"" help:"Adds a new stub response by method or type"`
24
+ List StubListCmd `cmd:"" help:"List all registered stubs"`
25
+ Get StubGetCmd `cmd:"" help:"Get a registered stub"`
26
+ Remove StubRemoveCmd `cmd:"" help:"Remove a registered stub"`
27
+ RemoveAll StubRemoveAllCmd `cmd:"" help:"Remove all stubs"`
22
28
}
23
29
24
30
type StubAddCmd struct {
@@ -32,7 +38,7 @@ func (c *StubAddCmd) Run(globals *Globals) error {
32
38
client := newStubClient (c .Addr )
33
39
stubs := []* stubsv1.Stub {}
34
40
if c .ID == "" {
35
- c .ID = gofakeit .LetterN ( 5 )
41
+ c .ID = gofakeit .AdjectiveDescriptive () + "-" + strings . ReplaceAll ( gofakeit . Animal (), " " , "-" ) + gofakeit . DigitN ( 3 )
36
42
}
37
43
stubs = append (stubs , & stubsv1.Stub {
38
44
Ref : & stubsv1.StubRef {
@@ -42,8 +48,12 @@ func (c *StubAddCmd) Run(globals *Globals) error {
42
48
Content : & stubsv1.Stub_Json {Json : c .JSON },
43
49
},
44
50
)
45
- _ , err := client .AddStubs (context .Background (), connect .NewRequest (& stubsv1.AddStubsRequest {Stubs : stubs }))
46
- return err
51
+ resp , err := client .AddStubs (context .Background (), connect .NewRequest (& stubsv1.AddStubsRequest {Stubs : stubs }))
52
+ if err != nil {
53
+ return err
54
+ }
55
+ outputStubs (resp .Msg .GetStubs ())
56
+ return nil
47
57
}
48
58
49
59
type StubListCmd struct {
@@ -64,31 +74,98 @@ func (c *StubListCmd) Run(globals *Globals) error {
64
74
}
65
75
66
76
for name , ids := range groupedStubs {
67
- fmt .Printf ("%s (%d) \n " , name , len ( ids ) )
77
+ fmt .Printf ("target=%s \n " , name )
68
78
slices .Sort (ids )
79
+
69
80
for _ , id := range ids {
70
- fmt .Printf (" - %s\n " , id )
81
+ fmt .Printf (" id= %s\n " , id )
71
82
}
72
83
}
73
84
return err
74
85
}
75
86
76
87
type StubGetCmd struct {
77
- Addr string `short:"a" help:"Address to bind to." default:"http://127.0.0.1:6660"`
88
+ Addr string `short:"a" help:"Address to bind to." default:"http://127.0.0.1:6660"`
89
+ Target string `arg:"" help:"Protobuf method or type" example:"'connectrpc.eliza.v1/Say', 'connectrpc.eliza.v1.IntroduceResponse'"`
90
+ ID string `arg:"" help:"ID to give this particular mock response, will be a random string if one isn't given" example:"bad-response"`
78
91
}
79
92
80
93
func (c * StubGetCmd ) Run (globals * Globals ) error {
81
94
client := newStubClient (c .Addr )
82
- resp , err := client .ListStubs (context .Background (), connect .NewRequest (& stubsv1.ListStubsRequest {}))
95
+ resp , err := client .ListStubs (context .Background (), connect .NewRequest (& stubsv1.ListStubsRequest {
96
+ StubRef : & stubsv1.StubRef {
97
+ Id : c .ID ,
98
+ Target : c .Target ,
99
+ },
100
+ }))
83
101
if err != nil {
84
102
return err
85
103
}
86
- jsonBody , err := protojson.MarshalOptions {Indent : " " }.Marshal (resp .Msg )
104
+ outputStubs (resp .Msg .GetStubs ())
105
+ return nil
106
+ }
107
+
108
+ type StubRemoveCmd struct {
109
+ Addr string `short:"a" help:"Address to bind to." default:"http://127.0.0.1:6660"`
110
+ Target string `arg:"" help:"Protobuf method or type" example:"'connectrpc.eliza.v1/Say', 'connectrpc.eliza.v1.IntroduceResponse'"`
111
+ ID string `arg:"" help:"ID to give this particular mock response, will be a random string if one isn't given" example:"bad-response"`
112
+ }
113
+
114
+ func (c * StubRemoveCmd ) Run (globals * Globals ) error {
115
+ client := newStubClient (c .Addr )
116
+ _ , err := client .RemoveStubs (context .Background (), connect .NewRequest (& stubsv1.RemoveStubsRequest {
117
+ StubRefs : []* stubsv1.StubRef {
118
+ {
119
+ Id : c .ID ,
120
+ Target : c .Target ,
121
+ },
122
+ },
123
+ }))
87
124
if err != nil {
88
125
return err
89
126
}
90
- fmt .Println (string (jsonBody ))
91
- return err
127
+ return nil
128
+ }
129
+
130
+ type StubRemoveAllCmd struct {
131
+ Addr string `short:"a" help:"Address to bind to." default:"http://127.0.0.1:6660"`
132
+ }
133
+
134
+ func (c * StubRemoveAllCmd ) Run (globals * Globals ) error {
135
+ client := newStubClient (c .Addr )
136
+ _ , err := client .RemoveAllStubs (context .Background (), connect .NewRequest (& stubsv1.RemoveAllStubsRequest {}))
137
+ if err != nil {
138
+ return err
139
+ }
140
+ return nil
141
+ }
142
+
143
+ type StubForOutput struct {
144
+ Ref * stubsv1.StubRef `json:"ref,omitempty"`
145
+ Content any `json:"content,omitempty"`
146
+ }
147
+
148
+ func outputStubs (stubs []* stubsv1.Stub ) {
149
+ slices .SortFunc (stubs , func (a * stubsv1.Stub , b * stubsv1.Stub ) int {
150
+ return cmp .Compare (a .GetRef ().GetId (), b .GetRef ().GetId ())
151
+ })
152
+ for _ , stub := range stubs {
153
+ var v any
154
+ if err := json .Unmarshal ([]byte (stub .GetJson ()), & v ); err != nil {
155
+ slog .Error ("error marshalling for output" , slog .Any ("error" , err ))
156
+ continue
157
+ }
158
+ outputStub := StubForOutput {
159
+ Ref : stub .Ref ,
160
+ Content : v ,
161
+ }
162
+ b , err := json .MarshalIndent (outputStub , "" , " " )
163
+ if err != nil {
164
+ slog .Error ("error marshalling for output" , slog .Any ("error" , err ))
165
+ continue
166
+ }
167
+ fmt .Println (string (b ))
168
+ }
92
169
}
93
170
94
171
func newStubClient (addr string ) stubsv1connect.StubsServiceClient {
0 commit comments