|
1 | 1 | package golinters |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "bytes" |
4 | 5 | "encoding/json" |
5 | 6 | "fmt" |
6 | 7 | "go/token" |
7 | 8 | "io/ioutil" |
8 | 9 |
|
| 10 | + "github.com/BurntSushi/toml" |
9 | 11 | "github.com/mgechev/dots" |
10 | 12 | reviveConfig "github.com/mgechev/revive/config" |
11 | 13 | "github.com/mgechev/revive/lint" |
| 14 | + "github.com/mgechev/revive/rule" |
12 | 15 | "golang.org/x/tools/go/analysis" |
13 | 16 |
|
14 | 17 | "github.com/golangci/golangci-lint/pkg/config" |
@@ -47,7 +50,7 @@ func NewRevive(cfg *config.ReviveSettings) *goanalysis.Linter { |
47 | 50 | files = append(files, pass.Fset.PositionFor(file.Pos(), false).Filename) |
48 | 51 | } |
49 | 52 |
|
50 | | - conf, err := setReviveConfig(cfg) |
| 53 | + conf, err := getReviveConfig(cfg) |
51 | 54 | if err != nil { |
52 | 55 | return nil, err |
53 | 56 | } |
@@ -128,46 +131,129 @@ func NewRevive(cfg *config.ReviveSettings) *goanalysis.Linter { |
128 | 131 | }).WithLoadMode(goanalysis.LoadModeSyntax) |
129 | 132 | } |
130 | 133 |
|
131 | | -func setReviveConfig(cfg *config.ReviveSettings) (*lint.Config, error) { |
132 | | - // Get revive default configuration |
133 | | - conf, err := reviveConfig.GetConfig("") |
| 134 | +// This function mimics the GetConfig function of revive. |
| 135 | +// This allow to get default values and right types. |
| 136 | +// https://github.com/golangci/golangci-lint/issues/1745 |
| 137 | +// https://github.com/mgechev/revive/blob/389ba853b0b3587f0c3b71b5f0c61ea4e23928ec/config/config.go#L155 |
| 138 | +func getReviveConfig(cfg *config.ReviveSettings) (*lint.Config, error) { |
| 139 | + rawRoot := createConfigMap(cfg) |
| 140 | + |
| 141 | + buf := bytes.NewBuffer(nil) |
| 142 | + |
| 143 | + err := toml.NewEncoder(buf).Encode(rawRoot) |
134 | 144 | if err != nil { |
135 | 145 | return nil, err |
136 | 146 | } |
137 | 147 |
|
138 | | - // Default is false |
139 | | - conf.IgnoreGeneratedHeader = cfg.IgnoreGeneratedHeader |
| 148 | + conf := defaultConfig() |
140 | 149 |
|
141 | | - if cfg.Severity != "" { |
142 | | - conf.Severity = lint.Severity(cfg.Severity) |
| 150 | + _, err = toml.DecodeReader(buf, conf) |
| 151 | + if err != nil { |
| 152 | + return nil, err |
143 | 153 | } |
144 | 154 |
|
145 | | - if cfg.Confidence != 0 { |
146 | | - conf.Confidence = cfg.Confidence |
147 | | - } |
| 155 | + normalizeConfig(conf) |
148 | 156 |
|
149 | 157 | // By default golangci-lint ignores missing doc comments, follow same convention by removing this default rule |
150 | 158 | // Relevant issue: https://github.com/golangci/golangci-lint/issues/456 |
| 159 | + delete(conf.Rules, "package-comments") |
151 | 160 | delete(conf.Rules, "exported") |
152 | 161 |
|
153 | | - if len(cfg.Rules) != 0 { |
154 | | - // Clear default rules, only use rules defined in config |
155 | | - conf.Rules = make(map[string]lint.RuleConfig, len(cfg.Rules)) |
| 162 | + return conf, nil |
| 163 | +} |
| 164 | + |
| 165 | +func createConfigMap(cfg *config.ReviveSettings) map[string]interface{} { |
| 166 | + rawRoot := map[string]interface{}{ |
| 167 | + "ignoreGeneratedHeader": cfg.IgnoreGeneratedHeader, |
| 168 | + "confidence": cfg.Confidence, |
| 169 | + "severity": cfg.Severity, |
| 170 | + "errorCode": cfg.ErrorCode, |
| 171 | + "warningCode": cfg.WarningCode, |
156 | 172 | } |
157 | | - for _, r := range cfg.Rules { |
158 | | - conf.Rules[r.Name] = lint.RuleConfig{Arguments: r.Arguments, Severity: lint.Severity(r.Severity)} |
| 173 | + |
| 174 | + rawDirectives := map[string]map[string]interface{}{} |
| 175 | + for _, directive := range cfg.Directives { |
| 176 | + rawDirectives[directive.Name] = map[string]interface{}{ |
| 177 | + "severity": directive.Severity, |
| 178 | + } |
159 | 179 | } |
160 | 180 |
|
161 | | - conf.ErrorCode = cfg.ErrorCode |
162 | | - conf.WarningCode = cfg.WarningCode |
| 181 | + if len(rawDirectives) > 0 { |
| 182 | + rawRoot["directive"] = rawDirectives |
| 183 | + } |
163 | 184 |
|
164 | | - if len(cfg.Directives) != 0 { |
165 | | - // Clear default Directives, only use Directives defined in config |
166 | | - conf.Directives = make(map[string]lint.DirectiveConfig, len(cfg.Directives)) |
| 185 | + rawRules := map[string]map[string]interface{}{} |
| 186 | + for _, s := range cfg.Rules { |
| 187 | + rawRules[s.Name] = map[string]interface{}{ |
| 188 | + "severity": s.Severity, |
| 189 | + "arguments": s.Arguments, |
| 190 | + } |
167 | 191 | } |
168 | | - for _, d := range cfg.Directives { |
169 | | - conf.Directives[d.Name] = lint.DirectiveConfig{Severity: lint.Severity(d.Severity)} |
| 192 | + |
| 193 | + if len(rawRules) > 0 { |
| 194 | + rawRoot["rule"] = rawRules |
170 | 195 | } |
171 | 196 |
|
172 | | - return conf, nil |
| 197 | + return rawRoot |
| 198 | +} |
| 199 | + |
| 200 | +// This element is not exported by revive, so we need copy the code. |
| 201 | +// Extracted from https://github.com/mgechev/revive/blob/389ba853b0b3587f0c3b71b5f0c61ea4e23928ec/config/config.go#L15 |
| 202 | +var defaultRules = []lint.Rule{ |
| 203 | + &rule.VarDeclarationsRule{}, |
| 204 | + &rule.PackageCommentsRule{}, |
| 205 | + &rule.DotImportsRule{}, |
| 206 | + &rule.BlankImportsRule{}, |
| 207 | + &rule.ExportedRule{}, |
| 208 | + &rule.VarNamingRule{}, |
| 209 | + &rule.IndentErrorFlowRule{}, |
| 210 | + &rule.IfReturnRule{}, |
| 211 | + &rule.RangeRule{}, |
| 212 | + &rule.ErrorfRule{}, |
| 213 | + &rule.ErrorNamingRule{}, |
| 214 | + &rule.ErrorStringsRule{}, |
| 215 | + &rule.ReceiverNamingRule{}, |
| 216 | + &rule.IncrementDecrementRule{}, |
| 217 | + &rule.ErrorReturnRule{}, |
| 218 | + &rule.UnexportedReturnRule{}, |
| 219 | + &rule.TimeNamingRule{}, |
| 220 | + &rule.ContextKeysType{}, |
| 221 | + &rule.ContextAsArgumentRule{}, |
| 222 | +} |
| 223 | + |
| 224 | +// This element is not exported by revive, so we need copy the code. |
| 225 | +// Extracted from https://github.com/mgechev/revive/blob/389ba853b0b3587f0c3b71b5f0c61ea4e23928ec/config/config.go#L133 |
| 226 | +func normalizeConfig(cfg *lint.Config) { |
| 227 | + if cfg.Confidence == 0 { |
| 228 | + cfg.Confidence = 0.8 |
| 229 | + } |
| 230 | + severity := cfg.Severity |
| 231 | + if severity != "" { |
| 232 | + for k, v := range cfg.Rules { |
| 233 | + if v.Severity == "" { |
| 234 | + v.Severity = severity |
| 235 | + } |
| 236 | + cfg.Rules[k] = v |
| 237 | + } |
| 238 | + for k, v := range cfg.Directives { |
| 239 | + if v.Severity == "" { |
| 240 | + v.Severity = severity |
| 241 | + } |
| 242 | + cfg.Directives[k] = v |
| 243 | + } |
| 244 | + } |
| 245 | +} |
| 246 | + |
| 247 | +// This element is not exported by revive, so we need copy the code. |
| 248 | +// Extracted from https://github.com/mgechev/revive/blob/389ba853b0b3587f0c3b71b5f0c61ea4e23928ec/config/config.go#L182 |
| 249 | +func defaultConfig() *lint.Config { |
| 250 | + defaultConfig := lint.Config{ |
| 251 | + Confidence: 0.0, |
| 252 | + Severity: lint.SeverityWarning, |
| 253 | + Rules: map[string]lint.RuleConfig{}, |
| 254 | + } |
| 255 | + for _, r := range defaultRules { |
| 256 | + defaultConfig.Rules[r.Name()] = lint.RuleConfig{} |
| 257 | + } |
| 258 | + return &defaultConfig |
173 | 259 | } |
0 commit comments