Skip to content

Commit 3293a3e

Browse files
committed
fix(index): keep the snapshot store out of the index-repo namespace
Verifying the guard on a real refresh showed it working — three index trees archived, 3.2 MB, snapshot ids being the upstream commit shas — and also showed where I had put the store: `<home>/registry/data/.index-snapshots`, i.e. inside the directory that IS the index-repo namespace. Everything that enumerates index repos does it by listing subdirectories of `data/`. Fetcher::sorted_index_dirs returns every one of them with no filter, and xlings walks the same tree. The store was being handed to those scanners as if it were an index. It happens to be harmless today: the store has no `pkgs/`, so a descriptor lookup stats a path that does not exist and moves on. That is a property of someone else's loop, not of this design, and it would stop holding the moment the store's internal layout changed or a scanner started matching on something other than `pkgs/`. The store is now a sibling of the data root — `<home>/registry/index-snapshots` — where no index scanner can reach it. The defensive skip in `index_dirs` stays: that loop decides what gets archived, and an archive of the archive is the one mistake that would grow without bound. Verified on a real refresh: `data/` clean, store in the new location, same 3.2 MB. unit 55/55, e2e 176 passed / 0 failed.
1 parent e01e6bf commit 3293a3e

1 file changed

Lines changed: 20 additions & 3 deletions

File tree

src/pm/index_snapshot.cppm

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,17 @@ export namespace mcpp::pm::index_snapshot {
6363
// mcpp index has changed its floor 6 times in its entire life).
6464
inline constexpr std::size_t kKeepPerIndex = 5;
6565

66-
// <dataRoot>/.index-snapshots/<index-dir-name>/<snapshot-id>/
66+
// The snapshot store is a SIBLING of the index data root, never inside it:
67+
//
68+
// <dataRoot>/.. index-snapshots/<index-dir-name>/<snapshot-id>/
69+
//
70+
// Everything that enumerates index repos does it by listing directories under
71+
// `data/` (mcpp's own Fetcher::sorted_index_dirs takes every subdirectory, and
72+
// xlings walks the same tree). A snapshot store living there would be handed to
73+
// those scanners as if it were an index. Today that happens to be harmless —
74+
// the store has no `pkgs/` so lookups miss and move on — but "harmless because
75+
// of a detail of someone else's loop" is not a property worth depending on,
76+
// and it costs nothing to put the store where no index scanner can reach it.
6777
std::filesystem::path snapshots_root(const std::filesystem::path& dataRoot);
6878
std::filesystem::path snapshot_dir(const std::filesystem::path& dataRoot,
6979
const std::filesystem::path& indexDir);
@@ -187,7 +197,11 @@ std::string sanitize_component(std::string s) {
187197
} // namespace
188198

189199
std::filesystem::path snapshots_root(const std::filesystem::path& dataRoot) {
190-
return dataRoot / ".index-snapshots";
200+
auto parent = dataRoot.parent_path();
201+
// Degenerate path (relative "data", or a root) — fall back to staying put
202+
// rather than climbing out of the home directory.
203+
if (parent.empty()) return dataRoot / ".index-snapshots";
204+
return parent / "index-snapshots";
191205
}
192206

193207
std::filesystem::path snapshot_dir(const std::filesystem::path& dataRoot,
@@ -212,7 +226,10 @@ index_dirs(const std::filesystem::path& dataRoot) {
212226
for (auto& e : std::filesystem::directory_iterator(dataRoot, ec)) {
213227
if (ec) break;
214228
if (!e.is_directory()) continue;
215-
// The snapshots store lives under the same root; never snapshot it.
229+
// The store is a sibling of dataRoot (see snapshots_root), so it
230+
// should never appear here. Skipped anyway: this loop decides what
231+
// gets archived, and an archive of the archive is the one mistake
232+
// that would grow without bound.
216233
if (e.path().filename() == ".index-snapshots") continue;
217234
std::error_code pec;
218235
if (!std::filesystem::is_directory(e.path() / "pkgs", pec)) continue;

0 commit comments

Comments
 (0)