This is also needed to run config validation.
The "validate" request and its response handling will be implemented in
the next batch.
| Alphare |
| hg-reviewers |
This is also needed to run config validation.
The "validate" request and its response handling will be implemented in
the next batch.
| Automatic diff as part of commit; lint not applicable. |
| Automatic diff as part of commit; unit tests not applicable. |
| Path | Packages | |||
|---|---|---|---|---|
| M | rust/chg/src/clientext.rs (14 lines) | |||
| M | rust/chg/src/locator.rs (7 lines) |
| O: AsRawFd, | O: AsRawFd, | ||||
| E: AsRawFd; | E: AsRawFd; | ||||
| /// Changes the working directory of the server. | /// Changes the working directory of the server. | ||||
| fn set_current_dir<P>(self, dir: P) -> OneShotRequest<C> | fn set_current_dir<P>(self, dir: P) -> OneShotRequest<C> | ||||
| where | where | ||||
| P: AsRef<Path>; | P: AsRef<Path>; | ||||
| /// Updates the environment variables of the server. | |||||
| fn set_env_vars_os<I, P>(self, vars: I) -> OneShotRequest<C> | |||||
| where | |||||
| I: IntoIterator<Item = (P, P)>, | |||||
| P: AsRef<OsStr>; | |||||
| /// Runs the specified Mercurial command with cHg extension. | /// Runs the specified Mercurial command with cHg extension. | ||||
| fn run_command_chg<I, P, H>(self, handler: H, args: I) -> ChgRunCommand<C, H> | fn run_command_chg<I, P, H>(self, handler: H, args: I) -> ChgRunCommand<C, H> | ||||
| where | where | ||||
| I: IntoIterator<Item = P>, | I: IntoIterator<Item = P>, | ||||
| P: AsRef<OsStr>, | P: AsRef<OsStr>, | ||||
| H: SystemHandler; | H: SystemHandler; | ||||
| } | } | ||||
| fn set_current_dir<P>(self, dir: P) -> OneShotRequest<C> | fn set_current_dir<P>(self, dir: P) -> OneShotRequest<C> | ||||
| where | where | ||||
| P: AsRef<Path>, | P: AsRef<Path>, | ||||
| { | { | ||||
| OneShotRequest::start_with_args(self, b"chdir", dir.as_ref().as_os_str().as_bytes()) | OneShotRequest::start_with_args(self, b"chdir", dir.as_ref().as_os_str().as_bytes()) | ||||
| } | } | ||||
| fn set_env_vars_os<I, P>(self, vars: I) -> OneShotRequest<C> | |||||
| where | |||||
| I: IntoIterator<Item = (P, P)>, | |||||
| P: AsRef<OsStr>, | |||||
| { | |||||
| OneShotRequest::start_with_args(self, b"setenv", message::pack_env_vars_os(vars)) | |||||
| } | |||||
| fn run_command_chg<I, P, H>(self, handler: H, args: I) -> ChgRunCommand<C, H> | fn run_command_chg<I, P, H>(self, handler: H, args: I) -> ChgRunCommand<C, H> | ||||
| where | where | ||||
| I: IntoIterator<Item = P>, | I: IntoIterator<Item = P>, | ||||
| P: AsRef<OsStr>, | P: AsRef<OsStr>, | ||||
| H: SystemHandler, | H: SystemHandler, | ||||
| { | { | ||||
| ChgRunCommand::with_client(self, handler, message::pack_args_os(args)) | ChgRunCommand::with_client(self, handler, message::pack_args_os(args)) | ||||
| } | } | ||||
| } | } | ||||
| use tokio_hglib::UnixClient; | use tokio_hglib::UnixClient; | ||||
| use tokio_process::{Child, CommandExt}; | use tokio_process::{Child, CommandExt}; | ||||
| use tokio_timer; | use tokio_timer; | ||||
| use super::clientext::ChgClientExt; | use super::clientext::ChgClientExt; | ||||
| use super::message::ServerSpec; | use super::message::ServerSpec; | ||||
| use super::procutil; | use super::procutil; | ||||
| const REQUIRED_SERVER_CAPABILITIES: &[&str] = &["attachio", "chdir", "runcommand"]; | const REQUIRED_SERVER_CAPABILITIES: &[&str] = &["attachio", "chdir", "runcommand", "setenv"]; | ||||
| /// Helper to connect to and spawn a server process. | /// Helper to connect to and spawn a server process. | ||||
| #[derive(Clone, Debug)] | #[derive(Clone, Debug)] | ||||
| pub struct Locator { | pub struct Locator { | ||||
| hg_command: OsString, | hg_command: OsString, | ||||
| current_dir: PathBuf, | current_dir: PathBuf, | ||||
| env_vars: Vec<(OsString, OsString)>, | env_vars: Vec<(OsString, OsString)>, | ||||
| process_id: u32, | process_id: u32, | ||||
| check_server_capabilities(client.server_spec())?; | check_server_capabilities(client.server_spec())?; | ||||
| Ok((loc, client)) | Ok((loc, client)) | ||||
| }) | }) | ||||
| .and_then(|(loc, client)| { | .and_then(|(loc, client)| { | ||||
| client | client | ||||
| .set_current_dir(&loc.current_dir) | .set_current_dir(&loc.current_dir) | ||||
| .map(|client| (loc, client)) | .map(|client| (loc, client)) | ||||
| }) | }) | ||||
| .and_then(|(loc, client)| { | |||||
| client | |||||
| .set_env_vars_os(loc.env_vars.iter().cloned()) | |||||
| .map(|client| (loc, client)) | |||||
| }) | |||||
| } | } | ||||
| /// Spawns new server process and connects to it. | /// Spawns new server process and connects to it. | ||||
| /// | /// | ||||
| /// The server will be spawned at the current working directory, then | /// The server will be spawned at the current working directory, then | ||||
| /// chdir to "/", so that the server will load configs from the target | /// chdir to "/", so that the server will load configs from the target | ||||
| /// repository. | /// repository. | ||||
| fn spawn_connect(self) -> impl Future<Item = (Self, UnixClient), Error = io::Error> { | fn spawn_connect(self) -> impl Future<Item = (Self, UnixClient), Error = io::Error> { | ||||