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

tflint: Allow config to be merged even with initial values #1670

Merged
merged 1 commit into from
Feb 5, 2023
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
4 changes: 3 additions & 1 deletion cmd/inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ func (cli *CLI) inspect(opts Options, args []string) int {
if opts.Recursive {
// Respect "--format" and "--force" flags in recursive mode
cli.formatter.Format = opts.Format
force = opts.Force
if opts.Force != nil {
force = *opts.Force
}
} else {
cli.formatter.Format = cli.config.Format
force = cli.config.Force
Expand Down
68 changes: 47 additions & 21 deletions cmd/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ type Options struct {
EnablePlugins []string `long:"enable-plugin" description:"Enable plugins from the command line" value-name:"PLUGIN_NAME"`
Varfiles []string `long:"var-file" description:"Terraform variable file name" value-name:"FILE"`
Variables []string `long:"var" description:"Set a Terraform variable" value-name:"'foo=bar'"`
Module bool `long:"module" description:"Inspect modules"`
Module *bool `long:"module" description:"Inspect modules"`
Chdir string `long:"chdir" description:"Switch to a different working directory before executing the command" value-name:"DIR"`
Recursive bool `long:"recursive" description:"Run command in each directory recursively"`
Filter []string `long:"filter" description:"Filter issues by file names or globs" value-name:"FILE"`
Force bool `long:"force" description:"Return zero exit status even if issues found"`
Force *bool `long:"force" description:"Return zero exit status even if issues found"`
MinimumFailureSeverity string `long:"minimum-failure-severity" description:"Sets minimum severity level for exiting with a non-zero error code" choice:"error" choice:"warning" choice:"notice"`
Color bool `long:"color" description:"Enable colorized output"`
NoColor bool `long:"no-color" description:"Disable colorized output"`
Expand All @@ -50,20 +50,38 @@ func (opts *Options) toConfig() *tflint.Config {
opts.Variables = []string{}
}

log.Printf("[DEBUG] CLI Options")
log.Printf("[DEBUG] Module: %t", opts.Module)
log.Printf("[DEBUG] Force: %t", opts.Force)
log.Printf("[DEBUG] IgnoreModules:")
for name, ignore := range ignoreModules {
log.Printf("[DEBUG] %s: %t", name, ignore)
var module, moduleSet bool
if opts.Module == nil {
module = false
moduleSet = false
} else {
module = *opts.Module
moduleSet = true
}

var force, forceSet bool
if opts.Force == nil {
force = false
forceSet = false
} else {
force = *opts.Force
forceSet = true
}

log.Printf("[DEBUG] CLI Options")
log.Printf("[DEBUG] Module: %t", module)
log.Printf("[DEBUG] Force: %t", force)
log.Printf("[DEBUG] Format: %s", opts.Format)
log.Printf("[DEBUG] Varfiles: %s", strings.Join(opts.Varfiles, ", "))
log.Printf("[DEBUG] Variables: %s", strings.Join(opts.Variables, ", "))
log.Printf("[DEBUG] EnableRules: %s", strings.Join(opts.EnableRules, ", "))
log.Printf("[DEBUG] DisableRules: %s", strings.Join(opts.DisableRules, ", "))
log.Printf("[DEBUG] Only: %s", strings.Join(opts.Only, ", "))
log.Printf("[DEBUG] EnablePlugins: %s", strings.Join(opts.EnablePlugins, ", "))
log.Printf("[DEBUG] Varfiles: %s", strings.Join(opts.Varfiles, ", "))
log.Printf("[DEBUG] Variables: %s", strings.Join(opts.Variables, ", "))
log.Printf("[DEBUG] Format: %s", opts.Format)
log.Printf("[DEBUG] IgnoreModules:")
for name, ignore := range ignoreModules {
log.Printf("[DEBUG] %s: %t", name, ignore)
}

rules := map[string]*tflint.RuleConfig{}
if len(opts.Only) > 0 {
Expand Down Expand Up @@ -107,15 +125,23 @@ func (opts *Options) toConfig() *tflint.Config {
}

return &tflint.Config{
Module: opts.Module,
Force: opts.Force,
IgnoreModules: ignoreModules,
Varfiles: varfiles,
Variables: opts.Variables,
DisabledByDefault: len(opts.Only) > 0,
Only: opts.Only,
Format: opts.Format,
Rules: rules,
Plugins: plugins,
Module: module,
ModuleSet: moduleSet,

Force: force,
ForceSet: forceSet,

Format: opts.Format,
FormatSet: opts.Format != "",

DisabledByDefault: len(opts.Only) > 0,
DisabledByDefaultSet: len(opts.Only) > 0,

Varfiles: varfiles,
Variables: opts.Variables,
Only: opts.Only,
IgnoreModules: ignoreModules,
Rules: rules,
Plugins: plugins,
}
}
18 changes: 11 additions & 7 deletions cmd/option_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func Test_toConfig(t *testing.T) {
Command: "./tflint --module",
Expected: &tflint.Config{
Module: true,
ModuleSet: true,
Force: false,
IgnoreModules: map[string]bool{},
Varfiles: []string{},
Expand All @@ -41,6 +42,7 @@ func Test_toConfig(t *testing.T) {
Expected: &tflint.Config{
Module: false,
Force: true,
ForceSet: true,
IgnoreModules: map[string]bool{},
Varfiles: []string{},
Variables: []string{},
Expand Down Expand Up @@ -173,13 +175,14 @@ func Test_toConfig(t *testing.T) {
Name: "--only",
Command: "./tflint --only aws_instance_invalid_type",
Expected: &tflint.Config{
Module: false,
Force: false,
IgnoreModules: map[string]bool{},
Varfiles: []string{},
Variables: []string{},
DisabledByDefault: true,
Only: []string{"aws_instance_invalid_type"},
Module: false,
Force: false,
IgnoreModules: map[string]bool{},
Varfiles: []string{},
Variables: []string{},
DisabledByDefault: true,
DisabledByDefaultSet: true,
Only: []string{"aws_instance_invalid_type"},
Rules: map[string]*tflint.RuleConfig{
"aws_instance_invalid_type": {
Name: "aws_instance_invalid_type",
Expand Down Expand Up @@ -226,6 +229,7 @@ func Test_toConfig(t *testing.T) {
Variables: []string{},
DisabledByDefault: false,
Format: "compact",
FormatSet: true,
Rules: map[string]*tflint.RuleConfig{},
Plugins: map[string]*tflint.PluginConfig{},
},
Expand Down
81 changes: 54 additions & 27 deletions tflint/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,27 @@ var validFormats = []string{

// Config describes the behavior of TFLint
type Config struct {
Module bool
Force bool
IgnoreModules map[string]bool
Varfiles []string
Variables []string
DisabledByDefault bool
Only []string
PluginDir string
Format string
Rules map[string]*RuleConfig
Plugins map[string]*PluginConfig
Module bool
ModuleSet bool

Force bool
ForceSet bool

DisabledByDefault bool
DisabledByDefaultSet bool

PluginDir string
PluginDirSet bool

Format string
FormatSet bool

Varfiles []string
Variables []string
Only []string
IgnoreModules map[string]bool
Rules map[string]*RuleConfig
Plugins map[string]*PluginConfig

sources map[string][]byte
}
Expand Down Expand Up @@ -185,10 +195,12 @@ func loadConfig(file afero.File) (*Config, error) {
for name, attr := range inner.Attributes {
switch name {
case "module":
config.ModuleSet = true
if err := gohcl.DecodeExpression(attr.Expr, nil, &config.Module); err != nil {
return config, err
}
case "force":
config.ForceSet = true
if err := gohcl.DecodeExpression(attr.Expr, nil, &config.Force); err != nil {
return config, err
}
Expand All @@ -205,14 +217,17 @@ func loadConfig(file afero.File) (*Config, error) {
return config, err
}
case "disabled_by_default":
config.DisabledByDefaultSet = true
if err := gohcl.DecodeExpression(attr.Expr, nil, &config.DisabledByDefault); err != nil {
return config, err
}
case "plugin_dir":
config.PluginDirSet = true
if err := gohcl.DecodeExpression(attr.Expr, nil, &config.PluginDir); err != nil {
return config, err
}
case "format":
config.FormatSet = true
if err := gohcl.DecodeExpression(attr.Expr, nil, &config.Format); err != nil {
return config, err
}
Expand Down Expand Up @@ -252,16 +267,22 @@ func loadConfig(file afero.File) (*Config, error) {

log.Printf("[DEBUG] Config loaded")
log.Printf("[DEBUG] Module: %t", config.Module)
log.Printf("[DEBUG] ModuleSet: %t", config.ModuleSet)
log.Printf("[DEBUG] Force: %t", config.Force)
log.Printf("[DEBUG] ForceSet: %t", config.ForceSet)
log.Printf("[DEBUG] DisabledByDefault: %t", config.DisabledByDefault)
log.Printf("[DEBUG] DisabledByDefaultSet: %t", config.DisabledByDefaultSet)
log.Printf("[DEBUG] PluginDir: %s", config.PluginDir)
log.Printf("[DEBUG] PluginDirSet: %t", config.PluginDirSet)
log.Printf("[DEBUG] Format: %s", config.Format)
log.Printf("[DEBUG] FormatSet: %t", config.FormatSet)
log.Printf("[DEBUG] Varfiles: %s", strings.Join(config.Varfiles, ", "))
log.Printf("[DEBUG] Variables: %s", strings.Join(config.Variables, ", "))
log.Printf("[DEBUG] Only: %s", strings.Join(config.Only, ", "))
log.Printf("[DEBUG] IgnoreModules:")
for name, ignore := range config.IgnoreModules {
log.Printf("[DEBUG] %s: %t", name, ignore)
}
log.Printf("[DEBUG] Varfiles: %s", strings.Join(config.Varfiles, ", "))
log.Printf("[DEBUG] Variables: %s", strings.Join(config.Variables, ", "))
log.Printf("[DEBUG] DisabledByDefault: %t", config.DisabledByDefault)
log.Printf("[DEBUG] PluginDir: %s", config.PluginDir)
log.Printf("[DEBUG] Format: %s", config.Format)
log.Printf("[DEBUG] Rules:")
for name, rule := range config.Rules {
log.Printf("[DEBUG] %s: %t", name, rule.Enabled)
Expand Down Expand Up @@ -328,29 +349,35 @@ func (c *Config) Sources() map[string][]byte {
// Merge merges the two configs and applies to itself.
// Since the argument takes precedence, it can be used as overwriting of the config.
func (c *Config) Merge(other *Config) {
if other.Module {
c.Module = true
if other.ModuleSet {
c.ModuleSet = true
c.Module = other.Module
}
if other.Force {
c.Force = true
if other.ForceSet {
c.ForceSet = true
c.Force = other.Force
}
if other.DisabledByDefault {
c.DisabledByDefault = true
if other.DisabledByDefaultSet {
c.DisabledByDefaultSet = true
c.DisabledByDefault = other.DisabledByDefault
}
if other.PluginDir != "" {
if other.PluginDirSet {
c.PluginDirSet = true
c.PluginDir = other.PluginDir
}
if other.Format != "" {
if other.FormatSet {
c.FormatSet = true
c.Format = other.Format
}

for name, ignore := range other.IgnoreModules {
c.IgnoreModules[name] = ignore
}
c.Varfiles = append(c.Varfiles, other.Varfiles...)
c.Variables = append(c.Variables, other.Variables...)
c.Only = append(c.Only, other.Only...)

for name, ignore := range other.IgnoreModules {
c.IgnoreModules[name] = ignore
}

for name, rule := range other.Rules {
// HACK: If you enable the rule through the CLI instead of the file, its hcl.Body will be nil.
// In this case, only override Enabled flag
Expand Down
Loading