- 修改版本比较逻辑,优先比较主版本号,然后是次版本号和修订号 - 增加对 beta版本的特殊处理,正式版比 beta 版更新 - 优化版本显示格式,移除不必要的 "v" 前缀 - 在主界面和日志中使用优化后的版本显示格式
190 lines
5.2 KiB
Go
190 lines
5.2 KiB
Go
package version
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"os"
|
||
"path/filepath"
|
||
"strconv"
|
||
"strings"
|
||
|
||
"AUTO_MAA_Go_Updater/logger"
|
||
)
|
||
|
||
// VersionInfo 表示来自 version.json 的版本信息
|
||
type VersionInfo struct {
|
||
MainVersion string `json:"main_version"`
|
||
VersionInfo map[string]map[string][]string `json:"version_info"`
|
||
}
|
||
|
||
// ParsedVersion 表示解析后的版本,包含主版本号、次版本号、补丁版本号和测试版本号组件
|
||
type ParsedVersion struct {
|
||
Major int
|
||
Minor int
|
||
Patch int
|
||
Beta int
|
||
}
|
||
|
||
// VersionManager 处理版本相关操作
|
||
type VersionManager struct {
|
||
executableDir string
|
||
logger logger.Logger
|
||
}
|
||
|
||
// NewVersionManager 创建新的版本管理器
|
||
func NewVersionManager() *VersionManager {
|
||
execPath, _ := os.Executable()
|
||
execDir := filepath.Dir(execPath)
|
||
return &VersionManager{
|
||
executableDir: execDir,
|
||
logger: logger.GetDefaultLogger(),
|
||
}
|
||
}
|
||
|
||
// createDefaultVersion 创建默认版本结构 v0.0.0
|
||
func (vm *VersionManager) createDefaultVersion() *VersionInfo {
|
||
return &VersionInfo{
|
||
MainVersion: "0.0.0.0", // 对应 v0.0.0
|
||
VersionInfo: make(map[string]map[string][]string),
|
||
}
|
||
}
|
||
|
||
// LoadVersionFromFile 从 resources/version.json 加载版本信息并处理回退
|
||
func (vm *VersionManager) LoadVersionFromFile() (*VersionInfo, error) {
|
||
versionPath := filepath.Join(vm.executableDir, "resources", "version.json")
|
||
|
||
data, err := os.ReadFile(versionPath)
|
||
if err != nil {
|
||
if os.IsNotExist(err) {
|
||
fmt.Println("未读取到版本信息,使用默认版本进行更新。")
|
||
return vm.createDefaultVersion(), nil
|
||
}
|
||
vm.logger.Warn("读取版本文件 %s 失败: %v,将使用默认版本", versionPath, err)
|
||
return vm.createDefaultVersion(), nil
|
||
}
|
||
|
||
var versionInfo VersionInfo
|
||
if err := json.Unmarshal(data, &versionInfo); err != nil {
|
||
vm.logger.Warn("解析版本文件 %s 失败: %v,将使用默认版本", versionPath, err)
|
||
return vm.createDefaultVersion(), nil
|
||
}
|
||
|
||
vm.logger.Debug("成功从 %s 加载版本信息", versionPath)
|
||
return &versionInfo, nil
|
||
}
|
||
|
||
// LoadVersionWithDefault 加载版本信息并保证回退到默认版本
|
||
func (vm *VersionManager) LoadVersionWithDefault() *VersionInfo {
|
||
versionInfo, err := vm.LoadVersionFromFile()
|
||
if err != nil {
|
||
// 这在更新的 LoadVersionFromFile 中不应该发生,但添加作为额外安全措施
|
||
vm.logger.Error("加载版本文件时出现意外错误: %v,使用默认版本", err)
|
||
return vm.createDefaultVersion()
|
||
}
|
||
|
||
// 验证我们有一个有效的版本结构
|
||
if versionInfo == nil {
|
||
vm.logger.Warn("版本信息为空,使用默认版本")
|
||
return vm.createDefaultVersion()
|
||
}
|
||
|
||
if versionInfo.MainVersion == "" {
|
||
vm.logger.Warn("版本信息主版本为空,使用默认版本")
|
||
return vm.createDefaultVersion()
|
||
}
|
||
|
||
if versionInfo.VersionInfo == nil {
|
||
vm.logger.Debug("版本信息映射为空,初始化空映射")
|
||
versionInfo.VersionInfo = make(map[string]map[string][]string)
|
||
}
|
||
|
||
return versionInfo
|
||
}
|
||
|
||
// ParseVersion 解析版本字符串如 "4.4.1.3" 为组件
|
||
func ParseVersion(versionStr string) (*ParsedVersion, error) {
|
||
parts := strings.Split(versionStr, ".")
|
||
if len(parts) < 3 || len(parts) > 4 {
|
||
return nil, fmt.Errorf("无效的版本格式: %s", versionStr)
|
||
}
|
||
|
||
major, err := strconv.Atoi(parts[0])
|
||
if err != nil {
|
||
return nil, fmt.Errorf("无效的主版本号: %s", parts[0])
|
||
}
|
||
|
||
minor, err := strconv.Atoi(parts[1])
|
||
if err != nil {
|
||
return nil, fmt.Errorf("无效的次版本号: %s", parts[1])
|
||
}
|
||
|
||
patch, err := strconv.Atoi(parts[2])
|
||
if err != nil {
|
||
return nil, fmt.Errorf("无效的补丁版本号: %s", parts[2])
|
||
}
|
||
|
||
beta := 0
|
||
if len(parts) == 4 {
|
||
beta, err = strconv.Atoi(parts[3])
|
||
if err != nil {
|
||
return nil, fmt.Errorf("无效的测试版本号: %s", parts[3])
|
||
}
|
||
}
|
||
|
||
return &ParsedVersion{
|
||
Major: major,
|
||
Minor: minor,
|
||
Patch: patch,
|
||
Beta: beta,
|
||
}, nil
|
||
}
|
||
|
||
// ToVersionString 将 ParsedVersion 转换回版本字符串格式
|
||
func (pv *ParsedVersion) ToVersionString() string {
|
||
if pv.Beta == 0 {
|
||
return fmt.Sprintf("%d.%d.%d.0", pv.Major, pv.Minor, pv.Patch)
|
||
}
|
||
return fmt.Sprintf("%d.%d.%d.%d", pv.Major, pv.Minor, pv.Patch, pv.Beta)
|
||
}
|
||
|
||
// ToDisplayVersion 将版本转换为显示格式 (4.4.0 或 4.4.1-beta3)
|
||
func (pv *ParsedVersion) ToDisplayVersion() string {
|
||
if pv.Beta == 0 {
|
||
return fmt.Sprintf("%d.%d.%d", pv.Major, pv.Minor, pv.Patch)
|
||
}
|
||
return fmt.Sprintf("%d.%d.%d-beta%d", pv.Major, pv.Minor, pv.Patch, pv.Beta)
|
||
}
|
||
|
||
// GetChannel 根据版本返回渠道 (stable 或 beta)
|
||
func (pv *ParsedVersion) GetChannel() string {
|
||
if pv.Beta == 0 {
|
||
return "stable"
|
||
}
|
||
return "beta"
|
||
}
|
||
|
||
// IsNewer 检查此版本是否比其他版本更新
|
||
func (pv *ParsedVersion) IsNewer(other *ParsedVersion) bool {
|
||
if pv.Major != other.Major {
|
||
return pv.Major > other.Major
|
||
}
|
||
if pv.Minor != other.Minor {
|
||
return pv.Minor > other.Minor
|
||
}
|
||
if pv.Patch != other.Patch {
|
||
return pv.Patch > other.Patch
|
||
}
|
||
|
||
// 对于相同的主版本号,正式版本(Beta=0)比beta版本(Beta>0)更新
|
||
// 例如:4.4.1.0(正式版)> 4.4.1.3(beta3)
|
||
if pv.Beta == 0 && other.Beta > 0 {
|
||
return true // 正式版比beta版更新
|
||
}
|
||
if pv.Beta > 0 && other.Beta == 0 {
|
||
return false // beta版比正式版旧
|
||
}
|
||
|
||
// 如果都是beta版本,比较beta版本号
|
||
return pv.Beta > other.Beta
|
||
}
|