generated from TrueCloudLab/basic
[#1] linters: add logs linter #2
14 changed files with 146 additions and 556 deletions
11
Makefile
11
Makefile
|
@ -1,8 +1,8 @@
|
|||
OUT_DIR?=./.bin
|
||||
PLUGIN_SOURCE?=main.go
|
||||
OUT_DIR ?= ./.bin
|
||||
PLUGIN_SOURCE ?= main.go
|
||||
|
||||
test:
|
||||
@go test -v ./...
|
||||
@go test -v ./... -count=1
|
||||
|
||||
lib:
|
||||
@mkdir -pv $(OUT_DIR)
|
||||
|
@ -11,3 +11,8 @@ lib:
|
|||
lint:
|
||||
@golangci-lint run
|
||||
dstepanov-yadro marked this conversation as resolved
|
||||
|
||||
staticcheck-install:
|
||||
@go install honnef.co/go/tools/cmd/staticcheck@latest
|
||||
|
||||
staticcheck-run:
|
||||
@staticcheck ./...
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
## Available linters
|
||||
|
||||
| Name | Description |
|
||||
| ----------- | ----------- |
|
||||
| --------- | --------------------------------------------------------------------------- |
|
||||
| noliteral | The tool prohibits the use of literal string arguments in logging functions |
|
||||
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
|||
|
||||
## Usage
|
||||
|
||||
Add to .golagci.yml
|
||||
Add to .golangci.yml
|
||||
|
||||
```yml
|
||||
|
||||
|
|
|
@ -1,264 +0,0 @@
|
|||
package noliteral
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/tools/go/analysis"
|
||||
)
|
||||
|
||||
func TestAnalyzerA_n(t *testing.T) {
|
||||
|
||||
_, filename, _, _ := runtime.Caller(0)
|
||||
dir := filepath.Dir(filename)
|
||||
|
||||
fset := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset, filepath.Join(dir, "test-case/src/a_negative._go"), nil, parser.AllErrors)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
Flag := false
|
||||
pass := &analysis.Pass{
|
||||
Fset: fset,
|
||||
Files: []*ast.File{f},
|
||||
Report: func(diag analysis.Diagnostic) {
|
||||
t.Log(diag.Message)
|
||||
Flag = true
|
||||
},
|
||||
}
|
||||
|
||||
_, err = run(pass)
|
||||
|
||||
if !Flag {
|
||||
t.Fail()
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnalyzerA_p(t *testing.T) {
|
||||
|
||||
_, filename, _, _ := runtime.Caller(0)
|
||||
dir := filepath.Dir(filename)
|
||||
|
||||
fset := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset, filepath.Join(dir, "test-case/src/a_positive._go"), nil, parser.AllErrors)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
flag := false
|
||||
pass := &analysis.Pass{
|
||||
Fset: fset,
|
||||
Files: []*ast.File{f},
|
||||
Report: func(diag analysis.Diagnostic) {
|
||||
t.Log(diag.Message)
|
||||
flag = true
|
||||
},
|
||||
}
|
||||
|
||||
_, err = run(pass)
|
||||
|
||||
if flag {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnalyzerB_n(t *testing.T) {
|
||||
|
||||
_, filename, _, _ := runtime.Caller(0)
|
||||
dir := filepath.Dir(filename)
|
||||
|
||||
fset := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset, filepath.Join(dir, "test-case/src/b_negative._go"), nil, parser.AllErrors)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
Flag := false
|
||||
pass := &analysis.Pass{
|
||||
Fset: fset,
|
||||
Files: []*ast.File{f},
|
||||
Report: func(diag analysis.Diagnostic) {
|
||||
t.Log(diag.Message)
|
||||
Flag = true
|
||||
},
|
||||
}
|
||||
|
||||
_, err = run(pass)
|
||||
|
||||
if !Flag {
|
||||
t.Fail()
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnalyzerB_p(t *testing.T) {
|
||||
|
||||
_, filename, _, _ := runtime.Caller(0)
|
||||
dir := filepath.Dir(filename)
|
||||
|
||||
fset := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset, filepath.Join(dir, "test-case/src/b_positive._go"), nil, parser.AllErrors)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
flag := false
|
||||
pass := &analysis.Pass{
|
||||
Fset: fset,
|
||||
Files: []*ast.File{f},
|
||||
Report: func(diag analysis.Diagnostic) {
|
||||
t.Log(diag.Message)
|
||||
flag = true
|
||||
},
|
||||
}
|
||||
|
||||
_, err = run(pass)
|
||||
|
||||
if flag {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnalyzerC_n(t *testing.T) {
|
||||
|
||||
_, filename, _, _ := runtime.Caller(0)
|
||||
dir := filepath.Dir(filename)
|
||||
|
||||
fset := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset, filepath.Join(dir, "test-case/src/c_negative._go"), nil, parser.AllErrors)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
Flag := false
|
||||
pass := &analysis.Pass{
|
||||
Fset: fset,
|
||||
Files: []*ast.File{f},
|
||||
Report: func(diag analysis.Diagnostic) {
|
||||
t.Log(diag.Message)
|
||||
Flag = true
|
||||
},
|
||||
}
|
||||
|
||||
_, err = run(pass)
|
||||
|
||||
if !Flag {
|
||||
t.Fail()
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnalyzerC_p(t *testing.T) {
|
||||
|
||||
_, filename, _, _ := runtime.Caller(0)
|
||||
dir := filepath.Dir(filename)
|
||||
|
||||
fset := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset, filepath.Join(dir, "test-case/src/c_positive._go"), nil, parser.AllErrors)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
flag := false
|
||||
pass := &analysis.Pass{
|
||||
Fset: fset,
|
||||
Files: []*ast.File{f},
|
||||
Report: func(diag analysis.Diagnostic) {
|
||||
t.Log(diag.Message)
|
||||
flag = true
|
||||
},
|
||||
}
|
||||
|
||||
_, err = run(pass)
|
||||
|
||||
if flag {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnalyzerD_n(t *testing.T) {
|
||||
|
||||
_, filename, _, _ := runtime.Caller(0)
|
||||
dir := filepath.Dir(filename)
|
||||
|
||||
fset := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset, filepath.Join(dir, "test-case/src/d_negative._go"), nil, parser.AllErrors)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
Flag := false
|
||||
pass := &analysis.Pass{
|
||||
Fset: fset,
|
||||
Files: []*ast.File{f},
|
||||
Report: func(diag analysis.Diagnostic) {
|
||||
t.Log(diag.Message)
|
||||
Flag = true
|
||||
},
|
||||
}
|
||||
|
||||
_, err = run(pass)
|
||||
|
||||
if Flag {
|
||||
t.Fail()
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnalyzerD_p(t *testing.T) {
|
||||
|
||||
_, filename, _, _ := runtime.Caller(0)
|
||||
dir := filepath.Dir(filename)
|
||||
|
||||
fset := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset, filepath.Join(dir, "test-case/src/d_positive._go"), nil, parser.AllErrors)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
flag := false
|
||||
pass := &analysis.Pass{
|
||||
Fset: fset,
|
||||
Files: []*ast.File{f},
|
||||
Report: func(diag analysis.Diagnostic) {
|
||||
t.Log(diag.Message)
|
||||
flag = true
|
||||
},
|
||||
}
|
||||
|
||||
_, err = run(pass)
|
||||
|
||||
if flag {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package src_test
|
||||
|
||||
func (c *cfg) f1_n() {
|
||||
c.log.Info("logs.MSG") //unacceptable
|
||||
}
|
||||
|
||||
type Logger interface {
|
||||
Debug(msg string)
|
||||
Info(msg string)
|
||||
Warn(msg string)
|
||||
Error(msg string)
|
||||
Abyr(msg string)
|
||||
}
|
||||
|
||||
type RealLogger struct{}
|
||||
|
||||
func (l RealLogger) Debug(msg string) {
|
||||
}
|
||||
func (l RealLogger) Info(msg string) {
|
||||
}
|
||||
func (l RealLogger) Warn(msg string) {
|
||||
}
|
||||
func (l RealLogger) Error(msg string) {
|
||||
}
|
||||
func (l RealLogger) Abyr(msg string) {
|
||||
}
|
||||
|
||||
var logs = struct {
|
||||
MSG string
|
||||
}{
|
||||
MSG: "some message",
|
||||
}
|
||||
|
||||
type cfg struct {
|
||||
log Logger
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
package src_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func (c *cfg) f1_ok() {
|
||||
c.log.Info(logs.MSG) //acceptable
|
||||
}
|
||||
|
||||
type Logger interface {
|
||||
Debug(msg string)
|
||||
Info(msg string)
|
||||
Warn(msg string)
|
||||
Error(msg string)
|
||||
Abyr(msg string)
|
||||
}
|
||||
|
||||
type RealLogger struct{}
|
||||
|
||||
func (l RealLogger) Debug(msg string) {
|
||||
}
|
||||
func (l RealLogger) Info(msg string) {
|
||||
}
|
||||
func (l RealLogger) Warn(msg string) {
|
||||
}
|
||||
func (l RealLogger) Error(msg string) {
|
||||
}
|
||||
func (l RealLogger) Abyr(msg string) {
|
||||
}
|
||||
|
||||
type RealLogger struct{}
|
||||
|
||||
func (l RealLogger) Info(msg string) {
|
||||
fmt.Println(msg)
|
||||
}
|
||||
|
||||
var logs = struct {
|
||||
MSG string
|
||||
}{
|
||||
MSG: "some message",
|
||||
}
|
||||
|
||||
type cfg struct {
|
||||
log Logger
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package src_test
|
||||
|
||||
func (c *cfg) f1_n() {
|
||||
c.log.Error("logs.MSG") //unacceptable
|
||||
}
|
||||
|
||||
type Logger interface {
|
||||
Debug(msg string)
|
||||
Info(msg string)
|
||||
Warn(msg string)
|
||||
Error(msg string)
|
||||
Abyr(msg string)
|
||||
}
|
||||
|
||||
type RealLogger struct{}
|
||||
|
||||
func (l RealLogger) Debug(msg string) {
|
||||
}
|
||||
func (l RealLogger) Info(msg string) {
|
||||
}
|
||||
func (l RealLogger) Warn(msg string) {
|
||||
}
|
||||
func (l RealLogger) Error(msg string) {
|
||||
}
|
||||
func (l RealLogger) Abyr(msg string) {
|
||||
}
|
||||
|
||||
var logs = struct {
|
||||
MSG string
|
||||
}{
|
||||
MSG: "some message",
|
||||
}
|
||||
|
||||
type cfg struct {
|
||||
log Logger
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
package src_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func (c *cfg) f1_ok() {
|
||||
c.log.Error(logs.MSG) //acceptable
|
||||
}
|
||||
|
||||
type Logger interface {
|
||||
Debug(msg string)
|
||||
Info(msg string)
|
||||
Warn(msg string)
|
||||
Error(msg string)
|
||||
Abyr(msg string)
|
||||
}
|
||||
|
||||
type RealLogger struct{}
|
||||
|
||||
func (l RealLogger) Debug(msg string) {
|
||||
}
|
||||
func (l RealLogger) Info(msg string) {
|
||||
}
|
||||
func (l RealLogger) Warn(msg string) {
|
||||
}
|
||||
func (l RealLogger) Error(msg string) {
|
||||
}
|
||||
func (l RealLogger) Abyr(msg string) {
|
||||
}
|
||||
|
||||
type RealLogger struct{}
|
||||
|
||||
func (l RealLogger) Info(msg string) {
|
||||
fmt.Println(msg)
|
||||
}
|
||||
|
||||
var logs = struct {
|
||||
MSG string
|
||||
}{
|
||||
MSG: "some message",
|
||||
}
|
||||
|
||||
type cfg struct {
|
||||
log Logger
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package src_test
|
||||
|
||||
func (c *cfg) f1_n() {
|
||||
c.log.Abyr("logs.MSG") //unacceptable
|
||||
}
|
||||
|
||||
type Logger interface {
|
||||
Debug(msg string)
|
||||
Info(msg string)
|
||||
Warn(msg string)
|
||||
Error(msg string)
|
||||
Abyr(msg string)
|
||||
}
|
||||
|
||||
type RealLogger struct{}
|
||||
|
||||
func (l RealLogger) Debug(msg string) {
|
||||
}
|
||||
func (l RealLogger) Info(msg string) {
|
||||
}
|
||||
func (l RealLogger) Warn(msg string) {
|
||||
}
|
||||
func (l RealLogger) Error(msg string) {
|
||||
}
|
||||
func (l RealLogger) Abyr(msg string) {
|
||||
}
|
||||
|
||||
var logs = struct {
|
||||
MSG string
|
||||
}{
|
||||
MSG: "some message",
|
||||
}
|
||||
|
||||
type cfg struct {
|
||||
log Logger
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
package src_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func (c *cfg) f1_ok() {
|
||||
c.log.Abyr(logs.MSG) //acceptable
|
||||
}
|
||||
|
||||
type Logger interface {
|
||||
Debug(msg string)
|
||||
Info(msg string)
|
||||
Warn(msg string)
|
||||
Error(msg string)
|
||||
Abyr(msg string)
|
||||
}
|
||||
|
||||
type RealLogger struct{}
|
||||
|
||||
func (l RealLogger) Debug(msg string) {
|
||||
}
|
||||
func (l RealLogger) Info(msg string) {
|
||||
}
|
||||
func (l RealLogger) Warn(msg string) {
|
||||
}
|
||||
func (l RealLogger) Error(msg string) {
|
||||
}
|
||||
func (l RealLogger) Abyr(msg string) {
|
||||
}
|
||||
|
||||
type RealLogger struct{}
|
||||
|
||||
func (l RealLogger) Info(msg string) {
|
||||
fmt.Println(msg)
|
||||
}
|
||||
|
||||
var logs = struct {
|
||||
MSG string
|
||||
}{
|
||||
MSG: "some message",
|
||||
}
|
||||
|
||||
type cfg struct {
|
||||
log Logger
|
||||
}
|
|
@ -3,8 +3,6 @@ package noliteral
|
|||
import (
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/tools/go/analysis"
|
||||
)
|
||||
|
@ -17,11 +15,7 @@ var LogsAnalyzer = &analysis.Analyzer{
|
|||
Run: run,
|
||||
}
|
||||
|
||||
var (
|
||||
methodsToSearchOnce = &sync.Once{}
|
||||
methodsToSearch = []string{"Debug", "Info", "Warn", "Error"}
|
||||
customLogs = "reportFlushError, reportError"
|
||||
)
|
||||
var methodsToSearch = []string{"Debug", "Info", "Warn", "Error", "reportFlushError", "reportError"}
|
||||
|
||||
func run(pass *analysis.Pass) (interface{}, error) {
|
||||
for _, file := range pass.Files {
|
||||
|
@ -32,17 +26,23 @@ func run(pass *analysis.Pass) (interface{}, error) {
|
|||
}
|
||||
|
||||
isLog, _ := isLogDot(expr.Fun)
|
||||
if isLog && len(expr.Args) > 0 && isStringValue(expr.Args[0]) {
|
||||
if !isLog {
|
||||
return true
|
||||
}
|
||||
|
||||
if len(expr.Args) == 0 || !isStringValue(expr.Args[0]) {
|
||||
return true
|
||||
}
|
||||
|
||||
pass.Report(analysis.Diagnostic{
|
||||
Pos: expr.Pos(),
|
||||
End: 0,
|
||||
End: expr.End(),
|
||||
Category: LinterName,
|
||||
Message: "Literals are not allowed in the body of the logger",
|
||||
SuggestedFixes: nil,
|
||||
})
|
||||
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -54,14 +54,6 @@ func isLogDot(expr ast.Expr) (bool, string) {
|
|||
if !ok {
|
||||
return false, ""
|
||||
}
|
||||
methodsToSearchOnce.Do(func() {
|
||||
for _, cl := range strings.Split(customLogs, ",") {
|
||||
cl = strings.Trim(cl, " ")
|
||||
if len(cl) > 0 {
|
||||
methodsToSearch = append(methodsToSearch, cl)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
for _, method := range methodsToSearch {
|
||||
if isIdent(sel.Sel, method) {
|
||||
|
@ -73,12 +65,10 @@ func isLogDot(expr ast.Expr) (bool, string) {
|
|||
|
||||
func isIdent(expr ast.Expr, ident string) bool {
|
||||
id, ok := expr.(*ast.Ident)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if id.Name == ident {
|
||||
if ok && id.Name == ident {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
70
internal/analyzers/noliteral/linter_test.go
Normal file
70
internal/analyzers/noliteral/linter_test.go
Normal file
|
@ -0,0 +1,70 @@
|
|||
package noliteral
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/tools/go/analysis"
|
||||
)
|
||||
|
||||
func TestAnalyzer_negative(t *testing.T) {
|
||||
_, filename, _, _ := runtime.Caller(0)
|
||||
dir := filepath.Dir(filename)
|
||||
|
||||
fset := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset, filepath.Join(dir, "test-case/src/negative._go"), nil, parser.AllErrors)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
Count := 0
|
||||
pass := &analysis.Pass{
|
||||
Fset: fset,
|
||||
Files: []*ast.File{f},
|
||||
Report: func(diag analysis.Diagnostic) {
|
||||
Count++
|
||||
},
|
||||
}
|
||||
|
||||
_, err = run(pass)
|
||||
|
||||
if Count != 6 {
|
||||
t.Fail()
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnalyzer_positive(t *testing.T) {
|
||||
_, filename, _, _ := runtime.Caller(0)
|
||||
dir := filepath.Dir(filename)
|
||||
|
||||
fset := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset, filepath.Join(dir, "test-case/src/positive._go"), nil, parser.AllErrors)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
flag := false
|
||||
pass := &analysis.Pass{
|
||||
Fset: fset,
|
||||
Files: []*ast.File{f},
|
||||
Report: func(diag analysis.Diagnostic) {
|
||||
flag = true
|
||||
},
|
||||
}
|
||||
_, err = run(pass)
|
||||
|
||||
if flag {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
|
@ -1,9 +1,32 @@
|
|||
package src_test
|
||||
|
||||
func (c *cfg) f1_n() {
|
||||
|
||||
func (c *cfg) info_n() {
|
||||
c.log.Info("logs.MSG") //unacceptable
|
||||
}
|
||||
|
||||
func (c *cfg) info_n() {
|
||||
log.Info("logs.MSG") //unacceptable
|
||||
}
|
||||
|
||||
func (c *cfg) debug_n() {
|
||||
c.log.Debug("logs.MSG") //unacceptable
|
||||
}
|
||||
|
||||
func (c *cfg) error_n() {
|
||||
c.log.Error("logs.MSG") //unacceptable
|
||||
}
|
||||
|
||||
func (c *cfg) reportFlushError_n() {
|
||||
c.log.reportFlushError("logs.MSG") //unacceptable
|
||||
}
|
||||
|
||||
func (c *cfg) reportError_n() {
|
||||
c.log.reportError("logs.MSG") //unacceptable
|
||||
}
|
||||
|
||||
|
||||
|
||||
type Logger interface {
|
||||
Debug(msg string)
|
||||
Info(msg string)
|
|
@ -4,10 +4,30 @@ import (
|
|||
"fmt"
|
||||
)
|
||||
|
||||
func (c *cfg) f1_ok() {
|
||||
func (c *cfg) info_ok() {
|
||||
c.log.Info(logs.MSG) //acceptable
|
||||
}
|
||||
|
||||
func (c *cfg) debug_ok() {
|
||||
c.log.Debug(logs.MSG) //acceptable
|
||||
}
|
||||
|
||||
func (c *cfg) error_ok() {
|
||||
c.log.Error(logs.MSG) //acceptable
|
||||
}
|
||||
|
||||
func (c *cfg) custom_ok_const() {
|
||||
c.log.Abyr(logs.MSG) //acceptable
|
||||
}
|
||||
|
||||
func (c *cfg) custom_ok_lit() {
|
||||
c.log.Abyr("logs.MSG") //acceptable
|
||||
}
|
||||
|
||||
func (c *cfg) custom_ok_lit() {
|
||||
log.Abyr("logs.MSG") //acceptable
|
||||
}
|
||||
|
||||
type Logger interface {
|
||||
Debug(msg string)
|
||||
Info(msg string)
|
10
main.go
10
main.go
|
@ -1,7 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
noliteral "git.frostfs.info/TrueCloudLab/linters/internal/analyzers/no-literal"
|
||||
noliteral "git.frostfs.info/TrueCloudLab/linters/internal/analyzers/noliteral"
|
||||
"golang.org/x/tools/go/analysis"
|
||||
)
|
||||
|
||||
|
@ -9,14 +9,6 @@ var AnalyzerPlugin analyzerPlugin
|
|||
|
||||
type analyzerPlugin struct{}
|
||||
|
||||
// for version ci-lint < '1.5.4'.
|
||||
func (*analyzerPlugin) GetAnalyzers() []*analysis.Analyzer {
|
||||
return []*analysis.Analyzer{noliteral.LogsAnalyzer}
|
||||
}
|
||||
|
||||
/*
|
||||
// for version ci-lint >= '1.5.4'.
|
||||
func New(conf any) ([]*analysis.Analyzer, error) {
|
||||
return []*analysis.Analyzer{noliteral.LogsAnalyzer}, nil
|
||||
}
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue
Please add
.golangci.yml
file with linter config like here: https://git.frostfs.info/TrueCloudLab/frostfs-node/src/branch/master/.golangci.ymlThe empty repository template already has a set of minimally necessary linters, therefore .golangci.yml is not present in the PR