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