main.rs

  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}