From 387ed4cbc4fcb4f949cfee14e77a53473be1ce2b Mon Sep 17 00:00:00 2001 From: syui Date: Fri, 23 Jan 2026 01:50:57 +0900 Subject: [PATCH] add cmd ver --- src/commands/mod.rs | 1 + src/commands/pds.rs | 76 +++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 31 ++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 src/commands/pds.rs diff --git a/src/commands/mod.rs b/src/commands/mod.rs index aac8da9..6da7743 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -5,3 +5,4 @@ pub mod gen; pub mod lang; pub mod did; pub mod index; +pub mod pds; diff --git a/src/commands/pds.rs b/src/commands/pds.rs new file mode 100644 index 0000000..c2d0376 --- /dev/null +++ b/src/commands/pds.rs @@ -0,0 +1,76 @@ +use anyhow::Result; +use serde::Deserialize; +use std::collections::HashMap; + +#[derive(Debug, Deserialize)] +struct Network { + plc: String, + bsky: String, + #[allow(dead_code)] + web: Option, + #[serde(rename = "handleDomains")] + #[allow(dead_code)] + handle_domains: Option>, +} + +#[derive(Debug, Deserialize)] +struct HealthResponse { + version: Option, +} + +#[derive(Debug, Deserialize)] +struct PackageJson { + dependencies: Option>, +} + +const PDS_PACKAGE_URL: &str = "https://raw.githubusercontent.com/bluesky-social/pds/main/service/package.json"; + +async fn get_latest_version(client: &reqwest::Client) -> String { + if let Ok(res) = client.get(PDS_PACKAGE_URL).send().await { + if res.status().is_success() { + if let Ok(pkg) = res.json::().await { + if let Some(deps) = pkg.dependencies { + if let Some(v) = deps.get("@atproto/pds") { + return v.clone(); + } + } + } + } + } + + "N/A".to_string() +} + +pub async fn check_versions(networks_path: &str) -> Result<()> { + // Read networks.json + let content = std::fs::read_to_string(networks_path)?; + let networks: HashMap = serde_json::from_str(&content)?; + + let client = reqwest::Client::new(); + + // Get latest version from GitHub + let latest = get_latest_version(&client).await; + println!("latest: {}", latest); + println!(); + + for (name, _network) in &networks { + // Check PDS using network name as domain + let url = format!("https://{}/xrpc/_health", name); + let version = match client.get(&url).send().await { + Ok(res) => { + if res.status().is_success() { + match res.json::().await { + Ok(health) => health.version.unwrap_or_else(|| "-".to_string()), + Err(_) => "-".to_string(), + } + } else { + "-".to_string() + } + } + Err(_) => "-".to_string(), + }; + println!("{}: {}", name, version); + } + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index 070e750..6f60264 100644 --- a/src/main.rs +++ b/src/main.rs @@ -152,6 +152,27 @@ enum Commands { #[arg(short, long, default_value = "public/content")] dir: String, }, + + /// Show ailog version + #[command(alias = "v")] + Version, + + /// PDS commands + Pds { + #[command(subcommand)] + command: PdsCommands, + }, +} + +#[derive(Subcommand)] +enum PdsCommands { + /// Check PDS versions + #[command(alias = "v")] + Version { + /// Networks JSON file + #[arg(short, long, default_value = "public/networks.json")] + networks: String, + }, } #[tokio::main] @@ -201,6 +222,16 @@ async fn main() -> Result<()> { Commands::Index { dir } => { commands::index::run(std::path::Path::new(&dir))?; } + Commands::Version => { + println!("{}", env!("CARGO_PKG_VERSION")); + } + Commands::Pds { command } => { + match command { + PdsCommands::Version { networks } => { + commands::pds::check_versions(&networks).await?; + } + } + } } Ok(())