Skip to content

Commit 2703210

Browse files
committed
Avoid to read file directly from plugin side
1 parent 3d438f7 commit 2703210

File tree

5 files changed

+63
-56
lines changed

5 files changed

+63
-56
lines changed

helper/runner.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@ func (r *Runner) Config() (*configs.Config, error) {
131131
return r.tfconfig, nil
132132
}
133133

134+
// File returns the hcl.File object
135+
func (r *Runner) File(filename string) (*hcl.File, error) {
136+
return r.Files[filename], nil
137+
}
138+
134139
// RootProvider returns the provider configuration.
135140
// In the helper runner, it always returns its own provider.
136141
func (r *Runner) RootProvider(name string) (*configs.Provider, error) {

tflint/client/client.go

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package client
22

33
import (
44
"fmt"
5-
"io/ioutil"
65
"log"
76
"net"
87
"net/rpc"
@@ -173,6 +172,20 @@ func (c *Client) Config() (*configs.Config, error) {
173172
return config, nil
174173
}
175174

175+
// File calls the server-side File method and returns the hcl.File object.
176+
func (c *Client) File(filename string) (*hcl.File, error) {
177+
var response FileResponse
178+
if err := c.rpcClient.Call("Plugin.File", FileRequest{Filename: filename}, &response); err != nil {
179+
return nil, err
180+
}
181+
182+
file, diags := parseConfig(response.Bytes, filename, response.Range.Start)
183+
if diags.HasErrors() {
184+
return nil, diags
185+
}
186+
return file, nil
187+
}
188+
176189
// RootProvider calls the server-side RootProvider method and returns the provider configuration.
177190
func (c *Client) RootProvider(name string) (*configs.Provider, error) {
178191
log.Printf("[DEBUG] Accessing to the `%s` provider config in the root module", name)
@@ -227,15 +240,14 @@ func (c *Client) EvaluateExpr(expr hcl.Expression, ret interface{}, wantType *ct
227240
wantType = &cty.Type{}
228241
}
229242

230-
var response EvalExprResponse
231-
var err error
232-
233-
src, err := ioutil.ReadFile(expr.Range().Filename)
243+
file, err := c.File(expr.Range().Filename)
234244
if err != nil {
235245
return err
236246
}
247+
248+
var response EvalExprResponse
237249
req := EvalExprRequest{Ret: ret, Type: *wantType}
238-
req.Expr, req.ExprRange = encodeExpr(src, expr)
250+
req.Expr, req.ExprRange = encodeExpr(file.Bytes, expr)
239251
if err := c.rpcClient.Call("Plugin.EvalExpr", req, &response); err != nil {
240252
return err
241253
}
@@ -267,16 +279,14 @@ func (c *Client) EvaluateExprOnRootCtx(expr hcl.Expression, ret interface{}, wan
267279
if wantType == nil {
268280
wantType = &cty.Type{}
269281
}
270-
271-
var response EvalExprResponse
272-
var err error
273-
274-
src, err := ioutil.ReadFile(expr.Range().Filename)
282+
file, err := c.File(expr.Range().Filename)
275283
if err != nil {
276284
return err
277285
}
286+
287+
var response EvalExprResponse
278288
req := EvalExprRequest{Ret: ret, Type: *wantType}
279-
req.Expr, req.ExprRange = encodeExpr(src, expr)
289+
req.Expr, req.ExprRange = encodeExpr(file.Bytes, expr)
280290
if err := c.rpcClient.Call("Plugin.EvalExprOnRootCtx", req, &response); err != nil {
281291
return err
282292
}
@@ -304,14 +314,14 @@ func (c *Client) EvaluateExprOnRootCtx(expr hcl.Expression, ret interface{}, wan
304314

305315
// IsNullExpr calls the server-side IsNullExpr method with the passed expression.
306316
func (c *Client) IsNullExpr(expr hcl.Expression) (bool, error) {
307-
var response IsNullExprResponse
308-
309-
src, err := ioutil.ReadFile(expr.Range().Filename)
317+
file, err := c.File(expr.Range().Filename)
310318
if err != nil {
311319
return false, err
312320
}
321+
322+
var response IsNullExprResponse
313323
req := &IsNullExprRequest{}
314-
req.Expr, req.Range = encodeExpr(src, expr)
324+
req.Expr, req.Range = encodeExpr(file.Bytes, expr)
315325
if err := c.rpcClient.Call("Plugin.IsNullExpr", req, &response); err != nil {
316326
return false, err
317327
}
@@ -321,17 +331,17 @@ func (c *Client) IsNullExpr(expr hcl.Expression) (bool, error) {
321331

322332
// EmitIssueOnExpr calls the server-side EmitIssue method with the passed expression.
323333
func (c *Client) EmitIssueOnExpr(rule tflint.Rule, message string, expr hcl.Expression) error {
334+
file, err := c.File(expr.Range().Filename)
335+
if err != nil {
336+
return err
337+
}
338+
324339
req := &EmitIssueRequest{
325340
Rule: encodeRule(rule),
326341
Message: message,
327342
Location: expr.Range(),
328343
}
329-
330-
src, err := ioutil.ReadFile(expr.Range().Filename)
331-
if err != nil {
332-
return err
333-
}
334-
req.Expr, req.ExprRange = encodeExpr(src, expr)
344+
req.Expr, req.ExprRange = encodeExpr(file.Bytes, expr)
335345

336346
if err := c.rpcClient.Call("Plugin.EmitIssue", &req, new(interface{})); err != nil {
337347
return err

tflint/client/client_test.go

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ package client
22

33
import (
44
"errors"
5-
"io/ioutil"
65
"net"
76
"net/rpc"
8-
"os"
97
"testing"
108

119
"github.com/google/go-cmp/cmp"
@@ -98,6 +96,11 @@ func (*mockServer) Backend(req *BackendRequest, resp *BackendResponse) error {
9896
return nil
9997
}
10098

99+
func (*mockServer) File(req *FileRequest, resp *FileResponse) error {
100+
*resp = FileResponse{Bytes: []byte("foo = 1"), Range: hcl.Range{Filename: req.Filename, Start: hcl.InitialPos}}
101+
return nil
102+
}
103+
101104
func (*mockServer) EvalExpr(req *EvalExprRequest, resp *EvalExprResponse) error {
102105
*resp = EvalExprResponse{Val: cty.StringVal("1"), Err: nil}
103106
return nil
@@ -339,16 +342,7 @@ func Test_EvaluateExpr(t *testing.T) {
339342
client, server := startMockServer(t)
340343
defer server.Listener.Close()
341344

342-
file, err := ioutil.TempFile("", "tflint-test-evaluateExpr-*.tf")
343-
if err != nil {
344-
t.Fatal(err)
345-
}
346-
defer os.Remove(file.Name())
347-
if _, err := file.Write([]byte("1")); err != nil {
348-
t.Fatal(err)
349-
}
350-
351-
expr, diags := hclsyntax.ParseExpression([]byte("1"), file.Name(), hcl.Pos{Line: 1, Column: 1})
345+
expr, diags := hclsyntax.ParseExpression([]byte("1"), "example.tf", hcl.Pos{Line: 1, Column: 7})
352346
if diags.HasErrors() {
353347
t.Fatal(diags)
354348
}
@@ -375,21 +369,12 @@ func Test_EmitIssueOnExpr(t *testing.T) {
375369
client, server := startMockServer(t)
376370
defer server.Listener.Close()
377371

378-
file, err := ioutil.TempFile("", "tflint-test-evaluateExpr-*.tf")
379-
if err != nil {
380-
t.Fatal(err)
381-
}
382-
defer os.Remove(file.Name())
383-
if _, err := file.Write([]byte("1")); err != nil {
384-
t.Fatal(err)
385-
}
386-
387-
expr, diags := hclsyntax.ParseExpression([]byte("1"), file.Name(), hcl.Pos{Line: 1, Column: 1})
372+
expr, diags := hclsyntax.ParseExpression([]byte("1"), "example.tf", hcl.Pos{Line: 1, Column: 7})
388373
if diags.HasErrors() {
389374
t.Fatal(diags)
390375
}
391376

392-
if err := client.EmitIssueOnExpr(&testRule{}, file.Name(), expr); err != nil {
377+
if err := client.EmitIssueOnExpr(&testRule{}, "example.tf", expr); err != nil {
393378
t.Fatal(err)
394379
}
395380
}
@@ -398,21 +383,12 @@ func Test_EmitIssue(t *testing.T) {
398383
client, server := startMockServer(t)
399384
defer server.Listener.Close()
400385

401-
file, err := ioutil.TempFile("", "tflint-test-evaluateExpr-*.tf")
402-
if err != nil {
403-
t.Fatal(err)
404-
}
405-
defer os.Remove(file.Name())
406-
if _, err := file.Write([]byte("1")); err != nil {
407-
t.Fatal(err)
408-
}
409-
410-
expr, diags := hclsyntax.ParseExpression([]byte("1"), file.Name(), hcl.Pos{Line: 1, Column: 1})
386+
expr, diags := hclsyntax.ParseExpression([]byte("1"), "example.tf", hcl.Pos{Line: 1, Column: 7})
411387
if diags.HasErrors() {
412388
t.Fatal(diags)
413389
}
414390

415-
if err := client.EmitIssue(&testRule{}, file.Name(), expr.Range()); err != nil {
391+
if err := client.EmitIssue(&testRule{}, "example.tf", expr.Range()); err != nil {
416392
t.Fatal(err)
417393
}
418394
}

tflint/client/rpc.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,17 @@ type ConfigResponse struct {
6767
Err error
6868
}
6969

70+
// FileRequest is a request to the server-side File method.
71+
type FileRequest struct {
72+
Filename string
73+
}
74+
75+
// FileResponse is a response to the server-side File method.
76+
type FileResponse struct {
77+
Bytes []byte
78+
Range hcl.Range
79+
}
80+
7081
// RootProviderRequest is a request to the server-side RootProvider method.
7182
type RootProviderRequest struct {
7283
Name string

tflint/interface.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ type Runner interface {
5454
// This object contains almost all accessible data structures from plugins.
5555
Config() (*configs.Config, error)
5656

57+
// File returns the hcl.File object.
58+
// This is low level API for accessing information such as comments and syntax.
59+
// When accessing resources, expressions, etc, it is recommended to use high-level APIs.
60+
File(string) (*hcl.File, error)
61+
5762
// RootProvider returns the provider configuration in the root module.
5863
// It can be used by child modules to access the credentials defined in the root module.
5964
RootProvider(name string) (*configs.Provider, error)

0 commit comments

Comments
 (0)