[M5+] cargoxx add evicts stale auto-discovered overlay rows
This commit is contained in:
@@ -139,6 +139,20 @@ auto cmd_add(const fs::path& project_root, const std::string& name,
|
|||||||
|
|
||||||
const auto effective_overlay = overlay_path.value_or(linkdb::default_overlay_path());
|
const auto effective_overlay = overlay_path.value_or(linkdb::default_overlay_path());
|
||||||
|
|
||||||
|
// Drop any auto-discovered overlay rows for this package before
|
||||||
|
// resolving — they may have been written by an older cargoxx whose
|
||||||
|
// scanner produced a different recipe (e.g. picked the wrong
|
||||||
|
// CMake config in a multi-config tree). Manual recipes survive.
|
||||||
|
{
|
||||||
|
auto db = linkdb::Database::open(effective_overlay);
|
||||||
|
if (!db) {
|
||||||
|
return std::unexpected(db.error());
|
||||||
|
}
|
||||||
|
if (auto r = db->evict_auto_recipes(name); !r) {
|
||||||
|
return std::unexpected(r.error());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto known = recipe_already_known(name, effective_version, components,
|
auto known = recipe_already_known(name, effective_version, components,
|
||||||
effective_overlay);
|
effective_overlay);
|
||||||
if (!known) {
|
if (!known) {
|
||||||
|
|||||||
@@ -104,6 +104,13 @@ auto overlay_set_libcxx_override(OverlayState& state, const std::string& package
|
|||||||
const std::string& source, bool value)
|
const std::string& source, bool value)
|
||||||
-> cargoxx::util::Result<void>;
|
-> cargoxx::util::Result<void>;
|
||||||
|
|
||||||
|
// Drops every overlay row for `package` whose source is not "manual".
|
||||||
|
// Used by `cargoxx add` to invalidate stale auto-discovered recipes
|
||||||
|
// when the resolver/scanner logic has changed under the user — they
|
||||||
|
// should never have to know `~/.cache/cargoxx/linkdb.sqlite` exists.
|
||||||
|
auto overlay_evict_auto(OverlayState& state, const std::string& package)
|
||||||
|
-> cargoxx::util::Result<void>;
|
||||||
|
|
||||||
auto overlay_query(OverlayState& state, const std::string& package)
|
auto overlay_query(OverlayState& state, const std::string& package)
|
||||||
-> cargoxx::util::Result<std::vector<OverlayRow>>;
|
-> cargoxx::util::Result<std::vector<OverlayRow>>;
|
||||||
|
|
||||||
@@ -144,6 +151,12 @@ class Database {
|
|||||||
const std::string& source, bool value)
|
const std::string& source, bool value)
|
||||||
-> util::Result<void>;
|
-> util::Result<void>;
|
||||||
|
|
||||||
|
// Evict every non-manual overlay row for `package`. Called by
|
||||||
|
// `cargoxx add` so users never have to manually drop stale
|
||||||
|
// auto-discovered recipes when cargoxx's resolver/scanner logic
|
||||||
|
// changes.
|
||||||
|
auto evict_auto_recipes(const std::string& package) -> util::Result<void>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Database() = default;
|
Database() = default;
|
||||||
std::map<std::string, std::vector<detail::CuratedRecipe>> curated_;
|
std::map<std::string, std::vector<detail::CuratedRecipe>> curated_;
|
||||||
|
|||||||
@@ -241,6 +241,28 @@ auto overlay_delete_recipe(OverlayState& state, const std::string& package,
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto overlay_evict_auto(OverlayState& state, const std::string& package)
|
||||||
|
-> util::Result<void> {
|
||||||
|
// `manual` rows are user-curated via `cargoxx linkdb add`; everything
|
||||||
|
// else (`nix-probe`, `conan`, `vcpkg`, …) was synthesized by the
|
||||||
|
// resolver from the current cargoxx logic and is safe to drop —
|
||||||
|
// the next add will re-discover with the latest scanner.
|
||||||
|
constexpr const char* SQL =
|
||||||
|
"DELETE FROM recipes WHERE package = ? AND source != 'manual'";
|
||||||
|
sqlite3* db = state.handle();
|
||||||
|
sqlite3_stmt* stmt = nullptr;
|
||||||
|
if (sqlite3_prepare_v2(db, SQL, -1, &stmt, nullptr) != SQLITE_OK) {
|
||||||
|
return std::unexpected(sqlite_error(db, "prepare evict"));
|
||||||
|
}
|
||||||
|
sqlite3_bind_text(stmt, 1, package.c_str(), -1, SQLITE_TRANSIENT);
|
||||||
|
auto rc = sqlite3_step(stmt);
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
if (rc != SQLITE_DONE) {
|
||||||
|
return std::unexpected(sqlite_error(db, "step evict"));
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
auto overlay_query(OverlayState& state, const std::string& package)
|
auto overlay_query(OverlayState& state, const std::string& package)
|
||||||
-> util::Result<std::vector<OverlayRow>> {
|
-> util::Result<std::vector<OverlayRow>> {
|
||||||
constexpr const char* SQL =
|
constexpr const char* SQL =
|
||||||
@@ -380,6 +402,14 @@ auto Database::abort_provisional(const std::string& package,
|
|||||||
return detail::overlay_delete_recipe(*overlay_, package, version_range, source);
|
return detail::overlay_delete_recipe(*overlay_, package, version_range, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto Database::evict_auto_recipes(const std::string& package)
|
||||||
|
-> util::Result<void> {
|
||||||
|
if (auto ok = require_overlay(overlay_); !ok) {
|
||||||
|
return std::unexpected(ok.error());
|
||||||
|
}
|
||||||
|
return detail::overlay_evict_auto(*overlay_, package);
|
||||||
|
}
|
||||||
|
|
||||||
auto Database::set_libcxx_override(const std::string& package,
|
auto Database::set_libcxx_override(const std::string& package,
|
||||||
const std::string& version_range,
|
const std::string& version_range,
|
||||||
const std::string& source, bool value)
|
const std::string& source, bool value)
|
||||||
|
|||||||
Reference in New Issue
Block a user