mirror of
https://github.com/komari-monitor/komari.git
synced 2026-11-12 01:00:51 +00:00
90 lines
1.9 KiB
Go
90 lines
1.9 KiB
Go
package plugin
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/komari-monitor/komari/utils"
|
|
)
|
|
|
|
// CheckKomariVersion validates a manifest komari constraint against the
|
|
// running server version. Supported constraints: empty (any version),
|
|
// "x.y.z" (exact), and ">=x.y.z", ">x.y.z", "<=x.y.z", "<x.y.z". An optional
|
|
// leading "v" is accepted.
|
|
func CheckKomariVersion(constraint string) error {
|
|
constraint = strings.TrimSpace(constraint)
|
|
if constraint == "" {
|
|
return nil
|
|
}
|
|
rest := constraint
|
|
op := ""
|
|
for _, candidate := range []string{">=", "<=", ">", "<", "="} {
|
|
if strings.HasPrefix(rest, candidate) {
|
|
op = candidate
|
|
rest = strings.TrimSpace(strings.TrimPrefix(rest, candidate))
|
|
break
|
|
}
|
|
}
|
|
want, err := parseSemver(rest)
|
|
if err != nil {
|
|
return fmt.Errorf("invalid komari version constraint %q: %w", constraint, err)
|
|
}
|
|
have, err := parseSemver(utils.CurrentVersion)
|
|
if err != nil {
|
|
// A malformed server version must not block plugin loading.
|
|
return nil
|
|
}
|
|
if !satisfies(compareSemver(have, want), op) {
|
|
return fmt.Errorf("plugin requires komari %s, running %s", constraint, utils.CurrentVersion)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func satisfies(cmp int, op string) bool {
|
|
switch op {
|
|
case ">=":
|
|
return cmp >= 0
|
|
case ">":
|
|
return cmp > 0
|
|
case "<=":
|
|
return cmp <= 0
|
|
case "<":
|
|
return cmp < 0
|
|
default: // exact
|
|
return cmp == 0
|
|
}
|
|
}
|
|
|
|
func parseSemver(s string) ([3]int, error) {
|
|
s = strings.TrimSpace(strings.TrimPrefix(s, "v"))
|
|
if s == "" {
|
|
return [3]int{}, fmt.Errorf("empty version")
|
|
}
|
|
parts := strings.Split(s, ".")
|
|
if len(parts) > 3 {
|
|
return [3]int{}, fmt.Errorf("too many version parts")
|
|
}
|
|
var v [3]int
|
|
for i, part := range parts {
|
|
n, err := strconv.Atoi(part)
|
|
if err != nil || n < 0 {
|
|
return [3]int{}, fmt.Errorf("invalid version part %q", part)
|
|
}
|
|
v[i] = n
|
|
}
|
|
return v, nil
|
|
}
|
|
|
|
func compareSemver(a, b [3]int) int {
|
|
for i := 0; i < 3; i++ {
|
|
if a[i] < b[i] {
|
|
return -1
|
|
}
|
|
if a[i] > b[i] {
|
|
return 1
|
|
}
|
|
}
|
|
return 0
|
|
}
|