diff --git a/README.md b/README.md index e8608712..e0e5e6a1 100644 --- a/README.md +++ b/README.md @@ -574,6 +574,7 @@ Flags: # gosec: False positive is triggered by 'src, err := ioutil.ReadFile(filename)' - Potential file inclusion via variable (default true) + --exclude-case-sensitive If set to true exclude and exclude rules regular expressions are case sensitive --max-issues-per-linter int Maximum issues count per one linter. Set to 0 to disable (default 50) --max-same-issues int Maximum count of issues with the same text. Set to 0 to disable (default 3) -n, --new Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed. diff --git a/docs/demo.svg b/docs/demo.svg index d5dbb4a8..da93b49d 100644 --- a/docs/demo.svg +++ b/docs/demo.svg @@ -1 +1 @@ -^~/go/src/github.com/astaxie/beego(master)$golangci-lintadmin.go:85:13:Errorreturnvalueof`r.ParseForm`isnotchecked(errcheck)r.ParseForm()^admin.go:88:11:Errorreturnvalueof`rw.Write`isnotchecked(errcheck)rw.Write([]byte("commandnotsupport"))^admin.go:105:15:Errorreturnvalueof`tmpl.Execute`isnotchecked(errcheck)tmpl.Execute(rw,data)^admin.go:160:11:Errorreturnvalueof`rw.Write`isnotchecked(errcheck)admin.go:246:13:Errorreturnvalueof`r.ParseForm`isnotchecked(errcheck)admin.go:268:11:Errorreturnvalueof`rw.Write`isnotchecked(errcheck)rw.Write(dataJSON)admin.go:321:15:Errorreturnvalueof`req.ParseForm`isnotchecked(errcheck)req.ParseForm()^admin.go:366:14:Errorreturnvalueof`tmpl.Execute`isnotchecked(errcheck)tmpl.Execute(rw,data)^app.go:477:30:Errorreturnvalueof`BeeApp.Handlers.InsertFilter`isnotchecked(errcheck)BeeApp.Handlers.InsertFilter(pattern,pos,filter,params...)^beego.go:106:10:Errorreturnvalueof`os.Chdir`isnotchecked(errcheck)os.Chdir(ap)^cache/file.go:69:16:Errorreturnvalueof`json.Unmarshal`isnotchecked(errcheck)json.Unmarshal([]byte(config),&cfg)^cache/file.go:101:16:Errorreturnvalueof`io.WriteString`isnotchecked(errcheck)io.WriteString(m,key)cache/file.go:126:11:Errorreturnvalueof`GobDecode`isnotchecked(errcheck)GobDecode(fileData,&to)^cache/file.go:182:8:Errorreturnvalueof`fc.Put`isnotchecked(errcheck)fc.Put(key,incr,FileCacheEmbedExpiry)^cache/file.go:195:8:Errorreturnvalueof`fc.Put`isnotchecked(errcheck)fc.Put(key,decr,FileCacheEmbedExpiry)cache/memcache/memcache.go:167:16:Errorreturnvalueof`json.Unmarshal`isnotchecked(errcheck)json.Unmarshal([]byte(config),&cf)cache/memory.go:198:16:Errorreturnvalueof`json.Unmarshal`isnotchecked(errcheck)config/ini.go:77:16:Errorreturnvalueof`buf.ReadByte`isnotchecked(errcheck)buf.ReadByte()context/context.go:86:26:Errorreturnvalueof`ctx.ResponseWriter.Write`isnotchecked(errcheck)ctx.ResponseWriter.Write([]byte(content))^context/input.go:321:34:Errorreturnvalueof`input.Context.Request.ParseForm`isnotchecked(errcheck)input.Context.Request.ParseForm()^context/input.go:444:34:Errorreturnvalueof`input.Context.Request.ParseForm`isnotchecked(errcheck)context/output.go:82:9:Errorreturnvalueof`io.Copy`isnotchecked(errcheck)io.Copy(output.Context.ResponseWriter,buf)^context/output.go:173:18:Errorreturnvalueof`ctx.Output.JSON`isnotchecked(errcheck)ctx.Output.JSON(value,false,false)^context/output.go:180:18:Errorreturnvalueof`ctx.Output.Body`isnotchecked(errcheck)ctx.Output.Body([]byte(err.Error()))context/output.go:361:37:Errorreturnvalueof`output.Context.Input.CruSession.Set`isnotchecked(errcheck)output.Context.Input.CruSession.Set(name,value)^controller.go:235:26:Errorreturnvalueof`ExecuteViewPathTemplate`isnotchecked(errcheck)ExecuteViewPathTemplate(&buf,c.Layout,c.viewPath(),c.Data)^controller.go:261:16:Errorreturnvalueof`BuildTemplate`isnotchecked(errcheck)BuildTemplate(c.viewPath(),buildFiles...)^controller.go:296:28:Errorreturnvalueof`c.Ctx.ResponseWriter.Write`isnotchecked(errcheck)c.Ctx.ResponseWriter.Write([]byte(body))^controller.go:329:19:Errorreturnvalueof`c.Ctx.Output.JSON`isnotchecked(errcheck)c.Ctx.Output.JSON(c.Data["json"],hasIndent,hasEncoding)^controller.go:338:20:Errorreturnvalueof`c.Ctx.Output.JSONP`isnotchecked(errcheck)c.Ctx.Output.JSONP(c.Data["jsonp"],hasIndent)^controller.go:347:18:Errorreturnvalueof`c.Ctx.Output.XML`isnotchecked(errcheck)c.Ctx.Output.XML(c.Data["xml"],hasIndent)controller.go:366:26:Errorreturnvalueof`c.Ctx.Request.ParseForm`isnotchecked(errcheck)c.Ctx.Request.ParseForm()controller.go:562:9:Errorreturnvalueof`io.Copy`isnotchecked(errcheck)io.Copy(f,file)controller.go:579:18:Errorreturnvalueof`c.CruSession.Set`isnotchecked(errcheck)c.CruSession.Set(name,value)controller.go:595:21:Errorreturnvalueof`c.CruSession.Delete`isnotchecked(errcheck)c.CruSession.Delete(name)^controller.go:610:30:Errorreturnvalueof`c.Ctx.Input.CruSession.Flush`isnotchecked(errcheck)c.Ctx.Input.CruSession.Flush()error.go:101:11:Errorreturnvalueof`t.Execute`isnotchecked(errcheck)t.Execute(ctx.ResponseWriter,data)error.go:374:11:Errorreturnvalueof`t.Execute`isnotchecked(errcheck)t.Execute(rw,data)grace/listener.go:37:17:Errorreturnvalueof`tc.SetKeepAlive`isnotchecked(errcheck)tc.SetKeepAlive(true)~/go/src/github.com/astaxie/beego(master)$golangci-lintrungrace/listener.go:38:23:Errorreturnvalueof`tc.SetKeepAlivePeriod`isnotchecked(errcheck)tc.SetKeepAlivePeriod(3*time.Minute)hooks.go:17:24:Errorreturnvalueof`mime.AddExtensionType`isnotchecked(errcheck)mime.AddExtensionType(k,v)^httplib/httplib.go:383:28:Errorreturnvalueof`bodyWriter.WriteField`isnotchecked(errcheck)bodyWriter.WriteField(k,vv)^logs/conn.go:94:23:Errorreturnvalueof`tcpConn.SetKeepAlive`isnotchecked(errcheck)tcpConn.SetKeepAlive(true)logs/file.go:167:11:Errorreturnvalueof`os.Chmod`isnotchecked(errcheck)os.Chmod(w.Filename,os.FileMode(perm))logs/file.go:300:15:Errorreturnvalueof`filepath.Walk`isnotchecked(errcheck)filepath.Walk(dir,func(pathstring,infoos.FileInfo,errerror)(returnErrerror){logs/file.go:330:19:Errorreturnvalueof`w.fileWriter.Sync`isnotchecked(errcheck)w.fileWriter.Sync()logs/log.go:153:14:Errorreturnvalueof`bl.setLogger`isnotchecked(errcheck)bl.setLogger(AdapterConsole)logs/log.go:263:15:Errorreturnvalueof`bl.setLogger`isnotchecked(errcheck)bl.setLogger(AdapterConsole)logs/log.go:355:13:Errorreturnvalueof`bl.writeMsg`isnotchecked(errcheck)bl.writeMsg(LevelEmergency,format,v...)logs/log.go:363:13:Errorreturnvalueof`bl.writeMsg`isnotchecked(errcheck)bl.writeMsg(LevelAlert,format,v...)logs/smtp.go:78:G402:TLSInsecureSkipVerifysettrue.(gas)InsecureSkipVerify:true,orm/db.go:283:G201:SQLstringformatting(gas)query:=fmt.Sprintf("INSERTINTO%s%s%s(%s%s%s)VALUES(%s)",Q,mi.table,Q,Q,columns,Q,qmarks)orm/db.go:350:G201:SQLstringformatting(gas)query:=fmt.Sprintf("SELECT%s%s%sFROM%s%s%sWHERE%s%s%s=?%s",Q,sels,Q,Q,mi.table,Q,Q,wheres,Q,forUpdate)orm/db.go:477:G201:SQLstringformatting(gas)orm/db.go:576:G202:SQLstringconcatenation(gas)query:=fmt.Sprintf("INSERTINTO%s%s%s(%s%s%s)VALUES(%s)%s"+qupdates,Q,mi.table,Q,Q,columns,Q,qmarks,iouStr)orm/db_mysql.go:157:G202:SQLstringconcatenation(gas)orm/db_tables.go:387:G202:SQLstringconcatenation(gas)where="WHERE"+wherelogs/alils/request.go:5:G501:Blacklistedimportcrypto/md5:weakcryptographicprimitive(gas)"crypto/md5"logs/alils/request.go:26:G401:Useofweakcryptographicprimitive(gas)bodyMD5:=fmt.Sprintf("%X",md5.Sum(body))cache/file.go:19:G501:Blacklistedimportcrypto/md5:weakcryptographicprimitive(gas)cache/file.go:100:G401:Useofweakcryptographicprimitive(gas)m:=md5.New()controller.go:230:G203:thismethodwillnotauto-escapeHTML.Verifydataiswellformed.(gas)c.Data[sectionName]=template.HTML(buf.String())error.go:372:G203:thismethodwillnotauto-escapeHTML.Verifydataiswellformed.(gas)"Content":template.HTML(errContent),templatefunc.go:272:G203:thismethodwillnotauto-escapeHTML.Verifydataiswellformed.(gas)returntemplate.HTML(text)logs/alils/log.pb.go:328:6:`encodeFixed64Log`isunused(deadcode)funcencodeFixed64Log(data[]byte,offsetint,vuint64)int{^logs/alils/log.pb.go:339:6:`encodeFixed32Log`isunused(deadcode)funcencodeFixed32Log(data[]byte,offsetint,vuint32)int{logs/alils/log.pb.go:447:6:`sozLog`isunused(deadcode)funcsozLog(xuint64)(nint){context/param/methodparams.go:19:2:`param`isunused(deadcode)paramparamType=iota^session/memcache/sess_memcache.go:109:2:`poolsize`isunused(structcheck)poolsizeintsession/memcache/sess_memcache.go:110:2:`password`isunused(structcheck)passwordstringorm/orm_log.go:110:2:`tx`isunused(structcheck)txtxerorm/orm_log.go:111:2:`txe`isunused(structcheck)txetxEnderorm/models_info_f.go:36:2:`rels`isunused(structcheck)rels[]*fieldInfocontroller.go:76:2:`gotofunc`isunused(structcheck)gotofuncstringparser.go:183:42:cutsetcontainsduplicatecharacters(megacheck)t:=strings.TrimSpace(strings.TrimLeft(c.Text,"//"))^parser.go:200:54:cutsetcontainsduplicatecharacters(megacheck)pv:=getparams(strings.TrimSpace(strings.TrimLeft(t,"@Param")))^session/sess_file.go:140:6:thisvalueoferrisneverused(megacheck)f,err=os.OpenFile(path.Join(fp.savePath,string(sid[0]),string(sid[1]),sid),os.O_RDWR,0777)session/sess_file.go:142:6:thisvalueoferrisneverused(megacheck)f,err=os.Create(path.Join(fp.savePath,string(sid[0]),string(sid[1]),sid))cache/memory.go:41:9:shouldusetime.Sinceinsteadoftime.Now().Sub(megacheck)returntime.Now().Sub(mi.createdTime)>mi.lifespanorm/orm_log.go:39:9:shouldusetime.Sinceinsteadoftime.Now().Sub(megacheck)sub:=time.Now().Sub(t)/1e5toolbox/profile.go:109:14:shouldusetime.Sinceinsteadoftime.Now().Sub(megacheck)elapsed:=time.Now().Sub(startTime)orm/db_tables.go:77:20:func(*dbTables).getisunused(megacheck)func(t*dbTables)get(namestring)(*dbTable,bool){~/go/src/github.com/astaxie/beego(master)$#~/go/src/github.com/astaxie/beego(master)$#too~/go/src/github.com/astaxie/beego(master)$#toomuch~/go/src/github.com/astaxie/beego(master)$#toomuchissues,~/go/src/github.com/astaxie/beego(master)$golangci-~/go/src/github.com/astaxie/beego(master)$golangci-l~/go/src/github.com/astaxie/beego(master)$golangci-li~/go/src/github.com/astaxie/beego(master)$golangci-lin~/go/src/github.com/astaxie/beego(master)$golangci-lintr~/go/src/github.com/astaxie/beego(master)$golangci-lintruorm/orm_log.go:39:9:s~/go/src/github.com/astaxie/beego(master)$~/go/src/github.com/astaxie/beego(master)$#t~/go/src/github.com/astaxie/beego(master)$#to~/go/src/github.com/astaxie/beego(master)$#toom~/go/src/github.com/astaxie/beego(master)$#toomu~/go/src/github.com/astaxie/beego(master)$#toomuc~/go/src/github.com/astaxie/beego(master)$#toomuchi~/go/src/github.com/astaxie/beego(master)$#toomuchis~/go/src/github.com/astaxie/beego(master)$#toomuchiss~/go/src/github.com/astaxie/beego(master)$#toomuchissu~/go/src/github.com/astaxie/beego(master)$#toomuchissue~/go/src/github.com/astaxie/beego(master)$#toomuchissues~/go/src/github.com/astaxie/beego(master)$#toomuchissues,l~/go/src/github.com/astaxie/beego(master)$#toomuchissues,le~/go/src/github.com/astaxie/beego(master)$#toomuchissues,let~/go/src/github.com/astaxie/beego(master)$#toomuchissues,let' \ No newline at end of file +~/go/src/github.com/astaxie/beego(master)$golangci-lint~/go/src/github.com/astaxie/beego(master)$golangci-lintrunadmin.go:85:13:Errorreturnvalueof`r.ParseForm`isnotchecked(errcheck)r.ParseForm()^admin.go:88:11:Errorreturnvalueof`rw.Write`isnotchecked(errcheck)rw.Write([]byte("commandnotsupport"))^admin.go:105:15:Errorreturnvalueof`tmpl.Execute`isnotchecked(errcheck)tmpl.Execute(rw,data)^admin.go:160:11:Errorreturnvalueof`rw.Write`isnotchecked(errcheck)admin.go:246:13:Errorreturnvalueof`r.ParseForm`isnotchecked(errcheck)admin.go:268:11:Errorreturnvalueof`rw.Write`isnotchecked(errcheck)rw.Write(dataJSON)admin.go:321:15:Errorreturnvalueof`req.ParseForm`isnotchecked(errcheck)req.ParseForm()^admin.go:366:14:Errorreturnvalueof`tmpl.Execute`isnotchecked(errcheck)tmpl.Execute(rw,data)^app.go:477:30:Errorreturnvalueof`BeeApp.Handlers.InsertFilter`isnotchecked(errcheck)BeeApp.Handlers.InsertFilter(pattern,pos,filter,params...)^beego.go:106:10:Errorreturnvalueof`os.Chdir`isnotchecked(errcheck)os.Chdir(ap)^cache/file.go:69:16:Errorreturnvalueof`json.Unmarshal`isnotchecked(errcheck)json.Unmarshal([]byte(config),&cfg)^cache/file.go:101:16:Errorreturnvalueof`io.WriteString`isnotchecked(errcheck)io.WriteString(m,key)cache/file.go:126:11:Errorreturnvalueof`GobDecode`isnotchecked(errcheck)GobDecode(fileData,&to)^cache/file.go:182:8:Errorreturnvalueof`fc.Put`isnotchecked(errcheck)fc.Put(key,incr,FileCacheEmbedExpiry)^cache/file.go:195:8:Errorreturnvalueof`fc.Put`isnotchecked(errcheck)fc.Put(key,decr,FileCacheEmbedExpiry)cache/memcache/memcache.go:167:16:Errorreturnvalueof`json.Unmarshal`isnotchecked(errcheck)json.Unmarshal([]byte(config),&cf)cache/memory.go:198:16:Errorreturnvalueof`json.Unmarshal`isnotchecked(errcheck)config/ini.go:77:16:Errorreturnvalueof`buf.ReadByte`isnotchecked(errcheck)buf.ReadByte()context/context.go:86:26:Errorreturnvalueof`ctx.ResponseWriter.Write`isnotchecked(errcheck)ctx.ResponseWriter.Write([]byte(content))^context/input.go:321:34:Errorreturnvalueof`input.Context.Request.ParseForm`isnotchecked(errcheck)input.Context.Request.ParseForm()^context/input.go:444:34:Errorreturnvalueof`input.Context.Request.ParseForm`isnotchecked(errcheck)context/output.go:82:9:Errorreturnvalueof`io.Copy`isnotchecked(errcheck)io.Copy(output.Context.ResponseWriter,buf)^context/output.go:173:18:Errorreturnvalueof`ctx.Output.JSON`isnotchecked(errcheck)ctx.Output.JSON(value,false,false)^context/output.go:180:18:Errorreturnvalueof`ctx.Output.Body`isnotchecked(errcheck)ctx.Output.Body([]byte(err.Error()))context/output.go:361:37:Errorreturnvalueof`output.Context.Input.CruSession.Set`isnotchecked(errcheck)output.Context.Input.CruSession.Set(name,value)^controller.go:235:26:Errorreturnvalueof`ExecuteViewPathTemplate`isnotchecked(errcheck)ExecuteViewPathTemplate(&buf,c.Layout,c.viewPath(),c.Data)^controller.go:261:16:Errorreturnvalueof`BuildTemplate`isnotchecked(errcheck)BuildTemplate(c.viewPath(),buildFiles...)^controller.go:296:28:Errorreturnvalueof`c.Ctx.ResponseWriter.Write`isnotchecked(errcheck)c.Ctx.ResponseWriter.Write([]byte(body))^controller.go:329:19:Errorreturnvalueof`c.Ctx.Output.JSON`isnotchecked(errcheck)c.Ctx.Output.JSON(c.Data["json"],hasIndent,hasEncoding)^controller.go:338:20:Errorreturnvalueof`c.Ctx.Output.JSONP`isnotchecked(errcheck)c.Ctx.Output.JSONP(c.Data["jsonp"],hasIndent)^controller.go:347:18:Errorreturnvalueof`c.Ctx.Output.XML`isnotchecked(errcheck)c.Ctx.Output.XML(c.Data["xml"],hasIndent)controller.go:366:26:Errorreturnvalueof`c.Ctx.Request.ParseForm`isnotchecked(errcheck)c.Ctx.Request.ParseForm()controller.go:562:9:Errorreturnvalueof`io.Copy`isnotchecked(errcheck)io.Copy(f,file)controller.go:579:18:Errorreturnvalueof`c.CruSession.Set`isnotchecked(errcheck)c.CruSession.Set(name,value)controller.go:595:21:Errorreturnvalueof`c.CruSession.Delete`isnotchecked(errcheck)c.CruSession.Delete(name)^controller.go:610:30:Errorreturnvalueof`c.Ctx.Input.CruSession.Flush`isnotchecked(errcheck)c.Ctx.Input.CruSession.Flush()error.go:101:11:Errorreturnvalueof`t.Execute`isnotchecked(errcheck)t.Execute(ctx.ResponseWriter,data)error.go:374:11:Errorreturnvalueof`t.Execute`isnotchecked(errcheck)t.Execute(rw,data)grace/listener.go:37:17:Errorreturnvalueof`tc.SetKeepAlive`isnotchecked(errcheck)tc.SetKeepAlive(true)^grace/listener.go:38:23:Errorreturnvalueof`tc.SetKeepAlivePeriod`isnotchecked(errcheck)tc.SetKeepAlivePeriod(3*time.Minute)hooks.go:17:24:Errorreturnvalueof`mime.AddExtensionType`isnotchecked(errcheck)mime.AddExtensionType(k,v)^httplib/httplib.go:383:28:Errorreturnvalueof`bodyWriter.WriteField`isnotchecked(errcheck)bodyWriter.WriteField(k,vv)^logs/conn.go:94:23:Errorreturnvalueof`tcpConn.SetKeepAlive`isnotchecked(errcheck)tcpConn.SetKeepAlive(true)logs/file.go:167:11:Errorreturnvalueof`os.Chmod`isnotchecked(errcheck)os.Chmod(w.Filename,os.FileMode(perm))logs/file.go:300:15:Errorreturnvalueof`filepath.Walk`isnotchecked(errcheck)filepath.Walk(dir,func(pathstring,infoos.FileInfo,errerror)(returnErrerror){logs/file.go:330:19:Errorreturnvalueof`w.fileWriter.Sync`isnotchecked(errcheck)w.fileWriter.Sync()logs/log.go:153:14:Errorreturnvalueof`bl.setLogger`isnotchecked(errcheck)bl.setLogger(AdapterConsole)logs/log.go:263:15:Errorreturnvalueof`bl.setLogger`isnotchecked(errcheck)bl.setLogger(AdapterConsole)logs/log.go:355:13:Errorreturnvalueof`bl.writeMsg`isnotchecked(errcheck)bl.writeMsg(LevelEmergency,format,v...)logs/log.go:363:13:Errorreturnvalueof`bl.writeMsg`isnotchecked(errcheck)bl.writeMsg(LevelAlert,format,v...)logs/smtp.go:78:G402:TLSInsecureSkipVerifysettrue.(gas)InsecureSkipVerify:true,orm/db.go:283:G201:SQLstringformatting(gas)query:=fmt.Sprintf("INSERTINTO%s%s%s(%s%s%s)VALUES(%s)",Q,mi.table,Q,Q,columns,Q,qmarks)orm/db.go:350:G201:SQLstringformatting(gas)query:=fmt.Sprintf("SELECT%s%s%sFROM%s%s%sWHERE%s%s%s=?%s",Q,sels,Q,Q,mi.table,Q,Q,wheres,Q,forUpdate)orm/db.go:477:G201:SQLstringformatting(gas)orm/db.go:576:G202:SQLstringconcatenation(gas)query:=fmt.Sprintf("INSERTINTO%s%s%s(%s%s%s)VALUES(%s)%s"+qupdates,Q,mi.table,Q,Q,columns,Q,qmarks,iouStr)orm/db_mysql.go:157:G202:SQLstringconcatenation(gas)orm/db_tables.go:387:G202:SQLstringconcatenation(gas)where="WHERE"+wherelogs/alils/request.go:5:G501:Blacklistedimportcrypto/md5:weakcryptographicprimitive(gas)"crypto/md5"logs/alils/request.go:26:G401:Useofweakcryptographicprimitive(gas)bodyMD5:=fmt.Sprintf("%X",md5.Sum(body))cache/file.go:19:G501:Blacklistedimportcrypto/md5:weakcryptographicprimitive(gas)cache/file.go:100:G401:Useofweakcryptographicprimitive(gas)m:=md5.New()controller.go:230:G203:thismethodwillnotauto-escapeHTML.Verifydataiswellformed.(gas)c.Data[sectionName]=template.HTML(buf.String())error.go:372:G203:thismethodwillnotauto-escapeHTML.Verifydataiswellformed.(gas)"Content":template.HTML(errContent),templatefunc.go:272:G203:thismethodwillnotauto-escapeHTML.Verifydataiswellformed.(gas)returntemplate.HTML(text)logs/alils/log.pb.go:328:6:`encodeFixed64Log`isunused(deadcode)funcencodeFixed64Log(data[]byte,offsetint,vuint64)int{^logs/alils/log.pb.go:339:6:`encodeFixed32Log`isunused(deadcode)funcencodeFixed32Log(data[]byte,offsetint,vuint32)int{logs/alils/log.pb.go:447:6:`sozLog`isunused(deadcode)funcsozLog(xuint64)(nint){context/param/methodparams.go:19:2:`param`isunused(deadcode)paramparamType=iota^session/memcache/sess_memcache.go:109:2:`poolsize`isunused(structcheck)poolsizeintsession/memcache/sess_memcache.go:110:2:`password`isunused(structcheck)passwordstringorm/orm_log.go:110:2:`tx`isunused(structcheck)txtxerorm/orm_log.go:111:2:`txe`isunused(structcheck)txetxEnderorm/models_info_f.go:36:2:`rels`isunused(structcheck)rels[]*fieldInfocontroller.go:76:2:`gotofunc`isunused(structcheck)gotofuncstringparser.go:183:42:cutsetcontainsduplicatecharacters(megacheck)t:=strings.TrimSpace(strings.TrimLeft(c.Text,"//"))^parser.go:200:54:cutsetcontainsduplicatecharacters(megacheck)pv:=getparams(strings.TrimSpace(strings.TrimLeft(t,"@Param")))^session/sess_file.go:140:6:thisvalueoferrisneverused(megacheck)f,err=os.OpenFile(path.Join(fp.savePath,string(sid[0]),string(sid[1]),sid),os.O_RDWR,0777)session/sess_file.go:142:6:thisvalueoferrisneverused(megacheck)f,err=os.Create(path.Join(fp.savePath,string(sid[0]),string(sid[1]),sid))cache/memory.go:41:9:shouldusetime.Sinceinsteadoftime.Now().Sub(megacheck)returntime.Now().Sub(mi.createdTime)>mi.lifespanorm/orm_log.go:39:9:shouldusetime.Sinceinsteadoftime.Now().Sub(megacheck)sub:=time.Now().Sub(t)/1e5toolbox/profile.go:109:14:shouldusetime.Sinceinsteadoftime.Now().Sub(megacheck)elapsed:=time.Now().Sub(startTime)orm/db_tables.go:77:20:func(*dbTables).getisunused(megacheck)func(t*dbTables)get(namestring)(*dbTable,bool){~/go/src/github.com/astaxie/beego(master)$#~/go/src/github.com/astaxie/beego(master)$#too~/go/src/github.com/astaxie/beego(master)$#toomuch~/go/src/github.com/astaxie/beego(master)$#toomuchissues,~/go/src/github.com/astaxie/beego(master)$golangci-~/go/src/github.com/astaxie/beego(master)$golangci-l~/go/src/github.com/astaxie/beego(master)$golangci-li~/go/src/github.com/astaxie/beego(master)$golangci-lin~/go/src/github.com/astaxie/beego(master)$golangci-lintr~/go/src/github.com/astaxie/beego(master)$golangci-lintruorm/orm_log.go:39:9:s~/go/src/github.com/astaxie/beego(master)$~/go/src/github.com/astaxie/beego(master)$#t~/go/src/github.com/astaxie/beego(master)$#to~/go/src/github.com/astaxie/beego(master)$#toom~/go/src/github.com/astaxie/beego(master)$#toomu~/go/src/github.com/astaxie/beego(master)$#toomuc~/go/src/github.com/astaxie/beego(master)$#toomuchi~/go/src/github.com/astaxie/beego(master)$#toomuchis~/go/src/github.com/astaxie/beego(master)$#toomuchiss~/go/src/github.com/astaxie/beego(master)$#toomuchissu~/go/src/github.com/astaxie/beego(master)$#toomuchissue~/go/src/github.com/astaxie/beego(master)$#toomuchissues~/go/src/github.com/astaxie/beego(master)$#toomuchissues,l~/go/src/github.com/astaxie/beego(master)$#toomuchissues,le~/go/src/github.com/astaxie/beego(master)$#toomuchissues,let~/go/src/github.com/astaxie/beego(master)$#toomuchissues,let' \ No newline at end of file diff --git a/pkg/commands/run.go b/pkg/commands/run.go index b805995e..17f0f3fb 100644 --- a/pkg/commands/run.go +++ b/pkg/commands/run.go @@ -189,6 +189,8 @@ func initFlagSet(fs *pflag.FlagSet, cfg *config.Config, m *lintersdb.Manager, is ic := &cfg.Issues fs.StringSliceVarP(&ic.ExcludePatterns, "exclude", "e", nil, wh("Exclude issue by regexp")) fs.BoolVar(&ic.UseDefaultExcludes, "exclude-use-default", true, getDefaultIssueExcludeHelp()) + fs.BoolVar(&ic.ExcludeCaseSensitive, "exclude-case-sensitive", false, wh("If set to true exclude "+ + "and exclude rules regular expressions are case sensitive")) fs.IntVar(&ic.MaxIssuesPerLinter, "max-issues-per-linter", 50, wh("Maximum issues count per one linter. Set to 0 to disable")) diff --git a/pkg/config/config.go b/pkg/config/config.go index f97ec591..2b3048cb 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -411,9 +411,10 @@ func (e ExcludeRule) Validate() error { } type Issues struct { - ExcludePatterns []string `mapstructure:"exclude"` - ExcludeRules []ExcludeRule `mapstructure:"exclude-rules"` - UseDefaultExcludes bool `mapstructure:"exclude-use-default"` + ExcludeCaseSensitive bool `mapstructure:"exclude-case-sensitive"` + ExcludePatterns []string `mapstructure:"exclude"` + ExcludeRules []ExcludeRule `mapstructure:"exclude-rules"` + UseDefaultExcludes bool `mapstructure:"exclude-use-default"` MaxIssuesPerLinter int `mapstructure:"max-issues-per-linter"` MaxSameIssues int `mapstructure:"max-same-issues"` diff --git a/pkg/lint/runner.go b/pkg/lint/runner.go index 4dc40f3f..dd9e6946 100644 --- a/pkg/lint/runner.go +++ b/pkg/lint/runner.go @@ -40,6 +40,13 @@ func NewRunner(cfg *config.Config, log logutils.Log, goenv *goutil.Env, excludeTotalPattern = fmt.Sprintf("(%s)", strings.Join(excludePatterns, "|")) } + var excludeProcessor processors.Processor + if cfg.Issues.ExcludeCaseSensitive { + excludeProcessor = processors.NewExcludeCaseSensitive(excludeTotalPattern) + } else { + excludeProcessor = processors.NewExclude(excludeTotalPattern) + } + skipFilesProcessor, err := processors.NewSkipFiles(cfg.Run.SkipFiles) if err != nil { return nil, err @@ -63,6 +70,12 @@ func NewRunner(cfg *config.Config, log logutils.Log, goenv *goutil.Env, Linters: r.Linters, }) } + var excludeRulesProcessor processors.Processor + if cfg.Issues.ExcludeCaseSensitive { + excludeRulesProcessor = processors.NewExcludeRulesCaseSensitive(excludeRules, lineCache, log.Child("exclude_rules")) + } else { + excludeRulesProcessor = processors.NewExcludeRules(excludeRules, lineCache, log.Child("exclude_rules")) + } return &Runner{ Processors: []processors.Processor{ @@ -81,8 +94,8 @@ func NewRunner(cfg *config.Config, log logutils.Log, goenv *goutil.Env, // Must be before exclude because users see already marked output and configure excluding by it. processors.NewIdentifierMarker(), - processors.NewExclude(excludeTotalPattern), - processors.NewExcludeRules(excludeRules, lineCache, log.Child("exclude_rules")), + excludeProcessor, + excludeRulesProcessor, processors.NewNolint(log.Child("nolint"), dbManager), processors.NewUniqByLine(cfg), diff --git a/pkg/result/processors/exclude.go b/pkg/result/processors/exclude.go index 80c4b894..92959a32 100644 --- a/pkg/result/processors/exclude.go +++ b/pkg/result/processors/exclude.go @@ -37,3 +37,23 @@ func (p Exclude) Process(issues []result.Issue) ([]result.Issue, error) { } func (p Exclude) Finish() {} + +type ExcludeCaseSensitive struct { + *Exclude +} + +var _ Processor = ExcludeCaseSensitive{} + +func NewExcludeCaseSensitive(pattern string) *ExcludeCaseSensitive { + var patternRe *regexp.Regexp + if pattern != "" { + patternRe = regexp.MustCompile(pattern) + } + return &ExcludeCaseSensitive{ + &Exclude{pattern: patternRe}, + } +} + +func (p ExcludeCaseSensitive) Name() string { + return "exclude-case-sensitive" +} diff --git a/pkg/result/processors/exclude_rules.go b/pkg/result/processors/exclude_rules.go index 6b16fdc5..b926af5b 100644 --- a/pkg/result/processors/exclude_rules.go +++ b/pkg/result/processors/exclude_rules.go @@ -37,24 +37,29 @@ func NewExcludeRules(rules []ExcludeRule, lineCache *fsutils.LineCache, log logu lineCache: lineCache, log: log, } + r.rules = createRules(rules, "(?i)") + return r +} + +func createRules(rules []ExcludeRule, prefix string) []excludeRule { + parsedRules := make([]excludeRule, 0, len(rules)) for _, rule := range rules { parsedRule := excludeRule{ linters: rule.Linters, } if rule.Text != "" { - parsedRule.text = regexp.MustCompile("(?i)" + rule.Text) + parsedRule.text = regexp.MustCompile(prefix + rule.Text) } if rule.Source != "" { - parsedRule.source = regexp.MustCompile("(?i)" + rule.Source) + parsedRule.source = regexp.MustCompile(prefix + rule.Source) } if rule.Path != "" { parsedRule.path = regexp.MustCompile(rule.Path) } - r.rules = append(r.rules, parsedRule) + parsedRules = append(parsedRules, parsedRule) } - - return r + return parsedRules } func (p ExcludeRules) Process(issues []result.Issue) ([]result.Issue, error) { @@ -118,3 +123,21 @@ func (ExcludeRules) Name() string { return "exclude-rules" } func (ExcludeRules) Finish() {} var _ Processor = ExcludeRules{} + +type ExcludeRulesCaseSensitive struct { + *ExcludeRules +} + +func NewExcludeRulesCaseSensitive(rules []ExcludeRule, lineCache *fsutils.LineCache, log logutils.Log) *ExcludeRulesCaseSensitive { + r := &ExcludeRules{ + lineCache: lineCache, + log: log, + } + r.rules = createRules(rules, "") + + return &ExcludeRulesCaseSensitive{r} +} + +func (ExcludeRulesCaseSensitive) Name() string { return "exclude-rules-case-sensitive" } + +var _ Processor = ExcludeCaseSensitive{} diff --git a/pkg/result/processors/exclude_rules_test.go b/pkg/result/processors/exclude_rules_test.go index ee2f15e1..80759d4f 100644 --- a/pkg/result/processors/exclude_rules_test.go +++ b/pkg/result/processors/exclude_rules_test.go @@ -31,26 +31,12 @@ func TestExcludeRulesMultiple(t *testing.T) { Linters: []string{"lll"}, }, }, lineCache, nil) - type issueCase struct { - Path string - Line int - Text string - Linter string - } - var newIssueCase = func(c issueCase) result.Issue { - return result.Issue{ - Text: c.Text, - FromLinter: c.Linter, - Pos: token.Position{ - Filename: c.Path, - Line: c.Line, - }, - } - } + cases := []issueCase{ {Path: "e.go", Text: "exclude", Linter: "linter"}, {Path: "e.go", Text: "some", Linter: "linter"}, {Path: "e_test.go", Text: "normal", Linter: "testlinter"}, + {Path: "e_Test.go", Text: "normal", Linter: "testlinter"}, {Path: "e_test.go", Text: "another", Linter: "linter"}, {Path: "e_test.go", Text: "testonly", Linter: "linter"}, {Path: filepath.Join("testdata", "exclude_rules.go"), Line: 3, Linter: "lll"}, @@ -71,11 +57,30 @@ func TestExcludeRulesMultiple(t *testing.T) { } expectedCases := []issueCase{ {Path: "e.go", Text: "some", Linter: "linter"}, + {Path: "e_Test.go", Text: "normal", Linter: "testlinter"}, {Path: "e_test.go", Text: "another", Linter: "linter"}, } assert.Equal(t, expectedCases, resultingCases) } +type issueCase struct { + Path string + Line int + Text string + Linter string +} + +func newIssueCase(c issueCase) result.Issue { + return result.Issue{ + Text: c.Text, + FromLinter: c.Linter, + Pos: token.Position{ + Filename: c.Path, + Line: c.Line, + }, + } +} + func TestExcludeRulesText(t *testing.T) { p := NewExcludeRules([]ExcludeRule{ { @@ -103,6 +108,96 @@ func TestExcludeRulesText(t *testing.T) { } assert.Equal(t, texts[1:], processedTexts) } + func TestExcludeRulesEmpty(t *testing.T) { processAssertSame(t, NewExcludeRules(nil, nil, nil), newTextIssue("test")) } + +func TestExcludeRulesCaseSensitiveMultiple(t *testing.T) { + lineCache := fsutils.NewLineCache(fsutils.NewFileCache()) + p := NewExcludeRulesCaseSensitive([]ExcludeRule{ + { + Text: "^exclude$", + Linters: []string{"linter"}, + }, + { + Linters: []string{"testlinter"}, + Path: `_test\.go`, + }, + { + Text: "^testonly$", + Path: `_test\.go`, + }, + { + Source: "^//go:generate ", + Linters: []string{"lll"}, + }, + }, lineCache, nil) + + cases := []issueCase{ + {Path: "e.go", Text: "exclude", Linter: "linter"}, + {Path: "e.go", Text: "excLude", Linter: "linter"}, + {Path: "e.go", Text: "some", Linter: "linter"}, + {Path: "e_test.go", Text: "normal", Linter: "testlinter"}, + {Path: "e_Test.go", Text: "normal", Linter: "testlinter"}, + {Path: "e_test.go", Text: "another", Linter: "linter"}, + {Path: "e_test.go", Text: "testonly", Linter: "linter"}, + {Path: "e_test.go", Text: "testOnly", Linter: "linter"}, + {Path: filepath.Join("testdata", "exclude_rules_case_sensitive.go"), Line: 3, Linter: "lll"}, + } + var issues []result.Issue + for _, c := range cases { + issues = append(issues, newIssueCase(c)) + } + processedIssues := process(t, p, issues...) + var resultingCases []issueCase + for _, i := range processedIssues { + resultingCases = append(resultingCases, issueCase{ + Path: i.FilePath(), + Linter: i.FromLinter, + Text: i.Text, + Line: i.Line(), + }) + } + expectedCases := []issueCase{ + {Path: "e.go", Text: "excLude", Linter: "linter"}, + {Path: "e.go", Text: "some", Linter: "linter"}, + {Path: "e_Test.go", Text: "normal", Linter: "testlinter"}, + {Path: "e_test.go", Text: "another", Linter: "linter"}, + {Path: "e_test.go", Text: "testOnly", Linter: "linter"}, + {Path: filepath.Join("testdata", "exclude_rules_case_sensitive.go"), Line: 3, Linter: "lll"}, + } + assert.Equal(t, expectedCases, resultingCases) +} + +func TestExcludeRulesCaseSensitiveText(t *testing.T) { + p := NewExcludeRulesCaseSensitive([]ExcludeRule{ + { + Text: "^exclude$", + Linters: []string{ + "linter", + }, + }, + }, nil, nil) + texts := []string{"exclude", "excLude", "1", "", "exclud", "notexclude"} + var issues []result.Issue + for _, t := range texts { + issues = append(issues, result.Issue{ + Text: t, + FromLinter: "linter", + }) + } + + processedIssues := process(t, p, issues...) + assert.Len(t, processedIssues, len(issues)-1) + + var processedTexts []string + for _, i := range processedIssues { + processedTexts = append(processedTexts, i.Text) + } + assert.Equal(t, texts[1:], processedTexts) +} + +func TestExcludeRulesCaseSensitiveEmpty(t *testing.T) { + processAssertSame(t, NewExcludeRulesCaseSensitive(nil, nil, nil), newTextIssue("test")) +} diff --git a/pkg/result/processors/exclude_test.go b/pkg/result/processors/exclude_test.go index 7f68d908..7965f2fd 100644 --- a/pkg/result/processors/exclude_test.go +++ b/pkg/result/processors/exclude_test.go @@ -51,3 +51,21 @@ func TestExclude(t *testing.T) { func TestNoExclude(t *testing.T) { processAssertSame(t, NewExclude(""), newTextIssue("test")) } + +func TestExcludeCaseSensitive(t *testing.T) { + p := NewExcludeCaseSensitive("^exclude$") + texts := []string{"excLude", "1", "", "exclud", "exclude"} + var issues []result.Issue + for _, t := range texts { + issues = append(issues, newTextIssue(t)) + } + + processedIssues := process(t, p, issues...) + assert.Len(t, processedIssues, len(issues)-1) + + var processedTexts []string + for _, i := range processedIssues { + processedTexts = append(processedTexts, i.Text) + } + assert.Equal(t, texts[:len(texts)-1], processedTexts) +} diff --git a/pkg/result/processors/testdata/exclude_rules_case_sensitive.go b/pkg/result/processors/testdata/exclude_rules_case_sensitive.go new file mode 100644 index 00000000..fe2cabdf --- /dev/null +++ b/pkg/result/processors/testdata/exclude_rules_case_sensitive.go @@ -0,0 +1,3 @@ +package testdata + +//GO:generate long line that will be excluded by default processor but will not be affected by case-sensitive one because of capital GO