1#![cfg_attr(target_os = "windows", allow(unused, dead_code))]
2
3use clap::{Parser, Subcommand};
4use std::path::PathBuf;
5
6#[derive(Parser)]
7#[command(disable_version_flag = true)]
8struct Cli {
9 #[command(subcommand)]
10 command: Option<Commands>,
11 /// Used for SSH/Git password authentication, to remove the need for netcat as a dependency,
12 /// by having Zed act like netcat communicating over a Unix socket.
13 #[arg(long, hide = true)]
14 askpass: Option<String>,
15 /// Used for recording minidumps on crashes by having the server run a separate
16 /// process communicating over a socket.
17 #[arg(long, hide = true)]
18 crash_handler: Option<PathBuf>,
19 /// Used for loading the environment from the project.
20 #[arg(long, hide = true)]
21 printenv: bool,
22}
23
24#[derive(Subcommand)]
25enum Commands {
26 Run {
27 #[arg(long)]
28 log_file: PathBuf,
29 #[arg(long)]
30 pid_file: PathBuf,
31 #[arg(long)]
32 stdin_socket: PathBuf,
33 #[arg(long)]
34 stdout_socket: PathBuf,
35 #[arg(long)]
36 stderr_socket: PathBuf,
37 },
38 Proxy {
39 #[arg(long)]
40 reconnect: bool,
41 #[arg(long)]
42 identifier: String,
43 },
44 Version,
45}
46
47#[cfg(windows)]
48fn main() {
49 unimplemented!()
50}
51
52#[cfg(not(windows))]
53fn main() {
54 use release_channel::{RELEASE_CHANNEL, ReleaseChannel};
55 use remote::proxy::ProxyLaunchError;
56 use remote_server::unix::{execute_proxy, execute_run};
57
58 let cli = Cli::parse();
59
60 if let Some(socket_path) = &cli.askpass {
61 askpass::main(socket_path);
62 return;
63 }
64
65 if let Some(socket) = &cli.crash_handler {
66 crashes::crash_server(socket.as_path());
67 return;
68 }
69
70 if cli.printenv {
71 util::shell_env::print_env();
72 return;
73 }
74
75 let result = match cli.command {
76 Some(Commands::Run {
77 log_file,
78 pid_file,
79 stdin_socket,
80 stdout_socket,
81 stderr_socket,
82 }) => execute_run(
83 log_file,
84 pid_file,
85 stdin_socket,
86 stdout_socket,
87 stderr_socket,
88 ),
89 Some(Commands::Proxy {
90 identifier,
91 reconnect,
92 }) => match execute_proxy(identifier, reconnect) {
93 Ok(_) => Ok(()),
94 Err(err) => {
95 if let Some(err) = err.downcast_ref::<ProxyLaunchError>() {
96 std::process::exit(err.to_exit_code());
97 }
98 Err(err)
99 }
100 },
101 Some(Commands::Version) => {
102 let release_channel = *RELEASE_CHANNEL;
103 match release_channel {
104 ReleaseChannel::Stable | ReleaseChannel::Preview => {
105 println!("{}", env!("ZED_PKG_VERSION"))
106 }
107 ReleaseChannel::Nightly | ReleaseChannel::Dev => {
108 println!(
109 "{}",
110 option_env!("ZED_COMMIT_SHA").unwrap_or(release_channel.dev_name())
111 )
112 }
113 };
114 std::process::exit(0);
115 }
116 None => {
117 eprintln!("usage: remote <run|proxy|version>");
118 std::process::exit(1);
119 }
120 };
121 if let Err(error) = result {
122 log::error!("exiting due to error: {}", error);
123 std::process::exit(1);
124 }
125}