Skip to content

Commit f62d607

Browse files
committed
#37: add tab output format: --out-format=tab
1 parent 1e0cacf commit f62d607

File tree

4 files changed

+80
-7
lines changed

4 files changed

+80
-7
lines changed

README.md

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

pkg/commands/run.go

+11-3
Original file line numberDiff line numberDiff line change
@@ -235,12 +235,19 @@ func (e *Executor) runAndPrint(ctx context.Context, args []string) error {
235235
}
236236

237237
var p printers.Printer
238-
if e.cfg.Output.Format == config.OutFormatJSON {
238+
format := e.cfg.Output.Format
239+
switch format {
240+
case config.OutFormatJSON:
239241
p = printers.NewJSON()
240-
} else {
242+
case config.OutFormatColoredLineNumber, config.OutFormatLineNumber:
241243
p = printers.NewText(e.cfg.Output.PrintIssuedLine,
242-
e.cfg.Output.Format == config.OutFormatColoredLineNumber, e.cfg.Output.PrintLinterName)
244+
format == config.OutFormatColoredLineNumber, e.cfg.Output.PrintLinterName)
245+
case config.OutFormatTab:
246+
p = printers.NewTab(e.cfg.Output.PrintLinterName)
247+
default:
248+
return fmt.Errorf("unknown output format %s", format)
243249
}
250+
244251
gotAnyIssues, err := p.Print(ctx, issues)
245252
if err != nil {
246253
return fmt.Errorf("can't print %d issues: %s", len(issues), err)
@@ -296,6 +303,7 @@ func (e *Executor) parseConfig() {
296303
e.initFlagSet(fs)
297304
e.initRootFlagSet(fs)
298305

306+
fs.Usage = func() {} // otherwise help text will be printed twice
299307
if err := fs.Parse(os.Args); err != nil {
300308
if err == pflag.ErrHelp {
301309
return

pkg/config/config.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ const (
1010
OutFormatJSON = "json"
1111
OutFormatLineNumber = "line-number"
1212
OutFormatColoredLineNumber = "colored-line-number"
13+
OutFormatTab = "tab"
1314
)
1415

15-
var OutFormats = []string{OutFormatColoredLineNumber, OutFormatLineNumber, OutFormatJSON}
16+
var OutFormats = []string{OutFormatColoredLineNumber, OutFormatLineNumber, OutFormatJSON, OutFormatTab}
1617

1718
type ExcludePattern struct {
1819
Pattern string
@@ -22,7 +23,7 @@ type ExcludePattern struct {
2223

2324
var DefaultExcludePatterns = []ExcludePattern{
2425
{
25-
Pattern: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|os\\.Remove(All)?|.*printf?|os\\.(Un)?Setenv). is not checked",
26+
Pattern: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|.*Flush|os\\.Remove(All)?|.*printf?|os\\.(Un)?Setenv). is not checked",
2627
Linter: "errcheck",
2728
Why: "Almost all programs ignore errors on these functions and in most cases it's ok",
2829
},

pkg/printers/tab.go

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package printers
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"io"
7+
"text/tabwriter"
8+
9+
"github.com/fatih/color"
10+
"github.com/golangci/golangci-lint/pkg/result"
11+
"github.com/sirupsen/logrus"
12+
)
13+
14+
type Tab struct {
15+
printLinterName bool
16+
}
17+
18+
func NewTab(printLinterName bool) *Tab {
19+
return &Tab{
20+
printLinterName: printLinterName,
21+
}
22+
}
23+
24+
func (p Tab) SprintfColored(ca color.Attribute, format string, args ...interface{}) string {
25+
c := color.New(ca)
26+
return c.Sprintf(format, args...)
27+
}
28+
29+
func (p *Tab) Print(ctx context.Context, issues <-chan result.Issue) (bool, error) {
30+
w := tabwriter.NewWriter(StdOut, 0, 0, 2, ' ', 0)
31+
32+
issuesN := 0
33+
for i := range issues {
34+
issuesN++
35+
p.printIssue(&i, w)
36+
}
37+
38+
if issuesN != 0 {
39+
logrus.Infof("Found %d issues", issuesN)
40+
} else if ctx.Err() == nil { // don't print "congrats" if timeouted
41+
outStr := p.SprintfColored(color.FgGreen, "Congrats! No issues were found.")
42+
fmt.Fprintln(StdOut, outStr)
43+
}
44+
45+
if err := w.Flush(); err != nil {
46+
logrus.Warnf("Can't flush tab writer: %s", err)
47+
}
48+
49+
return issuesN != 0, nil
50+
}
51+
52+
func (p Tab) printIssue(i *result.Issue, w io.Writer) {
53+
text := p.SprintfColored(color.FgRed, "%s", i.Text)
54+
if p.printLinterName {
55+
text = fmt.Sprintf("%s\t%s", i.FromLinter, text)
56+
}
57+
58+
pos := p.SprintfColored(color.Bold, "%s:%d", i.FilePath(), i.Line())
59+
if i.Pos.Column != 0 {
60+
pos += fmt.Sprintf(":%d", i.Pos.Column)
61+
}
62+
63+
fmt.Fprintf(w, "%s\t%s\n", pos, text)
64+
}

0 commit comments

Comments
 (0)