Skip to content

版本模型:精确键能表达上游的一切,范围表达不了 —— 且 lock 记的是范围本身 #363

Description

@speak-agent

起因

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) return std::unexpected("version: not a number"); ... }

首段必须是数字,且在第一个 -/+ 处截断。于是:

  • ^b10069 / ~b10069 不可能。首段非数字,resolve_semvercontinue 跳过该键;若它是唯一键则报 no valid versions in index

  • ^1.92.8 看不见 1.92.81.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;我把它放在这里是因为是同一次调查发现的。

建议方向

  1. 真正的 semver 预发布支持,而不是截断:1.92.8-docking 应当排在 1.92.8 之前且不相等,^1.92.8 默认不匹配预发布(Cargo/npm 的既有语义)。这样 docking 与非 docking 就不再塌成一个。
  2. 非 semver 上游方案的定位:b10069 这类只支持精确匹配是可以接受的,但应当明确而不是靠"恰好走了另一条代码路径"。至少 ^b10069 该给出可理解的错误,而不是静默跳过后报"索引里没有有效版本"。
  3. lock 应当写入解析后的具体版本

现状可用性

索引侧不被本 issue 阻塞 —— 精确版本键已经能表达上游的一切写法。受影响的只是消费者写范围的能力:ggml-org:llamacpp@b10069 只能被精确 pin,这在当前是可接受的。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions