main.rs

 1use clap::Parser;
 2use remote_server::Commands;
 3use std::path::PathBuf;
 4
 5#[derive(Parser)]
 6#[command(disable_version_flag = true)]
 7struct Cli {
 8    #[command(subcommand)]
 9    command: Option<Commands>,
10    /// Used for SSH/Git password authentication, to remove the need for netcat as a dependency,
11    /// by having Zed act like netcat communicating over a Unix socket.
12    #[arg(long, hide = true)]
13    askpass: Option<String>,
14    /// Used for recording minidumps on crashes by having the server run a separate
15    /// process communicating over a socket.
16    #[arg(long, hide = true)]
17    crash_handler: Option<PathBuf>,
18    /// Used for loading the environment from the project.
19    #[arg(long, hide = true)]
20    printenv: bool,
21}
22
23fn main() -> anyhow::Result<()> {
24    let cli = Cli::parse();
25
26    if let Some(socket_path) = &cli.askpass {
27        askpass::main(socket_path);
28        return Ok(());
29    }
30
31    if let Some(socket) = &cli.crash_handler {
32        crashes::crash_server(socket.as_path());
33        return Ok(());
34    }
35
36    if cli.printenv {
37        util::shell_env::print_env();
38        return Ok(());
39    }
40
41    if let Some(command) = cli.command {
42        use remote_server::ExecuteProxyError;
43
44        let res = remote_server::run(command);
45        if let Err(e) = &res
46            && let Some(e) = e.downcast_ref::<ExecuteProxyError>()
47        {
48            eprintln!("{e:#}");
49            // It is important for us to report the proxy spawn exit code here
50            // instead of the generic 1 that result returns
51            // The client reads the exit code to determine if the server process has died when trying to reconnect
52            // signaling that it needs to try spawning a new server
53            std::process::exit(e.to_exit_code());
54        }
55        res
56    } else {
57        eprintln!("usage: remote <run|proxy|version>");
58        std::process::exit(1);
59    }
60}