use serde::ser;
use serde::de;
-use core::{Package, PackageId, SourceId, Workspace};
+use core::{Package, PackageId, SourceId, Workspace, Dependency};
use util::{Graph, Config, internal};
use util::errors::{CargoResult, CargoResultExt, CargoError};
let id = match pkg.source.as_ref().or_else(|| path_deps.get(&pkg.name)) {
// We failed to find a local package in the workspace.
// It must have been removed and should be ignored.
- None => continue,
+ None => {
+ debug!("path dependency now missing {} v{}",
+ pkg.name,
+ pkg.version);
+ continue
+ }
Some(source) => PackageId::new(&pkg.name, &pkg.version, source)?
};
visited.insert(member.package_id().source_id().clone());
}
for member in members.iter() {
- build(member, ws.config(), &mut ret, &mut visited);
+ build_pkg(member, ws.config(), &mut ret, &mut visited);
+ }
+ for (_, deps) in ws.root_patch() {
+ for dep in deps {
+ build_dep(dep, ws.config(), &mut ret, &mut visited);
+ }
+ }
+ for &(_, ref dep) in ws.root_replace() {
+ build_dep(dep, ws.config(), &mut ret, &mut visited);
}
return ret;
- fn build(pkg: &Package,
- config: &Config,
- ret: &mut HashMap<String, SourceId>,
- visited: &mut HashSet<SourceId>) {
- let replace = pkg.manifest().replace().iter().map(|p| &p.1);
- let patch = pkg.manifest().patch().values().flat_map(|v| v);
- let deps = pkg.dependencies()
- .iter()
- .chain(replace)
- .chain(patch)
- .map(|d| d.source_id())
- .filter(|id| !visited.contains(id) && id.is_path())
- .filter_map(|id| id.url().to_file_path().ok())
- .map(|path| path.join("Cargo.toml"))
- .filter_map(|path| Package::for_path(&path, config).ok())
- .collect::<Vec<_>>();
- for pkg in deps {
- ret.insert(pkg.name().to_string(),
- pkg.package_id().source_id().clone());
- visited.insert(pkg.package_id().source_id().clone());
- build(&pkg, config, ret, visited);
+ fn build_pkg(pkg: &Package,
+ config: &Config,
+ ret: &mut HashMap<String, SourceId>,
+ visited: &mut HashSet<SourceId>) {
+ for dep in pkg.dependencies() {
+ build_dep(dep, config, ret, visited);
}
}
+
+ fn build_dep(dep: &Dependency,
+ config: &Config,
+ ret: &mut HashMap<String, SourceId>,
+ visited: &mut HashSet<SourceId>) {
+ let id = dep.source_id();
+ if visited.contains(id) || !id.is_path() {
+ return
+ }
+ let path = match id.url().to_file_path() {
+ Ok(p) => p.join("Cargo.toml"),
+ Err(_) => return,
+ };
+ let pkg = match Package::for_path(&path, config) {
+ Ok(p) => p,
+ Err(_) => return,
+ };
+ ret.insert(pkg.name().to_string(),
+ pkg.package_id().source_id().clone());
+ visited.insert(pkg.package_id().source_id().clone());
+ build_pkg(&pkg, config, ret, visited);
+ }
}
impl Patch {
to different sources
"));
}
+
+#[test]
+fn patch_in_virtual() {
+ Package::new("foo", "0.1.0").publish();
+
+ let p = project("bar")
+ .file("Cargo.toml", r#"
+ [workspace]
+ members = ["bar"]
+
+ [patch.crates-io]
+ foo = { path = "foo" }
+ "#)
+ .file("foo/Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ authors = []
+ "#)
+ .file("foo/src/lib.rs", r#""#)
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ version = "0.1.0"
+ authors = []
+
+ [dependencies]
+ foo = "0.1"
+ "#)
+ .file("bar/src/lib.rs", r#""#);
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0));
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stderr("\
+[FINISHED] [..]
+"));
+}