Split distant into distant-core and distant (bin)

pull/38/head
Chip Senkbeil 3 years ago
parent 156fe50423
commit df81894785
No known key found for this signature in database
GPG Key ID: 35EF1F8EC72A4131

20
Cargo.lock generated

@ -213,10 +213,27 @@ name = "distant"
version = "0.13.0"
dependencies = [
"assert_cmd",
"bytes",
"derive_more",
"distant-core",
"flexi_logger",
"fork",
"lazy_static",
"log",
"rand",
"serde_json",
"structopt",
"strum",
"tempfile",
"tokio",
"whoami",
]
[[package]]
name = "distant-core"
version = "0.13.0"
dependencies = [
"bytes",
"derive_more",
"futures",
"hex",
"k256",
@ -233,7 +250,6 @@ dependencies = [
"tokio",
"tokio-util",
"walkdir",
"whoami",
]
[[package]]

@ -10,33 +10,26 @@ repository = "https://github.com/chipsenkbeil/distant"
readme = "README.md"
license = "MIT OR Apache-2.0"
[workspace]
members = ["core"]
[profile.release]
opt-level = 'z'
lto = true
codegen-units = 1
[dependencies]
bytes = "1.0.1"
derive_more = { version = "0.99.16", default-features = false, features = ["display", "from", "error", "is_variant"] }
futures = "0.3.16"
hex = "0.4.3"
k256 = { version = "0.9.6", features = ["ecdh"] }
log = "0.4.14"
orion = "0.16.0"
rand = { version = "0.8.4", features = ["getrandom"] }
serde = { version = "1.0.126", features = ["derive"] }
serde_cbor = "0.11.1"
serde_json = "1.0.64"
strum = { version = "0.21.0", features = ["derive"] }
tokio = { version = "1.9.0", features = ["full"] }
tokio-util = { version = "0.6.7", features = ["codec"] }
walkdir = "2.3.2"
# Binary-specific dependencies
distant-core = { version = "=0.13.0", path = "core", features = ["structopt"] }
flexi_logger = "0.18.0"
fork = "0.1.18"
lazy_static = "1.4.0"
log = "0.4.14"
rand = { version = "0.8.4", features = ["getrandom"] }
tokio = { version = "1.9.0", features = ["full"] }
serde_json = "1.0.64"
structopt = "0.3.22"
strum = { version = "0.21.0", features = ["derive"] }
whoami = "1.1.2"
[dev-dependencies]

@ -0,0 +1,35 @@
[package]
name = "distant-core"
description = "Core library for distant, enabling operation on a remote computer through file and process manipulation"
categories = ["network-programming"]
version = "0.13.0"
authors = ["Chip Senkbeil <chip@senkbeil.org>"]
edition = "2018"
homepage = "https://github.com/chipsenkbeil/distant"
repository = "https://github.com/chipsenkbeil/distant"
readme = "README.md"
license = "MIT OR Apache-2.0"
[dependencies]
bytes = "1.0.1"
derive_more = { version = "0.99.16", default-features = false, features = ["display", "from", "error", "is_variant"] }
futures = "0.3.16"
hex = "0.4.3"
k256 = { version = "0.9.6", features = ["ecdh"] }
lazy_static = "1.4.0"
log = "0.4.14"
orion = "0.16.0"
rand = { version = "0.8.4", features = ["getrandom"] }
serde = { version = "1.0.126", features = ["derive"] }
serde_cbor = "0.11.1"
serde_json = "1.0.64"
strum = { version = "0.21.0", features = ["derive"] }
tokio = { version = "1.9.0", features = ["full"] }
tokio-util = { version = "0.6.7", features = ["codec"] }
walkdir = "2.3.2"
# Optional dependencies based on features
structopt = { version = "0.3.22", optional = true }
[dev-dependencies]
tempfile = "3.2.0"

@ -1,4 +1,4 @@
use crate::core::client::{SessionInfo, SessionInfoParseError};
use crate::client::{SessionInfo, SessionInfoParseError};
use derive_more::{Display, Error, From};
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};

@ -1,5 +1,5 @@
use super::{RemoteProcess, RemoteProcessError, RemoteStderr, RemoteStdin, RemoteStdout};
use crate::core::{client::Session, net::DataStream};
use crate::{client::Session, net::DataStream};
use std::{
fmt::Write,
io::{self, Cursor, Read},

@ -6,4 +6,3 @@ mod utils;
pub use lsp::*;
pub use process::{RemoteProcess, RemoteProcessError, RemoteStderr, RemoteStdin, RemoteStdout};
pub use session::*;
pub(crate) use utils::new_tenant;

@ -1,4 +1,4 @@
use crate::core::{
use crate::{
client::Session,
constants::CLIENT_BROADCAST_CHANNEL_CAPACITY,
data::{Request, RequestData, Response, ResponseData},

@ -1,4 +1,4 @@
use crate::core::{
use crate::{
client::utils,
constants::CLIENT_BROADCAST_CHANNEL_CAPACITY,
data::{Request, Response},
@ -216,7 +216,7 @@ where
#[cfg(test)]
mod tests {
use super::*;
use crate::core::{
use crate::{
constants::test::TENANT,
data::{RequestData, ResponseData},
};

@ -1,11 +1,6 @@
use std::{future::Future, time::Duration};
use tokio::{io, time};
// Generates a new tenant name
pub fn new_tenant() -> String {
format!("tenant_{}{}", rand::random::<u16>(), rand::random::<u8>())
}
// Wraps a future in a tokio timeout call, transforming the error into
// an io error
pub async fn timeout<T, F>(d: Duration, f: F) -> io::Result<T>

@ -0,0 +1,23 @@
/// Capacity associated with a client broadcasting its received messages that
/// do not have a callback associated
pub const CLIENT_BROADCAST_CHANNEL_CAPACITY: usize = 10000;
/// Represents the maximum size (in bytes) that data will be read from pipes
/// per individual `read` call
///
/// Current setting is 16k size
pub const MAX_PIPE_CHUNK_SIZE: usize = 16384;
/// Duration in milliseconds to sleep between reading stdout/stderr chunks
/// to avoid sending many small messages to clients
pub const READ_PAUSE_MILLIS: u64 = 50;
/// Represents the length of the salt to use for encryption
pub const SALT_LEN: usize = 16;
/// Test-only constants
#[cfg(test)]
pub mod test {
pub const BUFFER_SIZE: usize = 100;
pub const TENANT: &str = "test-tenant";
}

@ -1,7 +1,6 @@
use derive_more::{Display, IsVariant};
use serde::{Deserialize, Serialize};
use std::{io, path::PathBuf};
use structopt::StructOpt;
use strum::AsRefStr;
/// Represents the request to be performed on the remote machine
@ -40,7 +39,8 @@ impl Request {
}
/// Represents the payload of a request to be performed on the remote machine
#[derive(Clone, Debug, PartialEq, Eq, AsRefStr, IsVariant, StructOpt, Serialize, Deserialize)]
#[derive(Clone, Debug, PartialEq, Eq, AsRefStr, IsVariant, Serialize, Deserialize)]
#[cfg_attr(feature = "structopt", derive(structopt::StructOpt))]
#[serde(
rename_all = "snake_case",
deny_unknown_fields,
@ -50,7 +50,7 @@ impl Request {
#[strum(serialize_all = "snake_case")]
pub enum RequestData {
/// Reads a file from the specified path on the remote machine
#[structopt(visible_aliases = &["cat"])]
#[cfg_attr(feature = "structopt", structopt(visible_aliases = &["cat"]))]
FileRead {
/// The path to the file on the remote machine
path: PathBuf,
@ -102,7 +102,7 @@ pub enum RequestData {
},
/// Reads a directory from the specified path on the remote machine
#[structopt(visible_aliases = &["ls"])]
#[cfg_attr(feature = "structopt", structopt(visible_aliases = &["ls"]))]
DirRead {
/// The path to the directory on the remote machine
path: PathBuf,
@ -111,11 +111,11 @@ pub enum RequestData {
/// depth and 1 indicating the most immediate children within the
/// directory
#[serde(default = "one")]
#[structopt(short, long, default_value = "1")]
#[cfg_attr(feature = "structopt", structopt(short, long, default_value = "1"))]
depth: usize,
/// Whether or not to return absolute or relative paths
#[structopt(short, long)]
#[cfg_attr(feature = "structopt", structopt(short, long))]
absolute: bool,
/// Whether or not to canonicalize the resulting paths, meaning
@ -124,7 +124,7 @@ pub enum RequestData {
///
/// Note that the flag absolute must be true to have absolute paths
/// returned, even if canonicalize is flagged as true
#[structopt(short, long)]
#[cfg_attr(feature = "structopt", structopt(short, long))]
canonicalize: bool,
/// Whether or not to include the root directory in the retrieved
@ -132,35 +132,35 @@ pub enum RequestData {
///
/// If included, the root directory will also be a canonicalized,
/// absolute path and will not follow any of the other flags
#[structopt(long)]
#[cfg_attr(feature = "structopt", structopt(long))]
include_root: bool,
},
/// Creates a directory on the remote machine
#[structopt(visible_aliases = &["mkdir"])]
#[cfg_attr(feature = "structopt", structopt(visible_aliases = &["mkdir"]))]
DirCreate {
/// The path to the directory on the remote machine
path: PathBuf,
/// Whether or not to create all parent directories
#[structopt(short, long)]
#[cfg_attr(feature = "structopt", structopt(short, long))]
all: bool,
},
/// Removes a file or directory on the remote machine
#[structopt(visible_aliases = &["rm"])]
#[cfg_attr(feature = "structopt", structopt(visible_aliases = &["rm"]))]
Remove {
/// The path to the file or directory on the remote machine
path: PathBuf,
/// Whether or not to remove all contents within directory if is a directory.
/// Does nothing different for files
#[structopt(short, long)]
#[cfg_attr(feature = "structopt", structopt(short, long))]
force: bool,
},
/// Copies a file or directory on the remote machine
#[structopt(visible_aliases = &["cp"])]
#[cfg_attr(feature = "structopt", structopt(visible_aliases = &["cp"]))]
Copy {
/// The path to the file or directory on the remote machine
src: PathBuf,
@ -170,7 +170,7 @@ pub enum RequestData {
},
/// Moves/renames a file or directory on the remote machine
#[structopt(visible_aliases = &["mv"])]
#[cfg_attr(feature = "structopt", structopt(visible_aliases = &["mv"]))]
Rename {
/// The path to the file or directory on the remote machine
src: PathBuf,
@ -193,12 +193,12 @@ pub enum RequestData {
/// Whether or not to include a canonicalized version of the path, meaning
/// returning the canonical, absolute form of a path with all
/// intermediate components normalized and symbolic links resolved
#[structopt(short, long)]
#[cfg_attr(feature = "structopt", structopt(short, long))]
canonicalize: bool,
},
/// Runs a process on the remote machine
#[structopt(visible_aliases = &["run"])]
#[cfg_attr(feature = "structopt", structopt(visible_aliases = &["run"]))]
ProcRun {
/// Name of the command to run
cmd: String,
@ -208,7 +208,7 @@ pub enum RequestData {
},
/// Kills a process running on the remote machine
#[structopt(visible_aliases = &["kill"])]
#[cfg_attr(feature = "structopt", structopt(visible_aliases = &["kill"]))]
ProcKill {
/// Id of the actively-running process
id: usize,

@ -0,0 +1,21 @@
mod client;
pub use client::{
LspContent, LspContentParseError, LspData, LspDataParseError, LspHeader, LspHeaderParseError,
LspSessionInfoError, RemoteLspProcess, RemoteLspStderr, RemoteLspStdin, RemoteLspStdout,
RemoteProcess, RemoteProcessError, RemoteStderr, RemoteStdin, RemoteStdout, Session,
SessionInfo, SessionInfoFile, SessionInfoParseError,
};
mod constants;
mod net;
pub use net::{
DataStream, InmemoryStream, InmemoryStreamReadHalf, InmemoryStreamWriteHalf, Listener,
SecretKey, Transport, TransportError, TransportReadHalf, TransportWriteHalf,
};
pub mod data;
pub use data::{Request, RequestData, Response, ResponseData};
mod server;
pub use server::{DistantServer, PortRange, RelayServer};

@ -1,4 +1,4 @@
use crate::core::{constants::SALT_LEN, net::SecretKey};
use crate::{constants::SALT_LEN, net::SecretKey};
use codec::DistantCodec;
use derive_more::{Display, Error, From};
use futures::SinkExt;
@ -355,7 +355,7 @@ impl Transport<InmemoryStream> {
) -> (Transport<InmemoryStream>, Transport<InmemoryStream>) {
let crypt_key = Arc::new(SecretKey::default());
let (a, b) = InmemoryStream::pair(crate::core::constants::test::BUFFER_SIZE);
let (a, b) = InmemoryStream::pair(crate::constants::test::BUFFER_SIZE);
let a = Transport::new(a, ak1, Arc::clone(&crypt_key));
let b = Transport::new(b, ak2, crypt_key);
(a, b)
@ -364,14 +364,14 @@ impl Transport<InmemoryStream> {
/// Makes a connected pair of transports with matching auth and crypt keys
/// using test buffer size
pub fn make_pair() -> (Transport<InmemoryStream>, Transport<InmemoryStream>) {
Self::pair(crate::core::constants::test::BUFFER_SIZE)
Self::pair(crate::constants::test::BUFFER_SIZE)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core::constants::test::BUFFER_SIZE;
use crate::constants::test::BUFFER_SIZE;
use std::io;
#[tokio::test]

@ -1,4 +1,4 @@
use crate::core::{
use crate::{
constants::{MAX_PIPE_CHUNK_SIZE, READ_PAUSE_MILLIS},
data::{
self, DirEntry, FileType, Request, RequestData, Response, ResponseData, RunningProcess,

@ -3,7 +3,7 @@ mod state;
use state::State;
use crate::core::{
use crate::{
data::{Request, Response},
net::{DataStream, Listener, SecretKey, Transport, TransportReadHalf, TransportWriteHalf},
server::{

@ -1,4 +1,4 @@
use crate::core::{
use crate::{
client::Session,
constants::CLIENT_BROADCAST_CHANNEL_CAPACITY,
data::{Request, RequestData, Response, ResponseData},

@ -1,4 +1,4 @@
use distant::net::{Transport, TransportError, InmemoryStream, SecretKey};
use distant_core::{Transport, TransportError, InmemoryStream, SecretKey};
use std::{io, sync::Arc};
const BUFFER_SIZE: usize = 100;

@ -1,13 +0,0 @@
mod buf;
mod exit;
mod link;
mod opt;
mod output;
mod session;
mod stdin;
mod subcommand;
pub use exit::{ExitCode, ExitCodeError};
pub use opt::*;
pub use output::ResponseOut;
pub use session::CliSession;

@ -1,36 +1,18 @@
use std::{env, path::PathBuf};
/// Represents maximum time (in milliseconds) to wait on a network request
/// before failing (0 meaning indefinitely)
pub const TIMEOUT: usize = 15000;
/// Capacity associated with a client broadcasting its received messages that
/// do not have a callback associated
pub const CLIENT_BROADCAST_CHANNEL_CAPACITY: usize = 10000;
/// Capacity associated with a server receiving messages from a connection
/// with a client
pub const SERVER_CONN_MSG_CAPACITY: usize = 10000;
/// Represents the maximum size (in bytes) that data will be read from pipes
/// per individual `read` call
///
/// Current setting is 16k size
pub const MAX_PIPE_CHUNK_SIZE: usize = 16384;
/// Duration in milliseconds to sleep between reading stdout/stderr chunks
/// to avoid sending many small messages to clients
pub const READ_PAUSE_MILLIS: u64 = 50;
/// Represents the length of the salt to use for encryption
pub const SALT_LEN: usize = 16;
/// Capacity associated with a server receiving messages from a connection
/// with a client
pub const SERVER_CONN_MSG_CAPACITY: usize = 10000;
/// Test-only constants
#[cfg(test)]
pub mod test {
pub const BUFFER_SIZE: usize = 100;
pub const TENANT: &str = "test-tenant";
}
/// Represents maximum time (in milliseconds) to wait on a network request
/// before failing (0 meaning indefinitely)
pub const TIMEOUT: usize = 15000;
lazy_static::lazy_static! {
pub static ref TIMEOUT_STR: String = TIMEOUT.to_string();

@ -1,5 +0,0 @@
pub mod client;
pub mod constants;
pub mod data;
pub mod net;
pub mod server;

@ -1,4 +1,4 @@
use crate::core::{client::RemoteProcessError, net::TransportError};
use distant_core::{RemoteProcessError, TransportError};
/// Exit codes following https://www.freebsd.org/cgi/man.cgi?query=sysexits&sektion=3
#[derive(Copy, Clone, PartialEq, Eq, Hash)]

@ -1,12 +1,19 @@
mod cli;
mod core;
mod buf;
mod constants;
mod exit;
mod link;
mod opt;
mod output;
mod session;
mod stdin;
mod subcommand;
mod utils;
pub use self::core::{client::*, data, net, server::*};
use log::error;
/// Main entrypoint into the program
pub fn run() {
let opt = cli::Opt::load();
let opt = opt::Opt::load();
let logger = init_logging(&opt.common);
if let Err(x) = opt.subcommand.run(opt.common) {
error!("Exiting due to error: {}", x);
@ -17,7 +24,7 @@ pub fn run() {
}
}
fn init_logging(opt: &cli::CommonOpt) -> flexi_logger::LoggerHandle {
fn init_logging(opt: &opt::CommonOpt) -> flexi_logger::LoggerHandle {
use flexi_logger::{FileSpec, LevelFilter, LogSpecification, Logger};
let module = "distant";

@ -1,12 +1,6 @@
use crate::{
cli,
core::{
client::{
RemoteLspStderr, RemoteLspStdin, RemoteLspStdout, RemoteStderr, RemoteStdin,
RemoteStdout,
},
constants::MAX_PIPE_CHUNK_SIZE,
},
use crate::{constants::MAX_PIPE_CHUNK_SIZE, stdin};
use distant_core::{
RemoteLspStderr, RemoteLspStdin, RemoteLspStdout, RemoteStderr, RemoteStdin, RemoteStdout,
};
use std::{
io::{self, Write},
@ -25,7 +19,7 @@ pub struct RemoteProcessLink {
macro_rules! from_pipes {
($stdin:expr, $stdout:expr, $stderr:expr) => {{
let (stdin_thread, mut stdin_rx) = cli::stdin::spawn_channel(MAX_PIPE_CHUNK_SIZE);
let (stdin_thread, mut stdin_rx) = stdin::spawn_channel(MAX_PIPE_CHUNK_SIZE);
let stdin_task = tokio::spawn(async move {
loop {
if let Some(input) = stdin_rx.recv().await {

@ -1,15 +1,12 @@
use crate::{
cli::{subcommand, ExitCodeError},
core::{
constants::{
SERVER_CONN_MSG_CAPACITY_STR, SESSION_FILE_PATH_STR, SESSION_SOCKET_PATH_STR,
TIMEOUT_STR,
},
data::RequestData,
server::PortRange,
constants::{
SERVER_CONN_MSG_CAPACITY_STR, SESSION_FILE_PATH_STR, SESSION_SOCKET_PATH_STR, TIMEOUT_STR,
},
exit::ExitCodeError,
subcommand,
};
use derive_more::{Display, Error, From, IsVariant};
use distant_core::{PortRange, RequestData};
use lazy_static::lazy_static;
use std::{
env,

@ -1,7 +1,5 @@
use crate::{
cli::Format,
core::data::{Error, Response, ResponseData},
};
use crate::opt::Format;
use distant_core::{data::Error, Response, ResponseData};
use log::*;
use std::io;

@ -1,12 +1,7 @@
use crate::{
cli::{buf::StringBuf, stdin, Format, ResponseOut},
core::{
client::Session,
constants::MAX_PIPE_CHUNK_SIZE,
data::{Request, RequestData, Response},
net::DataStream,
},
buf::StringBuf, constants::MAX_PIPE_CHUNK_SIZE, opt::Format, output::ResponseOut, stdin,
};
use distant_core::{DataStream, Request, RequestData, Response, Session};
use log::*;
use std::{io, thread};
use structopt::StructOpt;
@ -15,7 +10,7 @@ use tokio::{sync::mpsc, task::JoinHandle};
/// Represents a wrapper around a session that provides CLI functionality such as reading from
/// stdin and piping results back out to stdout
pub struct CliSession {
stdin_thread: thread::JoinHandle<()>,
_stdin_thread: thread::JoinHandle<()>,
req_task: JoinHandle<()>,
res_task: JoinHandle<io::Result<()>>,
}
@ -52,7 +47,7 @@ impl CliSession {
});
Self {
stdin_thread,
_stdin_thread: stdin_thread,
req_task,
res_task,
}

@ -1,18 +1,16 @@
use crate::{
cli::{
link::RemoteProcessLink,
opt::{ActionSubcommand, CommonOpt, SessionInput},
CliSession, ExitCode, ExitCodeError, ResponseOut,
},
core::{
client::{
self, LspData, RemoteProcess, RemoteProcessError, Session, SessionInfo, SessionInfoFile,
},
data::{Request, RequestData},
net::{DataStream, TransportError},
},
exit::{ExitCode, ExitCodeError},
link::RemoteProcessLink,
opt::{ActionSubcommand, CommonOpt, SessionInput},
output::ResponseOut,
session::CliSession,
utils,
};
use derive_more::{Display, Error, From};
use distant_core::{
DataStream, LspData, RemoteProcess, RemoteProcessError, Request, RequestData, Session,
SessionInfo, SessionInfoFile, TransportError,
};
use tokio::{io, time::Duration};
#[derive(Debug, Display, Error, From)]
@ -121,7 +119,7 @@ where
// ProcRun request is specially handled and we ignore interactive as
// the stdin will be used for sending ProcStdin to remote process
(_, Some(RequestData::ProcRun { cmd, args })) => {
let mut proc = RemoteProcess::spawn(client::new_tenant(), session, cmd, args).await?;
let mut proc = RemoteProcess::spawn(utils::new_tenant(), session, cmd, args).await?;
// If we also parsed an LSP's initialize request for its session, we want to forward
// it along in the case of a process call
@ -155,7 +153,7 @@ where
// All other requests without interactive are oneoffs
(false, Some(data)) => {
let res = session
.send_timeout(Request::new(client::new_tenant(), vec![data]), timeout)
.send_timeout(Request::new(utils::new_tenant(), vec![data]), timeout)
.await?;
ResponseOut::new(cmd.format, res)?.print();
Ok(())
@ -167,14 +165,14 @@ where
// Send our first request if provided
if let Some(data) = maybe_req {
let res = session
.send_timeout(Request::new(client::new_tenant(), vec![data]), timeout)
.send_timeout(Request::new(utils::new_tenant(), vec![data]), timeout)
.await?;
ResponseOut::new(cmd.format, res)?.print();
}
// Enter into CLI session where we receive requests on stdin and send out
// over stdout/stderr
let cli_session = CliSession::new(client::new_tenant(), session, cmd.format);
let cli_session = CliSession::new(utils::new_tenant(), session, cmd.format);
cli_session.wait().await?;
Ok(())

@ -1,14 +1,11 @@
use crate::{
cli::{
opt::{CommonOpt, Format, LaunchSubcommand, SessionOutput},
CliSession, ExitCode, ExitCodeError,
},
core::{
client::{self, Session, SessionInfo, SessionInfoFile},
server::RelayServer,
},
exit::{ExitCode, ExitCodeError},
opt::{CommonOpt, Format, LaunchSubcommand, SessionOutput},
session::CliSession,
utils,
};
use derive_more::{Display, Error, From};
use distant_core::{RelayServer, Session, SessionInfo, SessionInfoFile};
use fork::{daemon, Fork};
use log::*;
use std::{path::Path, string::FromUtf8Error};
@ -127,7 +124,7 @@ pub fn run(cmd: LaunchSubcommand, opt: CommonOpt) -> Result<(), Error> {
async fn keep_loop(info: SessionInfo, format: Format, duration: Duration) -> io::Result<()> {
match Session::tcp_connect_timeout(info, duration).await {
Ok(session) => {
let cli_session = CliSession::new(client::new_tenant(), session, format);
let cli_session = CliSession::new(utils::new_tenant(), session, format);
cli_session.wait().await
}
Err(x) => Err(x),

@ -1,11 +1,9 @@
use crate::{
cli::{
opt::{CommonOpt, ConvertToIpAddrError, ListenSubcommand},
ExitCode, ExitCodeError,
},
core::server::DistantServer,
exit::{ExitCode, ExitCodeError},
opt::{CommonOpt, ConvertToIpAddrError, ListenSubcommand},
};
use derive_more::{Display, Error, From};
use distant_core::DistantServer;
use fork::{daemon, Fork};
use log::*;
use tokio::{io, task::JoinError};

@ -1,18 +1,14 @@
use crate::{
cli::{
link::RemoteProcessLink,
opt::{CommonOpt, LspSubcommand, SessionInput},
ExitCode, ExitCodeError,
},
core::{
client::{
self, LspData, RemoteLspProcess, RemoteProcessError, Session, SessionInfo,
SessionInfoFile,
},
net::DataStream,
},
exit::{ExitCode, ExitCodeError},
link::RemoteProcessLink,
opt::{CommonOpt, LspSubcommand, SessionInput},
utils,
};
use derive_more::{Display, Error, From};
use distant_core::{
DataStream, LspData, RemoteLspProcess, RemoteProcessError, Session, SessionInfo,
SessionInfoFile,
};
use tokio::io;
#[derive(Debug, Display, Error, From)]
@ -104,8 +100,7 @@ async fn start<T>(
where
T: DataStream + 'static,
{
let mut proc =
RemoteLspProcess::spawn(client::new_tenant(), session, cmd.cmd, cmd.args).await?;
let mut proc = RemoteLspProcess::spawn(utils::new_tenant(), session, cmd.cmd, cmd.args).await?;
// If we also parsed an LSP's initialize request for its session, we want to forward
// it along in the case of a process call

@ -0,0 +1,4 @@
// Generates a new tenant name
pub fn new_tenant() -> String {
format!("tenant_{}{}", rand::random::<u16>(), rand::random::<u8>())
}
Loading…
Cancel
Save