diff --git a/src/commands/doctor.rs b/src/commands/doctor.rs index fdfa345..d655316 100644 --- a/src/commands/doctor.rs +++ b/src/commands/doctor.rs @@ -15,4 +15,4 @@ impl Command { let component_manager = ComponentManager::new(github_token.clone()); component_manager.run_doctor_checks().await } -} \ No newline at end of file +} diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 94b8bfe..45af5a3 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -1,6 +1,7 @@ // Copyright (c) Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 +mod cleanup; mod default; mod doctor; mod install; @@ -11,7 +12,6 @@ mod show; mod switch; mod update; mod which; -mod cleanup; use crate::{handlers::self_::check_for_updates, types::BinaryVersion}; diff --git a/src/component/doctor.rs b/src/component/doctor.rs index 6e15479..2ba3f60 100644 --- a/src/component/doctor.rs +++ b/src/component/doctor.rs @@ -44,6 +44,7 @@ pub async fn run_doctor_checks() -> Result<()> { check_config_files(&mut check); check_dependencies(&mut check); check_network_connectivity(&mut check).await; + check_installed_binaries(&mut check); println!("\n{}", "Checkup complete.".bold()); if errors > 0 { @@ -236,6 +237,97 @@ async fn check_network_connectivity(check: &mut impl FnMut(&str, Result)) { + // First check suiup itself + check_suiup_installation(check); + + // Then check registered binaries + check_registered_binaries(check); +} + +fn check_suiup_installation(check: &mut impl FnMut(&str, Result)) { + // Check if suiup is in PATH + #[cfg(unix)] + let which_cmd = "which"; + #[cfg(windows)] + let which_cmd = "where"; + + if let Ok(output) = std::process::Command::new(which_cmd).arg("suiup").output() { + if output.status.success() { + let suiup_path = String::from_utf8_lossy(&output.stdout).trim().to_string(); + check("suiup binary", Ok(format!("found at {}", suiup_path))); + } else { + check( + "suiup binary", + Err("WARN: suiup not found in PATH".to_string()), + ); + } + } else { + check( + "suiup binary", + Err("WARN: Unable to check suiup installation".to_string()), + ); + } +} + +fn check_registered_binaries(check: &mut impl FnMut(&str, Result)) { + match InstalledBinaries::read_from_file() { + Ok(binaries) => { + let mut valid_binaries = Vec::new(); + let mut invalid_binaries = Vec::new(); + + for binary in binaries.binaries() { + let binary_path = get_default_bin_dir().join(&binary.binary_name); + if binary_path.exists() && binary_path.is_file() { + valid_binaries.push(format!("{} ({})", binary.binary_name, binary.version)); + } else { + invalid_binaries.push(format!("{} ({})", binary.binary_name, binary.version)); + } + } + + if invalid_binaries.is_empty() { + if valid_binaries.is_empty() { + check( + "Registered binaries", + Ok("No binaries registered yet".to_string()), + ); + } else { + check( + "Registered binaries", + Ok(format!( + "All {} binaries are valid: {}", + valid_binaries.len(), + valid_binaries.join(", ") + )), + ); + } + } else { + let invalid_list = invalid_binaries.join(", "); + let valid_list = if valid_binaries.is_empty() { + "none".to_string() + } else { + valid_binaries.join(", ") + }; + + check( + "Registered binaries", + Err(format!( + "WARN: {} valid, {} missing/invalid. Valid: {}. Missing/Invalid: {}", + valid_binaries.len(), + invalid_binaries.len(), + valid_list, + invalid_list + )), + ); + } + } + Err(_) => check( + "Registered binaries", + Ok("No binaries registered yet".to_string()), + ), + } +} + #[cfg(test)] mod tests { use super::*; @@ -307,7 +399,9 @@ mod tests { println!("Path exists: {}", path.exists()); let result = check_suiup_data_dir(); assert!(result.is_err()); - assert!(result.unwrap_err().contains("suiup data directory not found")); + assert!(result + .unwrap_err() + .contains("suiup data directory not found")); // Restore original env var #[cfg(windows)] diff --git a/src/component/mod.rs b/src/component/mod.rs index 7bf7627..1892743 100644 --- a/src/component/mod.rs +++ b/src/component/mod.rs @@ -39,7 +39,9 @@ impl ComponentManager { .await } ComponentCommands::Remove { binary } => self.remove_component(binary).await, - ComponentCommands::Cleanup { all, days, dry_run } => self.handle_cleanup(all, days, dry_run).await + ComponentCommands::Cleanup { all, days, dry_run } => { + self.handle_cleanup(all, days, dry_run).await + } } } diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index b64073f..889b0cd 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -20,6 +20,7 @@ use std::os::unix::fs::PermissionsExt; use tar::Archive; use version::extract_version_from_release; +pub mod cleanup; pub mod download; pub mod install; pub mod release; @@ -29,7 +30,6 @@ pub mod switch; pub mod update; pub mod version; pub mod which; -pub mod cleanup; pub const RELEASES_ARCHIVES_FOLDER: &str = "releases"; diff --git a/tests/commands_test.rs b/tests/commands_test.rs index 09b2590..474a22f 100644 --- a/tests/commands_test.rs +++ b/tests/commands_test.rs @@ -8,9 +8,9 @@ mod tests { use std::time::{Duration, SystemTime}; use suiup::commands::{parse_component_with_version, BinaryName, CommandMetadata}; use suiup::handlers::cleanup::handle_cleanup; + use suiup::handlers::switch::parse_binary_spec; use suiup::paths; use tempfile::TempDir; - use suiup::handlers::switch::parse_binary_spec; #[test] fn test_parse_component_with_version() -> Result<(), anyhow::Error> { diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 668866d..d4236a0 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -630,7 +630,7 @@ mod tests { cmd.assert() .success() .stdout(predicate::str::contains("Removing all release archives")) - .stdout(predicate::str::contains("Cache cleared successfully")); + .stdout(predicate::str::contains("Cache cleared successfully")); // All files should be removed assert!(!file1.exists());