remoting (#9680)
This PR provides some of the plumbing needed for a "remote" zed instance. The way this will work is: * From zed on your laptop you'll be able to manage a set of dev servers, each of which is identified by a token. * You'll run `zed --dev-server-token XXXX` to boot a remotable dev server. * From the zed on your laptop you'll be able to open directories and work on the projects on the remote server (exactly like collaboration works today). For now all this PR does is provide the ability for a zed instance to sign in using a "dev server token". The next steps will be: * Adding support to the collaboration protocol to instruct a dev server to "open" a directory and share it into a channel. * Adding UI to manage these servers and tokens (manually for now) Related #5347 Release Notes: - N/A --------- Co-authored-by: Nathan <nathan@zed.dev>
This commit is contained in:
parent
f56707e076
commit
cb4f868815
19 changed files with 582 additions and 296 deletions
|
@ -26,6 +26,7 @@ breadcrumbs.workspace = true
|
|||
call.workspace = true
|
||||
channel.workspace = true
|
||||
chrono.workspace = true
|
||||
clap.workspace = true
|
||||
cli.workspace = true
|
||||
client.workspace = true
|
||||
clock.workspace = true
|
||||
|
|
|
@ -6,8 +6,9 @@ mod zed;
|
|||
use anyhow::{anyhow, Context as _, Result};
|
||||
use backtrace::Backtrace;
|
||||
use chrono::Utc;
|
||||
use clap::{command, Parser};
|
||||
use cli::FORCE_CLI_MODE_ENV_VAR_NAME;
|
||||
use client::{parse_zed_link, Client, UserStore};
|
||||
use client::{parse_zed_link, Client, ClientSettings, DevServerToken, UserStore};
|
||||
use collab_ui::channel_view::ChannelView;
|
||||
use db::kvp::KEY_VALUE_STORE;
|
||||
use editor::Editor;
|
||||
|
@ -270,9 +271,28 @@ fn main() {
|
|||
|
||||
cx.activate(true);
|
||||
|
||||
let urls = collect_url_args(cx);
|
||||
if !urls.is_empty() {
|
||||
listener.open_urls(urls)
|
||||
let mut args = Args::parse();
|
||||
if let Some(dev_server_token) = args.dev_server_token.take() {
|
||||
let dev_server_token = DevServerToken(dev_server_token);
|
||||
let server_url = ClientSettings::get_global(&cx).server_url.clone();
|
||||
let client = client.clone();
|
||||
client.set_dev_server_token(dev_server_token);
|
||||
cx.spawn(|cx| async move {
|
||||
client.authenticate_and_connect(false, &cx).await?;
|
||||
log::info!("Connected to {}", server_url);
|
||||
anyhow::Ok(())
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
} else {
|
||||
let urls: Vec<_> = args
|
||||
.paths_or_urls
|
||||
.iter()
|
||||
.filter_map(|arg| parse_url_arg(arg, cx).log_err())
|
||||
.collect();
|
||||
|
||||
if !urls.is_empty() {
|
||||
listener.open_urls(urls)
|
||||
}
|
||||
}
|
||||
|
||||
let mut triggered_authentication = false;
|
||||
|
@ -898,23 +918,35 @@ fn stdout_is_a_pty() -> bool {
|
|||
std::env::var(FORCE_CLI_MODE_ENV_VAR_NAME).ok().is_none() && std::io::stdout().is_terminal()
|
||||
}
|
||||
|
||||
fn collect_url_args(cx: &AppContext) -> Vec<String> {
|
||||
env::args()
|
||||
.skip(1)
|
||||
.filter_map(|arg| match std::fs::canonicalize(Path::new(&arg)) {
|
||||
Ok(path) => Some(format!("file://{}", path.to_string_lossy())),
|
||||
Err(error) => {
|
||||
if arg.starts_with("file://") || arg.starts_with("zed-cli://") {
|
||||
Some(arg)
|
||||
} else if let Some(_) = parse_zed_link(&arg, cx) {
|
||||
Some(arg)
|
||||
} else {
|
||||
log::error!("error parsing path argument: {}", error);
|
||||
None
|
||||
}
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(name = "zed", disable_version_flag = true)]
|
||||
struct Args {
|
||||
/// A sequence of space-separated paths or urls that you want to open.
|
||||
///
|
||||
/// Use `path:line:row` syntax to open a file at a specific location.
|
||||
/// Non-existing paths and directories will ignore `:line:row` suffix.
|
||||
///
|
||||
/// URLs can either be file:// or zed:// scheme, or relative to https://zed.dev.
|
||||
paths_or_urls: Vec<String>,
|
||||
|
||||
/// Instructs zed to run as a dev server on this machine. (not implemented)
|
||||
#[arg(long)]
|
||||
dev_server_token: Option<String>,
|
||||
}
|
||||
|
||||
fn parse_url_arg(arg: &str, cx: &AppContext) -> Result<String> {
|
||||
match std::fs::canonicalize(Path::new(&arg)) {
|
||||
Ok(path) => Ok(format!("file://{}", path.to_string_lossy())),
|
||||
Err(error) => {
|
||||
if arg.starts_with("file://") || arg.starts_with("zed-cli://") {
|
||||
Ok(arg.into())
|
||||
} else if let Some(_) = parse_zed_link(&arg, cx) {
|
||||
Ok(arg.into())
|
||||
} else {
|
||||
Err(anyhow!("error parsing path argument: {}", error))
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn load_embedded_fonts(cx: &AppContext) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue