#37: add tab output format: --out-format=tab

This commit is contained in:
Denis Isaev 2018-06-02 20:53:36 +03:00
parent 1e0cacf411
commit f62d607410
No known key found for this signature in database
GPG Key ID: A36A0EC8E27A1A01
4 changed files with 80 additions and 7 deletions

View File

@ -217,7 +217,7 @@ Usage:
golangci-lint run [flags]
Flags:
--out-format string Format of output: colored-line-number|line-number|json (default "colored-line-number")
--out-format string Format of output: colored-line-number|line-number|json|tab (default "colored-line-number")
--print-issued-lines Print lines of code with issue (default true)
--print-linter-name Print linter name in issue line (default true)
--issues-exit-code int Exit code when issues were found (default 1)
@ -236,7 +236,7 @@ Flags:
-e, --exclude strings Exclude issue by regexp
--exclude-use-default Use or not use default excludes:
# errcheck: Almost all programs ignore errors on these functions and in most cases it's ok
- Error return value of .((os\.)?std(out|err)\..*|.*Close|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv). is not checked
- Error return value of .((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv). is not checked
# golint: Annoying issue about not having a comment. The rare codebase has such comments
- (should have comment|comment on exported method|should have a package comment)

View File

@ -235,12 +235,19 @@ func (e *Executor) runAndPrint(ctx context.Context, args []string) error {
}
var p printers.Printer
if e.cfg.Output.Format == config.OutFormatJSON {
format := e.cfg.Output.Format
switch format {
case config.OutFormatJSON:
p = printers.NewJSON()
} else {
case config.OutFormatColoredLineNumber, config.OutFormatLineNumber:
p = printers.NewText(e.cfg.Output.PrintIssuedLine,
e.cfg.Output.Format == config.OutFormatColoredLineNumber, e.cfg.Output.PrintLinterName)
format == config.OutFormatColoredLineNumber, e.cfg.Output.PrintLinterName)
case config.OutFormatTab:
p = printers.NewTab(e.cfg.Output.PrintLinterName)
default:
return fmt.Errorf("unknown output format %s", format)
}
gotAnyIssues, err := p.Print(ctx, issues)
if err != nil {
return fmt.Errorf("can't print %d issues: %s", len(issues), err)
@ -296,6 +303,7 @@ func (e *Executor) parseConfig() {
e.initFlagSet(fs)
e.initRootFlagSet(fs)
fs.Usage = func() {} // otherwise help text will be printed twice
if err := fs.Parse(os.Args); err != nil {
if err == pflag.ErrHelp {
return

View File

@ -10,9 +10,10 @@ const (
OutFormatJSON = "json"
OutFormatLineNumber = "line-number"
OutFormatColoredLineNumber = "colored-line-number"
OutFormatTab = "tab"
)
var OutFormats = []string{OutFormatColoredLineNumber, OutFormatLineNumber, OutFormatJSON}
var OutFormats = []string{OutFormatColoredLineNumber, OutFormatLineNumber, OutFormatJSON, OutFormatTab}
type ExcludePattern struct {
Pattern string
@ -22,7 +23,7 @@ type ExcludePattern struct {
var DefaultExcludePatterns = []ExcludePattern{
{
Pattern: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|os\\.Remove(All)?|.*printf?|os\\.(Un)?Setenv). is not checked",
Pattern: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|.*Flush|os\\.Remove(All)?|.*printf?|os\\.(Un)?Setenv). is not checked",
Linter: "errcheck",
Why: "Almost all programs ignore errors on these functions and in most cases it's ok",
},

64
pkg/printers/tab.go Normal file
View File

@ -0,0 +1,64 @@
package printers
import (
"context"
"fmt"
"io"
"text/tabwriter"
"github.com/fatih/color"
"github.com/golangci/golangci-lint/pkg/result"
"github.com/sirupsen/logrus"
)
type Tab struct {
printLinterName bool
}
func NewTab(printLinterName bool) *Tab {
return &Tab{
printLinterName: printLinterName,
}
}
func (p Tab) SprintfColored(ca color.Attribute, format string, args ...interface{}) string {
c := color.New(ca)
return c.Sprintf(format, args...)
}
func (p *Tab) Print(ctx context.Context, issues <-chan result.Issue) (bool, error) {
w := tabwriter.NewWriter(StdOut, 0, 0, 2, ' ', 0)
issuesN := 0
for i := range issues {
issuesN++
p.printIssue(&i, w)
}
if issuesN != 0 {
logrus.Infof("Found %d issues", issuesN)
} else if ctx.Err() == nil { // don't print "congrats" if timeouted
outStr := p.SprintfColored(color.FgGreen, "Congrats! No issues were found.")
fmt.Fprintln(StdOut, outStr)
}
if err := w.Flush(); err != nil {
logrus.Warnf("Can't flush tab writer: %s", err)
}
return issuesN != 0, nil
}
func (p Tab) printIssue(i *result.Issue, w io.Writer) {
text := p.SprintfColored(color.FgRed, "%s", i.Text)
if p.printLinterName {
text = fmt.Sprintf("%s\t%s", i.FromLinter, text)
}
pos := p.SprintfColored(color.Bold, "%s:%d", i.FilePath(), i.Line())
if i.Pos.Column != 0 {
pos += fmt.Sprintf(":%d", i.Pos.Column)
}
fmt.Fprintf(w, "%s\t%s\n", pos, text)
}