79 lines
1.7 KiB
Go
79 lines
1.7 KiB
Go
/*
|
|
©AngelaMos | 2026
|
|
reporter.go
|
|
|
|
Reporter interface and factory that dispatches to format-specific
|
|
implementations
|
|
|
|
NewReporter selects and constructs a TerminalReporter, JSONReporter,
|
|
SARIFReporter, or JUnitReporter based on the format string. When
|
|
outputFile is empty, output goes to stdout. baseReporter holds the
|
|
shared writer and closer for the concrete implementations.
|
|
|
|
Key exports:
|
|
Reporter - interface with Report(findings Collection) error
|
|
NewReporter - factory returning the correct implementation
|
|
|
|
Connects to:
|
|
scanner.go - calls NewReporter with cfg.Output and cfg.OutputFile
|
|
terminal.go, json.go, sarif.go, junit.go - implement Reporter
|
|
finding.go - Report() accepts finding.Collection
|
|
*/
|
|
|
|
package report
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
|
|
"github.com/CarterPerez-dev/docksec/internal/finding"
|
|
)
|
|
|
|
type Reporter interface {
|
|
Report(findings finding.Collection) error
|
|
}
|
|
|
|
func NewReporter(format, outputFile string) (Reporter, error) {
|
|
var w io.Writer = os.Stdout
|
|
var closer func() error
|
|
|
|
if outputFile != "" {
|
|
f, err := os.Create(outputFile)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("creating output file: %w", err)
|
|
}
|
|
w = f
|
|
closer = f.Close
|
|
}
|
|
|
|
switch format {
|
|
case "terminal", "":
|
|
return &TerminalReporter{
|
|
w: w,
|
|
closer: closer,
|
|
colored: outputFile == "",
|
|
}, nil
|
|
case "json":
|
|
return &JSONReporter{w: w, closer: closer}, nil
|
|
case "sarif":
|
|
return &SARIFReporter{w: w, closer: closer}, nil
|
|
case "junit":
|
|
return &JUnitReporter{w: w, closer: closer}, nil
|
|
default:
|
|
return nil, fmt.Errorf("unsupported output format: %s", format)
|
|
}
|
|
}
|
|
|
|
type baseReporter struct {
|
|
w io.Writer
|
|
closer func() error
|
|
}
|
|
|
|
func (r *baseReporter) close() error {
|
|
if r.closer != nil {
|
|
return r.closer()
|
|
}
|
|
return nil
|
|
}
|