From d580ff887efce2c43c3b8747d715685cd61a0527 Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Wed, 24 Jun 2026 08:58:50 +0800 Subject: [PATCH] fix(index): refresh-on-miss covers version-miss, not just package-file-miss MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WS3's offline-first gate (ensure_official_package_index_fresh) refreshes the index only when the package *file* is missing locally. A stale-but-present index file that lacks the requested *version* slipped through: e.g. `mcpp toolchain install llvm@20.1.7` on a cached sandbox whose llvm.lua predates 20.1.7 resolved to 'package xim:llvm@20.1.7 not found' and never refreshed (ci-linux LLVM-toolchain step, post-#155). Fix: in the install-failure path (exitCode != 0), refresh the xim index ONCE before the existing direct-install retry. This is lazy refresh-on-miss — steady-state installs (package+version already local) succeed first try and never reach here, so they stay offline; an actual miss (package OR version) now triggers one refresh + retry. Honors the '缺包/缺版本就刷新一次' intent at the version level too. Build: clean self-host. --- src/pm/package_fetcher.cppm | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/pm/package_fetcher.cppm b/src/pm/package_fetcher.cppm index 1e9a2d2..e917e72 100644 --- a/src/pm/package_fetcher.cppm +++ b/src/pm/package_fetcher.cppm @@ -775,6 +775,23 @@ Fetcher::resolve_xpkg_path(std::string_view target, // for large toolchain packages and keeps the real failure output // visible to CI/users when it still fails. mcpp::fallback::clean_incomplete_install(verdir); + + // Offline-first refresh-on-miss: the failure may be a stale local + // index that doesn't list this package@version (e.g. installing a + // NEW toolchain version when the cached index predates it). The + // pre-install gate only refreshes when the package *file* is + // missing, so a version-miss slips through. Refresh the index ONCE + // here — on an actual install miss — then retry. Steady-state + // installs (package+version already local) succeed on the first + // try and never reach this path, so they stay offline. + if (parsed.indexName == "xim") { + mcpp::xlings::Env refreshEnv{ cfg_.xlingsBinary, cfg_.xlingsHome() }; + mcpp::log::verbose("fetcher", + std::format("install failed for {}; refreshing index before retry", + targets[0])); + mcpp::xlings::update_index(refreshEnv, /*quiet=*/true); + } + mcpp::log::verbose("fetcher", std::format("interface install failed for {}; retrying direct xlings install", targets[0]));