v0.115.0: version-aware Supports (agent header channel) + DSM-validated NFS guidance — MinAgent: 0.81.0
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
package util
|
||||
|
||||
// Semantic-version parsing + comparison — THE one comparator in this repo (house rule: never a
|
||||
// second one). Moved verbatim from internal/selfupdate/version.go (v0.115.0) so that BOTH
|
||||
// selfupdate (floor/update decisions) and agentapi (the per-feature MinAgent capability
|
||||
// comparison) share it without an import cycle (selfupdate imports agentapi). selfupdate keeps
|
||||
// aliases, so its call sites and tests are unchanged.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Version represents a semantic version (Major.Minor.Patch).
|
||||
type Version struct {
|
||||
Major int
|
||||
Minor int
|
||||
Patch int
|
||||
Raw string
|
||||
}
|
||||
|
||||
// ParseVersion parses "X.Y.Z" or "vX.Y.Z". Returns error for "dev", "latest", or invalid formats.
|
||||
func ParseVersion(s string) (Version, error) {
|
||||
s = strings.TrimPrefix(s, "v")
|
||||
if s == "dev" || s == "latest" || s == "" {
|
||||
return Version{}, fmt.Errorf("invalid version: %q", s)
|
||||
}
|
||||
parts := strings.SplitN(s, ".", 3)
|
||||
if len(parts) != 3 {
|
||||
return Version{}, fmt.Errorf("invalid version format: %q (expected X.Y.Z)", s)
|
||||
}
|
||||
major, err := strconv.Atoi(parts[0])
|
||||
if err != nil {
|
||||
return Version{}, fmt.Errorf("invalid major version: %w", err)
|
||||
}
|
||||
minor, err := strconv.Atoi(parts[1])
|
||||
if err != nil {
|
||||
return Version{}, fmt.Errorf("invalid minor version: %w", err)
|
||||
}
|
||||
patch, err := strconv.Atoi(parts[2])
|
||||
if err != nil {
|
||||
return Version{}, fmt.Errorf("invalid patch version: %w", err)
|
||||
}
|
||||
return Version{Major: major, Minor: minor, Patch: patch, Raw: s}, nil
|
||||
}
|
||||
|
||||
// Compare returns -1 if a < b, 0 if a == b, 1 if a > b.
|
||||
func (a Version) Compare(b Version) int {
|
||||
if a.Major != b.Major {
|
||||
if a.Major < b.Major {
|
||||
return -1
|
||||
}
|
||||
return 1
|
||||
}
|
||||
if a.Minor != b.Minor {
|
||||
if a.Minor < b.Minor {
|
||||
return -1
|
||||
}
|
||||
return 1
|
||||
}
|
||||
if a.Patch != b.Patch {
|
||||
if a.Patch < b.Patch {
|
||||
return -1
|
||||
}
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// String returns the version as "X.Y.Z".
|
||||
func (v Version) String() string {
|
||||
return fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch)
|
||||
}
|
||||
Reference in New Issue
Block a user