mirror of
https://github.com/rust-lang/cargo.git
synced 2025-10-01 11:30:39 +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()) {
|
let (cmd, args) = match process(os::args()) {
|
||||||
Ok((cmd, args)) => (cmd, 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() {
|
if cmd == "config-for-key".to_str() {
|
||||||
@ -59,8 +59,8 @@ fn execute() {
|
|||||||
|
|
||||||
match command {
|
match command {
|
||||||
Ok(ExitStatus(0)) => (),
|
Ok(ExitStatus(0)) => (),
|
||||||
Ok(ExitStatus(i)) | Ok(ExitSignal(i)) => handle_error(CliError::new("", i as uint)),
|
Ok(ExitStatus(i)) | Ok(ExitSignal(i)) => handle_error(CliError::new("", i as uint), false),
|
||||||
Err(_) => handle_error(CliError::new("No such subcommand", 127))
|
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 serialize::{Decoder,Encoder,Decodable,Encodable,json};
|
||||||
use std::io;
|
use std::io;
|
||||||
use hammer::{FlagDecoder,FlagConfig,HammerError};
|
use hammer::{FlagDecoder, FlagConfig, HammerError, FlagConfiguration};
|
||||||
pub use util::{CliError, CliResult, human};
|
pub use util::{CargoError, CliError, CliResult, human};
|
||||||
|
|
||||||
macro_rules! some(
|
macro_rules! some(
|
||||||
($e:expr) => (
|
($e:expr) => (
|
||||||
@ -53,30 +53,48 @@ pub struct NoFlags;
|
|||||||
|
|
||||||
impl FlagConfig for 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>>) {
|
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>> {
|
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>());
|
let flags = try!(flags_from_args::<T>(args));
|
||||||
let json = try!(json_from_stdin::<U>());
|
let json = try!(json_from_stdin::<U>());
|
||||||
|
|
||||||
exec(flags, json)
|
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>>) {
|
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>> {
|
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>());
|
let flags = try!(flags_from_args::<T>(args));
|
||||||
|
|
||||||
exec(flags)
|
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 {
|
match result {
|
||||||
Err(e) => handle_error(e),
|
Err(e) => handle_error(e, flags.verbose),
|
||||||
Ok(encodable) => {
|
Ok(encodable) => {
|
||||||
encodable.map(|encodable| {
|
encodable.map(|encodable| {
|
||||||
let encoded = json::Encoder::str_encode(&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);
|
log!(4, "handle_error; err={}", err);
|
||||||
|
|
||||||
let CliError { error, exit_code, .. } = err;
|
let CliError { error, exit_code, .. } = err;
|
||||||
let _ = write!(&mut std::io::stderr(), "{}", error);
|
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);
|
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> {
|
fn args() -> Vec<String> {
|
||||||
std::os::args()
|
std::os::args()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flags_from_args<T: RepresentsFlags>() -> CliResult<T> {
|
fn flags_from_args<T: RepresentsFlags>(args: &[String]) -> CliResult<T> {
|
||||||
let mut decoder = FlagDecoder::new::<T>(args().tail());
|
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))
|
Decodable::decode(&mut decoder).map_err(|e: HammerError| CliError::new(e.message, 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user