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