diff options
| author | Daniel Polito <[email protected]> | 2026-01-05 14:07:46 -0300 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-01-06 01:07:46 +0800 |
| commit | 8e9a0c4ad014eb54d7ddd8de3b5f321de931f2f7 (patch) | |
| tree | 6d999aaf07fe3382a6aac28c3c47a03648cdd0cd /packages/desktop/src-tauri/src/cli.rs | |
| parent | ced093e64641de9e4fb7ed100325c3ffe730cc5c (diff) | |
| download | opencode-8e9a0c4ad014eb54d7ddd8de3b5f321de931f2f7.tar.gz opencode-8e9a0c4ad014eb54d7ddd8de3b5f321de931f2f7.zip | |
Desktop: Install CLI (#6526)
Co-authored-by: Brendan Allan <[email protected]>
Diffstat (limited to 'packages/desktop/src-tauri/src/cli.rs')
| -rw-r--r-- | packages/desktop/src-tauri/src/cli.rs | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/packages/desktop/src-tauri/src/cli.rs b/packages/desktop/src-tauri/src/cli.rs new file mode 100644 index 000000000..6b86cbcd2 --- /dev/null +++ b/packages/desktop/src-tauri/src/cli.rs @@ -0,0 +1,116 @@ +const CLI_INSTALL_DIR: &str = ".opencode/bin"; +const CLI_BINARY_NAME: &str = "opencode"; + +fn get_cli_install_path() -> Option<std::path::PathBuf> { + std::env::var("HOME").ok().map(|home| { + std::path::PathBuf::from(home) + .join(CLI_INSTALL_DIR) + .join(CLI_BINARY_NAME) + }) +} + +pub fn get_sidecar_path() -> std::path::PathBuf { + tauri::utils::platform::current_exe() + .expect("Failed to get current exe") + .parent() + .expect("Failed to get parent dir") + .join("opencode-cli") +} + +fn is_cli_installed() -> bool { + get_cli_install_path() + .map(|path| path.exists()) + .unwrap_or(false) +} + +const INSTALL_SCRIPT: &str = include_str!("../../../../install"); + +#[tauri::command] +pub fn install_cli() -> Result<String, String> { + if cfg!(not(unix)) { + return Err("CLI installation is only supported on macOS & Linux".to_string()); + } + + let sidecar = get_sidecar_path(); + if !sidecar.exists() { + return Err("Sidecar binary not found".to_string()); + } + + let temp_script = std::env::temp_dir().join("opencode-install.sh"); + std::fs::write(&temp_script, INSTALL_SCRIPT) + .map_err(|e| format!("Failed to write install script: {}", e))?; + + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + std::fs::set_permissions(&temp_script, std::fs::Permissions::from_mode(0o755)) + .map_err(|e| format!("Failed to set script permissions: {}", e))?; + } + + let output = std::process::Command::new(&temp_script) + .arg("--binary") + .arg(&sidecar) + .output() + .map_err(|e| format!("Failed to run install script: {}", e))?; + + let _ = std::fs::remove_file(&temp_script); + + if !output.status.success() { + let stderr = String::from_utf8_lossy(&output.stderr); + return Err(format!("Install script failed: {}", stderr)); + } + + let install_path = + get_cli_install_path().ok_or_else(|| "Could not determine install path".to_string())?; + + Ok(install_path.to_string_lossy().to_string()) +} + +pub fn sync_cli(app: tauri::AppHandle) -> Result<(), String> { + if cfg!(debug_assertions) { + println!("Skipping CLI sync for debug build"); + return Ok(()); + } + + if !is_cli_installed() { + println!("No CLI installation found, skipping sync"); + return Ok(()); + } + + let cli_path = + get_cli_install_path().ok_or_else(|| "Could not determine CLI install path".to_string())?; + + let output = std::process::Command::new(&cli_path) + .arg("--version") + .output() + .map_err(|e| format!("Failed to get CLI version: {}", e))?; + + if !output.status.success() { + return Err("Failed to get CLI version".to_string()); + } + + let cli_version_str = String::from_utf8_lossy(&output.stdout).trim().to_string(); + let cli_version = semver::Version::parse(&cli_version_str) + .map_err(|e| format!("Failed to parse CLI version '{}': {}", cli_version_str, e))?; + + let app_version = app.package_info().version.clone(); + + if cli_version >= app_version { + println!( + "CLI version {} is up to date (app version: {}), skipping sync", + cli_version, app_version + ); + return Ok(()); + } + + println!( + "CLI version {} is older than app version {}, syncing", + cli_version, app_version + ); + + install_cli()?; + + println!("Synced installed CLI"); + + Ok(()) +} |
