Skip to main content

relay_knowledge/application/update/workflow/
mod.rs

1use crate::{
2    clock::system_now_millis_or_zero, paths::RuntimePaths,
3    ports::release_metadata::ReleaseMetadataPort, project::PROJECT_NAME,
4};
5
6use super::{
7    cache::{read_fresh_cache, write_cache},
8    config::UpdateRuntimeConfig,
9    release::fetch_latest_version,
10    result::VersionCheckResponse,
11};
12
13pub async fn check_for_updates(
14    paths: &RuntimePaths,
15    metadata: &dyn ReleaseMetadataPort,
16    config: &UpdateRuntimeConfig,
17    force_refresh: bool,
18) -> VersionCheckResponse {
19    let now_ms = system_now_millis_or_zero();
20    let cache_path = paths.version_check_cache_file();
21    if !force_refresh
22        && let Some(cached) =
23            read_fresh_cache(&cache_path, now_ms, config.check_interval, config).await
24    {
25        return cached;
26    }
27
28    let response = fetch_latest_version(metadata, config, now_ms).await;
29    let _ = write_cache(&cache_path, &response, config).await;
30    response
31}
32
33pub async fn update_notice(
34    paths: &RuntimePaths,
35    metadata: &dyn ReleaseMetadataPort,
36    config: &UpdateRuntimeConfig,
37) -> Option<String> {
38    if !config.enabled {
39        return None;
40    }
41    let response = check_for_updates(paths, metadata, config, false).await;
42    notice_from_response(response)
43}
44
45fn notice_from_response(response: VersionCheckResponse) -> Option<String> {
46    if !response.update_available {
47        return None;
48    }
49
50    Some(format!(
51        "{} {} is available; current {}. Run `relay-knowledge version check` for details.\n",
52        PROJECT_NAME,
53        response
54            .latest_version
55            .unwrap_or_else(|| "unknown".to_owned()),
56        response.current_version
57    ))
58}
59
60#[cfg(test)]
61#[path = "mod_tests.rs"]
62mod tests;