mirror of
https://github.com/rust-lang/cargo
synced 2024-10-06 15:59:39 +00:00
Meta-packages
This commit is contained in:
parent
33b77bb059
commit
ea3cb31cec
|
@ -29,6 +29,7 @@ impl<'a> PackageRegistry<'a> {
|
|||
config: &'a mut Config<'a>) -> CargoResult<PackageRegistry<'a>> {
|
||||
|
||||
let mut reg = PackageRegistry::empty(config);
|
||||
let source_ids = dedup(source_ids);
|
||||
|
||||
for id in source_ids.iter() {
|
||||
try!(reg.load(id, false));
|
||||
|
@ -90,7 +91,7 @@ impl<'a> PackageRegistry<'a> {
|
|||
|
||||
// Get the summaries
|
||||
for summary in (try!(source.list())).iter() {
|
||||
assert!(!dst.contains(summary), "duplicate summaries");
|
||||
assert!(!dst.contains(summary), "duplicate summaries: {}", summary);
|
||||
dst.push(summary.clone());
|
||||
// self.summaries.push(summary.clone());
|
||||
}
|
||||
|
@ -106,6 +107,17 @@ impl<'a> PackageRegistry<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn dedup(ids: Vec<SourceId>) -> Vec<SourceId> {
|
||||
let mut seen = vec!();
|
||||
|
||||
for id in ids.move_iter() {
|
||||
if seen.contains(&id) { continue; }
|
||||
seen.push(id);
|
||||
}
|
||||
|
||||
seen
|
||||
}
|
||||
|
||||
impl<'a> Registry for PackageRegistry<'a> {
|
||||
fn query(&mut self, dep: &Dependency) -> CargoResult<Vec<Summary>> {
|
||||
let overrides = try!(self.overrides.query(dep)); // this can never fail in practice
|
||||
|
|
|
@ -61,7 +61,7 @@ pub enum Location {
|
|||
Remote(Url),
|
||||
}
|
||||
|
||||
#[deriving(Clone,PartialEq)]
|
||||
#[deriving(Clone, PartialEq, Eq)]
|
||||
pub struct SourceId {
|
||||
pub kind: SourceKind,
|
||||
pub location: Location,
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use std::collections::HashSet;
|
||||
use std::io::File;
|
||||
use std::io::{File, fs};
|
||||
use util;
|
||||
use core::{Package,Manifest,SourceId};
|
||||
use util::{CargoResult, human, important_paths};
|
||||
use util::{CargoResult, human};
|
||||
use util::important_paths::find_project_manifest_exact;
|
||||
|
||||
pub fn read_manifest(contents: &[u8], source_id: &SourceId)
|
||||
-> CargoResult<(Manifest, Vec<Path>)>
|
||||
|
@ -22,26 +23,85 @@ pub fn read_package(path: &Path, source_id: &SourceId)
|
|||
Ok((Package::new(manifest, path, source_id), nested))
|
||||
}
|
||||
|
||||
pub fn read_packages(path: &Path, source_id: &SourceId)
|
||||
-> CargoResult<Vec<Package>>
|
||||
pub fn read_packages(path: &Path,
|
||||
source_id: &SourceId) -> CargoResult<Vec<Package>>
|
||||
{
|
||||
return read_packages(path, source_id, &mut HashSet::new());
|
||||
let mut all_packages = Vec::new();
|
||||
let mut visited = HashSet::<Path>::new();
|
||||
|
||||
fn read_packages(path: &Path, source_id: &SourceId,
|
||||
visited: &mut HashSet<Path>) -> CargoResult<Vec<Package>> {
|
||||
if !visited.insert(path.clone()) { return Ok(Vec::new()) }
|
||||
log!(5, "looking for root package: {}, source_id={}", path.display(), source_id);
|
||||
try!(process_possible_package(path, &mut all_packages, source_id, &mut visited));
|
||||
|
||||
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];
|
||||
try!(walk(path, true, |dir| {
|
||||
log!(5, "looking for child package: {}", dir.display());
|
||||
if dir.filename_str() == Some(".git") { return Ok(false); }
|
||||
if dir.join(".git").is_dir() { return Ok(false); }
|
||||
try!(process_possible_package(dir, &mut all_packages, source_id, &mut visited));
|
||||
Ok(true)
|
||||
}));
|
||||
|
||||
for p in nested.iter() {
|
||||
ret.push_all(try!(read_packages(&path.join(p),
|
||||
source_id,
|
||||
visited)).as_slice());
|
||||
}
|
||||
|
||||
Ok(ret)
|
||||
if all_packages.is_empty() {
|
||||
Err(human(format!("Could not find Cargo.toml in `{}`", path.display())))
|
||||
} else {
|
||||
log!(5, "all packages: {}", all_packages);
|
||||
Ok(all_packages)
|
||||
}
|
||||
}
|
||||
|
||||
fn walk(path: &Path, is_root: bool, callback: |&Path| -> CargoResult<bool>) -> CargoResult<()> {
|
||||
if path.is_dir() {
|
||||
if !is_root {
|
||||
let continues = try!(callback(path));
|
||||
if !continues { log!(5, "Found submodule at {}", path.display()); return Ok(()); }
|
||||
}
|
||||
|
||||
for dir in try!(fs::readdir(path)).iter() {
|
||||
try!(walk(dir, false, |x| callback(x)))
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn process_possible_package(dir: &Path,
|
||||
all_packages: &mut Vec<Package>,
|
||||
source_id: &SourceId,
|
||||
visited: &mut HashSet<Path>) -> CargoResult<()> {
|
||||
|
||||
if !has_manifest(dir) { return Ok(()); }
|
||||
|
||||
let packages = try!(read_nested_packages(dir, source_id, visited));
|
||||
push_all(all_packages, packages);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn has_manifest(path: &Path) -> bool {
|
||||
find_project_manifest_exact(path, "Cargo.toml").is_ok()
|
||||
}
|
||||
|
||||
fn read_nested_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!(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_nested_packages(&path.join(p),
|
||||
source_id,
|
||||
visited)).as_slice());
|
||||
}
|
||||
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
fn push_all(set: &mut Vec<Package>, packages: Vec<Package>) {
|
||||
for package in packages.move_iter() {
|
||||
if set.contains(&package) { continue; }
|
||||
|
||||
set.push(package)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -203,7 +203,6 @@ fn prepare_rustc(root: &Path, target: &Target, crate_types: Vec<&str>,
|
|||
build_base_args(&mut args, target, crate_types, cx);
|
||||
build_deps_args(&mut args, cx);
|
||||
|
||||
|
||||
util::process("rustc")
|
||||
.cwd(root.clone())
|
||||
.args(args.as_slice())
|
||||
|
|
|
@ -227,6 +227,7 @@ test!(cargo_compile_git_dep_tag {
|
|||
cargo::util::process(project.bin("foo")),
|
||||
execs().with_stdout("hello world\n"));
|
||||
})
|
||||
|
||||
test!(cargo_compile_with_nested_paths {
|
||||
let git_project = git_repo("dep1", |project| {
|
||||
project
|
||||
|
@ -302,6 +303,79 @@ test!(cargo_compile_with_nested_paths {
|
|||
execs().with_stdout("hello world\n"));
|
||||
})
|
||||
|
||||
test!(cargo_compile_with_meta_package {
|
||||
let git_project = git_repo("meta-dep", |project| {
|
||||
project
|
||||
.file("dep1/Cargo.toml", r#"
|
||||
[project]
|
||||
|
||||
name = "dep1"
|
||||
version = "0.5.0"
|
||||
authors = ["carlhuda@example.com"]
|
||||
|
||||
[[lib]]
|
||||
|
||||
name = "dep1"
|
||||
"#)
|
||||
.file("dep1/src/dep1.rs", r#"
|
||||
pub fn hello() -> &'static str {
|
||||
"this is dep1"
|
||||
}
|
||||
"#)
|
||||
.file("dep2/Cargo.toml", r#"
|
||||
[project]
|
||||
|
||||
name = "dep2"
|
||||
version = "0.5.0"
|
||||
authors = ["carlhuda@example.com"]
|
||||
|
||||
[[lib]]
|
||||
|
||||
name = "dep2"
|
||||
"#)
|
||||
.file("dep2/src/dep2.rs", r#"
|
||||
pub fn hello() -> &'static str {
|
||||
"this is dep2"
|
||||
}
|
||||
"#)
|
||||
}).assert();
|
||||
|
||||
let p = project("parent")
|
||||
.file("Cargo.toml", format!(r#"
|
||||
[project]
|
||||
|
||||
name = "parent"
|
||||
version = "0.5.0"
|
||||
authors = ["wycats@example.com"]
|
||||
|
||||
[dependencies.dep1]
|
||||
|
||||
version = "0.5.0"
|
||||
git = "file:{}"
|
||||
|
||||
[dependencies.dep2]
|
||||
|
||||
version = "0.5.0"
|
||||
git = "file:{}"
|
||||
|
||||
[[bin]]
|
||||
|
||||
name = "parent"
|
||||
"#, escape_path(&git_project.root()), escape_path(&git_project.root())))
|
||||
.file("src/parent.rs",
|
||||
main_file(r#""{} {}", dep1::hello(), dep2::hello()"#, ["dep1", "dep2"]).as_slice());
|
||||
|
||||
p.cargo_process("cargo-build")
|
||||
.exec_with_output()
|
||||
.assert();
|
||||
|
||||
assert_that(&p.bin("parent"), existing_file());
|
||||
|
||||
assert_that(
|
||||
cargo::util::process(p.bin("parent")),
|
||||
execs().with_stdout("this is dep1 this is dep2\n"));
|
||||
})
|
||||
|
||||
test!(cargo_compile_with_short_ssh_git {
|
||||
let url = "git@github.com:a/dep";
|
||||
|
||||
|
|
Loading…
Reference in a new issue