Mercurial > hg-stable
comparison rust/rhg/src/main.rs @ 46761:bde90e9b4507
rhg: Remove `rhg.fallback-executable=hg` default configuration
When `rhg.on-unsupported` is configured to `fallback` and an unsupported
feature is encountered, the previous default was to look for an `hg`
executable in `$PATH`.
This default was fragile since it was easy to end up accidentally using
an older version of Mercurial installed system-wide,
when a local (perhaps patched) installation was intended.
Instead, it is now an error to have `rhg.on-unsupported=fallback`
without also configuring an explicit path or the fallback executable.
Differential Revision: https://phab.mercurial-scm.org/D10189
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Fri, 12 Mar 2021 21:44:07 +0100 |
parents | eb14264b98e8 |
children | 821929d59e01 |
comparison
equal
deleted
inserted
replaced
46760:b1e6265e8336 | 46761:bde90e9b4507 |
---|---|
136 } | 136 } |
137 if SCHEME_RE.is_match(&repo_path_bytes) { | 137 if SCHEME_RE.is_match(&repo_path_bytes) { |
138 exit( | 138 exit( |
139 &initial_current_dir, | 139 &initial_current_dir, |
140 &ui, | 140 &ui, |
141 OnUnsupported::from_config(&non_repo_config), | 141 OnUnsupported::from_config(&ui, &non_repo_config), |
142 Err(CommandError::UnsupportedFeature { | 142 Err(CommandError::UnsupportedFeature { |
143 message: format_bytes!( | 143 message: format_bytes!( |
144 b"URL-like --repository {}", | 144 b"URL-like --repository {}", |
145 repo_path_bytes | 145 repo_path_bytes |
146 ), | 146 ), |
156 Err(NoRepoInCwdError { cwd: at }) | 156 Err(NoRepoInCwdError { cwd: at }) |
157 } | 157 } |
158 Err(error) => exit( | 158 Err(error) => exit( |
159 &initial_current_dir, | 159 &initial_current_dir, |
160 &ui, | 160 &ui, |
161 OnUnsupported::from_config(&non_repo_config), | 161 OnUnsupported::from_config(&ui, &non_repo_config), |
162 Err(error.into()), | 162 Err(error.into()), |
163 ), | 163 ), |
164 }; | 164 }; |
165 | 165 |
166 let config = if let Ok(repo) = &repo_result { | 166 let config = if let Ok(repo) = &repo_result { |
167 repo.config() | 167 repo.config() |
168 } else { | 168 } else { |
169 &non_repo_config | 169 &non_repo_config |
170 }; | 170 }; |
171 let on_unsupported = OnUnsupported::from_config(&ui, config); | |
171 | 172 |
172 let result = main_with_result( | 173 let result = main_with_result( |
173 &process_start_time, | 174 &process_start_time, |
174 &ui, | 175 &ui, |
175 repo_result.as_ref(), | 176 repo_result.as_ref(), |
176 config, | 177 config, |
177 ); | 178 ); |
178 exit( | 179 exit(&initial_current_dir, &ui, on_unsupported, result) |
179 &initial_current_dir, | |
180 &ui, | |
181 OnUnsupported::from_config(config), | |
182 result, | |
183 ) | |
184 } | 180 } |
185 | 181 |
186 fn exit_code(result: &Result<(), CommandError>) -> i32 { | 182 fn exit_code(result: &Result<(), CommandError>) -> i32 { |
187 match result { | 183 match result { |
188 Ok(()) => exitcode::OK, | 184 Ok(()) => exitcode::OK, |
240 on_unsupported = OnUnsupported::Abort | 236 on_unsupported = OnUnsupported::Abort |
241 } | 237 } |
242 } | 238 } |
243 } | 239 } |
244 } | 240 } |
241 exit_no_fallback(ui, on_unsupported, result) | |
242 } | |
243 | |
244 fn exit_no_fallback( | |
245 ui: &Ui, | |
246 on_unsupported: OnUnsupported, | |
247 result: Result<(), CommandError>, | |
248 ) -> ! { | |
245 match &result { | 249 match &result { |
246 Ok(_) => {} | 250 Ok(_) => {} |
247 Err(CommandError::Unsuccessful) => {} | 251 Err(CommandError::Unsuccessful) => {} |
248 Err(CommandError::Abort { message }) => { | 252 Err(CommandError::Abort { message }) => { |
249 if !message.is_empty() { | 253 if !message.is_empty() { |
385 Fallback { executable: Vec<u8> }, | 389 Fallback { executable: Vec<u8> }, |
386 } | 390 } |
387 | 391 |
388 impl OnUnsupported { | 392 impl OnUnsupported { |
389 const DEFAULT: Self = OnUnsupported::Abort; | 393 const DEFAULT: Self = OnUnsupported::Abort; |
390 const DEFAULT_FALLBACK_EXECUTABLE: &'static [u8] = b"hg"; | 394 |
391 | 395 fn from_config(ui: &Ui, config: &Config) -> Self { |
392 fn from_config(config: &Config) -> Self { | |
393 match config | 396 match config |
394 .get(b"rhg", b"on-unsupported") | 397 .get(b"rhg", b"on-unsupported") |
395 .map(|value| value.to_ascii_lowercase()) | 398 .map(|value| value.to_ascii_lowercase()) |
396 .as_deref() | 399 .as_deref() |
397 { | 400 { |
398 Some(b"abort") => OnUnsupported::Abort, | 401 Some(b"abort") => OnUnsupported::Abort, |
399 Some(b"abort-silent") => OnUnsupported::AbortSilent, | 402 Some(b"abort-silent") => OnUnsupported::AbortSilent, |
400 Some(b"fallback") => OnUnsupported::Fallback { | 403 Some(b"fallback") => OnUnsupported::Fallback { |
401 executable: config | 404 executable: config |
402 .get(b"rhg", b"fallback-executable") | 405 .get(b"rhg", b"fallback-executable") |
403 .unwrap_or(Self::DEFAULT_FALLBACK_EXECUTABLE) | 406 .unwrap_or_else(|| { |
407 exit_no_fallback( | |
408 ui, | |
409 Self::Abort, | |
410 Err(CommandError::abort( | |
411 "abort: 'rhg.on-unsupported=fallback' without \ | |
412 'rhg.fallback-executable' set." | |
413 )), | |
414 ) | |
415 }) | |
404 .to_owned(), | 416 .to_owned(), |
405 }, | 417 }, |
406 None => Self::DEFAULT, | 418 None => Self::DEFAULT, |
407 Some(_) => { | 419 Some(_) => { |
408 // TODO: warn about unknown config value | 420 // TODO: warn about unknown config value |