github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/pkg/steampipeconfig/errors.go (about) 1 package steampipeconfig 2 3 import ( 4 "fmt" 5 "sort" 6 "strings" 7 8 "github.com/gertd/go-pluralize" 9 "github.com/turbot/steampipe/pkg/steampipeconfig/modconfig" 10 "github.com/turbot/steampipe/pkg/utils" 11 "github.com/turbot/terraform-components/tfdiags" 12 ) 13 14 type MissingVariableError struct { 15 MissingVariables []*modconfig.Variable 16 MissingTransitiveVariables map[DependencyPathKey][]*modconfig.Variable 17 workspaceMod *modconfig.Mod 18 } 19 20 func NewMissingVarsError(workspaceMod *modconfig.Mod) MissingVariableError { 21 return MissingVariableError{ 22 MissingTransitiveVariables: make(map[DependencyPathKey][]*modconfig.Variable), 23 workspaceMod: workspaceMod, 24 } 25 } 26 27 func (m MissingVariableError) Error() string { 28 //allMissing := append(m.MissingVariables, m.MissingTransitiveVariables...) 29 missingCount := len(m.MissingVariables) 30 for _, missing := range m.MissingTransitiveVariables { 31 missingCount += len(missing) 32 } 33 34 return fmt.Sprintf("missing %d variable %s:\n%s%s", 35 missingCount, 36 utils.Pluralize("value", missingCount), 37 m.getVariableMissingString(), 38 m.getTransitiveVariableMissingString(), 39 ) 40 } 41 42 func (m MissingVariableError) getVariableMissingString() string { 43 var sb strings.Builder 44 45 varNames := make([]string, len(m.MissingVariables)) 46 for i, v := range m.MissingVariables { 47 varNames[i] = m.getVariableName(v) 48 } 49 50 // sort names for top level first 51 sort.Slice(varNames, func(i, j int) bool { 52 if len(strings.Split(varNames[i], ".")) < len(strings.Split(varNames[j], ".")) { 53 return true 54 } else { 55 return false 56 } 57 }) 58 59 for _, v := range varNames { 60 sb.WriteString(fmt.Sprintf("\t%s not set\n", v)) 61 } 62 return sb.String() 63 } 64 65 func (m MissingVariableError) getTransitiveVariableMissingString() string { 66 var sb strings.Builder 67 for modPath, missingVars := range m.MissingTransitiveVariables { 68 parentPath := modPath.GetParent() 69 varCount := len(missingVars) 70 71 varNames := make([]string, len(missingVars)) 72 for i, v := range missingVars { 73 varNames[i] = m.getVariableName(v) 74 } 75 76 pluralizer := pluralize.NewClient() 77 pluralizer.AddIrregularRule("has", "have") 78 pluralizer.AddIrregularRule("an arg", "args") 79 varsString := strings.Join(varNames, ",") 80 81 sb.WriteString( 82 fmt.Sprintf("\tdependency mod %s cannot be loaded because %s %s %s no value. Mod %s must pass %s for %s in the `require` block of its mod.sp\n", 83 modPath, 84 pluralizer.Pluralize("variable", varCount, false), 85 varsString, 86 pluralizer.Pluralize("has", varCount, false), 87 parentPath, 88 pluralizer.Pluralize("a value", varCount, false), 89 varsString, 90 )) 91 92 } 93 return sb.String() 94 } 95 96 func (m MissingVariableError) getVariableName(v *modconfig.Variable) string { 97 if v.Mod.Name() == m.workspaceMod.Name() { 98 return v.ShortName 99 } 100 return fmt.Sprintf("%s.%s", v.Mod.ShortName, v.ShortName) 101 } 102 103 type VariableValidationFailedError struct { 104 diags tfdiags.Diagnostics 105 } 106 107 func newVariableValidationFailedError(diags tfdiags.Diagnostics) VariableValidationFailedError { 108 return VariableValidationFailedError{diags: diags} 109 } 110 func (m VariableValidationFailedError) Error() string { 111 var sb strings.Builder 112 113 for i, diag := range m.diags { 114 if diag.Severity() == tfdiags.Error { 115 sb.WriteString(fmt.Sprintf("%s: %s", 116 diag.Description().Summary, 117 diag.Description().Detail)) 118 if i < len(m.diags)-1 { 119 sb.WriteString("\n") 120 } 121 } 122 } 123 return sb.String() 124 }