@@ -246,6 +246,13 @@ bool is_index_fresh(const Env& env, std::int64_t ttlSeconds);
246246// toolchains live in xim-pkgindex, while modular libraries live in mcpplibs.
247247bool is_official_index_fresh (const Env& env, std::int64_t ttlSeconds);
248248
249+ // Check whether a specific package file exists in xlings' official xim index
250+ // and the index is fresh. This catches restored CI caches that have an index
251+ // directory and marker but predate a package added later.
252+ bool is_official_package_index_fresh (const Env& env,
253+ std::string_view packageName,
254+ std::int64_t ttlSeconds);
255+
249256// Run `xlings update` to refresh all index repos. Streams output to stdout.
250257// Returns the xlings exit code.
251258int update_index (const Env& env, bool quiet = false );
@@ -258,6 +265,12 @@ void ensure_index_fresh(const Env& env, std::int64_t ttlSeconds, bool quiet = fa
258265// Ensure xlings' official xim index is present and fresh.
259266void ensure_official_index_fresh (const Env& env, std::int64_t ttlSeconds, bool quiet = false );
260267
268+ // Ensure a specific package file exists in xlings' official xim index.
269+ void ensure_official_package_index_fresh (const Env& env,
270+ std::string_view packageName,
271+ std::int64_t ttlSeconds,
272+ bool quiet = false );
273+
261274// ─── run_capture utility ────────────────────────────────────────────
262275
263276std::expected<std::string, std::string> run_capture (const std::string& cmd);
@@ -298,6 +311,12 @@ std::filesystem::path index_refresh_marker(const std::filesystem::path& indexDir
298311 return indexDir / " .mcpp-index-updated" ;
299312}
300313
314+ std::filesystem::path official_package_file (const Env& env, std::string_view packageName) {
315+ if (packageName.empty ()) return {};
316+ std::string name (packageName);
317+ return official_index_dir (env) / " pkgs" / std::string (1 , name[0 ]) / (name + " .lua" );
318+ }
319+
301320void mark_index_refreshed (const std::filesystem::path& indexDir) {
302321 if (!std::filesystem::exists (index_pkgs_dir (indexDir))) return ;
303322 std::error_code ec;
@@ -1016,6 +1035,14 @@ bool is_official_index_fresh(const Env& env, std::int64_t ttlSeconds) {
10161035 return is_index_dir_fresh (official_index_dir (env), ttlSeconds);
10171036}
10181037
1038+ bool is_official_package_index_fresh (const Env& env,
1039+ std::string_view packageName,
1040+ std::int64_t ttlSeconds) {
1041+ if (!is_official_index_fresh (env, ttlSeconds)) return false ;
1042+ auto pkg = official_package_file (env, packageName);
1043+ return !pkg.empty () && std::filesystem::exists (pkg);
1044+ }
1045+
10191046int update_index (const Env& env, bool quiet) {
10201047 std::string cmd = build_command_prefix (env) + " update 2>&1" ;
10211048 int rc = mcpp::platform::process::run_streaming (cmd,
@@ -1040,4 +1067,14 @@ void ensure_official_index_fresh(const Env& env, std::int64_t ttlSeconds, bool q
10401067 update_index (env, /* quiet=*/ true );
10411068}
10421069
1070+ void ensure_official_package_index_fresh (const Env& env,
1071+ std::string_view packageName,
1072+ std::int64_t ttlSeconds,
1073+ bool quiet) {
1074+ if (is_official_package_index_fresh (env, packageName, ttlSeconds)) return ;
1075+ if (!quiet)
1076+ print_status (" Updating" , " package index (auto-refresh)" );
1077+ update_index (env, /* quiet=*/ true );
1078+ }
1079+
10431080} // namespace mcpp::xlings
0 commit comments