Skip to content

fix: load format from config file #2306

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

Closed
wants to merge 2 commits into from
Closed
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
54 changes: 35 additions & 19 deletions cmd/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/fatih/color"
"github.com/hashicorp/logutils"
flags "github.com/jessevdk/go-flags"
"github.com/spf13/afero"
"github.com/terraform-linters/tflint/formatter"
"github.com/terraform-linters/tflint/terraform"
"github.com/terraform-linters/tflint/tflint"
Expand Down Expand Up @@ -54,19 +55,46 @@ func NewCLI(outStream io.Writer, errStream io.Writer) (*CLI, error) {

// Run invokes the CLI with the given arguments.
func (cli *CLI) Run(args []string) int {
cli.formatter = &formatter.Formatter{
Stdout: cli.outStream,
Stderr: cli.errStream,
}

// Configure options parser
var opts Options
parser := flags.NewParser(&opts, flags.HelpFlag)
parser.Usage = "--chdir=DIR/--recursive [OPTIONS]"
parser.UnknownOptionHandler = unknownOptionHandler
// Parse commandline flag

// Parse command line options
args, err := parser.ParseArgs(args)
// Set up output formatter
cli.formatter = &formatter.Formatter{
Stdout: cli.outStream,
Stderr: cli.errStream,
Format: opts.Format,
Fix: opts.Fix,
if err != nil {
if flagsErr, ok := err.(*flags.Error); ok && flagsErr.Type == flags.ErrHelp {
fmt.Fprintln(cli.outStream, err)
return ExitCodeOK
}
cli.formatter.Print(tflint.Issues{}, fmt.Errorf("Failed to parse CLI options; %w", err), map[string][]byte{})
return ExitCodeError
}

if len(args) > 1 {
cli.formatter.Print(tflint.Issues{}, fmt.Errorf("Command line arguments support was dropped in v0.47. Use --chdir or --filter instead."), map[string][]byte{})
return ExitCodeError
}

// Setup config
cfg, err := tflint.LoadConfig(afero.Afero{Fs: afero.NewOsFs()}, opts.Config)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We must set the log level before loading the config, otherwise debug logs will always be shown.
Doing this will remove the hack in integrationtest/recursive/recursive_test.go.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we load a config outside of withinChangedDir, --chdir will be ignored.

$ tree -a
.
├── .tflint.hcl
└── work
    └── .tflint.hcl
$ cat .tflint.hcl
config {
  format = "json"
}
$ cat work/.tflint.hcl
config {
  format = "compact"
}
$ tflint --chdir work
{"issues":[],"errors":[]}

if err != nil {
fmt.Fprintf(cli.errStream, "Failed to load TFLint config; %s\n", err)
return ExitCodeError
}

cfg.Merge(opts.toConfig())

// Set formatter fields from options/config
cli.formatter.Format = cfg.Format
cli.formatter.Fix = opts.Fix

if opts.Color {
color.NoColor = false
cli.formatter.NoColor = false
Expand All @@ -83,18 +111,6 @@ func (cli *CLI) Run(args []string) int {
})
log.SetFlags(log.Ltime | log.Lshortfile)

if err != nil {
if flagsErr, ok := err.(*flags.Error); ok && flagsErr.Type == flags.ErrHelp {
fmt.Fprintln(cli.outStream, err)
return ExitCodeOK
}
cli.formatter.Print(tflint.Issues{}, fmt.Errorf("Failed to parse CLI options; %w", err), map[string][]byte{})
return ExitCodeError
}
if len(args) > 1 {
cli.formatter.Print(tflint.Issues{}, fmt.Errorf("Command line arguments support was dropped in v0.47. Use --chdir or --filter instead."), map[string][]byte{})
return ExitCodeError
}
if opts.MaxWorkers != nil && *opts.MaxWorkers <= 0 {
cli.formatter.Print(tflint.Issues{}, fmt.Errorf("Max workers should be greater than 0"), map[string][]byte{})
return ExitCodeError
Expand Down
18 changes: 16 additions & 2 deletions integrationtest/cli/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,25 @@ func TestIntegration(t *testing.T) {
stdout: "",
},
{
name: "specify format",
name: "format flag",
command: "./tflint --format json",
dir: "no_issues",
status: cmd.ExitCodeOK,
stdout: "[]",
stdout: `{"issues":[],"errors":[]}`,
},
{
name: "format config",
command: "./tflint",
dir: "format_config",
status: cmd.ExitCodeIssuesFound,
stdout: `main.tf:2:19: Error - instance type is t2.micro (aws_instance_example_type)`,
},
{
name: "format flag overrides config",
command: "./tflint --format json",
dir: "format_config",
status: cmd.ExitCodeIssuesFound,
stdout: `{"issues":[{"rule":{"name":"aws_instance_example_type","severity":"error","link":""},"message":"instance type is t2.micro","range":{"filename":"main.tf","start":{"line":2,"column":19},"end":{"line":2,"column":29}},"callers":[]}],"errors":[]}`,
},
{
name: "`--force` option with no issues",
Expand Down
7 changes: 7 additions & 0 deletions integrationtest/cli/format_config/.tflint.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
config {
format = "compact"
}

plugin "testing" {
enabled = true
}
3 changes: 3 additions & 0 deletions integrationtest/cli/format_config/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
resource "aws_instance" "main" {
instance_type = "t2.micro"
}
8 changes: 8 additions & 0 deletions integrationtest/recursive/recursive_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,14 @@ func TestIntegration(t *testing.T) {

opts := []cmp.Option{
cmpopts.IgnoreFields(formatter.JSONRule{}, "Link"),
// Only compare error messages up to the double new line.
// After this, stderr will be printed which is verbose.
cmp.Transformer("TruncateMessage", func(e formatter.JSONError) formatter.JSONError {
if parts := strings.Split(e.Message, "\n\n"); len(parts) > 1 {
e.Message = parts[0]
}
return e
}),
}
if test.ignoreOrder {
opts = append(opts, cmpopts.SortSlices(func(a, b formatter.JSONError) bool {
Expand Down
Loading