Updated doctor command to work with FreeBSD
This commit is contained in:
@@ -43,7 +43,6 @@ pub fn run_diagnostics(fix: bool) -> Result<()> {
|
|||||||
.bold()
|
.bold()
|
||||||
);
|
);
|
||||||
if fix {
|
if fix {
|
||||||
// Check optional tools
|
|
||||||
let optional_missing = !health.cmake_ok
|
let optional_missing = !health.cmake_ok
|
||||||
|| !health.cpp_compiler_ok
|
|| !health.cpp_compiler_ok
|
||||||
|| !health.git_ok;
|
|| !health.git_ok;
|
||||||
@@ -76,13 +75,11 @@ pub fn run_diagnostics(fix: bool) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_system_health() -> SystemHealth {
|
pub fn check_system_health() -> SystemHealth {
|
||||||
// arduino-cli
|
|
||||||
let (arduino_cli_ok, arduino_cli_path) = match board::find_arduino_cli() {
|
let (arduino_cli_ok, arduino_cli_path) = match board::find_arduino_cli() {
|
||||||
Some(path) => (true, Some(path.display().to_string())),
|
Some(path) => (true, Some(path.display().to_string())),
|
||||||
None => (false, None),
|
None => (false, None),
|
||||||
};
|
};
|
||||||
|
|
||||||
// AVR core
|
|
||||||
let avr_core_ok = if let Some(ref path_str) = arduino_cli_path {
|
let avr_core_ok = if let Some(ref path_str) = arduino_cli_path {
|
||||||
let path = std::path::Path::new(path_str);
|
let path = std::path::Path::new(path_str);
|
||||||
board::is_avr_core_installed(path)
|
board::is_avr_core_installed(path)
|
||||||
@@ -90,16 +87,10 @@ pub fn check_system_health() -> SystemHealth {
|
|||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
// avr-size (optional)
|
|
||||||
let avr_size_ok = which::which("avr-size").is_ok();
|
let avr_size_ok = which::which("avr-size").is_ok();
|
||||||
|
|
||||||
// dialout group (Linux only)
|
|
||||||
let dialout_ok = check_dialout();
|
let dialout_ok = check_dialout();
|
||||||
|
|
||||||
// cmake (optional -- for host tests)
|
|
||||||
let cmake_ok = which::which("cmake").is_ok();
|
let cmake_ok = which::which("cmake").is_ok();
|
||||||
|
|
||||||
// C++ compiler (optional -- for host tests)
|
|
||||||
let cpp_on_path = which::which("g++").is_ok()
|
let cpp_on_path = which::which("g++").is_ok()
|
||||||
|| which::which("clang++").is_ok()
|
|| which::which("clang++").is_ok()
|
||||||
|| which::which("cl").is_ok();
|
|| which::which("cl").is_ok();
|
||||||
@@ -109,10 +100,7 @@ pub fn check_system_health() -> SystemHealth {
|
|||||||
has_cpp_compiler()
|
has_cpp_compiler()
|
||||||
};
|
};
|
||||||
|
|
||||||
// git
|
|
||||||
let git_ok = which::which("git").is_ok();
|
let git_ok = which::which("git").is_ok();
|
||||||
|
|
||||||
// Serial ports
|
|
||||||
let ports_found = board::list_ports().len();
|
let ports_found = board::list_ports().len();
|
||||||
|
|
||||||
SystemHealth {
|
SystemHealth {
|
||||||
@@ -129,7 +117,6 @@ pub fn check_system_health() -> SystemHealth {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check for a C++ compiler on any platform.
|
|
||||||
fn has_cpp_compiler() -> bool {
|
fn has_cpp_compiler() -> bool {
|
||||||
if which::which("g++").is_ok() || which::which("clang++").is_ok() {
|
if which::which("g++").is_ok() || which::which("clang++").is_ok() {
|
||||||
return true;
|
return true;
|
||||||
@@ -139,8 +126,6 @@ fn has_cpp_compiler() -> bool {
|
|||||||
if which::which("cl").is_ok() {
|
if which::which("cl").is_ok() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// cl.exe may be installed via VS Build Tools but not on PATH.
|
|
||||||
// Check via vswhere.exe (ships with VS installer).
|
|
||||||
if let Ok(output) = std::process::Command::new(
|
if let Ok(output) = std::process::Command::new(
|
||||||
r"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe",
|
r"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe",
|
||||||
)
|
)
|
||||||
@@ -161,7 +146,6 @@ fn print_diagnostics(health: &SystemHealth) {
|
|||||||
println!("{}", "Required:".bright_yellow().bold());
|
println!("{}", "Required:".bright_yellow().bold());
|
||||||
println!();
|
println!();
|
||||||
|
|
||||||
// arduino-cli
|
|
||||||
if health.arduino_cli_ok {
|
if health.arduino_cli_ok {
|
||||||
println!(
|
println!(
|
||||||
" {} arduino-cli {}",
|
" {} arduino-cli {}",
|
||||||
@@ -176,7 +160,6 @@ fn print_diagnostics(health: &SystemHealth) {
|
|||||||
println!(" {} arduino-cli {}", "MISSING".red(), "not found in PATH".red());
|
println!(" {} arduino-cli {}", "MISSING".red(), "not found in PATH".red());
|
||||||
}
|
}
|
||||||
|
|
||||||
// AVR core
|
|
||||||
if health.avr_core_ok {
|
if health.avr_core_ok {
|
||||||
println!(" {} arduino:avr core installed", "ok".green());
|
println!(" {} arduino:avr core installed", "ok".green());
|
||||||
} else if health.arduino_cli_ok {
|
} else if health.arduino_cli_ok {
|
||||||
@@ -197,7 +180,6 @@ fn print_diagnostics(health: &SystemHealth) {
|
|||||||
println!("{}", "Optional:".bright_yellow().bold());
|
println!("{}", "Optional:".bright_yellow().bold());
|
||||||
println!();
|
println!();
|
||||||
|
|
||||||
// avr-size
|
|
||||||
if health.avr_size_ok {
|
if health.avr_size_ok {
|
||||||
println!(" {} avr-size (binary size reporting)", "ok".green());
|
println!(" {} avr-size (binary size reporting)", "ok".green());
|
||||||
} else if !health.avr_core_ok {
|
} else if !health.avr_core_ok {
|
||||||
@@ -214,32 +196,32 @@ fn print_diagnostics(health: &SystemHealth) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// dialout
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
{
|
{
|
||||||
|
let group_name = serial_group_name();
|
||||||
if health.dialout_ok {
|
if health.dialout_ok {
|
||||||
println!(" {} user in dialout group", "ok".green());
|
println!(" {} user in {} group", "ok".green(), group_name);
|
||||||
} else {
|
} else {
|
||||||
|
let fix_cmd = serial_group_fix_command();
|
||||||
println!(
|
println!(
|
||||||
" {} dialout group {}",
|
" {} {} group {}",
|
||||||
"WARN".yellow(),
|
"WARN".yellow(),
|
||||||
"run: sudo usermod -aG dialout $USER".yellow()
|
group_name,
|
||||||
|
format!("run: {}", fix_cmd).yellow()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// cmake
|
|
||||||
if health.cmake_ok {
|
if health.cmake_ok {
|
||||||
println!(" {} cmake (for host-side tests)", "ok".green());
|
println!(" {} cmake (for host-side tests)", "ok".green());
|
||||||
} else {
|
} else {
|
||||||
println!(
|
println!(
|
||||||
" {} cmake {}",
|
" {} cmake {}",
|
||||||
"na".yellow(),
|
"na".yellow(),
|
||||||
hint_cmake().yellow()
|
hint_cmake().as_str().yellow()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// C++ compiler
|
|
||||||
if health.cpp_on_path {
|
if health.cpp_on_path {
|
||||||
println!(" {} C++ compiler", "ok".green());
|
println!(" {} C++ compiler", "ok".green());
|
||||||
} else if health.cpp_compiler_ok {
|
} else if health.cpp_compiler_ok {
|
||||||
@@ -252,18 +234,17 @@ fn print_diagnostics(health: &SystemHealth) {
|
|||||||
println!(
|
println!(
|
||||||
" {} C++ compiler {}",
|
" {} C++ compiler {}",
|
||||||
"na".yellow(),
|
"na".yellow(),
|
||||||
hint_cpp_compiler().yellow()
|
hint_cpp_compiler().as_str().yellow()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// git
|
|
||||||
if health.git_ok {
|
if health.git_ok {
|
||||||
println!(" {} git", "ok".green());
|
println!(" {} git", "ok".green());
|
||||||
} else {
|
} else {
|
||||||
println!(
|
println!(
|
||||||
" {} git {}",
|
" {} git {}",
|
||||||
"na".yellow(),
|
"na".yellow(),
|
||||||
hint_git().yellow()
|
hint_git().as_str().yellow()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,15 +259,19 @@ fn print_diagnostics(health: &SystemHealth) {
|
|||||||
health.ports_found
|
health.ports_found
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
let port_hint = if is_freebsd() {
|
||||||
|
"(plug in a board to detect -- FreeBSD ports appear as /dev/cuaU0)"
|
||||||
|
} else {
|
||||||
|
"(plug in a board to detect)"
|
||||||
|
};
|
||||||
println!(
|
println!(
|
||||||
" {} no serial ports {}",
|
" {} no serial ports {}",
|
||||||
"na".yellow(),
|
"na".yellow(),
|
||||||
"(plug in a board to detect)".yellow()
|
port_hint.yellow()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Print step-by-step fix instructions when required items are missing.
|
|
||||||
fn print_fix_instructions(health: &SystemHealth) {
|
fn print_fix_instructions(health: &SystemHealth) {
|
||||||
println!("{}", "How to fix:".bright_cyan().bold());
|
println!("{}", "How to fix:".bright_cyan().bold());
|
||||||
println!();
|
println!();
|
||||||
@@ -310,11 +295,32 @@ fn print_fix_instructions(health: &SystemHealth) {
|
|||||||
println!(" Option C -- Direct download:");
|
println!(" Option C -- Direct download:");
|
||||||
println!(
|
println!(
|
||||||
" {}",
|
" {}",
|
||||||
"https://arduino.github.io/arduino-cli/installation/"
|
"https://arduino.github.io/arduino-cli/installation/".bright_cyan()
|
||||||
.bright_cyan()
|
|
||||||
);
|
);
|
||||||
} else if cfg!(target_os = "macos") {
|
} else if cfg!(target_os = "macos") {
|
||||||
println!(" {}", "brew install arduino-cli".bright_cyan());
|
println!(" {}", "brew install arduino-cli".bright_cyan());
|
||||||
|
} else if is_freebsd() {
|
||||||
|
println!();
|
||||||
|
println!(" FreeBSD -- download the Linux binary (runs via Linux compat layer):");
|
||||||
|
println!(
|
||||||
|
" {}",
|
||||||
|
"curl -L https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_Linux_64bit.tar.gz -o /tmp/arduino-cli.tar.gz"
|
||||||
|
.bright_cyan()
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
" {}",
|
||||||
|
"tar xzf /tmp/arduino-cli.tar.gz -C /tmp".bright_cyan()
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
" {}",
|
||||||
|
"sudo mv /tmp/arduino-cli /usr/local/bin/".bright_cyan()
|
||||||
|
);
|
||||||
|
println!();
|
||||||
|
println!(" Ensure Linux compat layer is active:");
|
||||||
|
println!(
|
||||||
|
" {}",
|
||||||
|
"sudo sysrc linux_enable=YES && sudo service linux start".bright_cyan()
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
println!();
|
println!();
|
||||||
println!(" Option A -- Install script:");
|
println!(" Option A -- Install script:");
|
||||||
@@ -362,46 +368,44 @@ fn print_fix_instructions(health: &SystemHealth) {
|
|||||||
println!(
|
println!(
|
||||||
" {}. {}",
|
" {}. {}",
|
||||||
step,
|
step,
|
||||||
"Install the AVR core and verify everything:"
|
"Install the AVR core and verify everything:".bright_white().bold()
|
||||||
.bright_white()
|
|
||||||
.bold()
|
|
||||||
);
|
);
|
||||||
println!(" {}", "anvil setup".bright_cyan());
|
println!(" {}", "anvil setup".bright_cyan());
|
||||||
println!();
|
println!();
|
||||||
// step += 1;
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
if !health.dialout_ok {
|
||||||
|
let fix_cmd = serial_group_fix_command();
|
||||||
|
println!(
|
||||||
|
" {}",
|
||||||
|
format!(
|
||||||
|
"Tip: add yourself to the serial group for board upload access: {}",
|
||||||
|
fix_cmd
|
||||||
|
)
|
||||||
|
.bright_black()
|
||||||
|
);
|
||||||
|
println!();
|
||||||
}
|
}
|
||||||
|
|
||||||
if !health.git_ok {
|
if !health.git_ok {
|
||||||
println!(
|
println!(
|
||||||
" {}",
|
" {}",
|
||||||
"Tip: git is optional but recommended for version control."
|
"Tip: git is optional but recommended for version control.".bright_black()
|
||||||
.bright_black()
|
|
||||||
);
|
);
|
||||||
if cfg!(target_os = "windows") {
|
if cfg!(target_os = "windows") {
|
||||||
println!(
|
println!(" {}", "winget install Git.Git".bright_black());
|
||||||
" {}",
|
|
||||||
"winget install Git.Git".bright_black()
|
|
||||||
);
|
|
||||||
} else if cfg!(target_os = "macos") {
|
} else if cfg!(target_os = "macos") {
|
||||||
println!(
|
println!(" {}", "xcode-select --install".bright_black());
|
||||||
" {}",
|
} else if is_freebsd() {
|
||||||
"xcode-select --install".bright_black()
|
println!(" {}", "sudo pkg install git".bright_black());
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
println!(
|
println!(" {}", "sudo apt install git".bright_black());
|
||||||
" {}",
|
|
||||||
"sudo apt install git".bright_black()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==========================================================================
|
|
||||||
// --fix: automated installation
|
|
||||||
// ==========================================================================
|
|
||||||
|
|
||||||
/// Prompt the user for yes/no confirmation.
|
|
||||||
fn confirm(prompt: &str) -> bool {
|
fn confirm(prompt: &str) -> bool {
|
||||||
print!("{} [Y/n] ", prompt);
|
print!("{} [Y/n] ", prompt);
|
||||||
io::stdout().flush().ok();
|
io::stdout().flush().ok();
|
||||||
@@ -413,7 +417,6 @@ fn confirm(prompt: &str) -> bool {
|
|||||||
trimmed.is_empty() || trimmed == "y" || trimmed == "yes"
|
trimmed.is_empty() || trimmed == "y" || trimmed == "yes"
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run a command, streaming output to the terminal.
|
|
||||||
fn run_cmd(program: &str, args: &[&str]) -> bool {
|
fn run_cmd(program: &str, args: &[&str]) -> bool {
|
||||||
println!(
|
println!(
|
||||||
" {} {} {}",
|
" {} {} {}",
|
||||||
@@ -428,7 +431,6 @@ fn run_cmd(program: &str, args: &[&str]) -> bool {
|
|||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Detect which package manager is available on the system.
|
|
||||||
fn detect_package_manager() -> Option<&'static str> {
|
fn detect_package_manager() -> Option<&'static str> {
|
||||||
if cfg!(target_os = "windows") {
|
if cfg!(target_os = "windows") {
|
||||||
if which::which("winget").is_ok() {
|
if which::which("winget").is_ok() {
|
||||||
@@ -444,8 +446,13 @@ fn detect_package_manager() -> Option<&'static str> {
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
} else if is_freebsd() {
|
||||||
|
if which::which("pkg").is_ok() {
|
||||||
|
Some("pkg")
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Linux
|
|
||||||
if which::which("apt").is_ok() {
|
if which::which("apt").is_ok() {
|
||||||
Some("apt")
|
Some("apt")
|
||||||
} else if which::which("dnf").is_ok() {
|
} else if which::which("dnf").is_ok() {
|
||||||
@@ -458,11 +465,9 @@ fn detect_package_manager() -> Option<&'static str> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fix required items (arduino-cli, avr core).
|
|
||||||
fn run_fix(health: &SystemHealth) -> Result<()> {
|
fn run_fix(health: &SystemHealth) -> Result<()> {
|
||||||
let pm = detect_package_manager();
|
let pm = detect_package_manager();
|
||||||
|
|
||||||
// -- arduino-cli --
|
|
||||||
if !health.arduino_cli_ok {
|
if !health.arduino_cli_ok {
|
||||||
println!(
|
println!(
|
||||||
"{}",
|
"{}",
|
||||||
@@ -524,10 +529,39 @@ fn run_fix(health: &SystemHealth) -> Result<()> {
|
|||||||
println!("{} arduino-cli installed.", "ok".green());
|
println!("{} arduino-cli installed.", "ok".green());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some("dnf") => {
|
Some("pkg") => {
|
||||||
println!(
|
println!(
|
||||||
" arduino-cli is not in dnf repos. Install manually:"
|
" {}",
|
||||||
|
"arduino-cli is not in the FreeBSD ports tree.".bright_yellow()
|
||||||
);
|
);
|
||||||
|
println!(
|
||||||
|
" {}",
|
||||||
|
"It runs via the Linux compatibility layer (linux_enable must be YES).".bright_black()
|
||||||
|
);
|
||||||
|
if confirm("Download and install the Linux arduino-cli binary now?") {
|
||||||
|
if !run_cmd("curl", &[
|
||||||
|
"-L",
|
||||||
|
"https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_Linux_64bit.tar.gz",
|
||||||
|
"-o", "/tmp/arduino-cli.tar.gz",
|
||||||
|
]) {
|
||||||
|
println!("{} Download failed. Check your internet connection.", "FAIL".red());
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
run_cmd("tar", &["xzf", "/tmp/arduino-cli.tar.gz", "-C", "/tmp"]);
|
||||||
|
if !run_cmd("sudo", &["mv", "/tmp/arduino-cli", "/usr/local/bin/arduino-cli"]) {
|
||||||
|
println!("{} Could not move binary to /usr/local/bin/.", "FAIL".red());
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
println!("{} arduino-cli installed.", "ok".green());
|
||||||
|
println!(
|
||||||
|
" {}",
|
||||||
|
"If it fails to run, ensure Linux compat is active: sudo sysrc linux_enable=YES && sudo service linux start"
|
||||||
|
.bright_black()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some("dnf") => {
|
||||||
|
println!(" arduino-cli is not in dnf repos. Install manually:");
|
||||||
println!(
|
println!(
|
||||||
" {}",
|
" {}",
|
||||||
"curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | sh"
|
"curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | sh"
|
||||||
@@ -545,19 +579,15 @@ fn run_fix(health: &SystemHealth) -> Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
println!(
|
println!(" No supported package manager found. Install manually:");
|
||||||
" No supported package manager found. Install manually:"
|
|
||||||
);
|
|
||||||
println!(
|
println!(
|
||||||
" {}",
|
" {}",
|
||||||
"https://arduino.github.io/arduino-cli/installation/"
|
"https://arduino.github.io/arduino-cli/installation/".bright_cyan()
|
||||||
.bright_cyan()
|
|
||||||
);
|
);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-check after install
|
|
||||||
if board::find_arduino_cli().is_none() {
|
if board::find_arduino_cli().is_none() {
|
||||||
println!();
|
println!();
|
||||||
println!(
|
println!(
|
||||||
@@ -568,7 +598,6 @@ fn run_fix(health: &SystemHealth) -> Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- AVR core --
|
|
||||||
if !health.avr_core_ok {
|
if !health.avr_core_ok {
|
||||||
if health.arduino_cli_ok || board::find_arduino_cli().is_some() {
|
if health.arduino_cli_ok || board::find_arduino_cli().is_some() {
|
||||||
println!();
|
println!();
|
||||||
@@ -589,13 +618,10 @@ fn run_fix(health: &SystemHealth) -> Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Offer optional tools too
|
|
||||||
run_fix_optional(health)?;
|
run_fix_optional(health)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fix optional items (cmake, C++ compiler, git).
|
|
||||||
fn run_fix_optional(health: &SystemHealth) -> Result<()> {
|
fn run_fix_optional(health: &SystemHealth) -> Result<()> {
|
||||||
let pm = detect_package_manager();
|
let pm = detect_package_manager();
|
||||||
|
|
||||||
@@ -666,6 +692,11 @@ fn fix_spec_cmake(pm: Option<&str>) -> FixSpec {
|
|||||||
program: "sudo",
|
program: "sudo",
|
||||||
args: &["apt", "install", "-y", "cmake"],
|
args: &["apt", "install", "-y", "cmake"],
|
||||||
},
|
},
|
||||||
|
Some("pkg") => FixSpec::Auto {
|
||||||
|
prompt: "Install cmake via pkg?",
|
||||||
|
program: "sudo",
|
||||||
|
args: &["pkg", "install", "-y", "cmake"],
|
||||||
|
},
|
||||||
Some("dnf") => FixSpec::Auto {
|
Some("dnf") => FixSpec::Auto {
|
||||||
prompt: "Install cmake via dnf?",
|
prompt: "Install cmake via dnf?",
|
||||||
program: "sudo",
|
program: "sudo",
|
||||||
@@ -702,6 +733,9 @@ fn fix_spec_cpp(pm: Option<&str>) -> FixSpec {
|
|||||||
program: "sudo",
|
program: "sudo",
|
||||||
args: &["apt", "install", "-y", "g++"],
|
args: &["apt", "install", "-y", "g++"],
|
||||||
},
|
},
|
||||||
|
Some("pkg") => FixSpec::Manual {
|
||||||
|
message: "clang++ is already part of the FreeBSD base system",
|
||||||
|
},
|
||||||
Some("dnf") => FixSpec::Auto {
|
Some("dnf") => FixSpec::Auto {
|
||||||
prompt: "Install g++ via dnf?",
|
prompt: "Install g++ via dnf?",
|
||||||
program: "sudo",
|
program: "sudo",
|
||||||
@@ -740,6 +774,11 @@ fn fix_spec_git(pm: Option<&str>) -> FixSpec {
|
|||||||
program: "sudo",
|
program: "sudo",
|
||||||
args: &["apt", "install", "-y", "git"],
|
args: &["apt", "install", "-y", "git"],
|
||||||
},
|
},
|
||||||
|
Some("pkg") => FixSpec::Auto {
|
||||||
|
prompt: "Install git via pkg?",
|
||||||
|
program: "sudo",
|
||||||
|
args: &["pkg", "install", "-y", "git"],
|
||||||
|
},
|
||||||
Some("dnf") => FixSpec::Auto {
|
Some("dnf") => FixSpec::Auto {
|
||||||
prompt: "Install git via dnf?",
|
prompt: "Install git via dnf?",
|
||||||
program: "sudo",
|
program: "sudo",
|
||||||
@@ -756,10 +795,6 @@ fn fix_spec_git(pm: Option<&str>) -> FixSpec {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// Platform-aware install hints (one-liners for the diagnostics table)
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
fn hint_avr_size_not_on_path() -> &'static str {
|
fn hint_avr_size_not_on_path() -> &'static str {
|
||||||
if cfg!(target_os = "windows") {
|
if cfg!(target_os = "windows") {
|
||||||
"installed but not on PATH (binary size reports will be skipped)"
|
"installed but not on PATH (binary size reports will be skipped)"
|
||||||
@@ -768,45 +803,82 @@ fn hint_avr_size_not_on_path() -> &'static str {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hint_cmake() -> &'static str {
|
fn hint_cmake() -> String {
|
||||||
if cfg!(target_os = "windows") {
|
if cfg!(target_os = "windows") {
|
||||||
"install: winget install Kitware.CMake (or choco install cmake)"
|
"install: winget install Kitware.CMake (or choco install cmake)".into()
|
||||||
} else if cfg!(target_os = "macos") {
|
} else if cfg!(target_os = "macos") {
|
||||||
"install: brew install cmake"
|
"install: brew install cmake".into()
|
||||||
|
} else if is_freebsd() {
|
||||||
|
"install: sudo pkg install cmake".into()
|
||||||
} else {
|
} else {
|
||||||
"install: sudo apt install cmake"
|
match detect_package_manager() {
|
||||||
|
Some("dnf") => "install: sudo dnf install cmake".into(),
|
||||||
|
Some("pacman") => "install: sudo pacman -S cmake".into(),
|
||||||
|
_ => "install: sudo apt install cmake".into(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hint_cpp_compiler() -> &'static str {
|
fn hint_cpp_compiler() -> String {
|
||||||
if cfg!(target_os = "windows") {
|
if cfg!(target_os = "windows") {
|
||||||
"install: choco install mingw (or open Developer Command Prompt for MSVC)"
|
"install: choco install mingw (or open Developer Command Prompt for MSVC)".into()
|
||||||
} else if cfg!(target_os = "macos") {
|
} else if cfg!(target_os = "macos") {
|
||||||
"install: xcode-select --install"
|
"install: xcode-select --install".into()
|
||||||
|
} else if is_freebsd() {
|
||||||
|
"clang++ is part of the FreeBSD base system -- check your PATH".into()
|
||||||
} else {
|
} else {
|
||||||
"install: sudo apt install g++"
|
match detect_package_manager() {
|
||||||
|
Some("dnf") => "install: sudo dnf install gcc-c++".into(),
|
||||||
|
Some("pacman") => "install: sudo pacman -S gcc".into(),
|
||||||
|
_ => "install: sudo apt install g++".into(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hint_git() -> &'static str {
|
fn hint_git() -> String {
|
||||||
if cfg!(target_os = "windows") {
|
if cfg!(target_os = "windows") {
|
||||||
"install: winget install Git.Git (or https://git-scm.com)"
|
"install: winget install Git.Git (or https://git-scm.com)".into()
|
||||||
} else if cfg!(target_os = "macos") {
|
} else if cfg!(target_os = "macos") {
|
||||||
"install: xcode-select --install (or brew install git)"
|
"install: xcode-select --install (or brew install git)".into()
|
||||||
|
} else if is_freebsd() {
|
||||||
|
"install: sudo pkg install git".into()
|
||||||
} else {
|
} else {
|
||||||
"install: sudo apt install git"
|
match detect_package_manager() {
|
||||||
|
Some("dnf") => "install: sudo dnf install git".into(),
|
||||||
|
Some("pacman") => "install: sudo pacman -S git".into(),
|
||||||
|
_ => "install: sudo apt install git".into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_freebsd() -> bool {
|
||||||
|
cfg!(target_os = "freebsd")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serial_group_name() -> &'static str {
|
||||||
|
if is_freebsd() {
|
||||||
|
"dialer"
|
||||||
|
} else {
|
||||||
|
"dialout"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serial_group_fix_command() -> String {
|
||||||
|
if is_freebsd() {
|
||||||
|
"sudo pw groupmod dialer -m $USER".to_string()
|
||||||
|
} else {
|
||||||
|
"sudo usermod -aG dialout $USER".to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_dialout() -> bool {
|
fn check_dialout() -> bool {
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
{
|
{
|
||||||
let output = std::process::Command::new("groups")
|
let group = serial_group_name();
|
||||||
.output();
|
match std::process::Command::new("groups").output() {
|
||||||
match output {
|
|
||||||
Ok(out) => {
|
Ok(out) => {
|
||||||
let groups = String::from_utf8_lossy(&out.stdout);
|
let groups = String::from_utf8_lossy(&out.stdout);
|
||||||
groups.contains("dialout")
|
groups.contains(group)
|
||||||
}
|
}
|
||||||
Err(_) => false,
|
Err(_) => false,
|
||||||
}
|
}
|
||||||
@@ -814,6 +886,6 @@ fn check_dialout() -> bool {
|
|||||||
|
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
{
|
{
|
||||||
true // Not applicable on Windows
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user