2023-10-25 11:56:42 +00:00
|
|
|
package diag
|
|
|
|
|
|
|
|
import (
|
2024-10-10 11:18:23 +00:00
|
|
|
"errors"
|
2023-10-25 11:56:42 +00:00
|
|
|
"fmt"
|
|
|
|
|
2023-12-22 13:20:45 +00:00
|
|
|
"github.com/databricks/cli/libs/dyn"
|
2023-10-25 11:56:42 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type Diagnostic struct {
|
|
|
|
Severity Severity
|
|
|
|
|
|
|
|
// Summary is a short description of the diagnostic.
|
|
|
|
// This is expected to be a single line and always present.
|
|
|
|
Summary string
|
|
|
|
|
|
|
|
// Detail is a longer description of the diagnostic.
|
|
|
|
// This may be multiple lines and may be nil.
|
|
|
|
Detail string
|
|
|
|
|
2024-07-23 17:20:11 +00:00
|
|
|
// Locations are the source code locations associated with the diagnostic message.
|
|
|
|
// It may be empty if there are no associated locations.
|
|
|
|
Locations []dyn.Location
|
2024-04-03 08:56:46 +00:00
|
|
|
|
2024-07-25 15:16:27 +00:00
|
|
|
// Paths are paths to the values in the configuration tree that the diagnostic is associated with.
|
|
|
|
// It may be nil if there are no associated paths.
|
|
|
|
Paths []dyn.Path
|
2024-10-10 11:18:23 +00:00
|
|
|
|
|
|
|
// A diagnostic ID. Only used for select diagnostic messages.
|
|
|
|
ID ID
|
2023-10-25 11:56:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Errorf creates a new error diagnostic.
|
|
|
|
func Errorf(format string, args ...any) Diagnostics {
|
|
|
|
return []Diagnostic{
|
|
|
|
{
|
|
|
|
Severity: Error,
|
|
|
|
Summary: fmt.Sprintf(format, args...),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-25 14:18:47 +00:00
|
|
|
// FromErr returns a new error diagnostic from the specified error, if any.
|
|
|
|
func FromErr(err error) Diagnostics {
|
|
|
|
if err == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return []Diagnostic{
|
|
|
|
{
|
|
|
|
Severity: Error,
|
|
|
|
Summary: err.Error(),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-25 11:56:42 +00:00
|
|
|
// Warningf creates a new warning diagnostic.
|
|
|
|
func Warningf(format string, args ...any) Diagnostics {
|
|
|
|
return []Diagnostic{
|
|
|
|
{
|
|
|
|
Severity: Warning,
|
|
|
|
Summary: fmt.Sprintf(format, args...),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Infof creates a new info diagnostic.
|
|
|
|
func Infof(format string, args ...any) Diagnostics {
|
|
|
|
return []Diagnostic{
|
|
|
|
{
|
|
|
|
Severity: Info,
|
|
|
|
Summary: fmt.Sprintf(format, args...),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-10 11:18:23 +00:00
|
|
|
// Diagnostics holds zero or more instances of [Diagnostic].
|
2023-10-25 11:56:42 +00:00
|
|
|
type Diagnostics []Diagnostic
|
|
|
|
|
|
|
|
// Append adds a new diagnostic to the end of the list.
|
|
|
|
func (ds Diagnostics) Append(d Diagnostic) Diagnostics {
|
|
|
|
return append(ds, d)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Extend adds all diagnostics from another list to the end of the list.
|
|
|
|
func (ds Diagnostics) Extend(other Diagnostics) Diagnostics {
|
|
|
|
return append(ds, other...)
|
|
|
|
}
|
|
|
|
|
|
|
|
// HasError returns true if any of the diagnostics are errors.
|
|
|
|
func (ds Diagnostics) HasError() bool {
|
|
|
|
for _, d := range ds {
|
|
|
|
if d.Severity == Error {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
2024-03-25 14:18:47 +00:00
|
|
|
|
|
|
|
// Return first error in the set of diagnostics.
|
|
|
|
func (ds Diagnostics) Error() error {
|
|
|
|
for _, d := range ds {
|
|
|
|
if d.Severity == Error {
|
2024-10-10 11:18:23 +00:00
|
|
|
message := d.Detail
|
|
|
|
if message == "" {
|
|
|
|
message = d.Summary
|
|
|
|
}
|
|
|
|
if d.ID != "" {
|
|
|
|
message = string(d.ID) + ": " + message
|
|
|
|
}
|
|
|
|
return errors.New(message)
|
2024-03-25 14:18:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2024-04-03 15:33:43 +00:00
|
|
|
|
|
|
|
// Filter returns a new list of diagnostics that match the specified severity.
|
|
|
|
func (ds Diagnostics) Filter(severity Severity) Diagnostics {
|
|
|
|
var out Diagnostics
|
|
|
|
for _, d := range ds {
|
|
|
|
if d.Severity == severity {
|
|
|
|
out = append(out, d)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return out
|
|
|
|
}
|