use core::PackageIdSpec;
use core::{Dependency, PackageId, Registry, Summary};
use util::config::Config;
-use util::errors::{CargoError, CargoResult};
+use util::errors::{CargoResult, PackageError};
use util::lev_distance::lev_distance;
use util::profile;
conflicting_activations: &HashMap<PackageId, ConflictReason>,
candidates: &[Candidate],
config: Option<&Config>,
-) -> CargoError {
+) -> PackageError {
+ let to_package_err = |err| PackageError::new(err, parent.package_id().clone());
+
let graph = cx.graph();
if !candidates.is_empty() {
let mut msg = format!("failed to select a version for `{}`.", dep.package_name());
msg.push_str(&*dep.package_name());
msg.push_str("` which could resolve this conflict");
- return format_err!("{}", msg);
+ return to_package_err(format_err!("{}", msg));
}
// We didn't actually find any candidates, so we need to
new_dep.set_version_req(all_req);
let mut candidates = match registry.query_vec(&new_dep, false) {
Ok(candidates) => candidates,
- Err(e) => return e,
+ Err(e) => return to_package_err(e),
};
candidates.sort_unstable_by(|a, b| b.version().cmp(a.version()));
// was meant. So we try asking the registry for a `fuzzy` search for suggestions.
let mut candidates = Vec::new();
if let Err(e) = registry.query(&new_dep, &mut |s| candidates.push(s.name()), true) {
- return e;
+ return to_package_err(e);
};
candidates.sort_unstable();
candidates.dedup();
}
}
- format_err!("{}", msg)
+ to_package_err(format_err!("{}", msg))
}
/// Returns String representation of dependency chain for a particular `pkgid`.
use std::str;
use std::path::PathBuf;
-use core::{TargetKind, Workspace};
+use core::{TargetKind, Workspace, PackageId};
use failure::{Context, Error, Fail};
use clap;
impl<'a> ::std::iter::FusedIterator for ManifestCauses<'a> {}
+/// Error wrapper related to a particular package and providing it's `PackageId`.
+///
+/// This error adds no displayable info of it's own.
+pub struct PackageError {
+ cause: Error,
+ package: PackageId,
+}
+
+impl PackageError {
+ pub fn new<E: Into<Error>>(cause: E, package: PackageId) -> Self {
+ Self {
+ cause: cause.into(),
+ package,
+ }
+ }
+
+ pub fn package_id(&self) -> &PackageId {
+ &self.package
+ }
+}
+
+impl Fail for PackageError {
+ fn cause(&self) -> Option<&Fail> {
+ self.cause.as_fail().cause()
+ }
+}
+
+impl fmt::Debug for PackageError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.cause.fmt(f)
+ }
+}
+
+impl fmt::Display for PackageError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.cause.fmt(f)
+ }
+}
+
// =============================================================================
// Process errors
#[derive(Debug, Fail)]
-use cargo::core::Workspace;
-use cargo::util::{config::Config, errors::ManifestError};
+use cargo::core::{compiler::CompileMode, Workspace};
+use cargo::ops::{self, CompileOptions};
+use cargo::util::{
+ config::Config,
+ errors::{ManifestError, PackageError},
+};
use support::project;
assert_eq!(causes[0].manifest_path(), &member_manifest_path);
assert_eq!(causes[1].manifest_path(), &missing_manifest_path);
}
+
+/// Test dependency version errors provide which package failed via a `PackageError`.
+#[test]
+fn member_manifest_version_error() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [project]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+
+ [dependencies]
+ bar = { path = "bar" }
+
+ [workspace]
+ "#,
+ )
+ .file("src/main.rs", "fn main() {}")
+ .file(
+ "bar/Cargo.toml",
+ r#"
+ [project]
+ name = "bar"
+ version = "0.1.0"
+ authors = []
+
+ [dependencies]
+ i-dont-exist = "0.55"
+ "#,
+ )
+ .file("bar/src/main.rs", "fn main() {}")
+ .build();
+
+ let config = Config::default().unwrap();
+ let ws = Workspace::new(&p.root().join("Cargo.toml"), &config).unwrap();
+ let compile_options = CompileOptions::new(&config, CompileMode::Build).unwrap();
+ let member_bar = ws.members().find(|m| &*m.name() == "bar").unwrap();
+
+ let error = ops::compile(&ws, &compile_options).map(|_| ()).unwrap_err();
+ eprintln!("{:?}", error);
+
+ let package_err: &PackageError = error.downcast_ref().expect("Not a PackageError");
+ assert_eq!(package_err.package_id(), member_bar.package_id());
+}