起因
mcpp-index 正在把包版本对齐到上游(mcpplibs.opencv@0.0.10 其实是 OpenCV 5.0.0,imgui@0.0.6 其实是 ImGui 1.92.8),对齐过程中撞上上游的两种非 semver 版本形态。以下每一条都在本机实测过,不是读代码推的。
1. 精确字面版本能用 —— 包括非 semver
llama.cpp 用 b10069 这样的构建号。造一个本地索引,描述符里版本键写 b10069:
Downloading probe.tinyver vb10069
wire address tried: probe:tinyver@b10069
一路走到下载,wire 地址正确,只因我的 URL 是假的才失败。解析、版本键匹配、wire 寻址全都正常。
带预发布后缀的同理。compat.imgui = "1.92.8-docking":
Compiling compat.imgui v1.92.8-docking
[package."compat.imgui"]
version = "1.92.8-docking"
拉的确实是 docking 的 tarball。
所以索引可以照抄上游版本,这条不需要改。
2. 范围表达不了它们
src/version_req.cppm:
// Strip prerelease/build metadata for M4 V1.if (auto dash = s.find_first_of("-+"); dash != std::string_view::npos) s = s.substr(0, dash);
...
if (start == i) { if (idx == 0) returnstd::unexpected("version: not a number"); ... }首段必须是数字,且在第一个 -/+ 处截断。于是:
^b10069 / ~b10069 不可能。首段非数字,resolve_semver 会 continue 跳过该键;若它是唯一键则报 no valid versions in index。
^1.92.8 看不见 1.92.8 与 1.92.8-docking 的区别。两者截断后都是 1.92.8,比较相等 —— 而它们是两个不同的 tarball、不同的 sha256(docking 是上游另一个分支)。实测 compat.imgui = "^1.92.8" 选中了非 docking 那个,两个 verdir 并存于 store:
~/.mcpp/registry/data/xpkgs/compat-x-imgui/1.92.8
~/.mcpp/registry/data/xpkgs/compat-x-imgui/1.92.8-docking
也就是说两个语义上不同的上游产物塌成了同一个可比较版本,范围在它们之间的取舍由一个看不见差别的序决定。
resolve_semver 返回 parsed[*idx].str(),而 str() 只能渲染 3–4 段数字。所以走范围解析的路径永远寻址不到非数字键。
3. 另一件事:lock 记的是范围,不是解析结果
compat.imgui = "^1.92.8" 之后:
[package."compat.imgui"]
namespace = "compat"version = "^1.92.8"source = "index+compat@^1.92.8"
记进 lock 的是约束本身。 一个记录范围的 lock 不锁定任何东西 —— 同一份 lock 在索引新增 1.92.9 之后会解析到不同的包。用户可见的输出也一并受影响(Compiling compat.imgui v^1.92.8)。
这条与 1/2 是不同的问题,建议单独 triage;我把它放在这里是因为是同一次调查发现的。
建议方向
- 真正的 semver 预发布支持,而不是截断:
1.92.8-docking 应当排在 1.92.8 之前且不相等,^1.92.8 默认不匹配预发布(Cargo/npm 的既有语义)。这样 docking 与非 docking 就不再塌成一个。 - 非 semver 上游方案的定位:
b10069 这类只支持精确匹配是可以接受的,但应当明确而不是靠"恰好走了另一条代码路径"。至少 ^b10069 该给出可理解的错误,而不是静默跳过后报"索引里没有有效版本"。 - lock 应当写入解析后的具体版本。
现状可用性
索引侧不被本 issue 阻塞 —— 精确版本键已经能表达上游的一切写法。受影响的只是消费者写范围的能力:ggml-org:llamacpp@b10069 只能被精确 pin,这在当前是可接受的。
起因
mcpp-index 正在把包版本对齐到上游(
mcpplibs.opencv@0.0.10其实是 OpenCV 5.0.0,imgui@0.0.6其实是 ImGui 1.92.8),对齐过程中撞上上游的两种非 semver 版本形态。以下每一条都在本机实测过,不是读代码推的。1. 精确字面版本能用 —— 包括非 semver
llama.cpp 用
b10069这样的构建号。造一个本地索引,描述符里版本键写b10069:一路走到下载,wire 地址正确,只因我的 URL 是假的才失败。解析、版本键匹配、wire 寻址全都正常。
带预发布后缀的同理。
compat.imgui = "1.92.8-docking":拉的确实是 docking 的 tarball。
所以索引可以照抄上游版本,这条不需要改。
2. 范围表达不了它们
src/version_req.cppm:首段必须是数字,且在第一个
-/+处截断。于是:^b10069/~b10069不可能。首段非数字,resolve_semver会continue跳过该键;若它是唯一键则报no valid versions in index。^1.92.8看不见1.92.8与1.92.8-docking的区别。两者截断后都是1.92.8,比较相等 —— 而它们是两个不同的 tarball、不同的 sha256(docking 是上游另一个分支)。实测compat.imgui = "^1.92.8"选中了非 docking 那个,两个 verdir 并存于 store:也就是说两个语义上不同的上游产物塌成了同一个可比较版本,范围在它们之间的取舍由一个看不见差别的序决定。
resolve_semver返回parsed[*idx].str(),而str()只能渲染 3–4 段数字。所以走范围解析的路径永远寻址不到非数字键。3. 另一件事:lock 记的是范围,不是解析结果
compat.imgui = "^1.92.8"之后:记进 lock 的是约束本身。 一个记录范围的 lock 不锁定任何东西 —— 同一份 lock 在索引新增 1.92.9 之后会解析到不同的包。用户可见的输出也一并受影响(
Compiling compat.imgui v^1.92.8)。这条与 1/2 是不同的问题,建议单独 triage;我把它放在这里是因为是同一次调查发现的。
建议方向
1.92.8-docking应当排在1.92.8之前且不相等,^1.92.8默认不匹配预发布(Cargo/npm 的既有语义)。这样 docking 与非 docking 就不再塌成一个。b10069这类只支持精确匹配是可以接受的,但应当明确而不是靠"恰好走了另一条代码路径"。至少^b10069该给出可理解的错误,而不是静默跳过后报"索引里没有有效版本"。现状可用性
索引侧不被本 issue 阻塞 —— 精确版本键已经能表达上游的一切写法。受影响的只是消费者写范围的能力:
ggml-org:llamacpp@b10069只能被精确 pin,这在当前是可接受的。