-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
writer.go
122 lines (111 loc) · 3.68 KB
/
writer.go
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package report
import (
"context"
"errors"
"io"
"strings"
"golang.org/x/xerrors"
cr "github.com/aquasecurity/trivy/pkg/compliance/report"
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
"github.com/aquasecurity/trivy/pkg/flag"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/report/cyclonedx"
"github.com/aquasecurity/trivy/pkg/report/github"
"github.com/aquasecurity/trivy/pkg/report/predicate"
"github.com/aquasecurity/trivy/pkg/report/spdx"
"github.com/aquasecurity/trivy/pkg/report/table"
"github.com/aquasecurity/trivy/pkg/types"
)
const (
SchemaVersion = 2
)
// Write writes the result to output, format as passed in argument
func Write(ctx context.Context, report types.Report, option flag.Options) (err error) {
output, cleanup, err := option.OutputWriter(ctx)
if err != nil {
return xerrors.Errorf("failed to create a file: %w", err)
}
defer func() {
if cerr := cleanup(); cerr != nil {
err = errors.Join(err, cerr)
}
}()
// Compliance report
if option.Compliance.Spec.ID != "" {
return complianceWrite(ctx, report, option, output)
}
var writer Writer
switch option.Format {
case types.FormatTable:
writer = &table.Writer{
Output: output,
Severities: option.Severities,
Tree: option.DependencyTree,
ShowSuppressed: option.ShowSuppressed,
IncludeNonFailures: option.IncludeNonFailures,
Trace: option.Trace,
LicenseRiskThreshold: option.LicenseRiskThreshold,
IgnoredLicenses: option.IgnoredLicenses,
}
case types.FormatJSON:
writer = &JSONWriter{Output: output}
case types.FormatGitHub:
writer = &github.Writer{
Output: output,
Version: option.AppVersion,
}
case types.FormatCycloneDX:
// TODO: support xml format option with cyclonedx writer
writer = cyclonedx.NewWriter(output, option.AppVersion)
case types.FormatSPDX, types.FormatSPDXJSON:
writer = spdx.NewWriter(output, option.AppVersion, option.Format)
case types.FormatTemplate:
// We keep `sarif.tpl` template working for backward compatibility for a while.
if strings.HasPrefix(option.Template, "@") && strings.HasSuffix(option.Template, "sarif.tpl") {
log.Logger.Warn("Using `--template sarif.tpl` is deprecated. Please migrate to `--format sarif`. See https://github.com/aquasecurity/trivy/discussions/1571")
writer = &SarifWriter{
Output: output,
Version: option.AppVersion,
}
break
}
var err error
if writer, err = NewTemplateWriter(output, option.Template, option.AppVersion); err != nil {
return xerrors.Errorf("failed to initialize template writer: %w", err)
}
case types.FormatSarif:
target := ""
if report.ArtifactType == ftypes.ArtifactFilesystem {
target = option.Target
}
writer = &SarifWriter{
Output: output,
Version: option.AppVersion,
Target: target,
}
case types.FormatCosignVuln:
writer = predicate.NewVulnWriter(output, option.AppVersion)
default:
return xerrors.Errorf("unknown format: %v", option.Format)
}
if err = writer.Write(ctx, report); err != nil {
return xerrors.Errorf("failed to write results: %w", err)
}
return nil
}
func complianceWrite(ctx context.Context, report types.Report, opt flag.Options, output io.Writer) error {
complianceReport, err := cr.BuildComplianceReport([]types.Results{report.Results}, opt.Compliance)
if err != nil {
return xerrors.Errorf("compliance report build error: %w", err)
}
return cr.Write(ctx, complianceReport, cr.Option{
Format: opt.Format,
Report: opt.ReportFormat,
Output: output,
Severities: opt.Severities,
})
}
// Writer defines the result write operation
type Writer interface {
Write(context.Context, types.Report) error
}