Skip to content

Commit 55eedca

Browse files
authored
Add GetProviderContent helper (#172)
1 parent 549898f commit 55eedca

File tree

4 files changed

+153
-1
lines changed

4 files changed

+153
-1
lines changed

helper/runner.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,29 @@ func (r *Runner) GetResourceContent(name string, schema *hclext.BodySchema, opts
9191
return content, nil
9292
}
9393

94+
// GetProviderContent gets a provider content of the current module
95+
func (r *Runner) GetProviderContent(name string, schema *hclext.BodySchema, opts *tflint.GetModuleContentOption) (*hclext.BodyContent, error) {
96+
body, err := r.GetModuleContent(&hclext.BodySchema{
97+
Blocks: []hclext.BlockSchema{
98+
{Type: "provider", LabelNames: []string{"name"}, Body: schema},
99+
},
100+
}, opts)
101+
if err != nil {
102+
return nil, err
103+
}
104+
105+
content := &hclext.BodyContent{Blocks: []*hclext.Block{}}
106+
for _, provider := range body.Blocks {
107+
if provider.Labels[0] != name {
108+
continue
109+
}
110+
111+
content.Blocks = append(content.Blocks, provider)
112+
}
113+
114+
return content, nil
115+
}
116+
94117
// GetFile returns the hcl.File object
95118
func (r *Runner) GetFile(filename string) (*hcl.File, error) {
96119
return r.files[filename], nil

plugin/plugin2host/client.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,34 @@ func (c *GRPCClient) GetResourceContent(name string, inner *hclext.BodySchema, o
6666
return content, nil
6767
}
6868

69+
// GetProviderContent gets the contents of providers based on the schema.
70+
// This is shorthand of GetModuleContent for providers
71+
func (c *GRPCClient) GetProviderContent(name string, inner *hclext.BodySchema, opts *tflint.GetModuleContentOption) (*hclext.BodyContent, error) {
72+
if opts == nil {
73+
opts = &tflint.GetModuleContentOption{}
74+
}
75+
76+
body, err := c.GetModuleContent(&hclext.BodySchema{
77+
Blocks: []hclext.BlockSchema{
78+
{Type: "provider", LabelNames: []string{"name"}, Body: inner},
79+
},
80+
}, opts)
81+
if err != nil {
82+
return nil, err
83+
}
84+
85+
content := &hclext.BodyContent{Blocks: []*hclext.Block{}}
86+
for _, provider := range body.Blocks {
87+
if provider.Labels[0] != name {
88+
continue
89+
}
90+
91+
content.Blocks = append(content.Blocks, provider)
92+
}
93+
94+
return content, nil
95+
}
96+
6997
// GetModuleContent gets the contents of the module based on the schema.
7098
func (c *GRPCClient) GetModuleContent(schema *hclext.BodySchema, opts *tflint.GetModuleContentOption) (*hclext.BodyContent, error) {
7199
if opts == nil {

plugin/plugin2host/plugin2host_test.go

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,103 @@ resource "aws_instance" "foo" {
321321
}
322322
}
323323

324+
func TestGetProviderContent(t *testing.T) {
325+
// default error check helper
326+
neverHappend := func(err error) bool { return err != nil }
327+
328+
// default getFileImpl function
329+
files := map[string][]byte{}
330+
fileExists := func() map[string][]byte {
331+
return files
332+
}
333+
334+
// test util functions
335+
hclFile := func(filename string, code string) *hcl.File {
336+
file, diags := hclsyntax.ParseConfig([]byte(code), filename, hcl.InitialPos)
337+
if diags.HasErrors() {
338+
panic(diags)
339+
}
340+
files[filename] = file.Bytes
341+
return file
342+
}
343+
344+
tests := []struct {
345+
Name string
346+
Args func() (string, *hclext.BodySchema, *tflint.GetModuleContentOption)
347+
ServerImpl func(*hclext.BodySchema, tflint.GetModuleContentOption) (*hclext.BodyContent, hcl.Diagnostics)
348+
Want func(string, *hclext.BodySchema, *tflint.GetModuleContentOption) (*hclext.BodyContent, hcl.Diagnostics)
349+
ErrCheck func(error) bool
350+
}{
351+
{
352+
Name: "get HCL content",
353+
Args: func() (string, *hclext.BodySchema, *tflint.GetModuleContentOption) {
354+
return "aws", &hclext.BodySchema{
355+
Attributes: []hclext.AttributeSchema{{Name: "region"}},
356+
}, nil
357+
},
358+
ServerImpl: func(schema *hclext.BodySchema, opts tflint.GetModuleContentOption) (*hclext.BodyContent, hcl.Diagnostics) {
359+
file := hclFile("test.tf", `
360+
provider "aws" {
361+
region = "us-east-1"
362+
}
363+
364+
provider "google" {
365+
region = "us-central1"
366+
}`)
367+
return hclext.PartialContent(file.Body, schema)
368+
},
369+
Want: func(resource string, schema *hclext.BodySchema, opts *tflint.GetModuleContentOption) (*hclext.BodyContent, hcl.Diagnostics) {
370+
// Removed "google" provider
371+
file := hclFile("test.tf", `
372+
provider "aws" {
373+
region = "us-east-1"
374+
}`)
375+
return hclext.Content(file.Body, &hclext.BodySchema{
376+
Blocks: []hclext.BlockSchema{
377+
{
378+
Type: "provider",
379+
LabelNames: []string{"name"},
380+
Body: &hclext.BodySchema{
381+
Attributes: []hclext.AttributeSchema{{Name: "region"}},
382+
},
383+
},
384+
},
385+
})
386+
},
387+
ErrCheck: neverHappend,
388+
},
389+
}
390+
391+
for _, test := range tests {
392+
t.Run(test.Name, func(t *testing.T) {
393+
client := startTestGRPCServer(t, newMockServer(mockServerImpl{getModuleContent: test.ServerImpl, getFiles: fileExists}))
394+
395+
got, err := client.GetProviderContent(test.Args())
396+
if test.ErrCheck(err) {
397+
t.Fatalf("failed to call GetProviderContent: %s", err)
398+
}
399+
want, diags := test.Want(test.Args())
400+
if diags.HasErrors() {
401+
t.Fatalf("failed to get want: %d diagsnotics", len(diags))
402+
for _, diag := range diags {
403+
t.Logf(" - %s", diag.Error())
404+
}
405+
}
406+
407+
opts := cmp.Options{
408+
cmp.Comparer(func(x, y cty.Value) bool {
409+
return x.GoString() == y.GoString()
410+
}),
411+
cmpopts.EquateEmpty(),
412+
allowAllUnexported,
413+
}
414+
if diff := cmp.Diff(got, want, opts); diff != "" {
415+
t.Errorf("diff: %s", diff)
416+
}
417+
})
418+
}
419+
}
420+
324421
func TestGetModuleContent(t *testing.T) {
325422
// default error check helper
326423
neverHappend := func(err error) bool { return err != nil }

tflint/interface.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,12 @@ type Runner interface {
9191
// ```
9292
GetResourceContent(resourceName string, schema *hclext.BodySchema, option *GetModuleContentOption) (*hclext.BodyContent, error)
9393

94+
// GetProviderContent retrieves the content of providers based on the passed schema.
95+
// This method is GetResourceContent for providers.
96+
GetProviderContent(providerName string, schema *hclext.BodySchema, option *GetModuleContentOption) (*hclext.BodyContent, error)
97+
9498
// GetModuleContent retrieves the content of the module based on the passed schema.
95-
// GetResourceContent is syntactic sugar for GetModuleContent, which you can use to access structures other than resources.
99+
// GetResourceContent/GetProviderContent are syntactic sugar for GetModuleContent, which you can use to access other structures.
96100
GetModuleContent(schema *hclext.BodySchema, option *GetModuleContentOption) (*hclext.BodyContent, error)
97101

98102
// GetFile returns the hcl.File object.

0 commit comments

Comments
 (0)