diff --git a/src/upgrade.rs b/src/upgrade.rs index de105c2..d2b2328 100644 --- a/src/upgrade.rs +++ b/src/upgrade.rs @@ -18,6 +18,7 @@ use crate::http::http_get; use crate::key::load_config_if_present; use crate::parse::{get_string_flag, ParsedArgs}; use crate::spawn::redact_value; +use crate::term; use crate::VERSION; /// How often the background checker hits GitHub Releases. @@ -498,43 +499,74 @@ pub fn run(parsed: &ParsedArgs, env: &BTreeMap) -> Result {latest_ver}"); - println!("Would download {url}"); + println!("{}", field("asset", &url)); + println!( + "{}", + status_change(term::warn("would update"), VERSION, latest_ver) + ); return Ok(0); } - println!("Upgrading {VERSION} -> {latest_ver}"); println!("Downloading {url}"); let dest = replace_current_binary(&url)?; - println!("Installed {latest_ver} -> {}", dest.display()); + println!( + "{}", + status_change(term::ok("updated"), VERSION, latest_ver) + ); + println!("{}", field("path", dest.display())); Ok(0) } +fn field(key: &str, value: impl std::fmt::Display) -> String { + format!("{:<8} {value}", format!("{key}:")) +} + +fn print_version_report(channel: Channel, latest_ver: &str) { + println!( + "{}", + field( + "current", + format!("{VERSION} (built {})", crate::buildinfo::display_time()) + ) + ); + println!("{}", field("latest", latest_ver)); + println!("{}", field("channel", channel.as_str())); +} + +/// `status: updated 0.1.0 -> 0.1.1` — `->` is only ever old version to new. +fn status_change(status: impl std::fmt::Display, from: &str, to: &str) -> String { + field("status", format!("{status} {from} -> {to}")) +} + #[cfg(test)] mod tests { use super::*; @@ -732,4 +764,26 @@ mod tests { assert!(version_eq("0.1.1", "v0.1.1")); assert!(!version_eq("0.1.1", "0.1.2")); } + + #[test] + fn field_aligns_values_and_keeps_colon() { + assert_eq!(field("current", "0.1.0"), "current: 0.1.0"); + assert_eq!(field("latest", "0.1.1"), "latest: 0.1.1"); + assert_eq!(field("channel", "beta"), "channel: beta"); + assert_eq!(field("status", "up to date"), "status: up to date"); + assert_eq!( + field("path", "/home/duyet/.local/bin/anyr"), + "path: /home/duyet/.local/bin/anyr" + ); + } + + #[test] + fn status_change_is_old_then_new_not_a_path() { + let line = status_change("updated", "0.1.11-beta.70", "0.1.11-beta.76"); + assert_eq!(line, "status: updated 0.1.11-beta.70 -> 0.1.11-beta.76"); + assert!( + !line.contains("/"), + "status must not reuse -> for an install path: {line}" + ); + } } diff --git a/tests/cli.rs b/tests/cli.rs index 6a886aa..19b8aab 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -768,7 +768,14 @@ fn update_beta_persists_channel_and_selects_prerelease() { assert_eq!(code, 0, "stderr={stderr}"); assert!(stdout.contains("channel set to beta"), "{stdout}"); assert!(stdout.contains("channel: beta"), "{stdout}"); - assert!(stdout.contains("latest: 0.2.0-beta.1"), "{stdout}"); + assert!( + stdout.contains("latest:") && stdout.contains("0.2.0-beta.1"), + "{stdout}" + ); + assert!( + stdout.contains("current:") && stdout.contains("status:"), + "{stdout}" + ); let cfg = std::fs::read_to_string(home.join("config.yaml")).expect("config"); assert!(cfg.contains("channel: beta"), "{cfg}"); } @@ -837,8 +844,15 @@ fn upgrade_check_newer_stable_would_upgrade() { }; assert_eq!(code, 0, "stderr={stderr}"); assert!(stdout.contains("channel: stable"), "{stdout}"); - assert!(stdout.contains("latest: 0.1.99"), "{stdout}"); + assert!( + stdout.contains("latest:") && stdout.contains("0.1.99"), + "{stdout}" + ); assert!(stdout.contains("update available"), "{stdout}"); + assert!( + stdout.contains("->") && stdout.contains("0.1.99"), + "check should show old -> new, got:\n{stdout}" + ); assert!( stdout.contains("github.com/anyrouter-dev/cli/releases/download/"), "{stdout}" @@ -862,7 +876,10 @@ fn upgrade_check_beta_selects_prerelease() { }; assert_eq!(code, 0, "stderr={stderr}"); assert!(stdout.contains("channel: beta"), "{stdout}"); - assert!(stdout.contains("latest: 0.2.0-beta.1"), "{stdout}"); + assert!( + stdout.contains("latest:") && stdout.contains("0.2.0-beta.1"), + "{stdout}" + ); assert!(stdout.contains("update available"), "{stdout}"); } @@ -1113,7 +1130,10 @@ fn upgrade_check_reads_channel_from_config() { let stderr = String::from_utf8_lossy(&out.stderr); assert_eq!(out.status.code().unwrap_or(1), 0, "stderr={stderr}"); assert!(stdout.contains("channel: beta"), "{stdout}"); - assert!(stdout.contains("latest: 0.2.0-beta.1"), "{stdout}"); + assert!( + stdout.contains("latest:") && stdout.contains("0.2.0-beta.1"), + "{stdout}" + ); } #[test]