1use fs::RealFs;
2use futures::channel::mpsc;
3use gpui::Context as _;
4use remote::{
5 json_log::LogRecord,
6 protocol::{read_message, write_message},
7 SshSession,
8};
9use remote_server::HeadlessProject;
10use smol::{io::AsyncWriteExt, stream::StreamExt as _, Async};
11use std::{
12 env,
13 io::{self, Write},
14 mem, process,
15 sync::Arc,
16};
17
18fn main() {
19 env::set_var("RUST_BACKTRACE", "1");
20 env_logger::builder()
21 .format(|buf, record| {
22 serde_json::to_writer(&mut *buf, &LogRecord::new(&record))?;
23 buf.write_all(b"\n")?;
24 Ok(())
25 })
26 .init();
27
28 let subcommand = std::env::args().nth(1);
29 match subcommand.as_deref() {
30 Some("run") => {}
31 Some("version") => {
32 println!("{}", env!("ZED_PKG_VERSION"));
33 return;
34 }
35 _ => {
36 eprintln!("usage: remote <run|version>");
37 process::exit(1);
38 }
39 }
40
41 gpui::App::headless().run(move |cx| {
42 HeadlessProject::init(cx);
43
44 let (incoming_tx, incoming_rx) = mpsc::unbounded();
45 let (outgoing_tx, mut outgoing_rx) = mpsc::unbounded();
46
47 let mut stdin = Async::new(io::stdin()).unwrap();
48 let mut stdout = Async::new(io::stdout()).unwrap();
49
50 let session = SshSession::server(incoming_rx, outgoing_tx, cx);
51 let project = cx.new_model(|cx| {
52 HeadlessProject::new(
53 session.clone(),
54 Arc::new(RealFs::new(Default::default(), None)),
55 cx,
56 )
57 });
58
59 cx.background_executor()
60 .spawn(async move {
61 let mut output_buffer = Vec::new();
62 while let Some(message) = outgoing_rx.next().await {
63 write_message(&mut stdout, &mut output_buffer, message).await?;
64 stdout.flush().await?;
65 }
66 anyhow::Ok(())
67 })
68 .detach();
69
70 cx.background_executor()
71 .spawn(async move {
72 let mut input_buffer = Vec::new();
73 loop {
74 let message = match read_message(&mut stdin, &mut input_buffer).await {
75 Ok(message) => message,
76 Err(error) => {
77 log::warn!("error reading message: {:?}", error);
78 process::exit(0);
79 }
80 };
81 incoming_tx.unbounded_send(message).ok();
82 }
83 })
84 .detach();
85
86 mem::forget(project);
87 });
88}