use crate::{Error, Result};
use console::style;
pub async fn execute(channel: String, rules_only: bool, dry_run: bool) -> Result<()> {
if dry_run {
println!(
"{}",
style("đ Dry run mode - showing what would be updated")
.bold()
.yellow()
);
} else {
println!("{}", style("đ Updating Ferrous Forge...").bold().cyan());
}
if rules_only {
update_rules(&channel, dry_run).await?;
} else {
update_binary(&channel, dry_run).await?;
update_rules(&channel, dry_run).await?;
}
if !dry_run {
println!("{}", style("â
Update complete!").bold().green());
}
Ok(())
}
async fn update_binary(channel: &str, dry_run: bool) -> Result<()> {
println!("đĻ Checking for binary updates on {} channel...", channel);
if dry_run {
println!(" Would check GitHub releases for newer version");
println!(
" Would download and install new binary for {}",
get_target_name()?
);
return Ok(());
}
let status = self_update::backends::github::Update::configure()
.repo_owner("kryptobaseddev")
.repo_name("ferrous-forge")
.bin_name("ferrous-forge")
.target(&get_target_name()?)
.bin_path_in_archive(&get_bin_path_in_archive())
.bin_install_path(
std::env::current_exe()
.map_err(|e| Error::io(format!("Cannot locate current executable: {e}")))?,
)
.current_version(env!("CARGO_PKG_VERSION"))
.show_download_progress(true)
.show_output(true)
.build()
.map_err(|e| Error::process(format!("Failed to configure updater: {e}")))?
.update()
.map_err(|e| Error::process(format!("Update failed: {e}")))?;
match status {
self_update::Status::Updated(v) => {
println!(
"{}",
style(format!("đ Updated to version {v}!")).green().bold()
);
}
self_update::Status::UpToDate(v) => {
println!("{}", style(format!("â
Already up to date (v{v})")).green());
}
}
Ok(())
}
fn get_target_name() -> Result<String> {
let os = std::env::consts::OS;
let arch = std::env::consts::ARCH;
let suffix = match (os, arch) {
("linux", "x86_64") => {
if cfg!(target_env = "musl") {
"linux-x86_64-musl.tar.gz"
} else {
"linux-x86_64.tar.gz"
}
}
("macos", "x86_64") => "macos-x86_64.tar.gz",
("macos", "aarch64") => "macos-aarch64.tar.gz",
("windows", "x86_64") => "windows-x86_64.zip",
_ => {
return Err(Error::config(format!(
"Self-update is not supported on {os}/{arch}"
)));
}
};
Ok(suffix.to_string())
}
fn get_bin_path_in_archive() -> String {
if cfg!(windows) {
"ferrous-forge.exe".to_string()
} else {
"ferrous-forge".to_string()
}
}
async fn update_rules(channel: &str, dry_run: bool) -> Result<()> {
println!("đ Checking for rules updates on {} channel...", channel);
if dry_run {
println!(" Would fetch latest clippy rules from repository");
println!(" Would update ~/.clippy.toml with new rules");
return Ok(());
}
println!(" âšī¸ Rules are bundled with the binary and updated automatically.");
Ok(())
}