vkit 0.1.4

Fast Rust dev CLI: manage git worktrees, Node ports, run scripts, install & sync VS Code / Cursor extensions.
//! 更新相关:后台检查 crates.io 新版本(仅提示),以及 `vkit update` 自更新。

use std::sync::mpsc::{self, Receiver};
use std::thread;

use anyhow::{anyhow, Result};
use update_informer::{registry, Check};

/// GitHub 仓库归属,用于自更新时定位 Releases。
const REPO_OWNER: &str = "stekovinbranturry";
const REPO_NAME: &str = "vkit-rs";

/// 一次后台检查的结果:拿到新版本号(如 `0.1.2`)则表示有更新可用。
pub type UpdateHandle = Receiver<String>;

/// 在后台线程查询 crates.io 的最新版本,若比当前版本新则通过 channel 发回版本号。
///
/// `update-informer` 自带磁盘缓存(默认 24h),因此频繁启动也不会每次都请求网络;
/// 网络失败或已是最新时不发送任何值,channel 会随线程结束而关闭。
pub fn check_in_background() -> UpdateHandle {
    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
        let name = env!("CARGO_PKG_NAME");
        // 本地预览用:设置 VKIT_CURRENT_VERSION 可伪装当前版本,方便看到「有新版本」提示。
        let overridden = std::env::var("VKIT_CURRENT_VERSION").ok();
        let version = overridden
            .clone()
            .unwrap_or_else(|| env!("CARGO_PKG_VERSION").to_string());

        let mut informer = update_informer::new(registry::Crates, name, version);
        // 伪装版本时关闭 24h 缓存,保证每次都真正查询 crates.io。
        if overridden.is_some() {
            informer = informer.interval(std::time::Duration::ZERO);
        }

        if let Ok(Some(new_version)) = informer.check_version() {
            let _ = tx.send(new_version.to_string());
        }
    });
    rx
}

/// `vkit update`:从 GitHub Releases 下载当前平台的最新二进制并原地替换自身。
pub fn run() -> Result<()> {
    let current = env!("CARGO_PKG_VERSION");
    let status = self_update::backends::github::Update::configure()
        .repo_owner(REPO_OWNER)
        .repo_name(REPO_NAME)
        .bin_name(env!("CARGO_PKG_NAME"))
        .show_download_progress(true)
        .current_version(current)
        .build()
        .map_err(|e| anyhow!("初始化更新器失败:{e}"))?
        .update()
        .map_err(|e| anyhow!("更新失败:{e}"))?;

    if status.updated() {
        println!("✓ 已更新到 v{}", status.version());
    } else {
        println!("✓ 已是最新版本 v{current}");
    }
    Ok(())
}