From 16bde4e0ae77b7753f37c15a8494c11b3e166921 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 9 Mar 2018 10:43:00 +0300 Subject: [PATCH] Unwind stack for cli errors --- src/bin/cargo.rs | 14 +++++++------- src/bin/cli/mod.rs | 4 ++-- src/cargo/lib.rs | 6 ++++++ src/cargo/util/errors.rs | 8 ++++++++ tests/testsuite/install.rs | 1 - 5 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/bin/cargo.rs b/src/bin/cargo.rs index 59ff6bb91..27c751d3a 100644 --- a/src/bin/cargo.rs +++ b/src/bin/cargo.rs @@ -31,18 +31,18 @@ fn main() { } }; - match main_inner(&mut config) { + let result = { + init_git_transports(&mut config); + let _token = cargo::util::job::setup(); + cli::do_main(&mut config) + }; + + match result { Err(e) => cargo::exit_with_error(e, &mut *config.shell()), Ok(()) => {} } } -fn main_inner(config: &mut Config) -> CliResult { - init_git_transports(config); - let _token = cargo::util::job::setup(); - cli::do_main(config) -} - fn aliased_command(config: &Config, command: &str) -> CargoResult>> { let alias_name = format!("alias.{}", command); let mut result = Ok(None); diff --git a/src/bin/cli/mod.rs b/src/bin/cli/mod.rs index 0b18d0a8b..561b204f2 100644 --- a/src/bin/cli/mod.rs +++ b/src/bin/cli/mod.rs @@ -29,7 +29,7 @@ use search_directories; use is_executable; pub fn do_main(config: &mut Config) -> CliResult { - let args = cli().get_matches(); + let args = cli().get_matches_safe()?; let is_verbose = args.occurrences_of("verbose") > 0; if args.is_present("version") { let version = cargo::version(); @@ -547,7 +547,7 @@ fn execute_subcommand(config: &mut Config, args: ArgMatches) -> CliResult { alias.extend(args.values_of("").unwrap_or_default().map(|s| s.to_string())); let args = cli() .setting(AppSettings::NoBinaryName) - .get_matches_from(alias); + .get_matches_from_safe(alias)?; return execute_subcommand(config, args); } let mut ext_args: Vec<&str> = vec![cmd]; diff --git a/src/cargo/lib.rs b/src/cargo/lib.rs index 271e6fce9..01a61ab6b 100644 --- a/src/cargo/lib.rs +++ b/src/cargo/lib.rs @@ -13,6 +13,7 @@ #[macro_use] extern crate serde_derive; #[macro_use] extern crate serde_json; extern crate atty; +extern crate clap; extern crate crates_io as registry; extern crate crossbeam; extern crate curl; @@ -113,6 +114,11 @@ pub fn print_json(obj: &T) { pub fn exit_with_error(err: CliError, shell: &mut Shell) -> ! { debug!("exit_with_error; err={:?}", err); + if let Some(ref err) = err.error { + if let Some(clap_err) = err.downcast_ref::() { + clap_err.exit() + } + } let CliError { error, exit_code, unknown } = err; // exit_code == 0 is non-fatal error, e.g. docopt version info diff --git a/src/cargo/util/errors.rs b/src/cargo/util/errors.rs index e552069d0..e5bc2bad8 100644 --- a/src/cargo/util/errors.rs +++ b/src/cargo/util/errors.rs @@ -6,6 +6,7 @@ use std::str; use core::{TargetKind, Workspace}; use failure::{Context, Error, Fail}; +use clap; pub use failure::Error as CargoError; pub type CargoResult = Result; @@ -169,6 +170,13 @@ impl From for CliError { } } +impl From for CliError { + fn from(err: clap::Error) -> CliError { + let code = if err.use_stderr() { 1 } else { 0 }; + CliError::new(err.into(), code) + } +} + // ============================================================================= // Construction helpers diff --git a/tests/testsuite/install.rs b/tests/testsuite/install.rs index f7272b1cb..ad5f3d60f 100644 --- a/tests/testsuite/install.rs +++ b/tests/testsuite/install.rs @@ -3,7 +3,6 @@ use std::fs::{self, File, OpenOptions}; use std::io::prelude::*; use cargo::util::ProcessBuilder; -use cargotest::ChannelChanger; use cargotest::install::{cargo_home, has_installed_exe}; use cargotest::support::git; use cargotest::support::paths;