fix(daemon): 区分当前下载与历史失败状态

This commit is contained in:
2026-07-15 23:22:30 +08:00
parent 5b31112e91
commit 169822abaf
5 changed files with 82 additions and 20 deletions
+66 -8
View File
@@ -1,9 +1,10 @@
use bat_adapters::official::yostar_jp::PatchPlatform;
use bat_infrastructure::{
lexical_absolute, open_append_file, read_file_no_symlink, read_version_state,
validate_output_root, validate_runtime_state_dir, write_file_atomic, OfficialServerInfoSource,
OfficialUpdateConfig, OfficialUpdateProgress, OfficialUpdateReport, OfficialUpdateService,
OfficialUpdateStatus, OfficialVerificationSummary, OfficialVersionState, PRIVATE_FILE_MODE,
validate_output_root, validate_runtime_state_dir, write_file_atomic,
OfficialFailedVersionRecord, OfficialServerInfoSource, OfficialUpdateConfig,
OfficialUpdateProgress, OfficialUpdateReport, OfficialUpdateService, OfficialUpdateStatus,
OfficialVerificationSummary, OfficialVersionRecord, OfficialVersionState, PRIVATE_FILE_MODE,
};
use serde::{Deserialize, Serialize};
use std::env;
@@ -1990,14 +1991,34 @@ fn print_daemon_version_state_summary(version_state: &OfficialVersionState) {
.as_ref()
.map(|version| version.id.as_str()),
);
print_field("失败版本数", version_state.failed_versions.len());
if let Some(failed) = version_state.failed_versions.last() {
print_field("最近失败版本", &failed.version.id);
print_field("最近失败时间", failed.failed_unix_seconds);
print_field("最近失败原因", &failed.error);
let historical_failures = visible_historical_failed_versions(version_state);
print_field("历史失败版本数", historical_failures.len());
if let Some(failed) = historical_failures.last() {
print_field("最近历史失败版本", &failed.version.id);
print_field("最近历史失败时间", failed.failed_unix_seconds);
print_field("最近历史失败原因", &failed.error);
}
}
fn visible_historical_failed_versions<'a>(
version_state: &'a OfficialVersionState,
) -> Vec<&'a OfficialFailedVersionRecord> {
let in_progress = version_state.in_progress_version.as_ref();
version_state
.failed_versions
.iter()
.filter(|failed| {
!in_progress.is_some_and(|version| version_matches_for_status(&failed.version, version))
})
.collect()
}
fn version_matches_for_status(left: &OfficialVersionRecord, right: &OfficialVersionRecord) -> bool {
left.app_version == right.app_version
&& left.bundle_version == right.bundle_version
&& left.addressables_root == right.addressables_root
}
fn print_json_field(value: &serde_json::Value, key: &str, label: &str) {
let Some(value) = value.get(key) else {
return;
@@ -4400,6 +4421,43 @@ mod tests {
assert!(!formatted.contains('{'));
}
#[test]
fn daemon_status_hides_failure_superseded_by_in_progress_version() {
let version = OfficialVersionRecord {
id: "1.70.0-current-attempt".to_string(),
app_version: "1.70.0".to_string(),
bundle_version: Some("s8tloc7lo3".to_string()),
addressables_root: "https://prod-clientpatch.bluearchiveyostar.com/r93_token"
.to_string(),
resource_root: PathBuf::from("/tmp/bat/.staging/current"),
snapshot_path: PathBuf::from("/tmp/bat/.staging/current/official-sync-snapshot.json"),
staging_path: Some(PathBuf::from("/tmp/bat/.staging/current")),
version_path: None,
started_unix_seconds: Some(100),
completed_unix_seconds: None,
};
let older_failure = OfficialFailedVersionRecord {
version: OfficialVersionRecord {
id: "1.70.0-older-failure".to_string(),
resource_root: PathBuf::from("/tmp/bat/.staging/older"),
snapshot_path: PathBuf::from("/tmp/bat/.staging/older/official-sync-snapshot.json"),
staging_path: Some(PathBuf::from("/tmp/bat/.staging/older")),
started_unix_seconds: Some(90),
..version.clone()
},
error: "官方 hash 校验失败 fixture".to_string(),
failed_unix_seconds: 95,
};
let state = OfficialVersionState {
in_progress_version: Some(version),
failed_versions: vec![older_failure],
updated_unix_seconds: 100,
..OfficialVersionState::default()
};
assert!(visible_historical_failed_versions(&state).is_empty());
}
#[test]
fn daemon_socket_path_uses_state_dir() {
assert_eq!(