File: sarif.go

package info (click to toggle)
golang-github-reviewdog-errorformat 0.0~git20240608.1d3280e-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 984 kB
  • sloc: python: 59; xml: 13; sh: 7; javascript: 4; haskell: 3; makefile: 3
file content (103 lines) | stat: -rw-r--r-- 2,176 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package writer

import (
	"encoding/json"
	"errors"
	"io"
	"os"
	"path/filepath"
	"sync"

	"github.com/haya14busa/go-sarif/sarif"
	"github.com/reviewdog/errorformat"
)

type Sarif struct {
	mu      sync.Mutex
	data    *sarif.Sarif
	run     *sarif.Run
	w       io.Writer
	srcRoot string
}

type SarifOption struct {
	ToolName string
}

func NewSarif(w io.Writer, opt SarifOption) (*Sarif, error) {
	if opt.ToolName == "" {
		return nil, errors.New("-sarif.tool-name is required.")
	}
	s := &Sarif{w: w, data: sarif.NewSarif(), run: &sarif.Run{
		Tool: sarif.Tool{
			Driver: sarif.ToolComponent{
				Name: opt.ToolName,
			},
		},
	}}
	s.srcRoot, _ = os.Getwd()
	return s, nil
}

func (s *Sarif) Write(e *errorformat.Entry) error {
	result := sarif.Result{}

	// Set Level
	switch e.Type {
	case 'e', 'E':
		result.Level = sarif.Error.Ptr()
	case 'w', 'W':
		result.Level = sarif.Warning.Ptr()
	case 'n', 'N', 'i', 'I': // Handle info as note.
		result.Level = sarif.Note.Ptr()
	}

	// Set Message
	result.Message.Text = sarif.String(e.Text)

	// Set Location
	loc := &sarif.PhysicalLocation{
		ArtifactLocation: &sarif.ArtifactLocation{
			URIBaseID: sarif.String("%SRCROOT%"),
		},
		Region: &sarif.Region{},
	}
	if e.Lnum != 0 {
		loc.Region.StartLine = sarif.Int64(int64(e.Lnum))
	}
	if e.EndLnum != 0 {
		loc.Region.EndLine = sarif.Int64(int64(e.EndLnum))
	}
	if e.Col != 0 {
		// Errorformat.Col is not usually unicodeCodePoints, but let's just keep it
		// as is...
		loc.Region.StartColumn = sarif.Int64(int64(e.Col))
	}
	if e.EndCol != 0 {
		loc.Region.EndColumn = sarif.Int64(int64(e.EndCol))
	}
	if e.Filename != "" {
		uri := e.Filename
		if filepath.IsAbs(e.Filename) && s.srcRoot != "" {
			uri, _ = filepath.Rel(s.srcRoot, e.Filename)
		}
		loc.ArtifactLocation.URI = sarif.String(uri)
	}
	result.Locations = append(result.Locations, sarif.Location{
		PhysicalLocation: loc,
	})

	s.mu.Lock()
	defer s.mu.Unlock()
	s.run.Results = append(s.run.Results, result)
	return nil
}

func (s *Sarif) Flush() error {
	s.mu.Lock()
	defer s.mu.Unlock()
	e := json.NewEncoder(s.w)
	e.SetIndent("", "  ")
	s.data.Runs = append(s.data.Runs, *s.run)
	return e.Encode(s.data)
}