SARIF 1: add structured detail (#843)

* sarif-1

* comment

* typos

* comments

* comments

* typo

* typo

* fixes

* linter

* linter

* linter
This commit is contained in:
laurentsimon 2021-08-16 16:26:19 -07:00 committed by GitHub
parent 0a0d292b3c
commit dbdcd4bea7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 125 additions and 19 deletions

View File

@ -42,18 +42,52 @@ const (
DetailDebug
)
// CheckDetail contains information for each detail.
//nolint:govet
type CheckDetail struct {
Type DetailType // Any of DetailWarn, DetailInfo, DetailDebug.
Msg string // A short string explaining why the details was recorded/logged..
// FileType is the type of a file.
type FileType int
const (
// FileTypeNone is a default, not defined.
FileTypeNone FileType = iota
// FileTypeSource is for source code files.
FileTypeSource
// FileTypeBinary is for binary files.
FileTypeBinary
// FileTypeText is for text files.
FileTypeText
// FileTypeURL for URLs.
FileTypeURL
)
// LogMessage is a structure that encapsulates detail's information.
// This allows updating the definition easily.
//nolint
type LogMessage struct {
Text string // A short string explaining why the detail was recorded/logged.
Path string // Fullpath to the file.
Type FileType // Type of file.
Offset int // Offset in the file of Path (line for source/text files).
Snippet string // Snippet of code
// UPGRADEv3: to remove.
Version int // `3` to indicate the detail was logged using new structure.
}
// DetailLogger logs map to CheckDetail struct.
// CheckDetail contains information for each detail.
type CheckDetail struct {
Msg LogMessage
Type DetailType // Any of DetailWarn, DetailInfo, DetailDebug.
}
// DetailLogger logs a CheckDetail struct.
type DetailLogger interface {
Info(desc string, args ...interface{})
Warn(desc string, args ...interface{})
Debug(desc string, args ...interface{})
// Functions to use for moving to SARIF format.
// UPGRADEv3: to rename.
Info3(msg *LogMessage)
Warn3(msg *LogMessage)
Debug3(msg *LogMessage)
}
//nolint

View File

@ -49,17 +49,45 @@ type logger struct {
}
func (l *logger) Info(desc string, args ...interface{}) {
cd := CheckDetail{Type: DetailInfo, Msg: fmt.Sprintf(desc, args...)}
cd := CheckDetail{Type: DetailInfo, Msg: LogMessage{Text: fmt.Sprintf(desc, args...)}}
l.messages2 = append(l.messages2, cd)
}
func (l *logger) Warn(desc string, args ...interface{}) {
cd := CheckDetail{Type: DetailWarn, Msg: fmt.Sprintf(desc, args...)}
cd := CheckDetail{Type: DetailWarn, Msg: LogMessage{Text: fmt.Sprintf(desc, args...)}}
l.messages2 = append(l.messages2, cd)
}
func (l *logger) Debug(desc string, args ...interface{}) {
cd := CheckDetail{Type: DetailDebug, Msg: fmt.Sprintf(desc, args...)}
cd := CheckDetail{Type: DetailDebug, Msg: LogMessage{Text: fmt.Sprintf(desc, args...)}}
l.messages2 = append(l.messages2, cd)
}
// UPGRADEv3: to rename.
func (l *logger) Info3(msg *LogMessage) {
cd := CheckDetail{
Type: DetailInfo,
Msg: *msg,
}
cd.Msg.Version = 3
l.messages2 = append(l.messages2, cd)
}
func (l *logger) Warn3(msg *LogMessage) {
cd := CheckDetail{
Type: DetailWarn,
Msg: *msg,
}
cd.Msg.Version = 3
l.messages2 = append(l.messages2, cd)
}
func (l *logger) Debug3(msg *LogMessage) {
cd := CheckDetail{
Type: DetailDebug,
Msg: *msg,
}
cd.Msg.Version = 3
l.messages2 = append(l.messages2, cd)
}
@ -100,9 +128,10 @@ func (r *Runner) Run(ctx context.Context, f CheckFn) CheckResult {
}
break
}
res.Details2 = l.messages2
for _, d := range l.messages2 {
res.Details = append(res.Details, d.Msg)
res.Details = append(res.Details, d.Msg.Text)
}
if err := logStats(ctx, startTime, &res); err != nil {
panic(err)

View File

@ -87,7 +87,7 @@ func (r *ScorecardResult) AsJSON(showDetails bool, logLevel zapcore.Level, write
return nil
}
// AsJSON2 is expoting results as JSON for new detail format.
// AsJSON2 exports results as JSON for new detail format.
func (r *ScorecardResult) AsJSON2(showDetails bool, logLevel zapcore.Level, writer io.Writer) error {
encoder := json.NewEncoder(writer)
@ -106,7 +106,7 @@ func (r *ScorecardResult) AsJSON2(showDetails bool, logLevel zapcore.Level, writ
}
if showDetails {
for _, d := range checkResult.Details2 {
tmpResult.Details = append(tmpResult.Details, d.Msg)
tmpResult.Details = append(tmpResult.Details, d.Msg.Text)
}
}
out.Checks = append(out.Checks, tmpResult)
@ -207,13 +207,25 @@ func (r *ScorecardResult) AsString(showDetails bool, logLevel zapcore.Level, wri
func detailsToString(details []checker.CheckDetail, logLevel zapcore.Level) (string, bool) {
// UPGRADEv2: change to make([]string, len(details))
// followed by sa[i] = instead of append.
//nolint
var sa []string
for _, v := range details {
if v.Type == checker.DetailDebug && logLevel != zapcore.DebugLevel {
continue
switch v.Msg.Version {
//nolint
case 3:
if v.Type == checker.DetailDebug && logLevel != zapcore.DebugLevel {
continue
}
if v.Msg.Path != "" {
sa = append(sa, fmt.Sprintf("%s: %s: %s:%d", typeToString(v.Type), v.Msg.Text, v.Msg.Path, v.Msg.Offset))
} else {
sa = append(sa, fmt.Sprintf("%s: %s: %s", typeToString(v.Type), v.Msg.Text, v.Msg.Path))
}
default:
if v.Type == checker.DetailDebug && logLevel != zapcore.DebugLevel {
continue
}
sa = append(sa, fmt.Sprintf("%s: %s", typeToString(v.Type), v.Msg.Text))
}
sa = append(sa, fmt.Sprintf("%s: %s", typeToString(v.Type), v.Msg))
}
return strings.Join(sa, "\n"), len(sa) > 0
}

View File

@ -60,19 +60,50 @@ type TestReturn struct {
// Info implements DetailLogger.Info.
func (l *TestDetailLogger) Info(desc string, args ...interface{}) {
cd := checker.CheckDetail{Type: checker.DetailInfo, Msg: fmt.Sprintf(desc, args...)}
cd := checker.CheckDetail{Type: checker.DetailInfo, Msg: checker.LogMessage{Text: fmt.Sprintf(desc, args...)}}
l.messages = append(l.messages, cd)
}
// Warn implements DetailLogger.Warn.
func (l *TestDetailLogger) Warn(desc string, args ...interface{}) {
cd := checker.CheckDetail{Type: checker.DetailWarn, Msg: fmt.Sprintf(desc, args...)}
cd := checker.CheckDetail{Type: checker.DetailWarn, Msg: checker.LogMessage{Text: fmt.Sprintf(desc, args...)}}
l.messages = append(l.messages, cd)
}
// Debug implements DetailLogger.Debug.
func (l *TestDetailLogger) Debug(desc string, args ...interface{}) {
cd := checker.CheckDetail{Type: checker.DetailDebug, Msg: fmt.Sprintf(desc, args...)}
cd := checker.CheckDetail{Type: checker.DetailDebug, Msg: checker.LogMessage{Text: fmt.Sprintf(desc, args...)}}
l.messages = append(l.messages, cd)
}
// UPGRADEv3: to rename.
//nolint:revive
func (l *TestDetailLogger) Info3(msg *checker.LogMessage) {
cd := checker.CheckDetail{
Type: checker.DetailInfo,
Msg: *msg,
}
cd.Msg.Version = 3
l.messages = append(l.messages, cd)
}
//nolint:revive
func (l *TestDetailLogger) Warn3(msg *checker.LogMessage) {
cd := checker.CheckDetail{
Type: checker.DetailWarn,
Msg: *msg,
}
cd.Msg.Version = 3
l.messages = append(l.messages, cd)
}
//nolint:revive
func (l *TestDetailLogger) Debug3(msg *checker.LogMessage) {
cd := checker.CheckDetail{
Type: checker.DetailDebug,
Msg: *msg,
}
cd.Msg.Version = 3
l.messages = append(l.messages, cd)
}