Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Files() method #122

Merged
merged 1 commit into from
Jun 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions helper/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,30 @@ import (

// Runner is a mock that satisfies the Runner interface for plugin testing.
type Runner struct {
Files map[string]*hcl.File
files map[string]*hcl.File
Issues Issues

tfconfig *configs.Config
config Config
}

// NewLocalRunner initialises a new test runner.
// Internal use only.
func NewLocalRunner(files map[string]*hcl.File, issues Issues) *Runner {
return &Runner{files: map[string]*hcl.File{}, Issues: issues}
}

// AddLocalFile adds a new file to the current mapped files.
// Internal use only.
func (r *Runner) AddLocalFile(name string, file *hcl.File) bool {
if _, exists := r.files[name]; exists {
return false
}

r.files[name] = file
return true
}

// Config is a pseudo TFLint config file object for testing from plugins.
type Config struct {
Rules []RuleConfig `hcl:"rule,block"`
Expand Down Expand Up @@ -134,7 +151,12 @@ func (r *Runner) Config() (*configs.Config, error) {

// File returns the hcl.File object
func (r *Runner) File(filename string) (*hcl.File, error) {
return r.Files[filename], nil
return r.files[filename], nil
}

// Files returns a map[string]hcl.File object
func (r *Runner) Files() (map[string]*hcl.File, error) {
return r.files, nil
}

// RootProvider returns the provider configuration.
Expand Down Expand Up @@ -264,7 +286,7 @@ func (r *Runner) initFromFiles() error {
},
}

for _, file := range r.Files {
for _, file := range r.files {
content, diags := file.Body.Content(configFileSchema)
if diags.HasErrors() {
return diags
Expand Down
28 changes: 28 additions & 0 deletions helper/runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -471,3 +471,31 @@ func Test_EnsureNoError(t *testing.T) {
t.Fatal("Expected to exec the passed proc, but doesn't")
}
}

func Test_Files(t *testing.T) {
var sources = map[string]string{
"main.tf": `
resource "aws_instance" "foo" {
instance_type = "t2.micro"
}`,
"outputs.tf": `
output "dummy" {
value = "test"
}`,
"providers.tf": `
provider "aws" {
region = "us-east-1"
}`,
}

runner := TestRunner(t, sources)

files, err := runner.Files()
if err != nil {
t.Fatalf("The response has an unexpected error: %s", err)
}

if !cmp.Equal(len(sources), len(files)) {
t.Fatalf("Sources and Files differ: %s", cmp.Diff(sources, files))
}
}
4 changes: 2 additions & 2 deletions helper/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
// TestRunner returns a mock Runner for testing.
// You can pass the map of file names and their contents in the second argument.
func TestRunner(t *testing.T, files map[string]string) *Runner {
runner := &Runner{Files: map[string]*hcl.File{}, Issues: Issues{}}
runner := NewLocalRunner(map[string]*hcl.File{}, Issues{})
parser := hclparse.NewParser()

for name, src := range files {
Expand All @@ -32,7 +32,7 @@ func TestRunner(t *testing.T, files map[string]string) *Runner {
}
runner.config = config
} else {
runner.Files[name] = file
runner.AddLocalFile(name, file)
}
}

Expand Down
20 changes: 20 additions & 0 deletions tflint/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,26 @@ func (c *Client) File(filename string) (*hcl.File, error) {
return file, nil
}

// Files calls the server-side Files method and returns a collection of hcl.File object.
func (c *Client) Files() (map[string]*hcl.File, error) {
var response FilesResponse
if err := c.rpcClient.Call("Plugin.Files", FilesRequest{}, &response); err != nil {
return nil, err
}

files := make(map[string]*hcl.File)
for filename, content := range response.Files {
file, diags := parseConfig(content, filename, hcl.InitialPos)

if diags.HasErrors() {
return nil, diags
}

files[filename] = file
}
return files, nil
}

// RootProvider calls the server-side RootProvider method and returns the provider configuration.
func (c *Client) RootProvider(name string) (*configs.Provider, error) {
log.Printf("[DEBUG] Accessing to the `%s` provider config in the root module", name)
Expand Down
9 changes: 9 additions & 0 deletions tflint/client/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,15 @@ type FileResponse struct {
Range hcl.Range
}

// FilesRequest is a request to the server-side Files method.
type FilesRequest struct{}

// FilesResponse is a response to the server-side Files method.
type FilesResponse struct {
Files map[string][]byte
Err error
}

// RootProviderRequest is a request to the server-side RootProvider method.
type RootProviderRequest struct {
Name string
Expand Down
4 changes: 4 additions & 0 deletions tflint/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ type Runner interface {
// When accessing resources, expressions, etc, it is recommended to use high-level APIs.
File(string) (*hcl.File, error)

// Files returns a map[string]hcl.File object, where the key is the file name.
// This is low level API for accessing information such as comments and syntax.
Files() (map[string]*hcl.File, error)

// RootProvider returns the provider configuration in the root module.
// It can be used by child modules to access the credentials defined in the root module.
RootProvider(name string) (*configs.Provider, error)
Expand Down
1 change: 1 addition & 0 deletions tflint/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ type Server interface {
Backend(*client.BackendRequest, *client.BackendResponse) error
EvalExpr(*client.EvalExprRequest, *client.EvalExprResponse) error
EmitIssue(*client.EmitIssueRequest, *interface{}) error
Files(*client.FilesRequest, *client.FilesResponse) error
}