Don't infinitely recurse on cyclic path deps

Instead, keep a table of what we've visited and halt recursion whenever we
re-visit a package.

Closes #77
This commit is contained in:
Alex Crichton 2014-06-28 13:33:29 -07:00
parent aa8986ffc4
commit 71e4252a90
2 changed files with 41 additions and 7 deletions

View File

@ -1,3 +1,4 @@
use std::collections::HashSet;
use std::io::File;
use util;
use core::{Package,Manifest,SourceId};
@ -24,13 +25,23 @@ pub fn read_package(path: &Path, source_id: &SourceId)
pub fn read_packages(path: &Path, source_id: &SourceId)
-> CargoResult<Vec<Package>>
{
let manifest = try!(important_paths::find_project_manifest_exact(path, "Cargo.toml"));
let (pkg, nested) = try!(read_package(&manifest, source_id));
let mut ret = vec!(pkg);
return read_packages(path, source_id, &mut HashSet::new());
for p in nested.iter() {
ret.push_all(try!(read_packages(&path.join(p), source_id)).as_slice());
fn read_packages(path: &Path, source_id: &SourceId,
visited: &mut HashSet<Path>) -> CargoResult<Vec<Package>> {
if !visited.insert(path.clone()) { return Ok(Vec::new()) }
let manifest = try!(important_paths::find_project_manifest_exact(path,
"Cargo.toml"));
let (pkg, nested) = try!(read_package(&manifest, source_id));
let mut ret = vec![pkg];
for p in nested.iter() {
ret.push_all(try!(read_packages(&path.join(p),
source_id,
visited)).as_slice());
}
Ok(ret)
}
Ok(ret)
}

View File

@ -603,3 +603,26 @@ test!(unused_keys {
execs().with_status(0)
.with_stderr("unused manifest key: lib.build\n"));
})
test!(self_dependency {
let mut p = project("foo");
p = p
.file("Cargo.toml", r#"
[package]
name = "test"
version = "0.0.0"
authors = []
[dependencies.test]
path = "."
[[lib]]
name = "test"
"#)
.file("src/test.rs", "fn main() {}");
assert_that(p.cargo_process("cargo-build"),
execs().with_status(0));
})