Skip to content

Commit fb38e51

Browse files
committed
add all warnings and error to json if out-format=json
1 parent 93311ae commit fb38e51

File tree

6 files changed

+136
-19
lines changed

6 files changed

+136
-19
lines changed

pkg/commands/executor.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package commands
33
import (
44
"github.com/golangci/golangci-lint/pkg/config"
55
"github.com/golangci/golangci-lint/pkg/logutils"
6+
"github.com/golangci/golangci-lint/pkg/report"
67
"github.com/spf13/cobra"
78
)
89

@@ -16,6 +17,8 @@ type Executor struct {
1617
version, commit, date string
1718

1819
log logutils.Log
20+
21+
reportData report.Data
1922
}
2023

2124
func NewExecutor(version, commit, date string) *Executor {
@@ -24,9 +27,10 @@ func NewExecutor(version, commit, date string) *Executor {
2427
version: version,
2528
commit: commit,
2629
date: date,
27-
log: logutils.NewStderrLog(""),
2830
}
2931

32+
e.log = report.NewLogWrapper(logutils.NewStderrLog(""), &e.reportData)
33+
3034
e.initRoot()
3135
e.initRun()
3236
e.initLinters()

pkg/commands/run.go

+33-13
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,17 @@ func (e *Executor) runAnalysis(ctx context.Context, args []string) (<-chan resul
211211
return nil, err
212212
}
213213

214+
for _, lc := range lintersdb.GetAllSupportedLinterConfigs() {
215+
isEnabled := false
216+
for _, linter := range linters {
217+
if linter.Linter.Name() == lc.Linter.Name() {
218+
isEnabled = true
219+
break
220+
}
221+
}
222+
e.reportData.AddLinter(lc.Linter.Name(), isEnabled, lc.EnabledByDefault)
223+
}
224+
214225
lintCtx, err := lint.LoadContext(ctx, linters, e.cfg, e.log.Child("load"))
215226
if err != nil {
216227
return nil, err
@@ -251,11 +262,30 @@ func (e *Executor) runAndPrint(ctx context.Context, args []string) error {
251262
return err
252263
}
253264

265+
p, err := e.createPrinter()
266+
if err != nil {
267+
return err
268+
}
269+
270+
gotAnyIssues, err := p.Print(ctx, issues)
271+
if err != nil {
272+
return fmt.Errorf("can't print %d issues: %s", len(issues), err)
273+
}
274+
275+
if gotAnyIssues {
276+
e.exitCode = e.cfg.Run.ExitCodeIfIssuesFound
277+
return nil
278+
}
279+
280+
return nil
281+
}
282+
283+
func (e *Executor) createPrinter() (printers.Printer, error) {
254284
var p printers.Printer
255285
format := e.cfg.Output.Format
256286
switch format {
257287
case config.OutFormatJSON:
258-
p = printers.NewJSON()
288+
p = printers.NewJSON(&e.reportData)
259289
case config.OutFormatColoredLineNumber, config.OutFormatLineNumber:
260290
p = printers.NewText(e.cfg.Output.PrintIssuedLine,
261291
format == config.OutFormatColoredLineNumber, e.cfg.Output.PrintLinterName, e.cfg.Run.Silent,
@@ -266,20 +296,10 @@ func (e *Executor) runAndPrint(ctx context.Context, args []string) error {
266296
case config.OutFormatCheckstyle:
267297
p = printers.NewCheckstyle()
268298
default:
269-
return fmt.Errorf("unknown output format %s", format)
299+
return nil, fmt.Errorf("unknown output format %s", format)
270300
}
271301

272-
gotAnyIssues, err := p.Print(ctx, issues)
273-
if err != nil {
274-
return fmt.Errorf("can't print %d issues: %s", len(issues), err)
275-
}
276-
277-
if gotAnyIssues {
278-
e.exitCode = e.cfg.Run.ExitCodeIfIssuesFound
279-
return nil
280-
}
281-
282-
return nil
302+
return p, nil
283303
}
284304

285305
func (e *Executor) executeRun(cmd *cobra.Command, args []string) {

pkg/logutils/stderr_log.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func (sl StderrLog) Debugf(format string, args ...interface{}) {
9393
func (sl StderrLog) Child(name string) Log {
9494
prefix := ""
9595
if sl.name != "" {
96-
prefix = sl.name + ":"
96+
prefix = sl.name + "/"
9797
}
9898

9999
child := sl

pkg/printers/json.go

+11-4
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,34 @@ import (
66
"fmt"
77

88
"github.com/golangci/golangci-lint/pkg/logutils"
9+
"github.com/golangci/golangci-lint/pkg/report"
910
"github.com/golangci/golangci-lint/pkg/result"
1011
)
1112

12-
type JSON struct{}
13+
type JSON struct {
14+
rd *report.Data
15+
}
1316

14-
func NewJSON() *JSON {
15-
return &JSON{}
17+
func NewJSON(rd *report.Data) *JSON {
18+
return &JSON{
19+
rd: rd,
20+
}
1621
}
1722

1823
type JSONResult struct {
1924
Issues []result.Issue
25+
Report *report.Data
2026
}
2127

22-
func (JSON) Print(ctx context.Context, issues <-chan result.Issue) (bool, error) {
28+
func (p JSON) Print(ctx context.Context, issues <-chan result.Issue) (bool, error) {
2329
allIssues := []result.Issue{}
2430
for i := range issues {
2531
allIssues = append(allIssues, i)
2632
}
2733

2834
res := JSONResult{
2935
Issues: allIssues,
36+
Report: p.rd,
3037
}
3138

3239
outputJSON, err := json.Marshal(res)

pkg/report/data.go

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package report
2+
3+
type Warning struct {
4+
Tag string `json:",omitempty"`
5+
Text string
6+
}
7+
8+
type LinterData struct {
9+
Name string
10+
Enabled bool `json:",omitempty"`
11+
EnabledByDefault bool `json:",omitempty"`
12+
}
13+
14+
type Data struct {
15+
Warnings []Warning `json:",omitempty"`
16+
Linters []LinterData `json:",omitempty"`
17+
Error string `json:",omitempty"`
18+
}
19+
20+
func (d *Data) AddLinter(name string, enabled, enabledByDefault bool) {
21+
d.Linters = append(d.Linters, LinterData{
22+
Name: name,
23+
Enabled: enabled,
24+
EnabledByDefault: enabledByDefault,
25+
})
26+
}

pkg/report/log.go

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package report
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
"github.com/golangci/golangci-lint/pkg/logutils"
8+
)
9+
10+
type LogWrapper struct {
11+
rd *Data
12+
tags []string
13+
origLog logutils.Log
14+
}
15+
16+
func NewLogWrapper(log logutils.Log, reportData *Data) *LogWrapper {
17+
return &LogWrapper{
18+
rd: reportData,
19+
origLog: log,
20+
}
21+
}
22+
23+
func (lw LogWrapper) Fatalf(format string, args ...interface{}) {
24+
lw.origLog.Fatalf(format, args...)
25+
}
26+
27+
func (lw LogWrapper) Errorf(format string, args ...interface{}) {
28+
lw.origLog.Errorf(format, args...)
29+
lw.rd.Error = fmt.Sprintf(format, args...)
30+
}
31+
32+
func (lw LogWrapper) Warnf(format string, args ...interface{}) {
33+
lw.origLog.Warnf(format, args...)
34+
w := Warning{
35+
Tag: strings.Join(lw.tags, "/"),
36+
Text: fmt.Sprintf(format, args...),
37+
}
38+
39+
lw.rd.Warnings = append(lw.rd.Warnings, w)
40+
}
41+
42+
func (lw LogWrapper) Infof(format string, args ...interface{}) {
43+
lw.origLog.Infof(format, args...)
44+
}
45+
46+
func (lw LogWrapper) Child(name string) logutils.Log {
47+
c := lw
48+
c.origLog = lw.origLog.Child(name)
49+
c.tags = append([]string{}, lw.tags...)
50+
c.tags = append(c.tags, name)
51+
return c
52+
}
53+
54+
func (lw LogWrapper) SetLevel(level logutils.LogLevel) {
55+
lw.origLog.SetLevel(level)
56+
}
57+
58+
func (lw LogWrapper) GoString() string {
59+
return fmt.Sprintf("lw: %+v, orig log: %#v", lw, lw.origLog)
60+
}

0 commit comments

Comments
 (0)