Repository: mgechev/revive (go)

Issue:
How to disable `rule.exported` for consts?
## TL;DR:

I am aware that the goal of this project is no longer to be a 100% drop-in replacement for golint (which I think is fair) but is there a way for me to disable the `exported` rule but only for consts?

## Full Details

At [pipeline-components](https://pipeline-components.dev/) we have a component for [go-lint](https://gitlab.com/pipeline-components/go-lint). Although it is not one of our larger components<sup>\[1]</sup>, I'm thinking of prolonging support by replacing `golint` with revive.

However, the current claim that the default behaviour is the same as `golint` does not appear to be 100% accurate.

To be specific, I am seeing the following warnings from revive that are not there with golint:

1. "should have a package comment"
2. "this block is empty, you can remove it"
3. "comment on exported const [..] should be of the form [..]"

The first two I can resolve by tweaking the default config,<sup>\[2]</sup>, which is fine for our purposes (as golint does not have a config, so we can just add one for revive).

But I have not yet been able to resolve the `comment on exported const [..] should be of the form [..]`. Please note, this is explicitly about exported "const", not other exported types.

How could this be achieved?

---

<sup>\[1]</sup> Currently it only has +/- 40K pulls on DockerHub ![][1]<br>
<details><summary><sup>[2]</sup> Click to see config</summary>

```toml
ignoreGeneratedHeader = false
severity = "warning"
confidence = 0.8
errorCode = 0
warningCode = 0

[rule.blank-imports]
[rule.context-as-argument]
[rule.context-keys-type]
[rule.dot-imports]
[rule.empty-block]
    Disabled = true
[rule.errorf]
[rule.error-naming]
[rule.error-return]
[rule.error-strings]
[rule.exported]
[rule.increment-decrement]
[rule.indent-error-flow]
[rule.package-comments]
     Disabled = true
[rule.range]
[rule.receiver-naming]
[rule.redefines-builtin-id]
[rule.superfluous-else]
[rule.time-naming]
[rule.unexported-return]
[rule.unreachable-code]
[rule.unused-parameter]
[rule.var-declaration]
[rule.var-naming]
```

</details>


[1]: https://img.shields.io/docker/pulls/pipelinecomponents/go-lint.png

Pull request:
Makes exported rule behave as golint
Closes #1045 by making the exported rule behave as `golint` did.

The rule accepted documentation comments in the same line of variable/constant declarations while `golint` doesn't. 

Patch:
diff --git a/rule/exported.go b/rule/exported.go
index 958191e..7d71505 100644
--- a/rule/exported.go
+++ b/rule/exported.go
@@ -204,8 +204,8 @@ func (w *lintExported) lintTypeDoc(t *ast.TypeSpec, doc *ast.CommentGroup) {
 		}
 	}
 	// if comment starts with name of type and has some text after - it's ok
-	expectedPrefix := t.Name.Name+" "
-	if strings.HasPrefix(s, expectedPrefix){
+	expectedPrefix := t.Name.Name + " "
+	if strings.HasPrefix(s, expectedPrefix) {
 		return
 	}
 	w.onFailure(lint.Failure{
@@ -244,7 +244,7 @@ func (w *lintExported) lintValueSpecDoc(vs *ast.ValueSpec, gd *ast.GenDecl, genD
 		return
 	}
 
-	if vs.Doc == nil && vs.Comment == nil && gd.Doc == nil {
+	if vs.Doc == nil && gd.Doc == nil {
 		if genDeclMissingComments[gd] {
 			return
 		}
@@ -348,7 +348,7 @@ func (w *lintExported) doCheckPublicInterface(typeName string, iface *ast.Interf
 
 func (w *lintExported) lintInterfaceMethod(typeName string, m *ast.Field) {
 	if len(m.Names) == 0 {
-		return 
+		return
 	}
 	if !ast.IsExported(m.Names[0].Name) {
 		return
diff --git a/rule/function-result-limit.go b/rule/function-result-limit.go
index 6a07480..c125d05 100644
--- a/rule/function-result-limit.go
+++ b/rule/function-result-limit.go
@@ -24,14 +24,14 @@ func (r *FunctionResultsLimitRule) configure(arguments lint.Arguments) {
 			r.max = defaultResultsLimit
 			return
 		}
-		max, ok := arguments[0].(int64) // Alt. non panicking version
+		maxResults, ok := arguments[0].(int64) // Alt. non panicking version
 		if !ok {
 			panic(fmt.Sprintf(`invalid value passed as return results number to the "function-result-limit" rule; need int64 but got %T`, arguments[0]))
 		}
-		if max < 0 {
+		if maxResults < 0 {
 			panic(`the value passed as return results number to the "function-result-limit" rule cannot be negative`)
 		}
-		r.max = int(max)
+		r.max = int(maxResults)
 	}
 }
 
diff --git a/rule/line-length-limit.go b/rule/line-length-limit.go
index 1a414f6..6e55cbb 100644
--- a/rule/line-length-limit.go
+++ b/rule/line-length-limit.go
@@ -29,12 +29,12 @@ func (r *LineLengthLimitRule) configure(arguments lint.Arguments) {
 			return
 		}
 
-		max, ok := arguments[0].(int64) // Alt. non panicking version
-		if !ok || max < 0 {
+		maxLength, ok := arguments[0].(int64) // Alt. non panicking version
+		if !ok || maxLength < 0 {
 			panic(`invalid value passed as argument number to the "line-length-limit" rule`)
 		}
 
-		r.max = int(max)
+		r.max = int(maxLength)
 	}
 }
 
diff --git a/rule/max-control-nesting.go b/rule/max-control-nesting.go
index c4eb361..e15d42e 100644
--- a/rule/max-control-nesting.go
+++ b/rule/max-control-nesting.go
@@ -120,9 +120,9 @@ func (r *MaxControlNestingRule) configure(arguments lint.Arguments) {
 
 	checkNumberOfArguments(1, arguments, r.Name())
 
-	max, ok := arguments[0].(int64) // Alt. non panicking version
+	maxNesting, ok := arguments[0].(int64) // Alt. non panicking version
 	if !ok {
 		panic(`invalid value passed as argument number to the "max-control-nesting" rule`)
 	}
-	r.max = max
+	r.max = maxNesting
 }
diff --git a/rule/max-public-structs.go b/rule/max-public-structs.go
index 25be3e6..b06e51f 100644
--- a/rule/max-public-structs.go
+++ b/rule/max-public-structs.go
@@ -27,11 +27,11 @@ func (r *MaxPublicStructsRule) configure(arguments lint.Arguments) {
 
 		checkNumberOfArguments(1, arguments, r.Name())
 
-		max, ok := arguments[0].(int64) // Alt. non panicking version
+		maxStructs, ok := arguments[0].(int64) // Alt. non panicking version
 		if !ok {
 			panic(`invalid value passed as argument number to the "max-public-structs" rule`)
 		}
-		r.max = max
+		r.max = maxStructs
 	}
 }
 


Test patch:
diff --git a/testdata/golint/const-block.go b/testdata/golint/const-block.go
index fcaf86f..75286b7 100644
--- a/testdata/golint/const-block.go
+++ b/testdata/golint/const-block.go
@@ -4,16 +4,16 @@
 package foo
 
 const (
-	InlineComment = "ShouldBeOK" // InlineComment is a valid comment
+	InlineComment = "ShouldBeOK" // InlineComment is not a valid documentation
+	// MATCH:7 /exported const InlineComment should have comment (or a comment on this block) or be unexported/
 
-	// Prefix for something.
 	// MATCH /comment on exported const InlineWhatever should be of the form "InlineWhatever ..."/
 	InlineWhatever = "blah"
 
 	Whatsit = "missing_comment"
-	// MATCH:13 /exported const Whatsit should have comment (or a comment on this block) or be unexported/
 
 	// We should only warn once per block for missing comments,
+	// thus do not warn on:13 /exported const Whatsit should have comment (or a comment on this block) or be unexported/
 	// but always complain about malformed comments.
 
 	WhosYourDaddy = "another_missing_one"