github.com/cmalfait/terraform@v0.11.12-beta1/config/module/versions.go (about)

     1  package module
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"sort"
     7  
     8  	version "github.com/hashicorp/go-version"
     9  	"github.com/hashicorp/terraform/registry/response"
    10  )
    11  
    12  const anyVersion = ">=0.0.0"
    13  
    14  // return the newest version that satisfies the provided constraint
    15  func newest(versions []string, constraint string) (string, error) {
    16  	if constraint == "" {
    17  		constraint = anyVersion
    18  	}
    19  	cs, err := version.NewConstraint(constraint)
    20  	if err != nil {
    21  		return "", err
    22  	}
    23  
    24  	switch len(versions) {
    25  	case 0:
    26  		return "", errors.New("no versions found")
    27  	case 1:
    28  		v, err := version.NewVersion(versions[0])
    29  		if err != nil {
    30  			return "", err
    31  		}
    32  
    33  		if !cs.Check(v) {
    34  			return "", fmt.Errorf("no version found matching constraint %q", constraint)
    35  		}
    36  		return versions[0], nil
    37  	}
    38  
    39  	sort.Slice(versions, func(i, j int) bool {
    40  		// versions should have already been validated
    41  		// sort invalid version strings to the end
    42  		iv, err := version.NewVersion(versions[i])
    43  		if err != nil {
    44  			return true
    45  		}
    46  		jv, err := version.NewVersion(versions[j])
    47  		if err != nil {
    48  			return true
    49  		}
    50  		return iv.GreaterThan(jv)
    51  	})
    52  
    53  	// versions are now in order, so just find the first which satisfies the
    54  	// constraint
    55  	for i := range versions {
    56  		v, err := version.NewVersion(versions[i])
    57  		if err != nil {
    58  			continue
    59  		}
    60  		if cs.Check(v) {
    61  			return versions[i], nil
    62  		}
    63  	}
    64  
    65  	return "", nil
    66  }
    67  
    68  // return the newest *moduleVersion that matches the given constraint
    69  // TODO: reconcile these two types and newest* functions
    70  func newestVersion(moduleVersions []*response.ModuleVersion, constraint string) (*response.ModuleVersion, error) {
    71  	var versions []string
    72  	modules := make(map[string]*response.ModuleVersion)
    73  
    74  	for _, m := range moduleVersions {
    75  		versions = append(versions, m.Version)
    76  		modules[m.Version] = m
    77  	}
    78  
    79  	match, err := newest(versions, constraint)
    80  	return modules[match], err
    81  }
    82  
    83  // return the newest moduleRecord that matches the given constraint
    84  func newestRecord(moduleVersions []moduleRecord, constraint string) (moduleRecord, error) {
    85  	var versions []string
    86  	modules := make(map[string]moduleRecord)
    87  
    88  	for _, m := range moduleVersions {
    89  		versions = append(versions, m.Version)
    90  		modules[m.Version] = m
    91  	}
    92  
    93  	match, err := newest(versions, constraint)
    94  	return modules[match], err
    95  }