annotate rust/chg/src/locator.rs @ 44756:27fe8cc1338f

rust-chg: clean up excessive indents Differential Revision: https://phab.mercurial-scm.org/D8450
author Yuya Nishihara <yuya@tcha.org>
date Sat, 11 Apr 2020 17:43:29 +0900
parents a347a329e48d
children 426294d06ddc
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
39976
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
1 // Copyright 2011, 2018 Yuya Nishihara <yuya@tcha.org>
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
2 //
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
3 // This software may be used and distributed according to the terms of the
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
4 // GNU General Public License version 2 or any later version.
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
5
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
6 //! Utility for locating command-server process.
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
7
44688
1f5ab1a9363d rust-chg: upgrade to 2018 edition and remove useless extern crates
Yuya Nishihara <yuya@tcha.org>
parents: 44684
diff changeset
8 use log::debug;
39976
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
9 use std::env;
40289
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
10 use std::ffi::{OsStr, OsString};
39976
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
11 use std::fs::{self, DirBuilder};
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
12 use std::io;
40289
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
13 use std::os::unix::ffi::{OsStrExt, OsStringExt};
39976
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
14 use std::os::unix::fs::{DirBuilderExt, MetadataExt};
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
15 use std::path::{Path, PathBuf};
44753
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
16 use std::process::{self, Child, Command};
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
17 use std::time::{Duration, Instant};
44737
e9e44e61042b rust-chg: upgrade to futures-0.3 based libraries
Yuya Nishihara <yuya@tcha.org>
parents: 44693
diff changeset
18 use tokio::time;
39976
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
19
44753
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
20 use crate::clientext::ChgClient;
44689
6bef9d43cc55 rust-chg: use "crate::" to import local modules
Yuya Nishihara <yuya@tcha.org>
parents: 44688
diff changeset
21 use crate::message::{Instruction, ServerSpec};
6bef9d43cc55 rust-chg: use "crate::" to import local modules
Yuya Nishihara <yuya@tcha.org>
parents: 44688
diff changeset
22 use crate::procutil;
39976
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
23
44683
065048e66f32 rust-chg: send client side umask to server
Yuya Nishihara <yuya@tcha.org>
parents: 44682
diff changeset
24 const REQUIRED_SERVER_CAPABILITIES: &[&str] = &[
065048e66f32 rust-chg: send client side umask to server
Yuya Nishihara <yuya@tcha.org>
parents: 44682
diff changeset
25 "attachio",
065048e66f32 rust-chg: send client side umask to server
Yuya Nishihara <yuya@tcha.org>
parents: 44682
diff changeset
26 "chdir",
065048e66f32 rust-chg: send client side umask to server
Yuya Nishihara <yuya@tcha.org>
parents: 44682
diff changeset
27 "runcommand",
065048e66f32 rust-chg: send client side umask to server
Yuya Nishihara <yuya@tcha.org>
parents: 44682
diff changeset
28 "setenv",
065048e66f32 rust-chg: send client side umask to server
Yuya Nishihara <yuya@tcha.org>
parents: 44682
diff changeset
29 "setumask2",
065048e66f32 rust-chg: send client side umask to server
Yuya Nishihara <yuya@tcha.org>
parents: 44682
diff changeset
30 "validate",
065048e66f32 rust-chg: send client side umask to server
Yuya Nishihara <yuya@tcha.org>
parents: 44682
diff changeset
31 ];
44672
7bf45ed9e25e rust-chg: abort if server doesn't have required capabilities
Yuya Nishihara <yuya@tcha.org>
parents: 44671
diff changeset
32
40289
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
33 /// Helper to connect to and spawn a server process.
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
34 #[derive(Clone, Debug)]
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
35 pub struct Locator {
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
36 hg_command: OsString,
44681
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
37 hg_early_args: Vec<OsString>,
40289
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
38 current_dir: PathBuf,
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
39 env_vars: Vec<(OsString, OsString)>,
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
40 process_id: u32,
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
41 base_sock_path: PathBuf,
44682
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
42 redirect_sock_path: Option<PathBuf>,
40289
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
43 timeout: Duration,
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
44 }
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
45
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
46 impl Locator {
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
47 /// Creates locator capturing the current process environment.
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
48 ///
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
49 /// If no `$CHGSOCKNAME` is specified, the socket directory will be
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
50 /// created as necessary.
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
51 pub fn prepare_from_env() -> io::Result<Locator> {
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
52 Ok(Locator {
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
53 hg_command: default_hg_command(),
44681
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
54 hg_early_args: Vec::new(),
40289
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
55 current_dir: env::current_dir()?,
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
56 env_vars: env::vars_os().collect(),
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
57 process_id: process::id(),
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
58 base_sock_path: prepare_server_socket_path()?,
44682
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
59 redirect_sock_path: None,
40289
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
60 timeout: default_timeout(),
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
61 })
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
62 }
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
63
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
64 /// Temporary socket path for this client process.
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
65 fn temp_sock_path(&self) -> PathBuf {
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
66 let src = self.base_sock_path.as_os_str().as_bytes();
44668
c11d98cff883 rust-chg: add brief comment about initial capacity of temp_sock_path()
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
67 let mut buf = Vec::with_capacity(src.len() + 6); // "{src}.{pid}".len()
40289
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
68 buf.extend_from_slice(src);
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
69 buf.extend_from_slice(format!(".{}", self.process_id).as_bytes());
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
70 OsString::from_vec(buf).into()
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
71 }
44671
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
72
44681
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
73 /// Specifies the arguments to be passed to the server at start.
44693
61fda2dbc522 rust-chg: leverage impl trait at argument position
Yuya Nishihara <yuya@tcha.org>
parents: 44689
diff changeset
74 pub fn set_early_args(&mut self, args: impl IntoIterator<Item = impl AsRef<OsStr>>) {
44681
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
75 self.hg_early_args = args.into_iter().map(|a| a.as_ref().to_owned()).collect();
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
76 }
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
77
44671
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
78 /// Connects to the server.
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
79 ///
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
80 /// The server process will be spawned if not running.
44753
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
81 pub async fn connect(&mut self) -> io::Result<ChgClient> {
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
82 for _cnt in 0..10 {
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
83 let mut client = self.try_connect().await?;
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
84 let instructions = client.validate(&self.hg_early_args).await?;
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
85 let reconnect = self.run_instructions(&instructions)?;
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
86 if !reconnect {
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
87 return Ok(client);
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
88 }
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
89 }
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
90
44756
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
91 let msg = format!(
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
92 concat!(
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
93 "too many redirections.\n",
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
94 "Please make sure {:?} is not a wrapper which ",
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
95 "changes sensitive environment variables ",
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
96 "before executing hg. If you have to use a ",
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
97 "wrapper, wrap chg instead of hg.",
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
98 ),
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
99 self.hg_command
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
100 );
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
101 Err(io::Error::new(io::ErrorKind::Other, msg))
44682
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
102 }
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
103
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
104 /// Runs instructions received from the server.
44753
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
105 ///
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
106 /// Returns true if the client should try connecting to the other server.
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
107 fn run_instructions(&mut self, instructions: &[Instruction]) -> io::Result<bool> {
44682
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
108 let mut reconnect = false;
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
109 for inst in instructions {
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
110 debug!("instruction: {:?}", inst);
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
111 match inst {
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
112 Instruction::Exit(_) => {
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
113 // Just returns the current connection to run the
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
114 // unparsable command and report the error
44753
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
115 return Ok(false);
44682
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
116 }
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
117 Instruction::Reconnect => {
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
118 reconnect = true;
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
119 }
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
120 Instruction::Redirect(path) => {
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
121 if path.parent() != self.base_sock_path.parent() {
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
122 let msg = format!(
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
123 "insecure redirect instruction from server: {}",
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
124 path.display()
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
125 );
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
126 return Err(io::Error::new(io::ErrorKind::InvalidData, msg));
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
127 }
44753
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
128 self.redirect_sock_path = Some(path.to_owned());
44682
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
129 reconnect = true;
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
130 }
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
131 Instruction::Unlink(path) => {
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
132 if path.parent() != self.base_sock_path.parent() {
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
133 let msg = format!(
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
134 "insecure unlink instruction from server: {}",
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
135 path.display()
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
136 );
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
137 return Err(io::Error::new(io::ErrorKind::InvalidData, msg));
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
138 }
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
139 fs::remove_file(path).unwrap_or(()); // may race
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
140 }
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
141 }
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
142 }
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
143
44753
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
144 Ok(reconnect)
44671
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
145 }
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
146
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
147 /// Tries to connect to the existing server, or spawns new if not running.
44753
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
148 async fn try_connect(&mut self) -> io::Result<ChgClient> {
44682
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
149 let sock_path = self
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
150 .redirect_sock_path
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
151 .as_ref()
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
152 .unwrap_or(&self.base_sock_path)
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
153 .clone();
9ce613d648de rust-chg: add config validation and process returned instructions
Yuya Nishihara <yuya@tcha.org>
parents: 44681
diff changeset
154 debug!("try connect to {}", sock_path.display());
44756
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
155 let mut client = match ChgClient::connect(sock_path).await {
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
156 Ok(client) => client,
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
157 Err(_) => {
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
158 // Prevent us from being re-connected to the outdated
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
159 // master server: We were told by the server to redirect
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
160 // to redirect_sock_path, which didn't work. We do not
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
161 // want to connect to the same master server again
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
162 // because it would probably tell us the same thing.
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
163 if self.redirect_sock_path.is_some() {
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
164 fs::remove_file(&self.base_sock_path).unwrap_or(());
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
165 // may race
44684
80d6e3415636 rust-chg: update name of the server process
Yuya Nishihara <yuya@tcha.org>
parents: 44683
diff changeset
166 }
44756
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
167 self.spawn_connect().await?
44753
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
168 }
44756
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
169 };
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
170 check_server_capabilities(client.server_spec())?;
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
171 // It's purely optional, and the server might not support this command.
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
172 if client.server_spec().capabilities.contains("setprocname") {
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
173 client
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
174 .set_process_name(format!("chg[worker/{}]", self.process_id))
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
175 .await?;
44753
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
176 }
44756
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
177 client.set_current_dir(&self.current_dir).await?;
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
178 client
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
179 .set_env_vars_os(self.env_vars.iter().cloned())
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
180 .await?;
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
181 Ok(client)
44671
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
182 }
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
183
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
184 /// Spawns new server process and connects to it.
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
185 ///
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
186 /// The server will be spawned at the current working directory, then
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
187 /// chdir to "/", so that the server will load configs from the target
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
188 /// repository.
44753
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
189 async fn spawn_connect(&mut self) -> io::Result<ChgClient> {
44671
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
190 let sock_path = self.temp_sock_path();
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
191 debug!("start cmdserver at {}", sock_path.display());
44753
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
192 let server = Command::new(&self.hg_command)
44671
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
193 .arg("serve")
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
194 .arg("--cmdserver")
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
195 .arg("chgunix")
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
196 .arg("--address")
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
197 .arg(&sock_path)
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
198 .arg("--daemon-postexec")
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
199 .arg("chdir:/")
44681
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
200 .args(&self.hg_early_args)
44671
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
201 .current_dir(&self.current_dir)
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
202 .env_clear()
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
203 .envs(self.env_vars.iter().cloned())
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
204 .env("CHGINTERNALMARK", "")
44753
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
205 .spawn()?;
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
206 let client = self.connect_spawned(server, &sock_path).await?;
44756
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
207 debug!(
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
208 "rename {} to {}",
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
209 sock_path.display(),
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
210 self.base_sock_path.display()
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
211 );
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
212 fs::rename(&sock_path, &self.base_sock_path)?;
27fe8cc1338f rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents: 44753
diff changeset
213 Ok(client)
44671
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
214 }
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
215
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
216 /// Tries to connect to the just spawned server repeatedly until timeout
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
217 /// exceeded.
44753
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
218 async fn connect_spawned(
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
219 &mut self,
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
220 mut server: Child,
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
221 sock_path: &Path,
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
222 ) -> io::Result<ChgClient> {
44671
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
223 debug!("try connect to {} repeatedly", sock_path.display());
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
224 // waits for either connection established or server failed to start
44753
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
225 let start_time = Instant::now();
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
226 while start_time.elapsed() < self.timeout {
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
227 if let Ok(client) = ChgClient::connect(&sock_path).await {
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
228 // server handle is dropped here, but the detached process
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
229 // will continue running in background
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
230 return Ok(client);
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
231 }
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
232
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
233 if let Some(st) = server.try_wait()? {
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
234 return Err(io::Error::new(
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
235 io::ErrorKind::Other,
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
236 format!("server exited too early: {}", st),
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
237 ));
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
238 }
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
239
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
240 // try again with slight delay
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
241 time::delay_for(Duration::from_millis(10)).await;
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
242 }
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
243
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
244 Err(io::Error::new(
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
245 io::ErrorKind::TimedOut,
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
246 "timed out while connecting to server",
a347a329e48d rust-chg: reimplement locator by using async/await and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents: 44737
diff changeset
247 ))
44671
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
248 }
40289
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
249 }
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
250
39976
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
251 /// Determines the server socket to connect to.
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
252 ///
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
253 /// If no `$CHGSOCKNAME` is specified, the socket directory will be created
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
254 /// as necessary.
44671
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 44668
diff changeset
255 fn prepare_server_socket_path() -> io::Result<PathBuf> {
39976
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
256 if let Some(s) = env::var_os("CHGSOCKNAME") {
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
257 Ok(PathBuf::from(s))
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
258 } else {
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
259 let mut path = default_server_socket_dir();
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
260 create_secure_dir(&path)?;
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
261 path.push("server");
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
262 Ok(path)
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
263 }
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
264 }
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
265
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
266 /// Determines the default server socket path as follows.
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
267 ///
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
268 /// 1. `$XDG_RUNTIME_DIR/chg`
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
269 /// 2. `$TMPDIR/chg$UID`
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
270 /// 3. `/tmp/chg$UID`
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
271 pub fn default_server_socket_dir() -> PathBuf {
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
272 // XDG_RUNTIME_DIR should be ignored if it has an insufficient permission.
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
273 // https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
274 if let Some(Ok(s)) = env::var_os("XDG_RUNTIME_DIR").map(check_secure_dir) {
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
275 let mut path = PathBuf::from(s);
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
276 path.push("chg");
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
277 path
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
278 } else {
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
279 let mut path = env::temp_dir();
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
280 path.push(format!("chg{}", procutil::get_effective_uid()));
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
281 path
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
282 }
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
283 }
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
284
40289
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
285 /// Determines the default hg command.
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
286 pub fn default_hg_command() -> OsString {
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
287 // TODO: maybe allow embedding the path at compile time (or load from hgrc)
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40289
diff changeset
288 env::var_os("CHGHG")
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40289
diff changeset
289 .or(env::var_os("HG"))
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40289
diff changeset
290 .unwrap_or(OsStr::new("hg").to_owned())
40289
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
291 }
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
292
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
293 fn default_timeout() -> Duration {
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40289
diff changeset
294 let secs = env::var("CHGTIMEOUT")
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40289
diff changeset
295 .ok()
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40289
diff changeset
296 .and_then(|s| s.parse().ok())
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40289
diff changeset
297 .unwrap_or(60);
40289
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
298 Duration::from_secs(secs)
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
299 }
7d3285f799cc rust-chg: add struct holding information needed to spawn server process
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
300
39976
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
301 /// Creates a directory which the other users cannot access to.
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
302 ///
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
303 /// If the directory already exists, tests its permission.
44693
61fda2dbc522 rust-chg: leverage impl trait at argument position
Yuya Nishihara <yuya@tcha.org>
parents: 44689
diff changeset
304 fn create_secure_dir(path: impl AsRef<Path>) -> io::Result<()> {
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40289
diff changeset
305 DirBuilder::new()
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40289
diff changeset
306 .mode(0o700)
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40289
diff changeset
307 .create(path.as_ref())
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40289
diff changeset
308 .or_else(|err| {
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40289
diff changeset
309 if err.kind() == io::ErrorKind::AlreadyExists {
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40289
diff changeset
310 check_secure_dir(path).map(|_| ())
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40289
diff changeset
311 } else {
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40289
diff changeset
312 Err(err)
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40289
diff changeset
313 }
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40289
diff changeset
314 })
39976
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
315 }
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
316
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
317 fn check_secure_dir<P>(path: P) -> io::Result<P>
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40289
diff changeset
318 where
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40289
diff changeset
319 P: AsRef<Path>,
39976
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
320 {
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
321 let a = fs::symlink_metadata(path.as_ref())?;
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
322 if a.is_dir() && a.uid() == procutil::get_effective_uid() && (a.mode() & 0o777) == 0o700 {
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
323 Ok(path)
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
324 } else {
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
325 Err(io::Error::new(io::ErrorKind::Other, "insecure directory"))
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
326 }
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
327 }
44672
7bf45ed9e25e rust-chg: abort if server doesn't have required capabilities
Yuya Nishihara <yuya@tcha.org>
parents: 44671
diff changeset
328
7bf45ed9e25e rust-chg: abort if server doesn't have required capabilities
Yuya Nishihara <yuya@tcha.org>
parents: 44671
diff changeset
329 fn check_server_capabilities(spec: &ServerSpec) -> io::Result<()> {
7bf45ed9e25e rust-chg: abort if server doesn't have required capabilities
Yuya Nishihara <yuya@tcha.org>
parents: 44671
diff changeset
330 let unsupported: Vec<_> = REQUIRED_SERVER_CAPABILITIES
7bf45ed9e25e rust-chg: abort if server doesn't have required capabilities
Yuya Nishihara <yuya@tcha.org>
parents: 44671
diff changeset
331 .iter()
7bf45ed9e25e rust-chg: abort if server doesn't have required capabilities
Yuya Nishihara <yuya@tcha.org>
parents: 44671
diff changeset
332 .cloned()
7bf45ed9e25e rust-chg: abort if server doesn't have required capabilities
Yuya Nishihara <yuya@tcha.org>
parents: 44671
diff changeset
333 .filter(|&s| !spec.capabilities.contains(s))
7bf45ed9e25e rust-chg: abort if server doesn't have required capabilities
Yuya Nishihara <yuya@tcha.org>
parents: 44671
diff changeset
334 .collect();
7bf45ed9e25e rust-chg: abort if server doesn't have required capabilities
Yuya Nishihara <yuya@tcha.org>
parents: 44671
diff changeset
335 if unsupported.is_empty() {
7bf45ed9e25e rust-chg: abort if server doesn't have required capabilities
Yuya Nishihara <yuya@tcha.org>
parents: 44671
diff changeset
336 Ok(())
7bf45ed9e25e rust-chg: abort if server doesn't have required capabilities
Yuya Nishihara <yuya@tcha.org>
parents: 44671
diff changeset
337 } else {
7bf45ed9e25e rust-chg: abort if server doesn't have required capabilities
Yuya Nishihara <yuya@tcha.org>
parents: 44671
diff changeset
338 let msg = format!(
7bf45ed9e25e rust-chg: abort if server doesn't have required capabilities
Yuya Nishihara <yuya@tcha.org>
parents: 44671
diff changeset
339 "insufficient server capabilities: {}",
7bf45ed9e25e rust-chg: abort if server doesn't have required capabilities
Yuya Nishihara <yuya@tcha.org>
parents: 44671
diff changeset
340 unsupported.join(", ")
7bf45ed9e25e rust-chg: abort if server doesn't have required capabilities
Yuya Nishihara <yuya@tcha.org>
parents: 44671
diff changeset
341 );
7bf45ed9e25e rust-chg: abort if server doesn't have required capabilities
Yuya Nishihara <yuya@tcha.org>
parents: 44671
diff changeset
342 Err(io::Error::new(io::ErrorKind::Other, msg))
7bf45ed9e25e rust-chg: abort if server doesn't have required capabilities
Yuya Nishihara <yuya@tcha.org>
parents: 44671
diff changeset
343 }
7bf45ed9e25e rust-chg: abort if server doesn't have required capabilities
Yuya Nishihara <yuya@tcha.org>
parents: 44671
diff changeset
344 }
44681
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
345
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
346 /// Collects arguments which need to be passed to the server at start.
44693
61fda2dbc522 rust-chg: leverage impl trait at argument position
Yuya Nishihara <yuya@tcha.org>
parents: 44689
diff changeset
347 pub fn collect_early_args(args: impl IntoIterator<Item = impl AsRef<OsStr>>) -> Vec<OsString> {
44681
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
348 let mut args_iter = args.into_iter();
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
349 let mut early_args = Vec::new();
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
350 while let Some(arg) = args_iter.next() {
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
351 let argb = arg.as_ref().as_bytes();
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
352 if argb == b"--" {
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
353 break;
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
354 } else if argb.starts_with(b"--") {
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
355 let mut split = argb[2..].splitn(2, |&c| c == b'=');
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
356 match split.next().unwrap() {
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
357 b"traceback" => {
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
358 if split.next().is_none() {
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
359 early_args.push(arg.as_ref().to_owned());
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
360 }
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
361 }
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
362 b"config" | b"cwd" | b"repo" | b"repository" => {
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
363 if split.next().is_some() {
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
364 // --<flag>=<val>
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
365 early_args.push(arg.as_ref().to_owned());
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
366 } else {
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
367 // --<flag> <val>
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
368 args_iter.next().map(|val| {
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
369 early_args.push(arg.as_ref().to_owned());
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
370 early_args.push(val.as_ref().to_owned());
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
371 });
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
372 }
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
373 }
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
374 _ => {}
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
375 }
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
376 } else if argb.starts_with(b"-R") {
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
377 if argb.len() > 2 {
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
378 // -R<val>
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
379 early_args.push(arg.as_ref().to_owned());
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
380 } else {
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
381 // -R <val>
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
382 args_iter.next().map(|val| {
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
383 early_args.push(arg.as_ref().to_owned());
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
384 early_args.push(val.as_ref().to_owned());
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
385 });
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
386 }
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
387 }
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
388 }
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
389
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
390 early_args
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
391 }
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
392
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
393 #[cfg(test)]
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
394 mod tests {
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
395 use super::*;
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
396
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
397 #[test]
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
398 fn collect_early_args_some() {
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
399 assert!(collect_early_args(&[] as &[&OsStr]).is_empty());
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
400 assert!(collect_early_args(&["log"]).is_empty());
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
401 assert_eq!(
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
402 collect_early_args(&["log", "-Ra", "foo"]),
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
403 os_string_vec_from(&[b"-Ra"])
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
404 );
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
405 assert_eq!(
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
406 collect_early_args(&["log", "-R", "repo", "", "--traceback", "a"]),
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
407 os_string_vec_from(&[b"-R", b"repo", b"--traceback"])
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
408 );
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
409 assert_eq!(
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
410 collect_early_args(&["log", "--config", "diff.git=1", "-q"]),
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
411 os_string_vec_from(&[b"--config", b"diff.git=1"])
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
412 );
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
413 assert_eq!(
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
414 collect_early_args(&["--cwd=..", "--repository", "r", "log"]),
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
415 os_string_vec_from(&[b"--cwd=..", b"--repository", b"r"])
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
416 );
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
417 assert_eq!(
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
418 collect_early_args(&["log", "--repo=r", "--repos", "a"]),
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
419 os_string_vec_from(&[b"--repo=r"])
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
420 );
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
421 }
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
422
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
423 #[test]
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
424 fn collect_early_args_orphaned() {
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
425 assert!(collect_early_args(&["log", "-R"]).is_empty());
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
426 assert!(collect_early_args(&["log", "--config"]).is_empty());
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
427 }
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
428
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
429 #[test]
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
430 fn collect_early_args_unwanted_value() {
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
431 assert!(collect_early_args(&["log", "--traceback="]).is_empty());
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
432 }
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
433
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
434 fn os_string_vec_from(v: &[&[u8]]) -> Vec<OsString> {
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
435 v.iter().map(|s| OsStr::from_bytes(s).to_owned()).collect()
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
436 }
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44675
diff changeset
437 }