package module import ( "errors" "fmt" "sort" version "github.com/hashicorp/go-version" "github.com/hashicorp/terraform/registry/response" ) const anyVersion = ">=0.0.0" // return the newest version that satisfies the provided constraint func newest(versions []string, constraint string) (string, error) { if constraint == "" { constraint = anyVersion } cs, err := version.NewConstraint(constraint) if err != nil { return "", err } switch len(versions) { case 0: return "", errors.New("no versions found") case 1: v, err := version.NewVersion(versions[0]) if err != nil { return "", err } if !cs.Check(v) { return "", fmt.Errorf("no version found matching constraint %q", constraint) } return versions[0], nil } sort.Slice(versions, func(i, j int) bool { // versions should have already been validated // sort invalid version strings to the end iv, err := version.NewVersion(versions[i]) if err != nil { return true } jv, err := version.NewVersion(versions[j]) if err != nil { return true } return iv.GreaterThan(jv) }) // versions are now in order, so just find the first which satisfies the // constraint for i := range versions { v, err := version.NewVersion(versions[i]) if err != nil { continue } if cs.Check(v) { return versions[i], nil } } return "", nil } // return the newest *moduleVersion that matches the given constraint // TODO: reconcile these two types and newest* functions func newestVersion(moduleVersions []*response.ModuleVersion, constraint string) (*response.ModuleVersion, error) { var versions []string modules := make(map[string]*response.ModuleVersion) for _, m := range moduleVersions { versions = append(versions, m.Version) modules[m.Version] = m } match, err := newest(versions, constraint) return modules[match], err } // return the newest moduleRecord that matches the given constraint func newestRecord(moduleVersions []moduleRecord, constraint string) (moduleRecord, error) { var versions []string modules := make(map[string]moduleRecord) for _, m := range moduleVersions { versions = append(versions, m.Version) modules[m.Version] = m } match, err := newest(versions, constraint) return modules[match], err }