use std::path::{Path, PathBuf};
use semver::Version;
-use core::{Dependency, Manifest, PackageId, SourceId, Registry, Target, Summary, Metadata};
+use core::{Dependency, Manifest, PackageId, SourceId, Target};
+use core::{Summary, Metadata, SourceMap};
use ops;
-use util::{CargoResult, graph, Config};
+use util::{CargoResult, Config};
use rustc_serialize::{Encoder,Encodable};
-use core::source::Source;
/// Information about a package that is available somewhere in the file system.
///
}
}
-#[derive(PartialEq,Clone,Debug)]
-pub struct PackageSet {
+pub struct PackageSet<'cfg> {
packages: Vec<Package>,
+ sources: SourceMap<'cfg>,
}
-impl PackageSet {
- pub fn new(packages: &[Package]) -> PackageSet {
- //assert!(packages.len() > 0,
- // "PackageSet must be created with at least one package")
- PackageSet { packages: packages.to_vec() }
- }
-
- pub fn is_empty(&self) -> bool {
- self.packages.is_empty()
- }
-
- pub fn len(&self) -> usize {
- self.packages.len()
- }
-
- pub fn pop(&mut self) -> Package {
- self.packages.pop().expect("PackageSet.pop: empty set")
- }
-
- /// Get a package by name out of the set
- pub fn get(&self, name: &str) -> &Package {
- self.packages.iter().find(|pkg| name == pkg.name())
- .expect("PackageSet.get: empty set")
- }
-
- pub fn get_all(&self, names: &[&str]) -> Vec<&Package> {
- names.iter().map(|name| self.get(*name) ).collect()
- }
-
- pub fn packages(&self) -> &[Package] { &self.packages }
-
- // For now, assume that the package set contains only one package with a
- // given name
- pub fn sort(&self) -> Option<PackageSet> {
- let mut graph = graph::Graph::new();
-
- for pkg in self.packages.iter() {
- let deps: Vec<&str> = pkg.dependencies().iter()
- .map(|dep| dep.name())
- .collect();
-
- graph.add(pkg.name(), &deps);
+impl<'cfg> PackageSet<'cfg> {
+ pub fn new(packages: Vec<Package>,
+ sources: SourceMap<'cfg>) -> PackageSet<'cfg> {
+ PackageSet {
+ packages: packages,
+ sources: sources,
}
-
- let pkgs = match graph.sort() {
- Some(pkgs) => pkgs,
- None => return None,
- };
- let pkgs = pkgs.iter().map(|name| {
- self.get(*name).clone()
- }).collect();
-
- Some(PackageSet {
- packages: pkgs
- })
}
- pub fn iter(&self) -> slice::Iter<Package> {
+ pub fn packages(&self) -> slice::Iter<Package> {
self.packages.iter()
}
-}
-impl Registry for PackageSet {
- fn query(&mut self, name: &Dependency) -> CargoResult<Vec<Summary>> {
- Ok(self.packages.iter()
- .filter(|pkg| name.name() == pkg.name())
- .map(|pkg| pkg.summary().clone())
- .collect())
+ pub fn sources(&self) -> &SourceMap<'cfg> {
+ &self.sources
}
}
-use std::collections::HashSet;
-use std::collections::hash_map::HashMap;
+use std::collections::{HashSet, HashMap};
use core::{Source, SourceId, SourceMap, Summary, Dependency, PackageId, Package};
+use core::PackageSet;
use util::{CargoResult, ChainError, Config, human, profile};
/// Source of information about a group of packages.
}
}
- pub fn get(&mut self, package_ids: &[PackageId]) -> CargoResult<Vec<Package>> {
+ pub fn get(mut self, package_ids: &[PackageId])
+ -> CargoResult<PackageSet<'cfg>> {
trace!("getting packages; sources={}", self.sources.len());
// TODO: Only call source with package ID if the package came from the
"could not get packages from registry; ids={:?}; ret={:?}",
package_ids, ret);
- Ok(ret)
- }
-
- pub fn move_sources(self) -> SourceMap<'cfg> {
- self.sources
+ Ok(PackageSet::new(ret, self.sources))
}
fn ensure_loaded(&mut self, namespace: &SourceId, kind: Kind) -> CargoResult<()> {
use std::fs;
use std::path::Path;
-use core::{Package, PackageSet, Profiles};
-use core::source::{Source, SourceMap};
-use core::registry::PackageRegistry;
+use core::{Package, Profiles};
+use core::source::Source;
use util::{CargoResult, human, ChainError, Config};
use ops::{self, Layout, Context, BuildConfig, Kind, Unit};
return rm_rf(&target_dir);
}
- // Load the lockfile (if one's available)
- let lockfile = root.root().join("Cargo.lock");
- let source_id = root.package_id().source_id();
- let resolve = match try!(ops::load_lockfile(&lockfile, source_id)) {
- Some(resolve) => resolve,
- None => bail!("a Cargo.lock must exist before cleaning")
- };
-
- // Create a compilation context to have access to information like target
- // filenames and such
- let srcs = SourceMap::new();
- let pkgs = PackageSet::new(&[]);
+ let (resolve, packages) = try!(ops::fetch(manifest_path, opts.config));
let dest = if opts.release {"release"} else {"debug"};
let host_layout = Layout::new(opts.config, &root, None, dest);
Layout::new(opts.config, &root, Some(target), dest)
});
- let cx = try!(Context::new(&resolve, &srcs, &pkgs, opts.config,
+ let cx = try!(Context::new(&resolve, &packages, opts.config,
host_layout, target_layout,
BuildConfig::default(),
root.manifest().profiles()));
- let mut registry = PackageRegistry::new(opts.config);
-
// resolve package specs and remove the corresponding packages
for spec in opts.spec {
+ // Translate the spec to a Package
let pkgid = try!(resolve.query(spec));
-
- // Translate the PackageId to a Package
- let pkg = {
- try!(registry.add_sources(&[pkgid.source_id().clone()]));
- (try!(registry.get(&[pkgid.clone()]))).into_iter().next().unwrap()
- };
+ let pkg = packages.packages().find(|p| p.package_id() == pkgid).unwrap();
// And finally, clean everything out!
for target in pkg.targets() {
use std::sync::Arc;
use core::registry::PackageRegistry;
-use core::{Source, SourceId, SourceMap, PackageSet, Package, Target};
+use core::{Source, SourceId, PackageSet, Package, Target};
use core::{Profile, TargetKind, Profiles};
use core::resolver::{Method, Resolve};
use ops::{self, BuildOutput, ExecEngine};
source: Option<Box<Source + 'a>>,
features: Vec<String>,
no_default_features: bool)
- -> CargoResult<(Vec<Package>, Resolve, SourceMap<'a>)> {
+ -> CargoResult<(PackageSet<'a>, Resolve)> {
let override_ids = try!(source_ids_from_config(config, root_package.root()));
method, Some(&resolve), None));
let packages = try!(ops::get_resolved_packages(&resolved_with_overrides,
- &mut registry));
+ registry));
- Ok((packages, resolved_with_overrides, registry.move_sources()))
+ Ok((packages, resolved_with_overrides))
}
pub fn compile_pkg<'a>(root_package: &Package,
bail!("jobs must be at least 1")
}
- let (packages, resolve_with_overrides, sources) = {
+ let (packages, resolve_with_overrides) = {
try!(resolve_dependencies(root_package, config, source, features,
no_default_features))
};
invalid_spec.join(", "))
}
- let to_builds = packages.iter().filter(|p| pkgids.contains(&p.package_id()))
+ let to_builds = packages.packages()
+ .filter(|p| pkgids.contains(&p.package_id()))
.collect::<Vec<_>>();
let mut general_targets = Vec::new();
}
try!(ops::compile_targets(&package_targets,
- &PackageSet::new(&packages),
+ &packages,
&resolve_with_overrides,
- &sources,
config,
build_config,
root_package.manifest().profiles(),
use std::path::Path;
use core::registry::PackageRegistry;
-use core::{Package, PackageId, Resolve};
+use core::{Package, PackageId, Resolve, PackageSet};
use ops;
use util::{CargoResult, Config, human, ChainError};
/// Executes `cargo fetch`.
-pub fn fetch(manifest_path: &Path, config: &Config) -> CargoResult<()> {
+pub fn fetch<'a>(manifest_path: &Path,
+ config: &'a Config)
+ -> CargoResult<(Resolve, PackageSet<'a>)> {
let package = try!(Package::for_path(manifest_path, config));
let mut registry = PackageRegistry::new(config);
let resolve = try!(ops::resolve_pkg(&mut registry, &package));
- let _ = try!(get_resolved_packages(&resolve, &mut registry));
- Ok(())
+ get_resolved_packages(&resolve, registry).map(move |packages| {
+ (resolve, packages)
+ })
}
-pub fn get_resolved_packages(resolve: &Resolve, registry: &mut PackageRegistry)
- -> CargoResult<Vec<Package>> {
+pub fn get_resolved_packages<'a>(resolve: &Resolve,
+ registry: PackageRegistry<'a>)
+ -> CargoResult<PackageSet<'a>> {
let ids: Vec<PackageId> = resolve.iter().cloned().collect();
registry.get(&ids).chain_error(|| {
human("unable to get packages from source")
use rustc_serialize::{Encodable, Encoder};
use core::resolver::Resolve;
-use core::{Source, Package, PackageId};
+use core::{Source, Package, PackageId, PackageSet};
use ops;
use sources::PathSource;
use util::config::Config;
let (packages, resolve) = deps;
Ok(ExportInfo {
- packages: packages,
+ packages: packages.packages().cloned().collect(),
resolve: Some(MetadataResolve(resolve)),
version: VERSION,
})
/// Loads the manifest and resolves the dependencies of the project to the
/// concrete used versions. Afterwards available overrides of dependencies are applied.
-fn resolve_dependencies(manifest: &Path,
- config: &Config,
- features: Vec<String>,
- no_default_features: bool)
- -> CargoResult<(Vec<Package>, Resolve)> {
+fn resolve_dependencies<'a>(manifest: &Path,
+ config: &'a Config,
+ features: Vec<String>,
+ no_default_features: bool)
+ -> CargoResult<(PackageSet<'a>, Resolve)> {
let mut source = try!(PathSource::for_path(manifest.parent().unwrap(), config));
try!(source.update());
let package = try!(source.root_package());
- let deps = try!(ops::resolve_dependencies(&package,
- config,
- Some(Box::new(source)),
- features,
- no_default_features));
-
- let (packages, resolve_with_overrides, _) = deps;
-
- Ok((packages, resolve_with_overrides))
+ ops::resolve_dependencies(&package,
+ config,
+ Some(Box::new(source)),
+ features,
+ no_default_features)
}
use regex::Regex;
-use core::{SourceMap, Package, PackageId, PackageSet, Resolve, Target, Profile};
+use core::{Package, PackageId, PackageSet, Resolve, Target, Profile};
use core::{TargetKind, LibKind, Profiles, Metadata, Dependency};
use core::dependency::Kind as DepKind;
use util::{self, CargoResult, ChainError, internal, Config, profile, Cfg, human};
pub struct Context<'a, 'cfg: 'a> {
pub config: &'cfg Config,
pub resolve: &'a Resolve,
- pub sources: &'a SourceMap<'cfg>,
pub compilation: Compilation<'cfg>,
+ pub packages: &'a PackageSet<'cfg>,
pub build_state: Arc<BuildState>,
pub build_explicit_deps: HashMap<Unit<'a>, (PathBuf, Vec<String>)>,
pub exec_engine: Arc<Box<ExecEngine>>,
target_triple: String,
target_info: TargetInfo,
host_info: TargetInfo,
- package_set: &'a PackageSet,
profiles: &'a Profiles,
}
impl<'a, 'cfg> Context<'a, 'cfg> {
pub fn new(resolve: &'a Resolve,
- sources: &'a SourceMap<'cfg>,
- deps: &'a PackageSet,
+ packages: &'a PackageSet<'cfg>,
config: &'cfg Config,
host: Layout,
target_layout: Option<Layout>,
host: host,
target: target_layout,
resolve: resolve,
- sources: sources,
- package_set: deps,
+ packages: packages,
config: config,
target_info: target_info,
host_info: host_info,
compilation: Compilation::new(config),
- build_state: Arc::new(BuildState::new(&build_config, deps)),
+ build_state: Arc::new(BuildState::new(&build_config, packages)),
build_config: build_config,
exec_engine: engine,
fingerprints: HashMap::new(),
/// Returns the appropriate output directory for the specified package and
/// target.
pub fn out_dir(&self, unit: &Unit) -> PathBuf {
- let out_dir = self.layout(unit.pkg, unit.kind);
- if unit.target.is_custom_build() {
- out_dir.build(unit.pkg)
- } else if unit.target.is_example() {
- out_dir.examples().to_path_buf()
- } else {
- out_dir.root().to_path_buf()
- }
+ self.layout(unit.pkg, unit.kind).out_dir(unit.pkg, unit.target)
}
/// Return the (prefix, suffix) pair for dynamic libraries.
/// Gets a package for the given package id.
pub fn get_package(&self, id: &PackageId) -> &'a Package {
- self.package_set.iter()
+ self.packages.packages()
.find(|pkg| id == pkg.package_id())
.expect("Should have found package")
}
pub fn new(config: &super::BuildConfig,
packages: &PackageSet) -> BuildState {
let mut sources = HashMap::new();
- for package in packages.iter() {
+ for package in packages.packages() {
match package.manifest().links() {
Some(links) => {
sources.insert(links.to_string(),
fn pkg_fingerprint(cx: &Context, pkg: &Package) -> CargoResult<String> {
let source_id = pkg.package_id().source_id();
- let source = try!(cx.sources.get(source_id).chain_error(|| {
+ let source = try!(cx.packages.sources().get(source_id).chain_error(|| {
internal("missing package source")
}));
source.fingerprint(pkg)
use std::io;
use std::path::{PathBuf, Path};
-use core::Package;
+use core::{Package, Target};
use util::Config;
use util::hex::short_hash;
pub fn build_out(&self, pkg: &Package) -> PathBuf { self.root.build_out(pkg) }
pub fn proxy(&self) -> &'a Layout { self.root }
+
+ pub fn out_dir(&self, pkg: &Package, target: &Target) -> PathBuf {
+ if target.is_custom_build() {
+ self.build(pkg)
+ } else if target.is_example() {
+ self.examples().to_path_buf()
+ } else {
+ self.root().to_path_buf()
+ }
+ }
}
pub fn validate(deps: &PackageSet) -> CargoResult<()> {
let mut map: HashMap<_, &PackageId> = HashMap::new();
- for dep in deps.iter() {
+ for dep in deps.packages() {
let lib = match dep.manifest().links() {
Some(lib) => lib,
None => continue,
use std::path::{self, PathBuf};
use std::sync::Arc;
-use core::{SourceMap, Package, PackageId, PackageSet, Target, Resolve};
+use core::{Package, PackageId, PackageSet, Target, Resolve};
use core::{Profile, Profiles};
use util::{self, CargoResult, human};
use util::{Config, internal, ChainError, profile, join_paths};
pub overrides: HashMap<String, BuildOutput>,
}
-pub type PackagesToBuild<'a> = [(&'a Package,Vec<(&'a Target,&'a Profile)>)];
+pub type PackagesToBuild<'a> = [(&'a Package, Vec<(&'a Target,&'a Profile)>)];
// Returns a mapping of the root package plus its immediate dependencies to
// where the compiled libraries are all located.
pub fn compile_targets<'a, 'cfg: 'a>(pkg_targets: &'a PackagesToBuild<'a>,
- deps: &'a PackageSet,
+ packages: &'a PackageSet<'cfg>,
resolve: &'a Resolve,
- sources: &'a SourceMap<'cfg>,
config: &'cfg Config,
build_config: BuildConfig,
profiles: &'a Profiles)
}
})
}).collect::<Vec<_>>();
- try!(links::validate(deps));
+ try!(links::validate(packages));
let dest = if build_config.release {"release"} else {"debug"};
- let root = deps.iter().find(|p| p.package_id() == resolve.root()).unwrap();
+ let root = packages.packages().find(|p| {
+ p.package_id() == resolve.root()
+ }).unwrap();
let host_layout = Layout::new(config, root, None, &dest);
let target_layout = build_config.requested_target.as_ref().map(|target| {
layout::Layout::new(config, root, Some(&target), &dest)
});
- let mut cx = try!(Context::new(resolve, sources, deps, config,
+ let mut cx = try!(Context::new(resolve, packages, config,
host_layout, target_layout,
build_config, profiles));