Mercurial > public > mercurial-scm > hg
diff rust/rhg/src/main.rs @ 46666:33f2d56acc73
rhg: Add a `rhg.on-unsupported` configuration key
For now the two values are:
* `abort-silent`: silently exit with code 252, the previous default behavior
* `abort`: print an error message about what feature
is not supported, then exit with code 252. Now the default.
Differential Revision: https://phab.mercurial-scm.org/D10091
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Mon, 01 Mar 2021 16:18:42 +0100 |
parents | 7284b524b441 |
children | 93e9f448273c |
line wrap: on
line diff
--- a/rust/rhg/src/main.rs Mon Mar 01 13:51:35 2021 +0100 +++ b/rust/rhg/src/main.rs Mon Mar 01 16:18:42 2021 +0100 @@ -84,8 +84,15 @@ let ui = ui::Ui::new(); let early_args = EarlyArgs::parse(std::env::args_os()); - let non_repo_config = Config::load(early_args.config) - .unwrap_or_else(|error| exit(&ui, Err(error.into()))); + let non_repo_config = + Config::load(early_args.config).unwrap_or_else(|error| { + // Normally this is decided based on config, but we don’t have that + // available. As of this writing config loading never returns an + // "unsupported" error but that is not enforced by the type system. + let on_unsupported = OnUnsupported::Abort; + + exit(&ui, on_unsupported, Err(error.into())) + }); let repo_path = early_args.repo.as_deref().map(get_path_from_bytes); let repo_result = match Repo::find(&non_repo_config, repo_path) { @@ -94,7 +101,11 @@ // Not finding a repo is not fatal yet, if `-R` was not given Err(NoRepoInCwdError { cwd: at }) } - Err(error) => exit(&ui, Err(error.into())), + Err(error) => exit( + &ui, + OnUnsupported::from_config(&non_repo_config), + Err(error.into()), + ), }; let config = if let Ok(repo) = &repo_result { @@ -109,7 +120,7 @@ repo_result.as_ref(), config, ); - exit(&ui, result) + exit(&ui, OnUnsupported::from_config(config), result) } fn exit_code(result: &Result<(), CommandError>) -> i32 { @@ -119,16 +130,37 @@ // Exit with a specific code and no error message to let a potential // wrapper script fallback to Python-based Mercurial. - Err(CommandError::Unimplemented) => exitcode::UNIMPLEMENTED, + Err(CommandError::UnsupportedFeature { .. }) => { + exitcode::UNIMPLEMENTED + } } } -fn exit(ui: &Ui, result: Result<(), CommandError>) -> ! { - if let Err(CommandError::Abort { message }) = &result { - if !message.is_empty() { - // Ignore errors when writing to stderr, we’re already exiting - // with failure code so there’s not much more we can do. - let _ = ui.write_stderr(&format_bytes!(b"abort: {}\n", message)); +fn exit( + ui: &Ui, + on_unsupported: OnUnsupported, + result: Result<(), CommandError>, +) -> ! { + match &result { + Ok(_) => {} + Err(CommandError::Abort { message }) => { + if !message.is_empty() { + // Ignore errors when writing to stderr, we’re already exiting + // with failure code so there’s not much more we can do. + let _ = + ui.write_stderr(&format_bytes!(b"abort: {}\n", message)); + } + } + Err(CommandError::UnsupportedFeature { message }) => { + match on_unsupported { + OnUnsupported::Abort => { + let _ = ui.write_stderr(&format_bytes!( + b"unsupported feature: {}\n", + message + )); + } + OnUnsupported::AbortSilent => {} + } } } std::process::exit(exit_code(&result)) @@ -226,3 +258,29 @@ Self { config, repo } } } + +/// What to do when encountering some unsupported feature. +/// +/// See `HgError::UnsupportedFeature` and `CommandError::UnsupportedFeature`. +enum OnUnsupported { + /// Print an error message describing what feature is not supported, + /// and exit with code 252. + Abort, + /// Silently exit with code 252. + AbortSilent, +} + +impl OnUnsupported { + fn from_config(config: &Config) -> Self { + let default = OnUnsupported::Abort; + match config.get(b"rhg", b"on-unsupported") { + Some(b"abort") => OnUnsupported::Abort, + Some(b"abort-silent") => OnUnsupported::AbortSilent, + None => default, + Some(_) => { + // TODO: warn about unknown config value + default + } + } + } +}