mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-29 22:06:38 +08:00
8ff017b5e8
下游 OpenFlare 的边缘守护进程与发布流程需要这些与业务无关的纯函数, 按上游/下游归属规约回流到平台层,避免下游在上游目录里长期携带本地文件: - version / version_compare:CompareVersions、ParseVersionInfo(版本区间比较) - network:GetIP、IsPrivateIPv4 - format / value / string / slice:Bytes2Size、Seconds2Time、Interface2String、 TrimStringFields、UniqueAndCleanStringSlice 与 IdentifiableTimeRecord 验证:go build 通过;go test ./... exit 0(48 包 ok); check_cordis_architecture.sh 0 violations;golangci-lint 0 issues;gofmt 干净。
130 lines
3.3 KiB
Go
130 lines
3.3 KiB
Go
// Copyright 2026 Arctel.net
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package util
|
|
|
|
import (
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
const gitDescribeMinIdentifiers = 2
|
|
|
|
// VersionInfo holds the parsed components of a semantic version string.
|
|
type VersionInfo struct {
|
|
Valid bool
|
|
IsDev bool
|
|
Numbers []int
|
|
Prerelease []string
|
|
GitDescribeDistance int
|
|
GitDescribeTail []string
|
|
}
|
|
|
|
// ParseVersionInfo parses a version string into a structured VersionInfo.
|
|
func ParseVersionInfo(version string) VersionInfo {
|
|
normalized := strings.TrimSpace(strings.TrimPrefix(version, "v"))
|
|
if normalized == "" || normalized == "dev" {
|
|
return VersionInfo{IsDev: strings.EqualFold(normalized, "dev")}
|
|
}
|
|
base := normalized
|
|
prerelease := ""
|
|
if separator := strings.IndexRune(normalized, '-'); separator >= 0 {
|
|
base = normalized[:separator]
|
|
prerelease = normalized[separator+1:]
|
|
}
|
|
|
|
segments := strings.Split(base, ".")
|
|
parts := make([]int, 0, len(segments))
|
|
for _, segment := range segments {
|
|
segment = strings.TrimSpace(segment)
|
|
if segment == "" {
|
|
parts = append(parts, 0)
|
|
continue
|
|
}
|
|
|
|
numeric := strings.Builder{}
|
|
for _, r := range segment {
|
|
if r < '0' || r > '9' {
|
|
break
|
|
}
|
|
numeric.WriteRune(r)
|
|
}
|
|
if numeric.Len() == 0 {
|
|
parts = append(parts, 0)
|
|
continue
|
|
}
|
|
value, err := strconv.Atoi(numeric.String())
|
|
if err != nil {
|
|
return VersionInfo{}
|
|
}
|
|
parts = append(parts, value)
|
|
}
|
|
info := VersionInfo{Valid: len(parts) > 0, Numbers: parts}
|
|
if prerelease != "" {
|
|
identifiers := splitPrereleaseIdentifiers(prerelease)
|
|
if distance, tail, ok := parseGitDescribeIdentifiers(identifiers); ok {
|
|
info.GitDescribeDistance = distance
|
|
info.GitDescribeTail = tail
|
|
} else {
|
|
info.Prerelease = identifiers
|
|
}
|
|
}
|
|
return info
|
|
}
|
|
|
|
func parseGitDescribeIdentifiers(identifiers []string) (int, []string, bool) {
|
|
if len(identifiers) < gitDescribeMinIdentifiers {
|
|
return 0, nil, false
|
|
}
|
|
distance, err := strconv.Atoi(strings.TrimSpace(identifiers[0]))
|
|
if err != nil || distance <= 0 {
|
|
return 0, nil, false
|
|
}
|
|
commitToken := strings.TrimSpace(identifiers[1])
|
|
if commitToken == "" || !strings.HasPrefix(strings.ToLower(commitToken), "g") {
|
|
return 0, nil, false
|
|
}
|
|
return distance, identifiers[1:], true
|
|
}
|
|
|
|
func splitPrereleaseIdentifiers(value string) []string {
|
|
parts := strings.FieldsFunc(strings.TrimSpace(value), func(r rune) bool {
|
|
return r == '.' || r == '-'
|
|
})
|
|
filtered := make([]string, 0, len(parts))
|
|
for _, part := range parts {
|
|
part = strings.TrimSpace(part)
|
|
if part != "" {
|
|
filtered = append(filtered, part)
|
|
}
|
|
}
|
|
return filtered
|
|
}
|
|
|
|
// CompareVersions compares two version strings.
|
|
// Returns -1 if left < right, 1 if left > right, and 0 if they are equal.
|
|
func CompareVersions(local, remote string) int {
|
|
left := ParseVersionInfo(local)
|
|
right := ParseVersionInfo(remote)
|
|
if left.IsDev {
|
|
if right.Valid {
|
|
return -1
|
|
}
|
|
return 0
|
|
}
|
|
if !left.Valid || !right.Valid {
|
|
return 0
|
|
}
|
|
|
|
if result := compareVersionNumbers(left, right); result != 0 {
|
|
return result
|
|
}
|
|
if result := compareGitDescribeDistance(left, right); result != 0 {
|
|
return result
|
|
}
|
|
if left.GitDescribeDistance > 0 || right.GitDescribeDistance > 0 {
|
|
return compareGitDescribeTails(left, right)
|
|
}
|
|
return comparePrereleaseIdentifiers(left, right)
|
|
}
|