Skip to content

Commit d8ff4ca

Browse files
committed
fix: strict marker semantics for cleanup, remove dead migration code
Round-4 review fix: clean_incomplete_install() now uses STRICT marker-only semantics. Used on the resolve/install path for the CURRENT target — absence of .mcpp_ok unambiguously means the install attempt was incomplete. A half-extracted dir with bin/ would otherwise escape cleanup and corrupt subsequent installs. clean_all_incomplete() (global scan via `mcpp self init`) keeps the legacy-aware behavior: packages without marker but with legacy content dirs are preserved for backward compatibility with pre-upgrade installs. is_install_complete() retains the legacy fallback for read-only compat in resolve_xpkg_path() — old packages are recognized as usable, but this doesn't shield them from explicit cleanup on the install path.
1 parent 8a2d003 commit d8ff4ca

1 file changed

Lines changed: 19 additions & 15 deletions

File tree

src/fallback/install_integrity.cppm

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -117,21 +117,15 @@ void mark_install_complete(const std::filesystem::path& xpkgDir) {
117117
bool clean_incomplete_install(const std::filesystem::path& xpkgDir) {
118118
if (!std::filesystem::exists(xpkgDir)) return false;
119119

120-
// Marker-only: if .mcpp_ok exists, this is a verified install — keep it.
121-
// Legacy packages (no marker but has content) are NOT cleaned here;
122-
// they're recognized by is_install_complete() for read-only compat.
120+
// STRICT marker-only semantics.
121+
// Used on the resolve/install path for the CURRENT target: we know
122+
// mcpp just attempted to install this package, so absence of .mcpp_ok
123+
// unambiguously means the attempt was incomplete (interrupted, failed
124+
// mid-extract, etc.). Legacy heuristic compat does NOT apply here —
125+
// a half-extracted dir that happens to have a `bin/` would otherwise
126+
// escape cleanup and corrupt subsequent installs.
123127
if (has_marker(xpkgDir)) return false;
124128

125-
// No marker. If it looks like a legacy complete package, don't clean
126-
// it either — it predates the marker system.
127-
if (looks_complete_legacy(xpkgDir)) {
128-
mcpp::log::debug("integrity", std::format(
129-
"legacy package without marker, skipping cleanup: {}",
130-
xpkgDir.string()));
131-
return false;
132-
}
133-
134-
// No marker, no legacy content — this is genuinely incomplete.
135129
mcpp::log::verbose("integrity",
136130
std::format("cleaning incomplete install: {}", xpkgDir.string()));
137131
std::error_code ec;
@@ -142,14 +136,24 @@ bool clean_incomplete_install(const std::filesystem::path& xpkgDir) {
142136
int clean_all_incomplete(const std::filesystem::path& xpkgsBase) {
143137
if (!std::filesystem::exists(xpkgsBase)) return 0;
144138

139+
// Global scan (used by `mcpp self init`). Keeps legacy packages
140+
// (no marker but has content) for backward compatibility — those
141+
// were installed before the marker system existed.
145142
int cleaned = 0;
146143
std::error_code ec;
147144
for (auto& pkgDir : std::filesystem::directory_iterator(xpkgsBase, ec)) {
148145
if (!pkgDir.is_directory()) continue;
149146
for (auto& verDir : std::filesystem::directory_iterator(pkgDir.path(), ec)) {
150147
if (!verDir.is_directory()) continue;
151-
if (clean_incomplete_install(verDir.path()))
152-
++cleaned;
148+
if (has_marker(verDir.path())) continue;
149+
if (looks_complete_legacy(verDir.path())) {
150+
mcpp::log::debug("integrity", std::format(
151+
"legacy package without marker, kept: {}",
152+
verDir.path().string()));
153+
continue;
154+
}
155+
std::filesystem::remove_all(verDir.path(), ec);
156+
if (!ec) ++cleaned;
153157
}
154158
}
155159
return cleaned;

0 commit comments

Comments
 (0)