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  }