From bddf15fb5314bc9f6705d5fd52c9a622e6aa589b Mon Sep 17 00:00:00 2001 From: Noel Gass Date: Mon, 19 Jun 2023 22:12:05 +0200 Subject: [PATCH] feat: added ignore dir --- README.md | 1 + cmd/cli.go | 18 +++++++++++++++++- cmd/option.go | 2 ++ cmd/option_test.go | 30 ++++++++++++++++++++++++++++++ tflint/config.go | 13 +++++++++++-- tflint/config_test.go | 9 ++++++++- 6 files changed, 69 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 85e38b395..ae61fe10e 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,7 @@ Application Options: --color Enable colorized output --no-color Disable colorized output --fix Fix issues automatically + --ignore-dir Ignore dir sources Help Options: -h, --help Show this help message diff --git a/cmd/cli.go b/cmd/cli.go index cb3bf9893..9b24d2860 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -15,6 +15,7 @@ import ( "github.com/terraform-linters/tflint/formatter" "github.com/terraform-linters/tflint/terraform" "github.com/terraform-linters/tflint/tflint" + "golang.org/x/exp/slices" ) // Exit codes are int values that represent an exit code for a particular error. @@ -72,6 +73,15 @@ func (cli *CLI) Run(args []string) int { color.NoColor = true cli.formatter.NoColor = true } + if len(opts.IgnoreDir) > 0 { + for idx, value := range opts.IgnoreDir { + if filepath.Separator == '/' { + opts.IgnoreDir[idx] = filepath.ToSlash(value) + } else { + opts.IgnoreDir[idx] = filepath.FromSlash(value) + } + } + } level := os.Getenv("TFLINT_LOG") log.SetOutput(&logutils.LevelFilter{ Levels: []logutils.LogLevel{"TRACE", "DEBUG", "INFO", "WARN", "ERROR"}, @@ -144,13 +154,19 @@ func findWorkingDirs(opts Options) ([]string, error) { if opts.Recursive { // NOTE: The target directory is always the current directory in recursive mode - err := filepath.WalkDir(".", func(path string, d os.DirEntry, err error) error { + var root, _ = filepath.Abs(".") + err := filepath.WalkDir(root, func(path string, d os.DirEntry, err error) error { if err != nil { return err } if !d.IsDir() { return nil } + // ignored directories are skipped + var relDirPath, _ = filepath.Rel(root, path) + if d.IsDir() && slices.Contains(opts.IgnoreDir, relDirPath) { + return nil + } // hidden directories are skipped if path != "." && strings.HasPrefix(d.Name(), ".") { return filepath.SkipDir diff --git a/cmd/option.go b/cmd/option.go index 620eb92ef..a2e2a2539 100644 --- a/cmd/option.go +++ b/cmd/option.go @@ -32,6 +32,7 @@ type Options struct { NoColor bool `long:"no-color" description:"Disable colorized output"` Fix bool `long:"fix" description:"Fix issues automatically"` ActAsBundledPlugin bool `long:"act-as-bundled-plugin" hidden:"true"` + IgnoreDir []string `long:"ignore-dir" description:"Disable dir sources" value-name:"DIR_PATH"` } func (opts *Options) toConfig() *tflint.Config { @@ -131,5 +132,6 @@ func (opts *Options) toConfig() *tflint.Config { IgnoreModules: ignoreModules, Rules: rules, Plugins: plugins, + IgnoreDir: opts.IgnoreDir, } } diff --git a/cmd/option_test.go b/cmd/option_test.go index 55f2467de..af2dfd5d3 100644 --- a/cmd/option_test.go +++ b/cmd/option_test.go @@ -249,6 +249,36 @@ func Test_toConfig(t *testing.T) { Plugins: map[string]*tflint.PluginConfig{}, }, }, + { + Name: "--ignore-dir", + Command: "./tflint --ignore-dir=modules/foo", + Expected: &tflint.Config{ + Module: false, + Force: false, + IgnoreModules: map[string]bool{}, + Varfiles: []string{}, + Variables: []string{}, + DisabledByDefault: false, + Rules: map[string]*tflint.RuleConfig{}, + Plugins: map[string]*tflint.PluginConfig{}, + IgnoreDir: []string{"modules/foo"}, + }, + }, + { + Name: "--ignore-dir", + Command: "./tflint --ignore-dir=modules/foo --ignore-dir=modules/bar", + Expected: &tflint.Config{ + Module: false, + Force: false, + IgnoreModules: map[string]bool{}, + Varfiles: []string{}, + Variables: []string{}, + DisabledByDefault: false, + Rules: map[string]*tflint.RuleConfig{}, + Plugins: map[string]*tflint.PluginConfig{}, + IgnoreDir: []string{"modules/foo", "modules/bar"}, + }, + }, } for _, tc := range cases { diff --git a/tflint/config.go b/tflint/config.go index 6496a9139..c2f91b77e 100644 --- a/tflint/config.go +++ b/tflint/config.go @@ -5,7 +5,7 @@ import ( "log" "strings" - hcl "github.com/hashicorp/hcl/v2" + "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/gohcl" "github.com/hashicorp/hcl/v2/hclparse" "github.com/hashicorp/hcl/v2/hclsyntax" @@ -44,6 +44,7 @@ var innerConfigSchema = &hcl.BodySchema{ {Name: "disabled_by_default"}, {Name: "plugin_dir"}, {Name: "format"}, + {Name: "ignore_dir"}, }, } @@ -80,6 +81,8 @@ type Config struct { Rules map[string]*RuleConfig Plugins map[string]*PluginConfig + IgnoreDir []string + sources map[string][]byte } @@ -242,6 +245,10 @@ func loadConfig(file afero.File) (*Config, error) { if !formatValid { return config, fmt.Errorf("%s is invalid format. Allowed formats are: %s", config.Format, strings.Join(validFormats, ", ")) } + case "ignore_dir": + if err := gohcl.DecodeExpression(attr.Expr, nil, &config.IgnoreDir); err != nil { + return config, err + } default: panic("never happened") } @@ -292,7 +299,7 @@ func loadConfig(file afero.File) (*Config, error) { for name, plugin := range config.Plugins { log.Printf("[DEBUG] %s: enabled=%t, version=%s, source=%s", name, plugin.Enabled, plugin.Version, plugin.Source) } - + log.Printf("[DEBUG] Variables: %s", strings.Join(config.IgnoreDir, ", ")) return config, nil } @@ -398,6 +405,8 @@ func (c *Config) Merge(other *Config) { c.Plugins[name] = plugin } } + + c.IgnoreDir = append(c.IgnoreDir, other.IgnoreDir...) } // ToPluginConfig converts self into the plugin configuration format diff --git a/tflint/config_test.go b/tflint/config_test.go index 5d1727bb7..8a731d544 100644 --- a/tflint/config_test.go +++ b/tflint/config_test.go @@ -385,7 +385,8 @@ func TestMerge(t *testing.T) { Body: file2.Body, }, }, - Plugins: map[string]*PluginConfig{}, + Plugins: map[string]*PluginConfig{}, + IgnoreDir: []string{"modules/foo", "modules/bar"}, } tests := []struct { @@ -452,6 +453,7 @@ func TestMerge(t *testing.T) { Enabled: false, }, }, + IgnoreDir: []string{"modules/foo", "modules/bar"}, }, other: &Config{ Module: false, @@ -491,6 +493,7 @@ func TestMerge(t *testing.T) { Enabled: true, }, }, + IgnoreDir: []string{"modules/baz"}, }, want: &Config{ Module: true, @@ -541,6 +544,7 @@ func TestMerge(t *testing.T) { Enabled: true, }, }, + IgnoreDir: []string{"modules/foo", "modules/bar", "modules/baz"}, }, }, { @@ -578,6 +582,7 @@ func TestMerge(t *testing.T) { Enabled: false, }, }, + IgnoreDir: []string{"modules/foo", "modules/bar"}, }, other: &Config{ Module: false, @@ -614,6 +619,7 @@ func TestMerge(t *testing.T) { Enabled: true, }, }, + IgnoreDir: []string{"modules/baz"}, }, want: &Config{ Module: true, @@ -661,6 +667,7 @@ func TestMerge(t *testing.T) { Enabled: true, }, }, + IgnoreDir: []string{"modules/foo", "modules/bar", "modules/baz"}, }, }, {