mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-09-18 17:19:58 +00:00
139 lines
3.5 KiB
Go
139 lines
3.5 KiB
Go
|
package tfconfig
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
|
||
|
legacyhclparser "github.com/hashicorp/hcl/hcl/parser"
|
||
|
"github.com/hashicorp/hcl2/hcl"
|
||
|
)
|
||
|
|
||
|
// Diagnostic describes a problem (error or warning) encountered during
|
||
|
// configuration loading.
|
||
|
type Diagnostic struct {
|
||
|
Severity DiagSeverity `json:"severity"`
|
||
|
Summary string `json:"summary"`
|
||
|
Detail string `json:"detail,omitempty"`
|
||
|
|
||
|
// Pos is not populated for all diagnostics, but when populated should
|
||
|
// indicate a particular line that the described problem relates to.
|
||
|
Pos *SourcePos `json:"pos,omitempty"`
|
||
|
}
|
||
|
|
||
|
// Diagnostics represents a sequence of diagnostics. This is the type that
|
||
|
// should be returned from a function that might generate diagnostics.
|
||
|
type Diagnostics []Diagnostic
|
||
|
|
||
|
// HasErrors returns true if there is at least one Diagnostic of severity
|
||
|
// DiagError in the receiever.
|
||
|
//
|
||
|
// If a function returns a Diagnostics without errors then the result can
|
||
|
// be assumed to be complete within the "best effort" constraints of this
|
||
|
// library. If errors are present then the caller may wish to employ more
|
||
|
// caution in relying on the result.
|
||
|
func (diags Diagnostics) HasErrors() bool {
|
||
|
for _, diag := range diags {
|
||
|
if diag.Severity == DiagError {
|
||
|
return true
|
||
|
}
|
||
|
}
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
func (diags Diagnostics) Error() string {
|
||
|
switch len(diags) {
|
||
|
case 0:
|
||
|
return "no problems"
|
||
|
case 1:
|
||
|
return fmt.Sprintf("%s: %s", diags[0].Summary, diags[0].Detail)
|
||
|
default:
|
||
|
return fmt.Sprintf("%s: %s (and %d other messages)", diags[0].Summary, diags[0].Detail, len(diags)-1)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Err returns an error representing the receiver if the receiver HasErrors, or
|
||
|
// nil otherwise.
|
||
|
//
|
||
|
// The returned error can be type-asserted back to a Diagnostics if needed.
|
||
|
func (diags Diagnostics) Err() error {
|
||
|
if diags.HasErrors() {
|
||
|
return diags
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// DiagSeverity describes the severity of a Diagnostic.
|
||
|
type DiagSeverity rune
|
||
|
|
||
|
// DiagError indicates a problem that prevented proper processing of the
|
||
|
// configuration. In the precense of DiagError diagnostics the result is
|
||
|
// likely to be incomplete.
|
||
|
const DiagError DiagSeverity = 'E'
|
||
|
|
||
|
// DiagWarning indicates a problem that the user may wish to consider but
|
||
|
// that did not prevent proper processing of the configuration.
|
||
|
const DiagWarning DiagSeverity = 'W'
|
||
|
|
||
|
// MarshalJSON is an implementation of encoding/json.Marshaler
|
||
|
func (s DiagSeverity) MarshalJSON() ([]byte, error) {
|
||
|
switch s {
|
||
|
case DiagError:
|
||
|
return []byte(`"error"`), nil
|
||
|
case DiagWarning:
|
||
|
return []byte(`"warning"`), nil
|
||
|
default:
|
||
|
return []byte(`"invalid"`), nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func diagnosticsHCL(diags hcl.Diagnostics) Diagnostics {
|
||
|
if len(diags) == 0 {
|
||
|
return nil
|
||
|
}
|
||
|
ret := make(Diagnostics, len(diags))
|
||
|
for i, diag := range diags {
|
||
|
ret[i] = Diagnostic{
|
||
|
Summary: diag.Summary,
|
||
|
Detail: diag.Detail,
|
||
|
}
|
||
|
switch diag.Severity {
|
||
|
case hcl.DiagError:
|
||
|
ret[i].Severity = DiagError
|
||
|
case hcl.DiagWarning:
|
||
|
ret[i].Severity = DiagWarning
|
||
|
}
|
||
|
if diag.Subject != nil {
|
||
|
pos := sourcePosHCL(*diag.Subject)
|
||
|
ret[i].Pos = &pos
|
||
|
}
|
||
|
}
|
||
|
return ret
|
||
|
}
|
||
|
|
||
|
func diagnosticsError(err error) Diagnostics {
|
||
|
if err == nil {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
if posErr, ok := err.(*legacyhclparser.PosError); ok {
|
||
|
pos := sourcePosLegacyHCL(posErr.Pos, "")
|
||
|
return Diagnostics{
|
||
|
Diagnostic{
|
||
|
Severity: DiagError,
|
||
|
Summary: posErr.Err.Error(),
|
||
|
Pos: &pos,
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return Diagnostics{
|
||
|
Diagnostic{
|
||
|
Severity: DiagError,
|
||
|
Summary: err.Error(),
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func diagnosticsErrorf(format string, args ...interface{}) Diagnostics {
|
||
|
return diagnosticsError(fmt.Errorf(format, args...))
|
||
|
}
|