DevelopmentNodeEnvironment_MicrosoftVSCodeDependency_22NodeVersion_Bundle_Clean_Debug_ElectronProfile_EsbuildCompiler_Mountain/IPC/WindServiceHandlers/NativeHost/
InstallShellCommand.rs1use std::path::PathBuf;
8
9use serde_json::Value;
10
11use crate::dev_log;
12
13const CLI_NAME:&str = "land";
14
15const SYMLINK_DIR:&str = "/usr/local/bin";
16
17pub async fn Fn(_Arguments:Vec<Value>) -> Result<Value, String> {
18 let ExePath = std::env::current_exe().map_err(|E| format!("installShellCommand: cannot get exe path: {E}"))?;
19
20 let Target = PathBuf::from(SYMLINK_DIR).join(CLI_NAME);
21
22 dev_log!("shell-cmd", "installShellCommand: {} → {}", Target.display(), ExePath.display());
23
24 let _ = std::fs::remove_file(&Target);
26
27 match std::os::unix::fs::symlink(&ExePath, &Target) {
28 Ok(()) => {
29 dev_log!("shell-cmd", "installShellCommand: symlink created");
30
31 Ok(Value::Bool(true))
32 },
33
34 Err(E) if E.kind() == std::io::ErrorKind::PermissionDenied => {
35 #[cfg(target_os = "macos")]
37 {
38 let Status = tokio::process::Command::new("osascript")
41 .env("SH_SRC", ExePath.as_os_str())
42 .env("SH_DST", Target.as_os_str())
43 .args([
44 "-e",
45 "do shell script (\"ln -sf \" & quoted form of (system attribute \"SH_SRC\") & \" \" & quoted \
46 form of (system attribute \"SH_DST\")) with administrator privileges",
47 ])
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}