DevelopmentNodeEnvironment_MicrosoftVSCodeDependency_22NodeVersion_Bundle_Clean_Debug_ElectronProfile_EsbuildCompiler_Mountain/IPC/WindServiceHandlers/NativeHost/
InstallShellCommand.rs1#![allow(non_snake_case)]
2
3use std::path::PathBuf;
10
11use serde_json::Value;
12
13use crate::dev_log;
14
15const CLI_NAME:&str = "land";
16
17const SYMLINK_DIR:&str = "/usr/local/bin";
18
19pub async fn InstallShellCommand(_Arguments:Vec<Value>) -> Result<Value, String> {
20 let ExePath = std::env::current_exe().map_err(|E| format!("installShellCommand: cannot get exe path: {E}"))?;
21
22 let Target = PathBuf::from(SYMLINK_DIR).join(CLI_NAME);
23
24 dev_log!("shell-cmd", "installShellCommand: {} → {}", Target.display(), ExePath.display());
25
26 let _ = std::fs::remove_file(&Target);
28
29 match std::os::unix::fs::symlink(&ExePath, &Target) {
30 Ok(()) => {
31 dev_log!("shell-cmd", "installShellCommand: symlink created");
32
33 Ok(Value::Bool(true))
34 },
35
36 Err(E) if E.kind() == std::io::ErrorKind::PermissionDenied => {
37 #[cfg(target_os = "macos")]
39 {
40 let Script = format!(
41 "do shell script \"ln -sf '{}' '{}'\" with administrator privileges",
42 ExePath.display(),
43 Target.display()
44 );
45
46 let Status = tokio::process::Command::new("osascript")
47 .args(["-e", &Script])
48 .status()
49 .await
50 .map_err(|E| format!("installShellCommand: osascript failed: {E}"))?;
51
52 if Status.success() {
53 dev_log!("shell-cmd", "installShellCommand: symlink created (elevated)");
54
55 return Ok(Value::Bool(true));
56 }
57 }
58
59 Err(format!("installShellCommand: permission denied and elevation failed"))
60 },
61
62 Err(E) => Err(format!("installShellCommand: {E}")),
63 }
64}