Repository: mgechev/revive (go)

Issue:
cannot set confidence to 0
**Describe the bug**
It's impossible to set revive's `confidence` setting to `0.0` because this is the default value and is overwritten here:
https://github.com/mgechev/revive/blob/389ba853b0b3587f0c3b71b5f0c61ea4e23928ec/config/config.go#L133


Pull request description:
Fix config initialisation
Closes #585. Also fixes the "default config" test, which I believe should fail when `reflect.DeepEqual(cfg, tc.wantConfig) == false`.

Patch:
diff --git a/config/config.go b/config/config.go
index 8666cf4..8999595 100644
--- a/config/config.go
+++ b/config/config.go
@@ -128,25 +128,19 @@ func GetLintingRules(config *lint.Config) ([]lint.Rule, error) {
 	return lintingRules, nil
 }
 
-func parseConfig(path string) (*lint.Config, error) {
-	config := &lint.Config{}
+func parseConfig(path string, config *lint.Config) error {
 	file, err := ioutil.ReadFile(path)
 	if err != nil {
-		return nil, errors.New("cannot read the config file")
+		return errors.New("cannot read the config file")
 	}
 	_, err = toml.Decode(string(file), config)
 	if err != nil {
-		return nil, fmt.Errorf("cannot parse the config file: %v", err)
+		return fmt.Errorf("cannot parse the config file: %v", err)
 	}
-	return config, nil
+	return nil
 }
 
 func normalizeConfig(config *lint.Config) {
-	const defaultConfidence = 0.8
-	if config.Confidence == 0 {
-		config.Confidence = defaultConfidence
-	}
-
 	if len(config.Rules) == 0 {
 		config.Rules = map[string]lint.RuleConfig{}
 	}
@@ -180,16 +174,23 @@ func normalizeConfig(config *lint.Config) {
 	}
 }
 
+const defaultConfidence = 0.8
+
 // GetConfig yields the configuration
 func GetConfig(configPath string) (*lint.Config, error) {
-	config := defaultConfig()
-	if configPath != "" {
-		var err error
-		config, err = parseConfig(configPath)
+	var config = &lint.Config{}
+	switch {
+	case configPath != "":
+		config.Confidence = defaultConfidence
+		err := parseConfig(configPath, config)
 		if err != nil {
 			return nil, err
 		}
+
+	default: // no configuration provided
+		config = defaultConfig()
 	}
+
 	normalizeConfig(config)
 	return config, nil
 }
@@ -210,7 +211,7 @@ func GetFormatter(formatterName string) (lint.Formatter, error) {
 
 func defaultConfig() *lint.Config {
 	defaultConfig := lint.Config{
-		Confidence: 0.0,
+		Confidence: defaultConfidence,
 		Severity:   lint.SeverityWarning,
 		Rules:      map[string]lint.RuleConfig{},
 	}


Test patch:
diff --git a/config/config_test.go b/config/config_test.go
index 3bf8540..53bff5f 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -11,9 +11,10 @@ import (
 
 func TestGetConfig(t *testing.T) {
 	tt := map[string]struct {
-		confPath   string
-		wantConfig *lint.Config
-		wantError  string
+		confPath       string
+		wantConfig     *lint.Config
+		wantError      string
+		wantConfidence float64
 	}{
 		"non-reg issue #470": {
 			confPath:  "testdata/issue-470.toml",
@@ -28,7 +29,20 @@ func TestGetConfig(t *testing.T) {
 			wantError: "cannot parse the config file",
 		},
 		"default config": {
-			wantConfig: defaultConfig(),
+			wantConfig: func() *lint.Config {
+				c := defaultConfig()
+				normalizeConfig(c)
+				return c
+			}(),
+			wantConfidence: defaultConfidence,
+		},
+		"config from file issue #585": {
+			confPath:       "testdata/issue-585.toml",
+			wantConfidence: 0.0,
+		},
+		"config from file default confidence issue #585": {
+			confPath:       "testdata/issue-585-defaultConfidence.toml",
+			wantConfidence: defaultConfidence,
 		},
 	}
 
@@ -40,10 +54,11 @@ func TestGetConfig(t *testing.T) {
 				t.Fatalf("Unexpected error\n\t%v", err)
 			case err != nil && !strings.Contains(err.Error(), tc.wantError):
 				t.Fatalf("Expected error\n\t%q\ngot:\n\t%v", tc.wantError, err)
-			case tc.wantConfig != nil && reflect.DeepEqual(cfg, tc.wantConfig):
+			case tc.wantConfig != nil && !reflect.DeepEqual(cfg, tc.wantConfig):
 				t.Fatalf("Expected config\n\t%+v\ngot:\n\t%+v", tc.wantConfig, cfg)
+			case tc.wantConfig != nil && tc.wantConfidence != cfg.Confidence:
+				t.Fatalf("Expected confidence\n\t%+v\ngot:\n\t%+v", tc.wantConfidence, cfg.Confidence)
 			}
-
 		})
 	}
 }
@@ -84,7 +99,6 @@ func TestGetLintingRules(t *testing.T) {
 			case len(rules) != tc.wantRulesCount:
 				t.Fatalf("Expected %v enabled linting rules got: %v", tc.wantRulesCount, len(rules))
 			}
-
 		})
 	}
 }
diff --git a/config/testdata/issue-585-defaultConfidence.toml b/config/testdata/issue-585-defaultConfidence.toml
new file mode 100644
index 0000000..443ee4c
--- /dev/null
+++ b/config/testdata/issue-585-defaultConfidence.toml
@@ -0,0 +1,4 @@
+ignoreGeneratedHeader = false
+severity = "warning"
+errorCode = 0
+warningCode = 0
diff --git a/config/testdata/issue-585.toml b/config/testdata/issue-585.toml
new file mode 100644
index 0000000..d66cd8b
--- /dev/null
+++ b/config/testdata/issue-585.toml
@@ -0,0 +1,5 @@
+ignoreGeneratedHeader = false
+severity = "warning"
+confidence = 0.0
+errorCode = 0
+warningCode = 0