}).collect::<Vec<_>>();
let mut ret = HashMap::new();
+ let mut visited = HashSet::new();
for member in members.iter() {
ret.insert(member.package_id().name().to_string(),
member.package_id().source_id().clone());
+ visited.insert(member.package_id().source_id().clone());
}
for member in members.iter() {
- build(member, ws.config(), &mut ret);
+ build(member, ws.config(), &mut ret, &mut visited);
}
return ret;
fn build(pkg: &Package,
config: &Config,
- ret: &mut HashMap<String, SourceId>) {
+ ret: &mut HashMap<String, SourceId>,
+ visited: &mut HashSet<SourceId>) {
let replace = pkg.manifest().replace();
let deps = pkg.dependencies()
.iter()
.chain(replace.iter().map(|p| &p.1))
- .filter(|d| !ret.contains_key(d.name()))
.map(|d| d.source_id())
- .filter(|id| id.is_path())
+ .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())
for pkg in deps {
ret.insert(pkg.name().to_string(),
pkg.package_id().source_id().clone());
- build(&pkg, config, ret);
+ visited.insert(pkg.package_id().source_id().clone());
+ build(&pkg, config, ret, visited);
}
}
}
use cargotest::sleep_ms;
use cargotest::support::paths::{self, CargoPathExt};
use cargotest::support::{project, execs, main_file};
+use cargotest::support::registry::Package;
use hamcrest::{assert_that, existing_file};
#[test]
[..] (os error [..])
"));
}
+
+#[test]
+fn invalid_path_dep_in_workspace_with_lockfile() {
+ Package::new("bar", "1.0.0").publish();
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "top"
+ version = "0.5.0"
+ authors = []
+
+ [workspace]
+
+ [dependencies]
+ foo = { path = "foo" }
+ "#)
+ .file("src/lib.rs", "")
+ .file("foo/Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+
+ [dependencies]
+ bar = "*"
+ "#)
+ .file("foo/src/lib.rs", "");
+ p.build();
+
+ // Generate a lock file
+ assert_that(p.cargo("build"), execs().with_status(0));
+
+ // Change the dependency on `bar` to an invalid path
+ File::create(&p.root().join("foo/Cargo.toml")).unwrap().write_all(br#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+
+ [dependencies]
+ bar = { path = "" }
+ "#).unwrap();
+
+ // Make sure we get a nice error. In the past this actually stack
+ // overflowed!
+ assert_that(p.cargo("build"),
+ execs().with_status(101)
+ .with_stderr("\
+error: no matching package named `bar` found (required by `foo`)
+location searched: [..]
+version required: *
+"));
+}