86 if !reconnect { |
86 if !reconnect { |
87 return Ok(client); |
87 return Ok(client); |
88 } |
88 } |
89 } |
89 } |
90 |
90 |
91 // TODO: unindent |
91 let msg = format!( |
92 { |
92 concat!( |
93 { |
93 "too many redirections.\n", |
94 let msg = format!( |
94 "Please make sure {:?} is not a wrapper which ", |
95 concat!( |
95 "changes sensitive environment variables ", |
96 "too many redirections.\n", |
96 "before executing hg. If you have to use a ", |
97 "Please make sure {:?} is not a wrapper which ", |
97 "wrapper, wrap chg instead of hg.", |
98 "changes sensitive environment variables ", |
98 ), |
99 "before executing hg. If you have to use a ", |
99 self.hg_command |
100 "wrapper, wrap chg instead of hg.", |
100 ); |
101 ), |
101 Err(io::Error::new(io::ErrorKind::Other, msg)) |
102 self.hg_command |
|
103 ); |
|
104 Err(io::Error::new(io::ErrorKind::Other, msg)) |
|
105 } |
|
106 } |
|
107 } |
102 } |
108 |
103 |
109 /// Runs instructions received from the server. |
104 /// Runs instructions received from the server. |
110 /// |
105 /// |
111 /// Returns true if the client should try connecting to the other server. |
106 /// Returns true if the client should try connecting to the other server. |
155 .redirect_sock_path |
150 .redirect_sock_path |
156 .as_ref() |
151 .as_ref() |
157 .unwrap_or(&self.base_sock_path) |
152 .unwrap_or(&self.base_sock_path) |
158 .clone(); |
153 .clone(); |
159 debug!("try connect to {}", sock_path.display()); |
154 debug!("try connect to {}", sock_path.display()); |
160 // TODO: unindent |
155 let mut client = match ChgClient::connect(sock_path).await { |
161 { |
156 Ok(client) => client, |
162 { |
157 Err(_) => { |
163 let mut client = match ChgClient::connect(sock_path).await { |
158 // Prevent us from being re-connected to the outdated |
164 Ok(client) => client, |
159 // master server: We were told by the server to redirect |
165 Err(_) => { |
160 // to redirect_sock_path, which didn't work. We do not |
166 // Prevent us from being re-connected to the outdated |
161 // want to connect to the same master server again |
167 // master server: We were told by the server to redirect |
162 // because it would probably tell us the same thing. |
168 // to redirect_sock_path, which didn't work. We do not |
163 if self.redirect_sock_path.is_some() { |
169 // want to connect to the same master server again |
164 fs::remove_file(&self.base_sock_path).unwrap_or(()); |
170 // because it would probably tell us the same thing. |
165 // may race |
171 if self.redirect_sock_path.is_some() { |
166 } |
172 fs::remove_file(&self.base_sock_path).unwrap_or(()); |
167 self.spawn_connect().await? |
173 // may race |
168 } |
174 } |
169 }; |
175 self.spawn_connect().await? |
170 check_server_capabilities(client.server_spec())?; |
176 } |
171 // It's purely optional, and the server might not support this command. |
177 }; |
172 if client.server_spec().capabilities.contains("setprocname") { |
178 check_server_capabilities(client.server_spec())?; |
173 client |
179 // It's purely optional, and the server might not support this command. |
174 .set_process_name(format!("chg[worker/{}]", self.process_id)) |
180 if client.server_spec().capabilities.contains("setprocname") { |
175 .await?; |
181 client |
|
182 .set_process_name(format!("chg[worker/{}]", self.process_id)) |
|
183 .await?; |
|
184 } |
|
185 client.set_current_dir(&self.current_dir).await?; |
|
186 client |
|
187 .set_env_vars_os(self.env_vars.iter().cloned()) |
|
188 .await?; |
|
189 Ok(client) |
|
190 } |
|
191 } |
176 } |
|
177 client.set_current_dir(&self.current_dir).await?; |
|
178 client |
|
179 .set_env_vars_os(self.env_vars.iter().cloned()) |
|
180 .await?; |
|
181 Ok(client) |
192 } |
182 } |
193 |
183 |
194 /// Spawns new server process and connects to it. |
184 /// Spawns new server process and connects to it. |
195 /// |
185 /// |
196 /// The server will be spawned at the current working directory, then |
186 /// The server will be spawned at the current working directory, then |
212 .env_clear() |
202 .env_clear() |
213 .envs(self.env_vars.iter().cloned()) |
203 .envs(self.env_vars.iter().cloned()) |
214 .env("CHGINTERNALMARK", "") |
204 .env("CHGINTERNALMARK", "") |
215 .spawn()?; |
205 .spawn()?; |
216 let client = self.connect_spawned(server, &sock_path).await?; |
206 let client = self.connect_spawned(server, &sock_path).await?; |
217 // TODO: unindent |
207 debug!( |
218 { |
208 "rename {} to {}", |
219 { |
209 sock_path.display(), |
220 debug!( |
210 self.base_sock_path.display() |
221 "rename {} to {}", |
211 ); |
222 sock_path.display(), |
212 fs::rename(&sock_path, &self.base_sock_path)?; |
223 self.base_sock_path.display() |
213 Ok(client) |
224 ); |
|
225 fs::rename(&sock_path, &self.base_sock_path)?; |
|
226 Ok(client) |
|
227 } |
|
228 } |
|
229 } |
214 } |
230 |
215 |
231 /// Tries to connect to the just spawned server repeatedly until timeout |
216 /// Tries to connect to the just spawned server repeatedly until timeout |
232 /// exceeded. |
217 /// exceeded. |
233 async fn connect_spawned( |
218 async fn connect_spawned( |