huanyan/desktopv0.1.3ceb88ba898283666fc1053a12485997cfe5fb70a → a78f6222a18cbfe9b9d1e060ac48268ec5f95275本增量实现 PRD #179 / D60「壳自更新检测」波 1(检测 + 提示,不自动升级),并对发布脚本做了一处加固。
| 文件 | 类型 | 说明 |
|---|---|---|
internal/ota/shell_check.go | 新增 | 壳自更新检测模块(后台 /shell/latest 探测) |
main.go | 修改 | runOTA 集成壳检测:清单地址裁决 + 新壳版本提示 |
internal/ota/ota_test.go | 修改 | 新增 TestShellCheckDecisions 用例 |
scripts/release.sh | 修改 | Gitea Release body 中 $VERSION → ${VERSION} |
internal/ota/shell_check.go)ShellLatestURL(apiBaseUrl, channel):拼 /api/v1/shell/latest?platform=&channel=;apiBaseUrl 为空返回空串(=跳过检测)。FetchShellLatest(url):3s 超时 GET,任何错误/非 200/code!=0/解析失败均返回 nil(后台不可达 → 静默跳过,保证离线韧性)。ShouldPromptShellUpdate(latest, current):仅当后台壳版本 严格高于 本壳时提示(只升不降,复用 payload.Compare)。ResolveManifestURL(fromBackend, fromConfig):OTA 清单地址裁决,后台下发优先、shell.json 兜底(换 OTA 域名不重发壳)。main.go 在 runOTA 中于首屏 2s 后执行:拉取 /shell/latest → 用后台清单地址覆盖 cfg.OTAManifestURL;若检测到更高壳版本,win.Show() 并 app.Browser.OpenURL(download_url) 引导下载。
本区间扫描器口径:修复 0 条。 无历史问题被本增量消除。
附:
scripts/release.sh的一处非扫描器识别的加固"...载荷 $VERSION——下载后..."→"...载荷 ${VERSION}——下载后..."该改动把裸变量改为花括号形式。在 bash/POSIX 语义下$VERSION后接多字节 UTF-8 破折号(——)本就会在非标识符字节处正确终止变量名,因此并非功能性 bug 修复,属可读性/健壮性加固。此处单列,不计入「修复 0 条」的扫描口径。
| 严重度 | 类型 | 位置 | 描述 |
|---|---|---|---|
| Medium | Complexity | main.go:181 | 函数过长:runOTA 达 81 行 |
| Low | Dependency | main.go:181 | 扇入扇出异常:runOTA fan-in 1 / fan-out 24(合计 25),超阈值 |
归因:两处均因在 runOTA 内联接入壳检测逻辑(约 +14 行、+多个被调函数)触发。runOTA 从「OTA 检查」膨胀为「壳检测 + 清单裁决 + 版本提示 + OTA 检查 + 升级提示」多职责函数。
同函数既有(非本增量新增,供参考):main.go:181 另有「过度日志(6 处 log)」「高耦合(直接依赖 24 个函数)」两条历史问题,与本次改动同源——建议一并处理。
新文件 internal/ota/shell_check.go 扫描结果:0 条问题,新模块本身结构清晰、职责单一(已通过 quality_list 按文件确认)。
download_url 会导致无意义的弹窗与打开操作(Low–Medium)ShouldPromptShellUpdate 只校验版本高低,不校验 DownloadURL 非空。若后台登记的壳版本更高但 download_url 为空:
win.Show() 仍会弹出窗口(在收银场景下可能干扰正在录入的操作);app.Browser.OpenURL("") 会被调用(由 logger.Warn 兜底,但用户侧表现为「弹了窗口却什么都没发生」)。建议:提示前增加 sl.DownloadURL != "" 守卫,或对空地址只记日志不弹窗。
shellVersion="dev" 会被判为「低版本」而反复提示(Low)shellVersion 默认值 "dev"。payload.Compare 对非数字段按 0 处理,故 Compare("0.1.3","dev")==1,即任何真实后台版本都会触发对 dev 壳的更新提示。对已分发版本无影响,但本地联调(配置了 apiBaseUrl)时会误弹。建议对 dev/非法版本号跳过提示。
shell.json 的「关闭 OTA」意图(Low,设计确认项)manifestURL = ResolveManifestURL(sl.OtaManifestURL, cfg.OTAManifestURL):即使运维在 shell.json 显式把 otaManifestUrl 置空以关闭 OTA,只要后台下发了 ota_manifest_url,OTA 会被重新启用。若这是「换域名不重发壳」的有意设计,建议在配置注释/PRD 中显式声明;否则应保留本地关闭开关的优先级。
壳检测在 runOTA 中同步执行(含最长 3s 超时)后才进入 u.CheckAndStage。后台慢/不可达时,OTA 检查被顺延最多 3s。属后台异步流程,不影响首屏,仅影响 OTA 生效时点,可接受;如需可改为并发或缩短超时。
win.Show() / app.Browser.OpenURL 在 go runOTA(...) 的 goroutine 中调用。既有代码(app.Dialog.*、win.Reload)已采用同一模式,故非本增量新引入的问题;若 Wails v3 对窗口/浏览器操作有主线程要求,建议统一封装到主线程调度。
main.go:181 的 runOTA。shell_check.go 质量良好(0 条扫描问题);既有 /shell/latest 网络逻辑对离线场景做了稳健降级(返回 nil 静默跳过),符合「收银优先」的容错取向。runOTA 抽出为独立函数(如 checkShellUpdate(app, win, logger, cfg) (string, bool) 返回清单地址),既消除 2 条新增问题,又能收敛既有的「过长/高耦合/过度日志」。抽出后 runOTA 可回到 OTA 单一职责。说明:第一节、第二节的修复/新增结论严格取自
codescan_issues_diff;第四节的潜在缺陷为基于源码(main.go、internal/ota/shell_check.go、internal/payload/layout.go、internal/shellcfg/config.go)的人工研判,未在扫描器中报出。