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

Fix file arguments handling when using --chdir #1636

Merged
merged 1 commit into from
Dec 29, 2022
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
50 changes: 1 addition & 49 deletions cmd/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,6 @@ func (cli *CLI) Run(args []string) int {
cli.formatter.Print(tflint.Issues{}, fmt.Errorf("Failed to parse CLI options; %w", err), map[string][]byte{})
return ExitCodeError
}
dir, filterFiles, err := processArgs(args[1:])
if err != nil {
cli.formatter.Print(tflint.Issues{}, fmt.Errorf("Failed to parse CLI arguments; %w", err), map[string][]byte{})
return ExitCodeError
}

switch {
case opts.Version:
Expand All @@ -104,51 +99,8 @@ func (cli *CLI) Run(args []string) int {
case opts.ActAsBundledPlugin:
return cli.actAsBundledPlugin()
default:
return cli.inspect(opts, dir, filterFiles)
}
}

func processArgs(args []string) (string, []string, error) {
if len(args) == 0 {
return ".", []string{}, nil
return cli.inspect(opts, args)
}

var dir string
filterFiles := []string{}

for _, file := range args {
fileInfo, err := os.Stat(file)
if err != nil {
if os.IsNotExist(err) {
return dir, filterFiles, fmt.Errorf("Failed to load `%s`: File not found", file)
}
return dir, filterFiles, fmt.Errorf("Failed to load `%s`: %s", file, err)
}

if fileInfo.IsDir() {
dir = file
if len(args) != 1 {
return dir, filterFiles, fmt.Errorf("Failed to load `%s`: Multiple arguments are not allowed when passing a directory", file)
}
return dir, filterFiles, nil
}

if !strings.HasSuffix(file, ".tf") && !strings.HasSuffix(file, ".tf.json") {
return dir, filterFiles, fmt.Errorf("Failed to load `%s`: File is not a target of Terraform", file)
}

fileDir := filepath.Dir(file)
if dir == "" {
dir = fileDir
filterFiles = append(filterFiles, file)
} else if fileDir == dir {
filterFiles = append(filterFiles, file)
} else {
return dir, filterFiles, fmt.Errorf("Failed to load `%s`: Multiple files in different directories are not allowed", file)
}
}

return dir, filterFiles, nil
}

func unknownOptionHandler(option string, arg flags.SplitArgument, args []string) ([]string, error) {
Expand Down
73 changes: 63 additions & 10 deletions cmd/inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package cmd

import (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/hashicorp/hcl/v2"
Expand All @@ -14,19 +16,10 @@ import (
"google.golang.org/grpc/status"
)

func (cli *CLI) inspect(opts Options, targetDir string, filterFiles []string) int {
func (cli *CLI) inspect(opts Options, args []string) int {
// Respect the "--format" flag until a config is loaded
cli.formatter.Format = opts.Format

if opts.Chdir != "" && targetDir != "." {
cli.formatter.Print(tflint.Issues{}, fmt.Errorf("Cannot use --chdir and directory argument at the same time"), map[string][]byte{})
return ExitCodeError
}
if opts.Recursive && (targetDir != "." || len(filterFiles) > 0) {
cli.formatter.Print(tflint.Issues{}, fmt.Errorf("Cannot use --recursive and arguments at the same time"), map[string][]byte{})
return ExitCodeError
}

workingDirs, err := findWorkingDirs(opts)
if err != nil {
cli.formatter.Print(tflint.Issues{}, fmt.Errorf("Failed to find workspaces; %w", err), map[string][]byte{})
Expand All @@ -37,6 +30,23 @@ func (cli *CLI) inspect(opts Options, targetDir string, filterFiles []string) in

for _, wd := range workingDirs {
err := cli.withinChangedDir(wd, func() error {
// Parse directory/file arguments after changing the working directory
targetDir, filterFiles, err := processArgs(args[1:])
if err != nil {
return fmt.Errorf("Failed to parse CLI arguments; %w", err)
}

if opts.Chdir != "" && targetDir != "." {
return fmt.Errorf("Cannot use --chdir and directory argument at the same time")
}
if opts.Recursive && (targetDir != "." || len(filterFiles) > 0) {
return fmt.Errorf("Cannot use --recursive and arguments at the same time")
}

// Join with the working directory to create the fullpath
for i, file := range filterFiles {
filterFiles[i] = filepath.Join(wd, file)
}
moduleIssues, err := cli.inspectModule(opts, targetDir, filterFiles)
if err != nil {
return err
Expand Down Expand Up @@ -73,6 +83,49 @@ func (cli *CLI) inspect(opts Options, targetDir string, filterFiles []string) in
return ExitCodeOK
}

func processArgs(args []string) (string, []string, error) {
if len(args) == 0 {
return ".", []string{}, nil
}

var dir string
filterFiles := []string{}

for _, file := range args {
fileInfo, err := os.Stat(file)
if err != nil {
if os.IsNotExist(err) {
return dir, filterFiles, fmt.Errorf("Failed to load `%s`: File not found", file)
}
return dir, filterFiles, fmt.Errorf("Failed to load `%s`: %s", file, err)
}

if fileInfo.IsDir() {
dir = file
if len(args) != 1 {
return dir, filterFiles, fmt.Errorf("Failed to load `%s`: Multiple arguments are not allowed when passing a directory", file)
}
return dir, filterFiles, nil
}

if !strings.HasSuffix(file, ".tf") && !strings.HasSuffix(file, ".tf.json") {
return dir, filterFiles, fmt.Errorf("Failed to load `%s`: File is not a target of Terraform", file)
}

fileDir := filepath.Dir(file)
if dir == "" {
dir = fileDir
filterFiles = append(filterFiles, file)
} else if fileDir == dir {
filterFiles = append(filterFiles, file)
} else {
return dir, filterFiles, fmt.Errorf("Failed to load `%s`: Multiple files in different directories are not allowed", file)
}
}

return dir, filterFiles, nil
}

func (cli *CLI) inspectModule(opts Options, dir string, filterFiles []string) (tflint.Issues, error) {
issues := tflint.Issues{}
var err error
Expand Down
3 changes: 3 additions & 0 deletions integrationtest/cli/chdir/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
resource "aws_instance" "main" {
instance_type = "t2.micro"
}
3 changes: 3 additions & 0 deletions integrationtest/cli/chdir/subdir/.tflint.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
plugin "testing" {
enabled = true
}
3 changes: 3 additions & 0 deletions integrationtest/cli/chdir/subdir/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
resource "aws_instance" "main" {
instance_type = "m5.2xlarge"
}
3 changes: 3 additions & 0 deletions integrationtest/cli/chdir/subdir/nested/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
resource "aws_instance" "main" {
instance_type = "t2.nano"
}
33 changes: 27 additions & 6 deletions integrationtest/cli/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,22 +276,43 @@ func TestIntegration(t *testing.T) {
},
{
name: "--chdir",
command: "./tflint --chdir subdir",
dir: "multiple_files",
command: "./tflint --chdir=subdir",
dir: "chdir",
status: cmd.ExitCodeIssuesFound,
stdout: fmt.Sprintf("%s (aws_instance_example_type)", color.New(color.Bold).Sprint("instance type is m5.2xlarge")),
},
{
name: "--chdir and file argument",
command: "./tflint --chdir=subdir main.tf",
dir: "chdir",
status: cmd.ExitCodeIssuesFound,
stdout: fmt.Sprintf("%s (aws_instance_example_type)", color.New(color.Bold).Sprint("instance type is m5.2xlarge")),
},
{
name: "--chdir and directory argument",
command: "./tflint --chdir subdir ../",
dir: "multiple_files",
command: "./tflint --chdir=subdir ../",
dir: "chdir",
status: cmd.ExitCodeError,
stderr: "Cannot use --chdir and directory argument at the same time",
},
{
name: "--recursive and arguments",
name: "--chdir and file under the directory argument",
command: fmt.Sprintf("./tflint --chdir=subdir %s", filepath.Join("nested", "main.tf")),
dir: "chdir",
status: cmd.ExitCodeError,
stderr: "Cannot use --chdir and directory argument at the same time",
},
{
name: "--recursive and file argument",
command: "./tflint --recursive main.tf",
dir: "chdir",
status: cmd.ExitCodeError,
stderr: "Cannot use --recursive and arguments at the same time",
},
{
name: "--recursive and directory argument",
command: "./tflint --recursive subdir",
dir: "multiple_files",
dir: "chdir",
status: cmd.ExitCodeError,
stderr: "Cannot use --recursive and arguments at the same time",
},
Expand Down