Remove mirror types and methods from branch_store.rs
Intent: Eliminate the three mirror-related data structs (`MirrorSyncRunRecord`, `MirrorStatusRecord`, `MirrorSyncRunInput`), the three `Store` impl methods (`record_mirror_sync_run`, `get_mirror_status`, `list_recent_mirror_sync_runs`), the two private helpers (`map_mirror_sync_row`, `classify_mirror_failure_kind`), and the unit test from the branch store module so they can live in their own dedicated module.
Affected files: crates/pika-news/src/branch_store.rs
Evidence
@@ -209,48 +209,6 @@ pub struct PendingNightlyLaneJob {
@@ -1571,174 +1529,6 @@ impl Store {
@@ -3236,62 +3026,6 @@ fn update_target_health_after_lane_finish(
@@ -3436,7 +3170,7 @@ fn update_nightly_run_status(conn: &Connection, nightly_run_id: i64) -> anyhow::
@@ -3530,38 +3264,6 @@ mod tests {
The bulk of this branch is a deletion pass across branch_store.rs. Three struct definitions totalling ~42 lines are removed from the top of the file (lines 212–253 in the old file). Three impl Store methods spanning ~174 lines are cut from the middle (record_mirror_sync_run, get_mirror_status, list_recent_mirror_sync_runs). Two private free functions (map_mirror_sync_row and classify_mirror_failure_kind, ~62 lines) are removed from near the bottom. Finally, the classifies_mirror_failure_kinds_for_runtime_safety_cases test and its classify_mirror_failure_kind import are deleted from the mod tests block.
Nothing else in branch_store.rs is modified beyond these removals and adjusting the test-module import line:
// Before
use super::{classify_mirror_failure_kind, BranchUpsertInput, CI_LANE_LEASE_LOST};
// After
use super::{BranchUpsertInput, CI_LANE_LEASE_LOST};
Create the new mirror_store.rs module
Intent: Provide a focused, self-contained module that owns all mirror-persistence concerns: data types, database queries, row-mapping helpers, failure classification logic, and their unit tests.
Affected files: crates/pika-news/src/mirror_store.rs
Evidence
@@ -0,0 +1,313 @@
A new file mirror_store.rs (313 lines) is created containing everything removed from branch_store.rs:
- Imports —
anyhow::Context, rusqlite::{params, OptionalExtension}, and crate::storage::Store.
- Three structs —
MirrorSyncRunRecord, MirrorStatusRecord, and MirrorSyncRunInput, copied verbatim.
impl Store block with the three public methods:
record_mirror_sync_run — records a new sync run row. One notable change: the repo-metadata lookup now calls self.ensure_forge_repo_metadata(...) before entering with_connection, rather than calling the module-private ensure_repo_metadata inside the connection closure. This decouples the metadata upsert from the insert transaction.
get_mirror_status — aggregates the latest attempt, last success/failure timestamps, and consecutive-failure streak for a given remote.
list_recent_mirror_sync_runs — returns the N most recent sync runs for a remote.
map_mirror_sync_row — maps a rusqlite::Row into MirrorSyncRunRecord, calling classify_mirror_failure_kind to populate failure_kind.
classify_mirror_failure_kind — pattern-matches error text into categories: obsolete, stale, busy, timeout, config, or transient.
#[cfg(test)] mod tests — the classifies_mirror_failure_kinds_for_runtime_safety_cases test verifying the classifier against four representative error strings.
// New standalone impl block in mirror_store.rs
impl Store {
pub fn record_mirror_sync_run(&self, input: &MirrorSyncRunInput) -> anyhow::Result<i64> {
let repo_id = self.ensure_forge_repo_metadata(
&input.repo,
&input.canonical_git_dir,
&input.default_branch,
"ci/forge-lanes.toml",
)?;
self.with_connection(|conn| { /* INSERT ... */ })
}
// ... get_mirror_status, list_recent_mirror_sync_runs
}
Register the new module in main.rs
Intent: Make the Rust compiler aware of `mirror_store` so other modules can import from it.
Affected files: crates/pika-news/src/main.rs
Evidence
@@ -12,6 +12,7 @@ mod github;
mod live;
mod local;
mod mirror;
+mod mirror_store;
mod model;
A single line mod mirror_store; is added to main.rs in alphabetical order between mod mirror and mod model. This is the only change needed to wire the new module into the crate's module tree.
Update imports in forge_runtime.rs
Intent: Point the forge runtime's mirror-status import at the new module instead of branch_store.
Affected files: crates/pika-news/src/forge_runtime.rs
Evidence
@@ -6,12 +6,12 @@ use std::time::Duration;
use chrono::{SecondsFormat, Utc};
use tokio::sync::Notify;
-use crate::branch_store::MirrorStatusRecord;
use crate::ci;
use crate::config::{Config, ForgeRepoConfig};
use crate::forge;
use crate::live::CiLiveUpdates;
use crate::mirror;
+use crate::mirror_store::MirrorStatusRecord;
use crate::poller;
In forge_runtime.rs, the import of MirrorStatusRecord switches from crate::branch_store to crate::mirror_store. The import is also repositioned alphabetically among the use statements.
Update imports in mirror.rs
Intent: Redirect the mirror module's type imports to mirror_store, since it consumes all three mirror data types.
Affected files: crates/pika-news/src/mirror.rs
Evidence
@@ -3,9 +3,9 @@ use std::env;
use anyhow::Context;
use chrono::{DateTime, NaiveDateTime, Utc};
-use crate::branch_store::{MirrorStatusRecord, MirrorSyncRunInput, MirrorSyncRunRecord};
use crate::config::Config;
use crate::forge;
+use crate::mirror_store::{MirrorStatusRecord, MirrorSyncRunInput, MirrorSyncRunRecord};
mirror.rs is the primary consumer of all three mirror types. The single grouped import line is moved from crate::branch_store to crate::mirror_store, keeping MirrorStatusRecord, MirrorSyncRunInput, and MirrorSyncRunRecord in the same import.
Update imports in web.rs tests
Intent: Fix the test module's imports so mirror types resolve from the new module.
Affected files: crates/pika-news/src/web.rs
Evidence
@@ -4254,7 +4254,7 @@ mod tests {
ForgePikaciLogsQuery, InboxListParams, PageNoticeView, ReviewModeQuery,
};
use crate::auth::AuthState;
- use crate::branch_store::{BranchUpsertInput, MirrorStatusRecord, MirrorSyncRunRecord};
+ use crate::branch_store::BranchUpsertInput;
@@ -4264,6 +4264,7 @@ mod tests {
use crate::forge_service::ForgeService;
use crate::mirror::MirrorRuntimeStatus;
+ use crate::mirror_store::{MirrorStatusRecord, MirrorSyncRunRecord};
In the web.rs test module, the combined import from branch_store is split: BranchUpsertInput stays with crate::branch_store, while MirrorStatusRecord and MirrorSyncRunRecord move to a new use crate::mirror_store line. This is the last consumer that needed updating.