selfupdate

package
v0.3.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 21, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

clicheck.go —— CLI 侧的限流版本检查与提示行。

边界:

  • **CLI 永远不自动替换自己**(D13):CLI 是交互工具,在用户敲命令时不知情地 换掉自己不合适,脚本化场景下行为还会突变。这里只打一行提示
  • 读缓存的失败一律静默:这条路径挂在**每一条** handoff 命令上, 一个坏掉的缓存文件让所有命令都吐错误,代价远大于少提示一次更新
  • 本文件持有全仓唯一的版本比较入口 CompareVersion

Package selfupdate 提供「能不能安全换版 / 要不要提示更新」的判据。

职责:

  • IsManaged:判断换完版 exit(0) 之后还有没有人把 agentd 拉起来, 换版接口(POST /api/update)的闸二用它做硬拒绝判据
  • CLI 侧版本检查提示(clicheck.go):每条命令跑完后提示有没有新版本

边界:

  • 不做下载、不做 rename、不做换版编排:那是 internal/release 与 handoff upgrade 命令的职责
  • 不 import internal/agentd(会成环)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CLICheckPath

func CLICheckPath(dataDir string) string

CLICheckPath 返回缓存文件路径。

func CLICheckStale

func CLICheckStale(c *CLICheck, now time.Time) bool

CLICheckStale 判断是否该重新检查。nil(没查过)视为过期。

func CompareVersion added in v0.3.0

func CompareVersion(a, b string) (int, bool)

CompareVersion 比较两个版本号,是**全仓唯一**的版本比较入口。

参数:

  • a, b: 形如 v0.1.2 或 v0.1.2-rc3 的标签,前缀 v 可有可无, +构建元数据 按 semver 规则忽略

返回:

  • a 小于/等于/大于 b 时分别为 -1/0/1
  • 核心段不是三段非负整数时 ok 为 false,此时第一个返回值无意义

注意:

  • 三段核心号都按整数比,不能用字典序——字典序会判定 v0.10.0 比 v0.9.0 旧
  • **预发布号一律早于同号正式版**(semver 规则):v0.3.0-rc11 < v0.3.0
  • **标识符内部按「自然序」比,这是对严格 semver 的刻意偏离。** semver 规定字母数字标识符按 ASCII 字典序比,那样 "rc11" < "rc8" (因为 '1' < '8')——正好和我们要的相反。本仓库的 tag 用 -rcN 而不是 semver 推荐的 -rc.N,所以这里把数字段与非数字段拆开、数字段按数值比, 于是 rc2 < rc8 < rc11。点分形态(-rc.1)照样正确
  • **不要在别处另写一份。** 消费者已有三个(CLI 提示、桌面同步、桌面 通知);本函数被写错过一次(B59 验收抓出的反向提示),三份实现意味着 错一次要修三处、而且一定有一处会被漏掉

边界:本函数只回答「谁新谁旧」。**「该不该给用户装这个版本」是另一回事** ——install.sh 的 latest_tag 只认 releases/latest 的重定向,GitHub 本就把 预发布排除在外,所以放宽这里不会让谁被自动装上一个 rc。

func IsManaged

func IsManaged(getenv func(string) string) bool

IsManaged 判断换完版 exit(0) 之后还有没有人把 agentd 拉起来。

参数:

  • getenv: 取环境变量的函数(测试注入用;生产传 os.Getenv)

返回:

  • true 表示托管。**判不出来一律返回 false(fail-closed)**

注意:

  • 这是「非托管则拒绝自动更新」这条防线的判据,也是整个自动更新里最 重要的一个判断。如果 agentd 不是被管理器拉起的,换完版 exit(0) 之后 没人拉起,机器上就此没有 handoff 在跑,而且没有任何信号告诉任何人
  • **绝不能用 PPID**。手工 nohup / `zsh -c … &` 起的进程被 init 收养后 PPID 同样是 1,拿 PPID==1 当判据会把所有裸进程误判成托管, 正好把这条防线打穿
  • XPC_SERVICE_NAME 的 `!= "0"` 是必要的额外防御:从 Finder / Terminal.app 启动的进程会继承 XPC_SERVICE_NAME=0(launchd 给非 XPC 服务的占位值), 只判「非空」会把桌面上手动跑的 agentd 误判成托管
  • 判据取值来自 spec §7.1 的 P1 真机实测:launchd 托管时该变量等于 job Label,ssh / tmux / 裸进程三种形态全为空

func NotifyLine

func NotifyLine(c *CLICheck, current string) string

NotifyLine 生成提示行;不需要提示时返回空串。

参数:

  • c: 缓存(可为 nil)
  • current: 本进程版本;**空串表示非 release 构建**

注意:

  • current 为空时一律不提示。开发时每条命令都被劝「有新版」是纯噪音, 而且本地构建本来就不该被劝去装 release
  • **只有缓存里的版本严格新于当前版本才提示**。缓存最长会陈 24h, 刚升级完的机器读到的仍是升级前那次检查的结果;只判「不相等」就会 反过来劝人降级。这不是假设:v0.1.1 发布当天实测被劝 「有新版本 v0.1.0(当前 v0.1.1)」,且这条错误提示会挂满一整个刷新周期

func SaveCLICheck

func SaveCLICheck(dataDir string, c *CLICheck) error

SaveCLICheck 写缓存,自动建目录。

Types

type CLICheck

type CLICheck struct {
	CheckedAt time.Time `json:"checked_at"`
	Latest    string    `json:"latest"`
}

CLICheck 是 CLI 侧版本检查的缓存。

func LoadCLICheck

func LoadCLICheck(dataDir string) *CLICheck

LoadCLICheck 读缓存。

返回:

  • 缓存;**缺失或损坏一律返回 nil,不返回错误**(理由见文件头注释)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL