feat(version): 第18条 显示版本与内部版本解耦(V/A 双系)

- config 新增 displayVersion 注入变量(默认 1.0.0):GetDisplayVersion/
  GetMasterDisplayVersion(V)/GetAgentDisplayVersion(A),以后升版只改注入值
- ParseDisplayVersion/CompareDisplayVersion:三段数值比较,个位进位规则
  (1.0.9<1.1.0) 天然成立;不可解析(dev 标签/3.7.0-agent.1)返回 ok=false
- 显示位切换:dist 注入 X_UI_CUR_VER、-v、TG 报告 → V 系;
  agent 遥测 agentVersion → A 系;节点行 A 系原样显示、老 agent 沿用
  "agent " 前缀兼容
- 内部流不动:GetBaseVersion/GetPanelVersion 及其比较/订阅/远端状态
  消费方保持原样,传统节点更新判定与徽标行为不变
This commit is contained in:
Muse
2026-10-22 13:01:50 +00:00
parent e5f39ed20b
commit 1edb8f71da
7 changed files with 186 additions and 5 deletions
+72
View File
@@ -53,6 +53,78 @@ func TestGetBaseVersionBuildVersionOverride(t *testing.T) {
}
}
func TestDisplayVersionDefaultsAndOverride(t *testing.T) {
orig := displayVersion
t.Cleanup(func() { displayVersion = orig })
displayVersion = ""
if got := GetDisplayVersion(); got != "1.0.0" {
t.Fatalf("default display version = %q, want 1.0.0", got)
}
if got := GetMasterDisplayVersion(); got != "V1.0.0" {
t.Fatalf("default master display version = %q, want V1.0.0", got)
}
if got := GetAgentDisplayVersion(); got != "A1.0.0" {
t.Fatalf("default agent display version = %q, want A1.0.0", got)
}
displayVersion = "1.0.1"
if got := GetMasterDisplayVersion(); got != "V1.0.1" {
t.Fatalf("injected master display version = %q, want V1.0.1", got)
}
if got := GetAgentDisplayVersion(); got != "A1.0.1" {
t.Fatalf("injected agent display version = %q, want A1.0.1", got)
}
}
func TestParseDisplayVersion(t *testing.T) {
valid := map[string][3]int{
"1.0.0": {1, 0, 0},
"V1.0.0": {1, 0, 0},
"A1.0.9": {1, 0, 9},
"v2.0.0": {2, 0, 0},
" 1.2.3 ": {1, 2, 3},
}
for in, want := range valid {
got, ok := ParseDisplayVersion(in)
if !ok || got != want {
t.Fatalf("ParseDisplayVersion(%q) = %v, %v; want %v, true", in, got, ok, want)
}
}
invalid := []string{"", "3.7.0-agent.1", "dev+1a2b3c4d", "1.0", "1.0.0.1", "1.x.0", "V", "1..0"}
for _, in := range invalid {
if _, ok := ParseDisplayVersion(in); ok {
t.Fatalf("ParseDisplayVersion(%q) ok=true, want false", in)
}
}
}
func TestCompareDisplayVersion(t *testing.T) {
cases := []struct {
a, b string
want int
}{
{"1.0.0", "1.0.0", 0},
{"V1.0.0", "A1.0.0", 0}, // prefix letters are flavour, not value
{"1.0.9", "1.1.0", -1}, // single-digit carry step
{"1.1.0", "1.0.9", 1}, // carry compares numerically, not lexically
{"1.9.9", "2.0.0", -1}, // full carry
{"A1.0.1", "A1.0.0", 1}, // agent series
{"V1.0.1", "1.0.0", 1}, // release tag vs current
{"2.0.0", "1.9.9", 1},
{"1.0.0", "1.0.1", -1},
}
for _, tc := range cases {
got, ok := CompareDisplayVersion(tc.a, tc.b)
if !ok || got != tc.want {
t.Fatalf("CompareDisplayVersion(%q, %q) = %d, %v; want %d, true", tc.a, tc.b, got, ok, tc.want)
}
}
if _, ok := CompareDisplayVersion("3.7.0-agent.1", "1.0.0"); ok {
t.Fatal("unparseable side must report ok=false")
}
}
func TestGetPortOverride(t *testing.T) {
tests := []struct {
name string