Instead delay all downloads until just before they're needed. This should ensure
that we don't download any more packages than we really need to.
use core::{Dependency, Manifest, PackageId, SourceId, Target};
use core::{Summary, Metadata, SourceMap};
use ops;
-use util::{CargoResult, Config, LazyCell, ChainError, internal};
+use util::{CargoResult, Config, LazyCell, ChainError, internal, human};
use rustc_serialize::{Encoder,Encodable};
/// Information about a package that is available somewhere in the file system.
}
impl<'cfg> PackageSet<'cfg> {
- pub fn new(packages: Vec<Package>,
+ pub fn new(package_ids: &[PackageId],
sources: SourceMap<'cfg>) -> PackageSet<'cfg> {
PackageSet {
- packages: packages.into_iter().map(|pkg| {
- (pkg.package_id().clone(), LazyCell::new(Some(pkg)))
+ packages: package_ids.iter().map(|id| {
+ (id.clone(), LazyCell::new(None))
}).collect(),
sources: RefCell::new(sources),
}
let source = try!(sources.get_mut(id.source_id()).chain_error(|| {
internal(format!("couldn't find source for `{}`", id))
}));
- let pkg = try!(source.download(id));
+ let pkg = try!(source.download(id).chain_error(|| {
+ human("unable to get packages from source")
+ }));
assert!(slot.fill(pkg).is_ok());
Ok(slot.borrow().unwrap())
}
use core::{Source, SourceId, SourceMap, Summary, Dependency, PackageId, Package};
use core::PackageSet;
-use util::{CargoResult, ChainError, Config, human, internal, profile};
+use util::{CargoResult, ChainError, Config, human, profile};
/// Source of information about a group of packages.
///
}
}
- pub fn get(mut self, package_ids: &[PackageId])
- -> CargoResult<PackageSet<'cfg>> {
+ pub fn get(self, package_ids: &[PackageId]) -> PackageSet<'cfg> {
trace!("getting packages; sources={}", self.sources.len());
-
- let pkgs = try!(package_ids.iter().map(|id| {
- let src = try!(self.sources.get_mut(id.source_id()).chain_error(|| {
- internal(format!("failed to find a source listed for `{}`", id))
- }));
- src.download(id)
- }).collect::<CargoResult<Vec<_>>>());
-
- Ok(PackageSet::new(pkgs, self.sources))
+ PackageSet::new(package_ids, self.sources)
}
fn ensure_loaded(&mut self, namespace: &SourceId, kind: Kind) -> CargoResult<()> {
try!(ops::resolve_with_previous(&mut registry, root_package,
method, Some(&resolve), None));
- let packages = try!(ops::get_resolved_packages(&resolved_with_overrides,
- registry));
+ let packages = ops::get_resolved_packages(&resolved_with_overrides,
+ registry);
Ok((packages, resolved_with_overrides))
}
use core::registry::PackageRegistry;
use core::{Package, PackageId, Resolve, PackageSet};
use ops;
-use util::{CargoResult, Config, human, ChainError};
+use util::{CargoResult, Config};
/// Executes `cargo fetch`.
pub fn fetch<'a>(manifest_path: &Path,
let package = try!(Package::for_path(manifest_path, config));
let mut registry = PackageRegistry::new(config);
let resolve = try!(ops::resolve_pkg(&mut registry, &package));
- get_resolved_packages(&resolve, registry).map(move |packages| {
- (resolve, packages)
- })
+ let packages = get_resolved_packages(&resolve, registry);
+ for id in resolve.iter() {
+ try!(packages.get(id));
+ }
+ Ok((resolve, packages))
}
pub fn get_resolved_packages<'a>(resolve: &Resolve,
registry: PackageRegistry<'a>)
- -> CargoResult<PackageSet<'a>> {
+ -> PackageSet<'a> {
let ids: Vec<PackageId> = resolve.iter().cloned().collect();
- registry.get(&ids).chain_error(|| {
- human("unable to get packages from source")
- })
+ registry.get(&ids)
}
});
test!(bad_license_file {
+ Package::new("foo", "1.0.0").publish();
let p = project("all")
.file("Cargo.toml", r#"
[project]
execs().with_status(0));
});
-test!(use_semver {
- let p = project("foo")
- .file("Cargo.toml", r#"
- [project]
- name = "bar"
- version = "0.5.0"
- authors = []
+test!(use_semver {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "bar"
+ version = "0.5.0"
+ authors = []
- [dependencies]
- foo = "1.2.3-alpha.0"
- "#)
- .file("src/main.rs", "fn main() {}");
- p.build();
+ [dependencies]
+ foo = "1.2.3-alpha.0"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
- Package::new("foo", "1.2.3-alpha.0").publish();
+ Package::new("foo", "1.2.3-alpha.0").publish();
assert_that(p.cargo("build"), execs().with_status(0));
});
+
+test!(only_download_relevant {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "bar"
+ version = "0.5.0"
+ authors = []
+
+ [target.foo.dependencies]
+ foo = "*"
+ [dev-dependencies]
+ bar = "*"
+ [dependencies]
+ baz = "*"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ Package::new("foo", "0.1.0").publish();
+ Package::new("bar", "0.1.0").publish();
+ Package::new("baz", "0.1.0").publish();
+
+ assert_that(p.cargo("build"),
+ execs().with_status(0).with_stdout(&format!("\
+{updating} registry `[..]`
+{downloading} baz v0.1.0 ([..])
+{compiling} baz v0.1.0 ([..])
+{compiling} bar v0.5.0 ([..])
+", downloading = DOWNLOADING, compiling = COMPILING, updating = UPDATING)));
+});