ferrous_forge/commands/
update.rs1use crate::{Error, Result};
4use console::style;
5
6pub async fn execute(channel: String, rules_only: bool, dry_run: bool) -> Result<()> {
12 if dry_run {
13 println!(
14 "{}",
15 style("đ Dry run mode - showing what would be updated")
16 .bold()
17 .yellow()
18 );
19 } else {
20 println!("{}", style("đ Updating Ferrous Forge...").bold().cyan());
21 }
22
23 if rules_only {
24 update_rules(&channel, dry_run).await?;
25 } else {
26 update_binary(&channel, dry_run).await?;
27 update_rules(&channel, dry_run).await?;
28 }
29
30 if !dry_run {
31 println!("{}", style("â
Update complete!").bold().green());
32 }
33
34 Ok(())
35}
36
37async fn update_binary(channel: &str, dry_run: bool) -> Result<()> {
46 println!("đĻ Checking for binary updates on {} channel...", channel);
47
48 if dry_run {
49 println!(" Would check GitHub releases for newer version");
50 println!(
51 " Would download and install new binary for {}",
52 get_target_name()?
53 );
54 return Ok(());
55 }
56
57 let status = tokio::task::spawn_blocking(move || {
60 self_update::backends::github::Update::configure()
61 .repo_owner("kryptobaseddev")
62 .repo_name("ferrous-forge")
63 .bin_name("ferrous-forge")
64 .target(&get_target_name()?)
65 .bin_path_in_archive(&get_bin_path_in_archive())
66 .bin_install_path(
67 std::env::current_exe()
68 .map_err(|e| Error::io(format!("Cannot locate current executable: {e}")))?,
69 )
70 .current_version(env!("CARGO_PKG_VERSION"))
71 .show_download_progress(true)
72 .show_output(true)
73 .build()
74 .map_err(|e| Error::process(format!("Failed to configure updater: {e}")))?
75 .update()
76 .map_err(|e| Error::process(format!("Update failed: {e}")))
77 })
78 .await
79 .map_err(|e| Error::process(format!("Update task panicked: {e}")))??;
80
81 match status {
82 self_update::Status::Updated(v) => {
83 println!(
84 "{}",
85 style(format!("đ Updated to version {v}!")).green().bold()
86 );
87 }
88 self_update::Status::UpToDate(v) => {
89 println!("{}", style(format!("â
Already up to date (v{v})")).green());
90 }
91 }
92
93 Ok(())
94}
95
96fn get_target_name() -> Result<String> {
101 let os = std::env::consts::OS;
102 let arch = std::env::consts::ARCH;
103
104 let suffix = match (os, arch) {
105 ("linux", "x86_64") => {
106 if cfg!(target_env = "musl") {
107 "linux-x86_64-musl.tar.gz"
108 } else {
109 "linux-x86_64.tar.gz"
110 }
111 }
112 ("macos", "x86_64") => "macos-x86_64.tar.gz",
113 ("macos", "aarch64") => "macos-aarch64.tar.gz",
114 ("windows", "x86_64") => "windows-x86_64.zip",
115 _ => {
116 return Err(Error::config(format!(
117 "Self-update is not supported on {os}/{arch}"
118 )));
119 }
120 };
121
122 Ok(suffix.to_string())
123}
124
125fn get_bin_path_in_archive() -> String {
127 if cfg!(windows) {
128 "ferrous-forge.exe".to_string()
129 } else {
130 "ferrous-forge".to_string()
131 }
132}
133
134async fn update_rules(channel: &str, dry_run: bool) -> Result<()> {
143 println!("đ Checking for rules updates on {} channel...", channel);
144
145 if dry_run {
146 println!(" Would fetch latest clippy rules from repository");
147 println!(" Would update ~/.clippy.toml with new rules");
148 return Ok(());
149 }
150
151 println!(" âšī¸ Rules are bundled with the binary and updated automatically.");
153
154 Ok(())
155}