##// END OF EJS Templates
rust-chg: collect server flags from command arguments...
Yuya Nishihara -
r45172:00ac6065 default
parent child Browse files
Show More
@@ -30,6 +30,7 b' const REQUIRED_SERVER_CAPABILITIES: &[&s'
30 30 #[derive(Clone, Debug)]
31 31 pub struct Locator {
32 32 hg_command: OsString,
33 hg_early_args: Vec<OsString>,
33 34 current_dir: PathBuf,
34 35 env_vars: Vec<(OsString, OsString)>,
35 36 process_id: u32,
@@ -45,6 +46,7 b' impl Locator {'
45 46 pub fn prepare_from_env() -> io::Result<Locator> {
46 47 Ok(Locator {
47 48 hg_command: default_hg_command(),
49 hg_early_args: Vec::new(),
48 50 current_dir: env::current_dir()?,
49 51 env_vars: env::vars_os().collect(),
50 52 process_id: process::id(),
@@ -62,6 +64,15 b' impl Locator {'
62 64 OsString::from_vec(buf).into()
63 65 }
64 66
67 /// Specifies the arguments to be passed to the server at start.
68 pub fn set_early_args<I, P>(&mut self, args: I)
69 where
70 I: IntoIterator<Item = P>,
71 P: AsRef<OsStr>,
72 {
73 self.hg_early_args = args.into_iter().map(|a| a.as_ref().to_owned()).collect();
74 }
75
65 76 /// Connects to the server.
66 77 ///
67 78 /// The server process will be spawned if not running.
@@ -109,6 +120,7 b' impl Locator {'
109 120 .arg(&sock_path)
110 121 .arg("--daemon-postexec")
111 122 .arg("chdir:/")
123 .args(&self.hg_early_args)
112 124 .current_dir(&self.current_dir)
113 125 .env_clear()
114 126 .envs(self.env_vars.iter().cloned())
@@ -275,3 +287,100 b' fn check_server_capabilities(spec: &Serv'
275 287 Err(io::Error::new(io::ErrorKind::Other, msg))
276 288 }
277 289 }
290
291 /// Collects arguments which need to be passed to the server at start.
292 pub fn collect_early_args<I, P>(args: I) -> Vec<OsString>
293 where
294 I: IntoIterator<Item = P>,
295 P: AsRef<OsStr>,
296 {
297 let mut args_iter = args.into_iter();
298 let mut early_args = Vec::new();
299 while let Some(arg) = args_iter.next() {
300 let argb = arg.as_ref().as_bytes();
301 if argb == b"--" {
302 break;
303 } else if argb.starts_with(b"--") {
304 let mut split = argb[2..].splitn(2, |&c| c == b'=');
305 match split.next().unwrap() {
306 b"traceback" => {
307 if split.next().is_none() {
308 early_args.push(arg.as_ref().to_owned());
309 }
310 }
311 b"config" | b"cwd" | b"repo" | b"repository" => {
312 if split.next().is_some() {
313 // --<flag>=<val>
314 early_args.push(arg.as_ref().to_owned());
315 } else {
316 // --<flag> <val>
317 args_iter.next().map(|val| {
318 early_args.push(arg.as_ref().to_owned());
319 early_args.push(val.as_ref().to_owned());
320 });
321 }
322 }
323 _ => {}
324 }
325 } else if argb.starts_with(b"-R") {
326 if argb.len() > 2 {
327 // -R<val>
328 early_args.push(arg.as_ref().to_owned());
329 } else {
330 // -R <val>
331 args_iter.next().map(|val| {
332 early_args.push(arg.as_ref().to_owned());
333 early_args.push(val.as_ref().to_owned());
334 });
335 }
336 }
337 }
338
339 early_args
340 }
341
342 #[cfg(test)]
343 mod tests {
344 use super::*;
345
346 #[test]
347 fn collect_early_args_some() {
348 assert!(collect_early_args(&[] as &[&OsStr]).is_empty());
349 assert!(collect_early_args(&["log"]).is_empty());
350 assert_eq!(
351 collect_early_args(&["log", "-Ra", "foo"]),
352 os_string_vec_from(&[b"-Ra"])
353 );
354 assert_eq!(
355 collect_early_args(&["log", "-R", "repo", "", "--traceback", "a"]),
356 os_string_vec_from(&[b"-R", b"repo", b"--traceback"])
357 );
358 assert_eq!(
359 collect_early_args(&["log", "--config", "diff.git=1", "-q"]),
360 os_string_vec_from(&[b"--config", b"diff.git=1"])
361 );
362 assert_eq!(
363 collect_early_args(&["--cwd=..", "--repository", "r", "log"]),
364 os_string_vec_from(&[b"--cwd=..", b"--repository", b"r"])
365 );
366 assert_eq!(
367 collect_early_args(&["log", "--repo=r", "--repos", "a"]),
368 os_string_vec_from(&[b"--repo=r"])
369 );
370 }
371
372 #[test]
373 fn collect_early_args_orphaned() {
374 assert!(collect_early_args(&["log", "-R"]).is_empty());
375 assert!(collect_early_args(&["log", "--config"]).is_empty());
376 }
377
378 #[test]
379 fn collect_early_args_unwanted_value() {
380 assert!(collect_early_args(&["log", "--traceback="]).is_empty());
381 }
382
383 fn os_string_vec_from(v: &[&[u8]]) -> Vec<OsString> {
384 v.iter().map(|s| OsStr::from_bytes(s).to_owned()).collect()
385 }
386 }
@@ -9,7 +9,7 b' extern crate log;'
9 9 extern crate tokio;
10 10 extern crate tokio_hglib;
11 11
12 use chg::locator::Locator;
12 use chg::locator::{self, Locator};
13 13 use chg::procutil;
14 14 use chg::{ChgClientExt, ChgUiHandler};
15 15 use futures::sync::oneshot;
@@ -73,7 +73,8 b' fn main() {'
73 73 }
74 74
75 75 fn run() -> io::Result<i32> {
76 let loc = Locator::prepare_from_env()?;
76 let mut loc = Locator::prepare_from_env()?;
77 loc.set_early_args(locator::collect_early_args(env::args_os().skip(1)));
77 78 let handler = ChgUiHandler::new();
78 79 let (result_tx, result_rx) = oneshot::channel();
79 80 let fut = loc
General Comments 0
You need to be logged in to leave comments. Login now