github.com/jae-cisco/terraform@v0.11.12-beta1/command/format/diagnostic.go (about) 1 package format 2 3 import ( 4 "bytes" 5 "fmt" 6 7 "github.com/hashicorp/terraform/tfdiags" 8 "github.com/mitchellh/colorstring" 9 wordwrap "github.com/mitchellh/go-wordwrap" 10 ) 11 12 // Diagnostic formats a single diagnostic message. 13 // 14 // The width argument specifies at what column the diagnostic messages will 15 // be wrapped. If set to zero, messages will not be wrapped by this function 16 // at all. Although the long-form text parts of the message are wrapped, 17 // not all aspects of the message are guaranteed to fit within the specified 18 // terminal width. 19 func Diagnostic(diag tfdiags.Diagnostic, color *colorstring.Colorize, width int) string { 20 if diag == nil { 21 // No good reason to pass a nil diagnostic in here... 22 return "" 23 } 24 25 var buf bytes.Buffer 26 27 switch diag.Severity() { 28 case tfdiags.Error: 29 buf.WriteString(color.Color("\n[bold][red]Error: [reset]")) 30 case tfdiags.Warning: 31 buf.WriteString(color.Color("\n[bold][yellow]Warning: [reset]")) 32 default: 33 // Clear out any coloring that might be applied by Terraform's UI helper, 34 // so our result is not context-sensitive. 35 buf.WriteString(color.Color("\n[reset]")) 36 } 37 38 desc := diag.Description() 39 sourceRefs := diag.Source() 40 41 // We don't wrap the summary, since we expect it to be terse, and since 42 // this is where we put the text of a native Go error it may not always 43 // be pure text that lends itself well to word-wrapping. 44 if sourceRefs.Subject != nil { 45 fmt.Fprintf(&buf, color.Color("[bold]%s[reset] at %s\n\n"), desc.Summary, sourceRefs.Subject.StartString()) 46 } else { 47 fmt.Fprintf(&buf, color.Color("[bold]%s[reset]\n\n"), desc.Summary) 48 } 49 50 // TODO: also print out the relevant snippet of config source with the 51 // relevant section highlighted, so the user doesn't need to manually 52 // correlate back to config. Before we can do this, the HCL2 parser 53 // needs to be more deeply integrated so that we can use it to obtain 54 // the parsed source code and AST. 55 56 if desc.Detail != "" { 57 detail := desc.Detail 58 if width != 0 { 59 detail = wordwrap.WrapString(detail, uint(width)) 60 } 61 fmt.Fprintf(&buf, "%s\n", detail) 62 } 63 64 return buf.String() 65 }