kubeform.dev/terraform-backend-sdk@v0.0.0-20220310143633-45f07fe731c5/configs/version_constraint.go (about)

     1  package configs
     2  
     3  import (
     4  	"fmt"
     5  
     6  	version "github.com/hashicorp/go-version"
     7  	"github.com/hashicorp/hcl/v2"
     8  	"github.com/zclconf/go-cty/cty"
     9  	"github.com/zclconf/go-cty/cty/convert"
    10  )
    11  
    12  // VersionConstraint represents a version constraint on some resource
    13  // (e.g. Terraform Core, a provider, a module, ...) that carries with it
    14  // a source range so that a helpful diagnostic can be printed in the event
    15  // that a particular constraint does not match.
    16  type VersionConstraint struct {
    17  	Required  version.Constraints
    18  	DeclRange hcl.Range
    19  }
    20  
    21  func decodeVersionConstraint(attr *hcl.Attribute) (VersionConstraint, hcl.Diagnostics) {
    22  	ret := VersionConstraint{
    23  		DeclRange: attr.Range,
    24  	}
    25  
    26  	val, diags := attr.Expr.Value(nil)
    27  	if diags.HasErrors() {
    28  		return ret, diags
    29  	}
    30  	var err error
    31  	val, err = convert.Convert(val, cty.String)
    32  	if err != nil {
    33  		diags = append(diags, &hcl.Diagnostic{
    34  			Severity: hcl.DiagError,
    35  			Summary:  "Invalid version constraint",
    36  			Detail:   fmt.Sprintf("A string value is required for %s.", attr.Name),
    37  			Subject:  attr.Expr.Range().Ptr(),
    38  		})
    39  		return ret, diags
    40  	}
    41  
    42  	if val.IsNull() {
    43  		// A null version constraint is strange, but we'll just treat it
    44  		// like an empty constraint set.
    45  		return ret, diags
    46  	}
    47  
    48  	if !val.IsWhollyKnown() {
    49  		// If there is a syntax error, HCL sets the value of the given attribute
    50  		// to cty.DynamicVal. A diagnostic for the syntax error will already
    51  		// bubble up, so we will move forward gracefully here.
    52  		return ret, diags
    53  	}
    54  
    55  	constraintStr := val.AsString()
    56  	constraints, err := version.NewConstraint(constraintStr)
    57  	if err != nil {
    58  		// NewConstraint doesn't return user-friendly errors, so we'll just
    59  		// ignore the provided error and produce our own generic one.
    60  		diags = append(diags, &hcl.Diagnostic{
    61  			Severity: hcl.DiagError,
    62  			Summary:  "Invalid version constraint",
    63  			Detail:   "This string does not use correct version constraint syntax.", // Not very actionable :(
    64  			Subject:  attr.Expr.Range().Ptr(),
    65  		})
    66  		return ret, diags
    67  	}
    68  
    69  	ret.Required = constraints
    70  	return ret, diags
    71  }