mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +00:00
Add --verbose cause chain support
This commit is contained in:
parent
bee480e465
commit
fce9983203
@ -1 +1 @@
|
||||
Subproject commit 673bbd95858fc0e6eae39d0d30a2781ba4c8d87e
|
||||
Subproject commit 9af78f5b1fdfd09580758ec3b559c7704e6a5382
|
@ -34,7 +34,7 @@ fn execute() {
|
||||
|
||||
let (cmd, args) = match process(os::args()) {
|
||||
Ok((cmd, args)) => (cmd, args),
|
||||
Err(err) => return handle_error(err)
|
||||
Err(err) => return handle_error(err, false)
|
||||
};
|
||||
|
||||
if cmd == "config-for-key".to_str() {
|
||||
@ -59,8 +59,8 @@ fn execute() {
|
||||
|
||||
match command {
|
||||
Ok(ExitStatus(0)) => (),
|
||||
Ok(ExitStatus(i)) | Ok(ExitSignal(i)) => handle_error(CliError::new("", i as uint)),
|
||||
Err(_) => handle_error(CliError::new("No such subcommand", 127))
|
||||
Ok(ExitStatus(i)) | Ok(ExitSignal(i)) => handle_error(CliError::new("", i as uint), false),
|
||||
Err(_) => handle_error(CliError::new("No such subcommand", 127), false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,8 +19,8 @@ extern crate hamcrest;
|
||||
|
||||
use serialize::{Decoder,Encoder,Decodable,Encodable,json};
|
||||
use std::io;
|
||||
use hammer::{FlagDecoder,FlagConfig,HammerError};
|
||||
pub use util::{CliError, CliResult, human};
|
||||
use hammer::{FlagDecoder, FlagConfig, HammerError, FlagConfiguration};
|
||||
pub use util::{CargoError, CliError, CliResult, human};
|
||||
|
||||
macro_rules! some(
|
||||
($e:expr) => (
|
||||
@ -53,30 +53,48 @@ pub struct NoFlags;
|
||||
|
||||
impl FlagConfig for NoFlags {}
|
||||
|
||||
#[deriving(Decodable)]
|
||||
pub struct GlobalFlags {
|
||||
verbose: bool,
|
||||
rest: Vec<String>
|
||||
}
|
||||
|
||||
impl FlagConfig for GlobalFlags {
|
||||
fn config(_: Option<GlobalFlags>, c: FlagConfiguration) -> FlagConfiguration {
|
||||
c.short("verbose", 'v')
|
||||
}
|
||||
}
|
||||
|
||||
pub fn execute_main<'a, T: RepresentsFlags, U: RepresentsJSON, V: Encodable<json::Encoder<'a>, io::IoError>>(exec: fn(T, U) -> CliResult<Option<V>>) {
|
||||
fn call<'a, T: RepresentsFlags, U: RepresentsJSON, V: Encodable<json::Encoder<'a>, io::IoError>>(exec: fn(T, U) -> CliResult<Option<V>>) -> CliResult<Option<V>> {
|
||||
let flags = try!(flags_from_args::<T>());
|
||||
fn call<'a, T: RepresentsFlags, U: RepresentsJSON, V: Encodable<json::Encoder<'a>, io::IoError>>(exec: fn(T, U) -> CliResult<Option<V>>, args: &[String]) -> CliResult<Option<V>> {
|
||||
let flags = try!(flags_from_args::<T>(args));
|
||||
let json = try!(json_from_stdin::<U>());
|
||||
|
||||
exec(flags, json)
|
||||
}
|
||||
|
||||
process_executed(call(exec))
|
||||
match global_flags() {
|
||||
Err(e) => handle_error(e, true),
|
||||
Ok(val) => process_executed(call(exec, val.rest.as_slice()), val)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn execute_main_without_stdin<'a, T: RepresentsFlags, V: Encodable<json::Encoder<'a>, io::IoError>>(exec: fn(T) -> CliResult<Option<V>>) {
|
||||
fn call<'a, T: RepresentsFlags, V: Encodable<json::Encoder<'a>, io::IoError>>(exec: fn(T) -> CliResult<Option<V>>) -> CliResult<Option<V>> {
|
||||
let flags = try!(flags_from_args::<T>());
|
||||
fn call<'a, T: RepresentsFlags, V: Encodable<json::Encoder<'a>, io::IoError>>(exec: fn(T) -> CliResult<Option<V>>, args: &[String]) -> CliResult<Option<V>> {
|
||||
let flags = try!(flags_from_args::<T>(args));
|
||||
|
||||
exec(flags)
|
||||
}
|
||||
|
||||
process_executed(call(exec));
|
||||
match global_flags() {
|
||||
Err(e) => handle_error(e, true),
|
||||
Ok(val) => process_executed(call(exec, val.rest.as_slice()), val)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn process_executed<'a, T: Encodable<json::Encoder<'a>, io::IoError>>(result: CliResult<Option<T>>) {
|
||||
pub fn process_executed<'a, T: Encodable<json::Encoder<'a>, io::IoError>>(result: CliResult<Option<T>>, flags: GlobalFlags) {
|
||||
match result {
|
||||
Err(e) => handle_error(e),
|
||||
Err(e) => handle_error(e, flags.verbose),
|
||||
Ok(encodable) => {
|
||||
encodable.map(|encodable| {
|
||||
let encoded = json::Encoder::str_encode(&encodable);
|
||||
@ -86,23 +104,37 @@ pub fn process_executed<'a, T: Encodable<json::Encoder<'a>, io::IoError>>(result
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_error(err: CliError) {
|
||||
pub fn handle_error(err: CliError, verbose: bool) {
|
||||
log!(4, "handle_error; err={}", err);
|
||||
|
||||
let CliError { error, exit_code, .. } = err;
|
||||
let _ = write!(&mut std::io::stderr(), "{}", error);
|
||||
// TODO: Cause chains
|
||||
//detail.map(|d| write!(&mut std::io::stderr(), ":\n{}", d));
|
||||
|
||||
if verbose {
|
||||
error.cause().map(handle_cause);
|
||||
}
|
||||
|
||||
std::os::set_exit_status(exit_code as int);
|
||||
}
|
||||
|
||||
fn handle_cause(err: &CargoError) {
|
||||
println!("\nCaused by:");
|
||||
println!(" {}", err.description());
|
||||
|
||||
err.cause().map(handle_cause);
|
||||
}
|
||||
|
||||
fn args() -> Vec<String> {
|
||||
std::os::args()
|
||||
}
|
||||
|
||||
fn flags_from_args<T: RepresentsFlags>() -> CliResult<T> {
|
||||
let mut decoder = FlagDecoder::new::<T>(args().tail());
|
||||
fn flags_from_args<T: RepresentsFlags>(args: &[String]) -> CliResult<T> {
|
||||
let mut decoder = FlagDecoder::new::<T>(args);
|
||||
Decodable::decode(&mut decoder).map_err(|e: HammerError| CliError::new(e.message, 1))
|
||||
}
|
||||
|
||||
fn global_flags() -> CliResult<GlobalFlags> {
|
||||
let mut decoder = FlagDecoder::new::<GlobalFlags>(args().tail());
|
||||
Decodable::decode(&mut decoder).map_err(|e: HammerError| CliError::new(e.message, 1))
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user