kcl-lang.io/kpm@v0.8.7-0.20240520061008-9fc4c5efc8c7/pkg/semver/semver.go (about)

     1  package semver
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/hashicorp/go-version"
     7  	"kcl-lang.io/kpm/pkg/constants"
     8  	"kcl-lang.io/kpm/pkg/errors"
     9  	"kcl-lang.io/kpm/pkg/reporter"
    10  )
    11  
    12  func LatestVersion(versions []string) (string, error) {
    13  	var latest *version.Version
    14  	for _, v := range versions {
    15  		// Do not support the latest version.
    16  		if v == constants.LATEST {
    17  			continue
    18  		}
    19  		ver, err := version.NewVersion(v)
    20  		if err != nil {
    21  			return "", reporter.NewErrorEvent(reporter.FailedParseVersion, err, fmt.Sprintf("failed to parse version %s", v))
    22  		}
    23  		if latest == nil || ver.GreaterThan(latest) {
    24  			latest = ver
    25  		}
    26  	}
    27  
    28  	if latest == nil {
    29  		return "", errors.InvalidVersionFormat
    30  	}
    31  
    32  	return latest.Original(), nil
    33  }
    34  
    35  func OldestVersion(versions []string) (string, error) {
    36  	var oldest *version.Version
    37  	for _, v := range versions {
    38  		ver, err := version.NewVersion(v)
    39  		if err != nil {
    40  			return "", reporter.NewErrorEvent(reporter.FailedParseVersion, err, fmt.Sprintf("failed to parse version %s", v))
    41  		}
    42  		if oldest == nil || ver.LessThan(oldest) {
    43  			oldest = ver
    44  		}
    45  	}
    46  
    47  	if oldest == nil {
    48  		return "", errors.InvalidVersionFormat
    49  	}
    50  
    51  	return oldest.Original(), nil
    52  }
    53  
    54  func filterCompatibleVersions(versions []string, baseVersion string) ([]string, error) {
    55  	base, err := version.NewVersion(baseVersion)
    56  	if err != nil {
    57  		return nil, fmt.Errorf("invalid base version: %v", err)
    58  	}
    59  	var compatibleVersions []string
    60  	for _, v := range versions {
    61  		ver, err := version.NewVersion(v)
    62  		if err != nil {
    63  			continue // skip versions that fail to parse
    64  		}
    65  		if ver.Segments()[0] == base.Segments()[0] && ver.Prerelease() == "" {
    66  			compatibleVersions = append(compatibleVersions, ver.Original())
    67  		}
    68  	}
    69  	return compatibleVersions, nil
    70  }
    71  
    72  func LatestCompatibleVersion(versions []string, baseVersion string) (string, error) {
    73  	compatibleVersions, err := filterCompatibleVersions(versions, baseVersion)
    74  	if err != nil {
    75  		return "", err
    76  	}
    77  	return LatestVersion(compatibleVersions)
    78  }
    79  
    80  func LeastOldCompatibleVersion(versions []string, baseVersion string) (string, error) {
    81  	compatibleVersions, err := filterCompatibleVersions(versions, baseVersion)
    82  	if err != nil {
    83  		return "", err
    84  	}
    85  	return OldestVersion(compatibleVersions)
    86  }