diff --git a/src/cargo/lib.rs b/src/cargo/lib.rs index d60792c7a74..ae09710aa51 100644 --- a/src/cargo/lib.rs +++ b/src/cargo/lib.rs @@ -50,6 +50,7 @@ use core::shell::Verbosity::Verbose; pub use util::{CargoError, CargoResult, CliError, CliResult, Config}; pub use util::errors::Internal; +use util::important_paths::{find_project_manifest}; pub const CARGO_ENV: &'static str = "CARGO"; @@ -117,12 +118,48 @@ pub fn call_main_without_stdin<'de, Flags: Deserialize<'de>>( let flags = docopt.deserialize().map_err(|e| { let code = if e.fatal() {1} else {0}; + + // Overwrites the missing --example docopt error. + // Fix for [issue](https://github.com/rust-lang/cargo/issues/2548) + if &format!("{}", e) == "Expected argument for flag '--example' but reached end of arguments. + +Usage: + cargo run [options] [--] [...]" { + + // Can't handle manifest without the `run` `Options` type. + // let flags: run::Options = docopt.deserialize().map_err(|_| CliError::new(e.into(), code))?; + + if let Some(mut examples) = find_project_manifest(config.cwd(), "cargo.toml").ok() + .and_then(|mut root| { + root.pop(); + root.push("examples"); + + std::fs::read_dir(root).ok() + }).map(|paths: std::fs::ReadDir| { + paths.filter_map(|p| p.ok() ) + .filter(|p| p.path().extension().and_then(|s|s.to_str()) == Some("rs")) + .filter_map(|p| p.path().file_stem().and_then(|s| s.to_str()).map(|s| String::from(s))) + .collect::>() + }) { + examples.sort(); + return CliError::new(format_err!("{}\n\n{}\n\n{}", "Expected argument for flag '--example' but reached end of arguments.", + match examples.len() { + 0 => String::from("There are no examples in the 'examples' directory"), + 1 => String::from("Available examples are: ") + &examples[0], + _ => String::from("Available examples are: ") + &examples.as_slice()[..examples.len()-1].join(", ") + " and " + &examples[examples.len()-1] + }, + "Usage:\n cargo run [options] [--] [...]").into(), code); + } + } + CliError::new(e.into(), code) })?; exec(flags, config) } + + pub fn print_json(obj: &T) { let encoded = serde_json::to_string(&obj).unwrap(); println!("{}", encoded);