use crate::config::Settings;
use crate::env;
use crate::error::{CjvError, Result};
use crate::resolve;
use crate::toolchain::Toolchain;
use std::process::Command;
pub const PROXY_TOOLS: &[&str] = &[
"cjc",
"cjc-frontend",
"cjpm",
"cjfmt",
"cjlint",
"cjdb",
"cjcov",
"cjprof",
];
pub fn is_proxy_tool(name: &str) -> bool {
let name = std::path::Path::new(name)
.file_stem()
.map(|s| s.to_string_lossy())
.unwrap_or(std::borrow::Cow::Borrowed(name));
PROXY_TOOLS.contains(&name.as_ref())
}
pub fn extract_tool_name(arg0: &str) -> String {
std::path::Path::new(arg0)
.file_stem()
.map(|s| s.to_string_lossy().to_string())
.unwrap_or_else(|| arg0.to_string())
}
pub fn run_proxy(tool_name: &str, args: &[String]) -> Result<i32> {
let settings = Settings::load()?;
let active_tc = crate::config::resolve_active_toolchain(&settings)
.ok_or_else(|| {
CjvError::Other(
"No active toolchain configured. Install one with 'cjv install lts' and set it as default with 'cjv default lts'".to_string(),
)
})?;
if !Toolchain::is_installed(&active_tc) {
if settings.get_auto_install() {
println!(
"Toolchain '{}' is not installed. Installing automatically...",
active_tc
);
let rt = tokio::runtime::Runtime::new()
.map_err(|e| CjvError::Other(format!("Failed to create runtime: {}", e)))?;
rt.block_on(auto_install_toolchain(&active_tc, &settings))?;
} else {
return Err(CjvError::ToolchainNotInstalled(active_tc));
}
}
let tool_path = resolve::find_tool_path(&active_tc, tool_name)?;
let mut cmd = Command::new(&tool_path);
cmd.args(args);
env::inject_runtime_env(&mut cmd, &active_tc);
let mut child = cmd
.stdin(std::process::Stdio::inherit())
.stdout(std::process::Stdio::inherit())
.stderr(std::process::Stdio::inherit())
.spawn()
.map_err(|e| {
CjvError::Proxy(format!(
"Failed to execute '{}': {}",
tool_path.display(),
e
))
})?;
let status = child
.wait()
.map_err(|e| CjvError::Proxy(format!("Failed to wait for '{}': {}", tool_name, e)))?;
Ok(status.code().unwrap_or(1))
}
async fn auto_install_toolchain(name: &str, settings: &Settings) -> Result<()> {
let tc_name = crate::dist::download_and_install_toolchain(name, settings).await?;
println!("Toolchain '{}' installed automatically.", tc_name);
Ok(())
}