Skip to content

feat: search 结果与 add 建议显示包的可用版本(默认最新 3 个,--all-versions 全量) - #488

Closed
wellwei wants to merge 1 commit into
mcpp-community:mainfrom
wellwei:feat/add-search-show-versions
Closed

feat: search 结果与 add 建议显示包的可用版本(默认最新 3 个,--all-versions 全量)#488
wellwei wants to merge 1 commit into
mcpp-community:mainfrom
wellwei:feat/add-search-show-versions

Conversation

@wellwei

@wellwei wellwei commented Aug 22, 2026

Copy link
Copy Markdown
Member

Summary

Closes #487,补上 #324 遗留的「建议不带版本」半边。

mcpp search <keyword>:命中行追加该包描述符 per-OS 版本表的并集——semver 降序、按键去重,默认显示最新 3 个并以 , ... 标记截断;--all-versions 显示全部。描述符不可读或未发布任何版本的包保持原两列输出,富化是尽力而为的展示,不是新的失败路径。

$ mcpp search imgui
  compat:imgui      Dear ImGui immediate-mode GUI library core sources       (1.92.8, 1.92.8-docking)
  mcpplibs:imgui    C++23 module package for Dear ImGui core and GLFW/OpenGL3 backends  (0.0.6, 0.0.5, 0.0.4)
  ocornut:imgui     Dear ImGui 1.92.8 core and GLFW/OpenGL3 backend modules for mcpp (import imgui.core;)  (1.92.8)

$ mcpp search imgui --all-versions   # mcpplibs:imgui → (0.0.6, 0.0.5, 0.0.4, 0.0.3, 0.0.2, 0.0.1)

mcpp add ns.name@ver 未命中时:跨命名空间建议从裸 FQN 升级为带版本:

  a package with this name exists under another namespace:
    compat.eui-neo (0.5.6, 0.5.5, 0.5.3)

数据是白捡的:did-you-mean 扫描本就要打开每个候选 .lua 读身份(#278),版本只是同一段文本的再一次遍历。build 失败路径的同款提示同步升级,两条路径不说两套话。warn_unpublished_version 的 warn-not-fail 策略不动。

实现

Test plan

  • 单测 95 通过 0 失败(新增:merge 排序 8 例含预发布/四段/不可解析键;扫描携带版本 3 例;versions_for_hit 3 例)
  • tests/e2e/162_bare_name_namespace_scope.sh 扩展并全绿:build 路径断言 acme.widget (1.0.0)、add 路径断言 compat.gadget (2.0.0),且被拒的 add 不写 manifest
  • 相邻 E2E 用 fresh 二进制通过:12_add_command.sh93_xpkg_parse.sh
  • 真机实测:mcpp search imgui [--all-versions]mcpp add mcpplibs.eui-neo@1.0.0 输出符合上述契约

`mcpp search` 的命中行追加描述符 per-OS 版本表的并集:semver 降序、按键去重,
默认显示最新 3 个并以 ", ..." 标记截断,--all-versions 显示全部;描述符不可读
或未发布版本的包保持原两列输出——富化是尽力而为的展示,不是新的失败路径。

`mcpp add` 未命中时的跨命名空间建议从裸 FQN 升级为带版本:
compat.eui-neo (0.5.6, 0.5.5, 0.5.3)。数据是白捡的:did-you-mean 扫描本就要
打开每个候选 .lua 读身份(mcpp-community#278),版本只是同一段文本的再一次遍历。build 失败
路径的同款提示同步升级,两条路径不说两套话。

实现:

- manifest 新增 merge_xpkg_versions_desc:per-OS 键列表的并集视图。排序用
  version_req 的 SemVer 解析;不可解析的键保留原文排在最后(mcpp-community#363 的教训:
  任意的索引键无法从解析形态复原);等值异写("1.0"/"1.0.0")保持首见序。
- mcpp-community#278 的扫描由 scan_fqns_with_short_name 改为 scan_short_name_matches,
  携带 fqn + versions;三条约束不变(只在已失败路径调用、结果只进错误文本/
  展示、空结果不是错误),版本列表受同一纪律约束——描述存在性,不做解析输入。
- cross_namespace_matches 更名 cross_namespace_suggestions 返回富记录;
  prepare.cppm 与 commands.cppm 两个调用点同步渲染。
- Fetcher 新增 versions_for_hit:search 命中的 ns:name → 描述符 → 版本并集;
  无 ns 前缀或读不到描述符时返回空。
- search_packages 增加 --all-versions;cli 注册选项。

测试:merge 排序 8 例(含预发布/四段/不可解析键)、扫描携带版本 3 例、
versions_for_hit 3 例;e2e 162 断言 build 与 add 两侧建议都带版本
(acme.widget (1.0.0) / compat.gadget (2.0.0)),且被拒的 add 不写 manifest。

Closes mcpp-community#487
Refs mcpp-community#324
@wellwei
wellwei requested review from Sunrisepeak, ZheFeng7110 and speak-agent and removed request for Sunrisepeak and speak-agent August 23, 2026 07:36
Sunrisepeak pushed a commit that referenced this pull request Sep 5, 2026
Carries wellwei's #487 work onto current main. The CHANGELOG entry moves into
[Unreleased]; it was filed under a [2026.8.22.1] section that no longer exists.

The version display is one function now. #488 grew two joins of the same list
-- `ShortNameMatch::versions_label` and a file-local `join_versions` in
index_management -- and only the first appended the `, ...` truncation marker.
So `mcpp search` cut the list to three and said nothing about it, against a
description that promises the marker and a package (mcpplibs:imgui) that has
six. Both callers now render through `manifest::join_versions_desc`, with the
count policy as one `kVersionsShown`, and a unit test pins the marker for the
truncated and exact-fit cases -- neither was covered.

`all_xpkg_versions_desc` replaces two copies of "read every OS table, then
merge" that each spelled the platform axis as a literal `{"linux", "macosx",
"windows"}`. The axis already exists once, as `platform::xpkg_platforms`; a
fourth OS should not need a sweep for the call sites that knew three.

`merge_xpkg_versions_desc` parses each key once beside the key instead of on
every comparison -- the comparator runs O(n log n) times and the parse was its
whole cost. The optional-adapting lambda goes with it: the comparator only ever
used `operator bool` and `operator*`, which `std::expected` already provides.
Ordering is unchanged, `stable_sort` included, so `1.0` and `1.0.0` still hold
first-seen order.

`search_packages`'s defaulted `allVersions` is dropped; its one caller passes
the flag explicitly.

Co-authored-by: wellwei <ywellwei@qq.com>
@Sunrisepeak

Copy link
Copy Markdown
Member

Reviewed and carried forward as #573, with a Co-authored-by trailer so the squash keeps your authorship. Your branch is in a fork this repository cannot push to, so the rebase onto current main (73 commits of drift; the code merged cleanly, only the CHANGELOG conflicted — its entry sat under a [2026.8.22.1] section that no longer exists) landed on a base-repo branch instead.

The design holds and went in as written: the scan #278 already pays for on a failed lookup is reused rather than a new index built, and both constraint comments are explicit that the version list is display-only and never a resolution input. read_xpkg_lua is a local read, so the enrichment costs mcpp search no network call.

One behavioural gap, and one consolidation:

mcpp search truncated without saying so. The PR grew two joins of the same list — ShortNameMatch::versions_label and a file-local join_versions in index_management — and only the first appended the , ... marker. So search cut to three and said nothing, against a description that promises the marker and against mcpplibs:imgui, which has six versions. Nothing tested it. Both callers now render through one manifest::join_versions_desc, with the count policy as one kVersionsShown, and a unit test pins the truncated and exact-fit cases.

The platform axis existed already. versions_for_hit and the scan each spelled it {"linux", "macosx", "windows"}; platform::xpkg_platforms is the one definition, so both now call manifest::all_xpkg_versions_desc. merge_xpkg_versions_desc also parses each key once beside the key rather than on every comparison — the ordering, stable_sort included, is unchanged, so 1.0 and 1.0.0 still hold first-seen order.

mcpp search is not documented under docs/ at all, so --all-versions has nowhere to go short of writing that section; left as it is.

Thanks — the reasoning in the constraint comments is what made this quick to review.

Sunrisepeak added a commit that referenced this pull request Sep 5, 2026
…, and docs/21 (#565, #487)

Two contributor PRs, each reviewed and amended, plus the docs chapter both of
them needed and neither had a place for.

`mcpp clean --stale` (#568, closes #565) removes the fingerprint directories
under target/ that no recorded build still uses, so reclaiming disk no longer
costs a full rebuild. "Current" is what target/.build_cache already records
rather than a second authority; with no record the command refuses instead of
guessing, and an unrecorded directory written within --older-than is kept.

`mcpp search` and the `mcpp add` did-you-mean now show what a package publishes
(#488, closes #487), merged across the descriptor's per-OS tables and sorted
semver-descending. The scan is the one #278 already pays for on a failed
lookup; its result reaches error text and display only, never resolution.

Three defects were found in review and fixed here. `mcpp clean --older-than 3d`
set neither --stale nor --dry-run, so it reached clean_project and deleted every
triple and profile under target/ -- silently, and precisely the outcome --stale
exists to avoid. `--older-than -1s`, a typo for `1s`, parsed to a negative
window that keeps nothing, disabling the freshness guard without a word. And
609's closing assertion -- the one that catches clean --stale destroying live
build state -- used GNU `stat -c` in a test that declares no capabilities, so
on macOS BSD stat rejected it, the `| sort` swallowed the status for want of
pipefail, and two empty strings compared equal while the test printed OK.

`mcpp search` also truncated its version list to three without the `, ...`
marker its own description promised, because the feature grew two joins of the
same list and only one appended it. Both callers now render through a single
manifest::join_versions_desc with one kVersionsShown, and a unit test pins the
truncated and exact-fit cases; neither had been covered.

Simplifications: clean_stale keeps one map<triple, set<fingerprint>> where it
kept a set of pairs and a parallel set of triples; all_xpkg_versions_desc
replaces two copies of "read every OS table, then merge" that each spelled the
platform axis as a literal, when platform::xpkg_platforms already defines it
once; and merge_xpkg_versions_desc parses each key once beside the key rather
than on every comparison, ordering unchanged.

docs/21 documents the commands whose name does not announce their situation --
search, why, index status, xpkg parse had no entry under docs/ at all. Every
transcript in it is real output from this branch, and two claims were weakened
after failing that check: cache list is not ordered by last use, and the cost of
rebuilding a std BMI is the implementation's stated rationale, not a
measurement.

Closes #565. Closes #487. Supersedes #568 and #488.

Co-authored-by: Cloud_Yun <yunfeng66645@gmail.com>
Co-authored-by: wellwei <ywellwei@qq.com>
@Sunrisepeak

Copy link
Copy Markdown
Member

Merged as 090c016 — the squash carries Co-authored-by: wellwei <ywellwei@qq.com>. Closing here because this branch is in a fork the repository cannot push to, so the rebase onto current main and the review fixes landed on a base-repo branch instead. Thanks for the feature.

@Sunrisepeak Sunrisepeak closed this Sep 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add 建议与 search 结果显示包的可用版本(最新少数 + --all-versions)

2 participants