##// END OF EJS Templates
rhg: add exit code to HgError::Abort()...
Pulkit Goyal -
r48199:6e49769b default
parent child Browse files
Show More
@@ -0,0 +1,19 b''
1 pub type ExitCode = i32;
2
3 /// Successful exit
4 pub const OK: ExitCode = 0;
5
6 /// Generic abort
7 pub const ABORT: ExitCode = 255;
8
9 // Abort when there is a config related error
10 pub const CONFIG_ERROR_ABORT: ExitCode = 30;
11
12 // Abort when there is an error while parsing config
13 pub const CONFIG_PARSE_ERROR_ABORT: ExitCode = 10;
14
15 /// Generic something completed but did not succeed
16 pub const UNSUCCESSFUL: ExitCode = 1;
17
18 /// Command or feature not implemented by rhg
19 pub const UNIMPLEMENTED: ExitCode = 252;
@@ -8,6 +8,7 b''
8 8 // GNU General Public License version 2 or any later version.
9 9
10 10 use crate::errors::HgError;
11 use crate::exit_codes::CONFIG_PARSE_ERROR_ABORT;
11 12 use crate::utils::files::{get_bytes_from_path, get_path_from_bytes};
12 13 use format_bytes::{format_bytes, write_bytes, DisplayBytes};
13 14 use lazy_static::lazy_static;
@@ -73,11 +74,14 b' impl ConfigLayer {'
73 74 if let Some((section, item, value)) = parse_one(arg) {
74 75 layer.add(section, item, value, None);
75 76 } else {
76 Err(HgError::abort(format!(
77 "abort: malformed --config option: '{}' \
77 Err(HgError::abort(
78 format!(
79 "abort: malformed --config option: '{}' \
78 80 (use --config section.name=value)",
79 String::from_utf8_lossy(arg),
80 )))?
81 String::from_utf8_lossy(arg),
82 ),
83 CONFIG_PARSE_ERROR_ABORT,
84 ))?
81 85 }
82 86 }
83 87 if layer.sections.is_empty() {
@@ -1,4 +1,5 b''
1 1 use crate::config::ConfigValueParseError;
2 use crate::exit_codes;
2 3 use std::fmt;
3 4
4 5 /// Common error cases that can happen in many different APIs
@@ -27,9 +28,12 b' pub enum HgError {'
27 28
28 29 /// Operation cannot proceed for some other reason.
29 30 ///
30 /// The given string is a short explanation for users, not intended to be
31 /// The message is a short explanation for users, not intended to be
31 32 /// machine-readable.
32 Abort(String),
33 Abort {
34 message: String,
35 detailed_exit_code: exit_codes::ExitCode,
36 },
33 37
34 38 /// A configuration value is not in the expected syntax.
35 39 ///
@@ -69,8 +73,15 b' impl HgError {'
69 73 pub fn unsupported(explanation: impl Into<String>) -> Self {
70 74 HgError::UnsupportedFeature(explanation.into())
71 75 }
72 pub fn abort(explanation: impl Into<String>) -> Self {
73 HgError::Abort(explanation.into())
76
77 pub fn abort(
78 explanation: impl Into<String>,
79 exit_code: exit_codes::ExitCode,
80 ) -> Self {
81 HgError::Abort {
82 message: explanation.into(),
83 detailed_exit_code: exit_code,
84 }
74 85 }
75 86 }
76 87
@@ -78,7 +89,7 b' impl HgError {'
78 89 impl fmt::Display for HgError {
79 90 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
80 91 match self {
81 HgError::Abort(explanation) => write!(f, "{}", explanation),
92 HgError::Abort { message, .. } => write!(f, "{}", message),
82 93 HgError::IoError { error, context } => {
83 94 write!(f, "abort: {}: {}", context, error)
84 95 }
@@ -11,6 +11,7 b' pub use ancestors::{AncestorsIterator, L'
11 11 pub mod dirstate;
12 12 pub mod dirstate_tree;
13 13 pub mod discovery;
14 pub mod exit_codes;
14 15 pub mod requirements;
15 16 pub mod testing; // unconditionally built, for use from integration tests
16 17 pub use dirstate::{
@@ -1,5 +1,6 b''
1 1 use crate::config::{Config, ConfigError, ConfigParseError};
2 2 use crate::errors::{HgError, IoErrorContext, IoResultExt};
3 use crate::exit_codes;
3 4 use crate::requirements;
4 5 use crate::utils::files::get_path_from_bytes;
5 6 use crate::utils::SliceExt;
@@ -150,6 +151,7 b' impl Repo {'
150 151 Some(b"abort") | None => HgError::abort(
151 152 "abort: share source does not support share-safe requirement\n\
152 153 (see `hg help config.format.use-share-safe` for more information)",
154 exit_codes::ABORT,
153 155 ),
154 156 _ => HgError::unsupported("share-safe downgrade"),
155 157 }
@@ -161,6 +163,7 b' impl Repo {'
161 163 "abort: version mismatch: source uses share-safe \
162 164 functionality while the current share does not\n\
163 165 (see `hg help config.format.use-share-safe` for more information)",
166 exit_codes::ABORT,
164 167 ),
165 168 _ => HgError::unsupported("share-safe upgrade"),
166 169 }
@@ -1,10 +1,10 b''
1 use crate::exitcode;
2 1 use crate::ui::utf8_to_local;
3 2 use crate::ui::UiError;
4 3 use crate::NoRepoInCwdError;
5 4 use format_bytes::format_bytes;
6 5 use hg::config::{ConfigError, ConfigParseError, ConfigValueParseError};
7 6 use hg::errors::HgError;
7 use hg::exit_codes;
8 8 use hg::repo::RepoError;
9 9 use hg::revlog::revlog::RevlogError;
10 10 use hg::utils::files::get_bytes_from_path;
@@ -17,7 +17,7 b' pub enum CommandError {'
17 17 /// Exit with an error message and "standard" failure exit code.
18 18 Abort {
19 19 message: Vec<u8>,
20 detailed_exit_code: exitcode::ExitCode,
20 detailed_exit_code: exit_codes::ExitCode,
21 21 },
22 22
23 23 /// Exit with a failure exit code but no message.
@@ -32,12 +32,12 b' pub enum CommandError {'
32 32
33 33 impl CommandError {
34 34 pub fn abort(message: impl AsRef<str>) -> Self {
35 CommandError::abort_with_exit_code(message, exitcode::ABORT)
35 CommandError::abort_with_exit_code(message, exit_codes::ABORT)
36 36 }
37 37
38 38 pub fn abort_with_exit_code(
39 39 message: impl AsRef<str>,
40 detailed_exit_code: exitcode::ExitCode,
40 detailed_exit_code: exit_codes::ExitCode,
41 41 ) -> Self {
42 42 CommandError::Abort {
43 43 // TODO: bytes-based (instead of Unicode-based) formatting
@@ -78,7 +78,7 b' impl From<ConfigValueParseError> for Com'
78 78 fn from(error: ConfigValueParseError) -> Self {
79 79 CommandError::abort_with_exit_code(
80 80 error.to_string(),
81 exitcode::CONFIG_ERROR_ABORT,
81 exit_codes::CONFIG_ERROR_ABORT,
82 82 )
83 83 }
84 84 }
@@ -100,7 +100,7 b' impl From<RepoError> for CommandError {'
100 100 b"abort: repository {} not found",
101 101 get_bytes_from_path(at)
102 102 ),
103 detailed_exit_code: exitcode::ABORT,
103 detailed_exit_code: exit_codes::ABORT,
104 104 },
105 105 RepoError::ConfigParseError(error) => error.into(),
106 106 RepoError::Other(error) => error.into(),
@@ -116,7 +116,7 b" impl<'a> From<&'a NoRepoInCwdError> for "
116 116 b"abort: no repository found in '{}' (.hg not found)!",
117 117 get_bytes_from_path(cwd)
118 118 ),
119 detailed_exit_code: exitcode::ABORT,
119 detailed_exit_code: exit_codes::ABORT,
120 120 }
121 121 }
122 122 }
@@ -149,7 +149,7 b' impl From<ConfigParseError> for CommandE'
149 149 line_message,
150 150 message
151 151 ),
152 detailed_exit_code: exitcode::CONFIG_ERROR_ABORT,
152 detailed_exit_code: exit_codes::CONFIG_ERROR_ABORT,
153 153 }
154 154 }
155 155 }
@@ -6,6 +6,7 b' use clap::Arg;'
6 6 use clap::ArgMatches;
7 7 use format_bytes::{format_bytes, join};
8 8 use hg::config::{Config, ConfigSource};
9 use hg::exit_codes;
9 10 use hg::repo::{Repo, RepoError};
10 11 use hg::utils::files::{get_bytes_from_os_str, get_path_from_bytes};
11 12 use hg::utils::SliceExt;
@@ -15,7 +16,6 b' use std::process::Command;'
15 16
16 17 mod blackbox;
17 18 mod error;
18 mod exitcode;
19 19 mod ui;
20 20 use error::CommandError;
21 21
@@ -297,7 +297,7 b' fn exit_code('
297 297 use_detailed_exit_code: bool,
298 298 ) -> i32 {
299 299 match result {
300 Ok(()) => exitcode::OK,
300 Ok(()) => exit_codes::OK,
301 301 Err(CommandError::Abort {
302 302 message: _,
303 303 detailed_exit_code,
@@ -305,15 +305,15 b' fn exit_code('
305 305 if use_detailed_exit_code {
306 306 *detailed_exit_code
307 307 } else {
308 exitcode::ABORT
308 exit_codes::ABORT
309 309 }
310 310 }
311 Err(CommandError::Unsuccessful) => exitcode::UNSUCCESSFUL,
311 Err(CommandError::Unsuccessful) => exit_codes::UNSUCCESSFUL,
312 312
313 313 // Exit with a specific code and no error message to let a potential
314 314 // wrapper script fallback to Python-based Mercurial.
315 315 Err(CommandError::UnsupportedFeature { .. }) => {
316 exitcode::UNIMPLEMENTED
316 exit_codes::UNIMPLEMENTED
317 317 }
318 318 }
319 319 }
@@ -352,7 +352,7 b' fn exit('
352 352 let result = command.status();
353 353 match result {
354 354 Ok(status) => std::process::exit(
355 status.code().unwrap_or(exitcode::ABORT),
355 status.code().unwrap_or(exit_codes::ABORT),
356 356 ),
357 357 Err(error) => {
358 358 let _ = ui.write_stderr(&format_bytes!(
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now