Files
ReleaseKit/internal/validation/diagnostic.go

111 lines
2.9 KiB
Go

package validation
import (
"fmt"
"strings"
)
// Check identifies one shared validation check.
type Check string
const (
// GoTest identifies the base Go test suite.
GoTest Check = "go-test"
// GoVet identifies the separate full vet pass.
GoVet Check = "go-vet"
// PackageCompile identifies selected-target package compilation.
PackageCompile Check = "package-compile"
// GoFormat identifies committed Go source formatting.
GoFormat Check = "go-format"
// WorkspaceFiles identifies committed workspace files in module source.
WorkspaceFiles Check = "workspace-files"
// LocalReplacements identifies filesystem replacements in committed modules.
LocalReplacements Check = "local-replacements"
// FileSize identifies committed blobs that exceed a selected size limit.
FileSize Check = "file-size"
)
// Finding describes a validation observation at an optional source location.
type Finding struct {
Path string
Line int
Column int
Message string
Target string
Directive string
}
// FileSizeMeasurement describes a measured file size and its selected limit.
type FileSizeMeasurement struct {
Bytes int64
LimitBytes int64
}
// Failure describes a failed shared validation check and preserves its cause.
type Failure struct {
Check Check
Findings []Finding
Measurement *FileSizeMeasurement
Cause error
}
// Error returns a useful summary of the failed check.
func (failure *Failure) Error() string {
return formatFailure(failure)
}
// Unwrap returns the underlying validation error.
func (failure *Failure) Unwrap() error {
if failure == nil {
return nil
}
return failure.Cause
}
func formatFailure(failure *Failure) string {
if failure == nil {
return "<nil>"
}
var summary strings.Builder
if failure.Check == "" {
summary.WriteString("validation failed")
} else {
fmt.Fprintf(&summary, "%s validation failed", failure.Check)
}
for _, finding := range failure.Findings {
summary.WriteString(": ")
if finding.Path != "" {
summary.WriteString(finding.Path)
if finding.Line > 0 {
fmt.Fprintf(&summary, ":%d", finding.Line)
if finding.Column > 0 {
fmt.Fprintf(&summary, ":%d", finding.Column)
}
}
summary.WriteString(": ")
}
summary.WriteString(finding.Message)
if finding.Target != "" {
fmt.Fprintf(&summary, " (target %q)", finding.Target)
}
if finding.Directive != "" {
fmt.Fprintf(&summary, " (directive %q)", finding.Directive)
}
}
if failure.Measurement != nil {
fmt.Fprintf(&summary, ": measured %d bytes against a %d byte limit", failure.Measurement.Bytes, failure.Measurement.LimitBytes)
}
if failure.Cause != nil {
if len(failure.Findings) == 0 && failure.Measurement == nil {
summary.WriteString(": ")
} else {
summary.WriteString("; ")
}
summary.WriteString(failure.Cause.Error())
}
return summary.String()
}
var _ error = (*Failure)(nil)
var _ interface{ Unwrap() error } = (*Failure)(nil)