Skip to content

Commit 7c3de47

Browse files
committed
#30 wip support for WalkResources API
1 parent 8f8f107 commit 7c3de47

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed

tflint/client.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,47 @@ func (c *Client) WalkResourceBlocks(resource, blockName string, walker func(*hcl
140140
return nil
141141
}
142142

143+
// ResourcesRequest is the interface used to communicate via RPC.
144+
type ResourcesRequest struct {
145+
Name string
146+
}
147+
148+
// ResourcesResponse is the interface used to communicate via RPC.
149+
type ResourcesResponse struct {
150+
Resources []*Resource
151+
Err error
152+
}
153+
154+
// Resource is an intermediate representation of configs.Resource.
155+
type Resource struct {
156+
Name string
157+
Type string
158+
159+
DeclRange hcl.Range
160+
TypeRange hcl.Range
161+
}
162+
163+
// WalkResources queries the host process, receives a list of blocks that match the conditions,
164+
// and passes each to the walker function.
165+
func (c *Client) WalkResources(resource string, walker func(*Resource) error) error {
166+
log.Printf("[DEBUG] Walk `%s` resource", resource)
167+
168+
var response ResourcesResponse
169+
if err := c.rpcClient.Call("Plugin.Resources", ResourcesRequest{Name: resource}, &response); err != nil {
170+
return err
171+
}
172+
if response.Err != nil {
173+
return response.Err
174+
}
175+
176+
for _, block := range response.Resources {
177+
if err := walker(block); err != nil {
178+
return err
179+
}
180+
}
181+
return nil
182+
}
183+
143184
// EvalExprRequest is the interface used to communicate via RPC.
144185
type EvalExprRequest struct {
145186
Expr []byte

tflint/client_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,18 @@ func (*mockServer) Blocks(req *BlocksRequest, resp *BlocksResponse) error {
5656
return nil
5757
}
5858

59+
func (*mockServer) Resources(req *ResourcesRequest, resp *ResourcesResponse) error {
60+
*resp = ResourcesResponse{Resources: []*Resource{
61+
{
62+
Name: "example",
63+
Type: "resource",
64+
DeclRange: hcl.Range{Filename: "example.tf", Start: hcl.Pos{Line: 1, Column: 1}, End: hcl.Pos{Line: 1, Column: 29}},
65+
TypeRange: hcl.Range{Filename: "example.tf", Start: hcl.Pos{Line: 1, Column: 1}, End: hcl.Pos{Line: 1, Column: 8}},
66+
},
67+
}, Err: nil}
68+
return nil
69+
}
70+
5971
func (*mockServer) EvalExpr(req *EvalExprRequest, resp *EvalExprResponse) error {
6072
*resp = EvalExprResponse{Val: cty.StringVal("1"), Err: nil}
6173
return nil
@@ -179,6 +191,39 @@ func Test_WalkResourceBlocks(t *testing.T) {
179191
}
180192
}
181193

194+
func Test_WalkResources(t *testing.T) {
195+
client, server := startMockServer(t)
196+
defer server.Listener.Close()
197+
198+
walked := []*Resource{}
199+
walker := func(block *Resource) error {
200+
walked = append(walked, block)
201+
return nil
202+
}
203+
204+
if err := client.WalkResources("example", walker); err != nil {
205+
t.Fatal(err)
206+
}
207+
208+
expected := []*Resource{
209+
{
210+
Name: "example",
211+
Type: "resource",
212+
DeclRange: hcl.Range{Filename: "example.tf", Start: hcl.Pos{Line: 1, Column: 1}, End: hcl.Pos{Line: 1, Column: 29}},
213+
TypeRange: hcl.Range{Filename: "example.tf", Start: hcl.Pos{Line: 1, Column: 1}, End: hcl.Pos{Line: 1, Column: 8}},
214+
},
215+
}
216+
217+
opts := []cmp.Option{
218+
cmpopts.IgnoreUnexported(hclsyntax.Body{}),
219+
cmpopts.IgnoreFields(hclsyntax.LiteralValueExpr{}, "Val"),
220+
cmpopts.IgnoreFields(hcl.Pos{}, "Byte"),
221+
}
222+
if !cmp.Equal(expected, walked, opts...) {
223+
t.Fatalf("Diff: %s", cmp.Diff(expected, walked, opts...))
224+
}
225+
}
226+
182227
func Test_EvaluateExpr(t *testing.T) {
183228
client, server := startMockServer(t)
184229
defer server.Listener.Close()

0 commit comments

Comments
 (0)