rusty_commit/commands/
update.rs1use crate::cli::UpdateCommand;
2use crate::update::{check_for_update, perform_update, InstallMethod};
3use anyhow::Result;
4use colored::*;
5use semver::Version;
6
7pub async fn execute(cmd: UpdateCommand) -> Result<()> {
8 if let Some(target_version) = cmd.version {
10 return update_to_specific_version(&target_version, cmd.force).await;
11 }
12
13 let update_info = check_for_update().await?;
15
16 println!("{}", "Checking for updates...".blue());
17 println!(
18 "Current version: {}",
19 format!("v{}", update_info.current_version).cyan()
20 );
21 println!(
22 "Latest version: {}",
23 format!("v{}", update_info.latest_version).cyan()
24 );
25 println!(
26 "Install method: {}",
27 format!("{:?}", update_info.install_method).cyan()
28 );
29
30 if cmd.check {
32 if update_info.needs_update {
33 println!(
34 "\n{}",
35 format!(
36 "Update available! Run 'rco update' to update to v{}",
37 update_info.latest_version
38 )
39 .yellow()
40 );
41 } else {
42 println!("\n{}", "You're running the latest version! 🎉".green());
43 }
44 return Ok(());
45 }
46
47 if !update_info.needs_update && !cmd.force {
49 println!(
50 "\n{}",
51 "You're already running the latest version! 🎉".green()
52 );
53 println!(
54 "{}",
55 "Use --force to reinstall the current version.".dimmed()
56 );
57 return Ok(());
58 }
59
60 if update_info.install_method == InstallMethod::Unknown {
62 eprintln!(
63 "\n{}",
64 "Warning: Could not detect installation method.".yellow()
65 );
66 eprintln!(
67 "{}",
68 "Please update manually or use the install script:".yellow()
69 );
70 eprintln!(
71 " {}",
72 "curl -fsSL https://raw.githubusercontent.com/hongkongkiwi/rusty-commit/main/install.sh | bash".cyan()
73 );
74 return Ok(());
75 }
76
77 if !confirm_update(
79 &update_info.current_version,
80 &update_info.latest_version,
81 cmd.force,
82 )? {
83 println!("{}", "Update cancelled.".yellow());
84 return Ok(());
85 }
86
87 println!();
89 perform_update(&update_info).await?;
90
91 Ok(())
92}
93
94async fn update_to_specific_version(version_str: &str, force: bool) -> Result<()> {
95 let version_str = version_str.trim_start_matches('v');
97
98 let target_version = Version::parse(version_str)?;
100 let current_version = Version::parse(env!("CARGO_PKG_VERSION"))?;
101
102 if target_version == current_version && !force {
104 println!(
105 "{}",
106 format!("Already running version v{}!", version_str).green()
107 );
108 println!(
109 "{}",
110 "Use --force to reinstall the current version.".dimmed()
111 );
112 return Ok(());
113 }
114
115 let install_method = crate::update::detect_install_method()?;
117
118 if install_method == InstallMethod::Unknown {
119 eprintln!(
120 "{}",
121 "Warning: Could not detect installation method.".yellow()
122 );
123 eprintln!(
124 "{}",
125 "Please update manually or use the install script:".yellow()
126 );
127 eprintln!(
128 " {}",
129 format!("curl -fsSL https://raw.githubusercontent.com/hongkongkiwi/rusty-commit/main/install.sh | bash -s -- --version v{}", version_str).cyan()
130 );
131 return Ok(());
132 }
133
134 let update_info = crate::update::UpdateInfo {
136 current_version: env!("CARGO_PKG_VERSION").to_string(),
137 latest_version: version_str.to_string(),
138 install_method,
139 executable_path: std::env::current_exe()?,
140 needs_update: true, };
142
143 if !confirm_update(
145 &update_info.current_version,
146 &update_info.latest_version,
147 force,
148 )? {
149 println!("{}", "Update cancelled.".yellow());
150 return Ok(());
151 }
152
153 println!();
155 perform_update(&update_info).await?;
156
157 Ok(())
158}
159
160fn confirm_update(current: &str, target: &str, force: bool) -> Result<bool> {
161 use std::io::{self, Write};
162
163 if force {
164 println!(
165 "\n{}",
166 format!("Force updating from v{} to v{}", current, target).yellow()
167 );
168 return Ok(true);
169 }
170
171 print!(
172 "\n{} ",
173 format!("Update from v{} to v{}? [Y/n]", current, target).yellow()
174 );
175 io::stdout().flush()?;
176
177 let mut input = String::new();
178 io::stdin().read_line(&mut input)?;
179
180 let input = input.trim().to_lowercase();
181 Ok(input.is_empty() || input == "y" || input == "yes")
182}