From 25518da782785ee317627e330da0a00b6d6e73ac Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Thu, 20 Oct 2016 23:57:51 -0400 Subject: [PATCH 01/11] avoid panic when virtual workspace has no members --- src/cargo/core/resolver/encode.rs | 18 +++++++++--------- tests/workspaces.rs | 23 +++++++++++++++++++++++ 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/cargo/core/resolver/encode.rs b/src/cargo/core/resolver/encode.rs index 47c20b89bea..6640e53e3aa 100644 --- a/src/cargo/core/resolver/encode.rs +++ b/src/cargo/core/resolver/encode.rs @@ -283,14 +283,15 @@ impl<'a, 'cfg> Encodable for WorkspaceResolve<'a, 'cfg> { let root = self.ws.members().max_by_key(|member| { member.name() - }).unwrap().package_id(); + }).map(Package::package_id); let encodable = ids.iter().filter_map(|&id| { - if self.use_root_key && root == id { - return None + match root { + Some(ref root) if !(self.use_root_key && *root == id) => { + Some(encodable_resolve_node(id, self.resolve)) + }, + _ => None, } - - Some(encodable_resolve_node(id, self.resolve)) }).collect::>(); let mut metadata = self.resolve.metadata.clone(); @@ -307,10 +308,9 @@ impl<'a, 'cfg> Encodable for WorkspaceResolve<'a, 'cfg> { let metadata = if metadata.len() == 0 {None} else {Some(metadata)}; - let root = if self.use_root_key { - Some(encodable_resolve_node(&root, self.resolve)) - } else { - None + let root = match root { + Some(root) if self.use_root_key => Some(encodable_resolve_node(&root, self.resolve)), + _ => None, }; EncodableResolve { package: Some(encodable), diff --git a/tests/workspaces.rs b/tests/workspaces.rs index 42ac608da46..00bb68bd43d 100644 --- a/tests/workspaces.rs +++ b/tests/workspaces.rs @@ -652,6 +652,29 @@ manifest located at: [..] #[test] fn virtual_build() { + let p = project("foo") + .file("Cargo.toml", r#" + [workspace] + members = ["bar"] + "#) + .file("bar/Cargo.toml", r#" + [project] + name = "bar" + version = "0.1.0" + authors = [] + "#) + .file("bar/src/main.rs", "fn main() {}"); + p.build(); + assert_that(p.cargo("build"), + execs().with_status(101) + .with_stderr("\ +error: manifest path `[..]` is a virtual manifest, but this command \ +requires running against an actual package in this workspace +")); +} + +#[test] +fn virtual_build_no_members() { let p = project("foo") .file("Cargo.toml", r#" [workspace] From 62c0497912f6c424a4a68d7af504f7943fad9864 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Thu, 20 Oct 2016 16:14:54 -0400 Subject: [PATCH 02/11] add `--all` flag to `cargo-test` --- src/bin/bench.rs | 2 +- src/bin/build.rs | 2 +- src/bin/doc.rs | 4 +- src/bin/install.rs | 2 +- src/bin/run.rs | 4 +- src/bin/rustc.rs | 6 +- src/bin/rustdoc.rs | 6 +- src/bin/test.rs | 19 +++- src/cargo/ops/cargo_compile.rs | 37 ++++++-- src/cargo/ops/cargo_doc.rs | 17 +++- src/cargo/ops/cargo_package.rs | 2 +- src/cargo/ops/cargo_rustc/context.rs | 12 ++- src/cargo/ops/cargo_rustc/job_queue.rs | 4 +- src/cargo/ops/cargo_rustc/mod.rs | 4 +- src/cargo/ops/mod.rs | 2 +- tests/test.rs | 126 +++++++++++++++++++++++++ 16 files changed, 213 insertions(+), 36 deletions(-) diff --git a/src/bin/bench.rs b/src/bin/bench.rs index 774b3003cf7..bee11df314b 100644 --- a/src/bin/bench.rs +++ b/src/bin/bench.rs @@ -88,7 +88,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { features: &options.flag_features, all_features: options.flag_all_features, no_default_features: options.flag_no_default_features, - spec: &options.flag_package, + spec: ops::Packages::Packages(&options.flag_package), release: true, mode: ops::CompileMode::Bench, filter: ops::CompileFilter::new(options.flag_lib, diff --git a/src/bin/build.rs b/src/bin/build.rs index 7e6688b410f..446c87ea8e0 100644 --- a/src/bin/build.rs +++ b/src/bin/build.rs @@ -84,7 +84,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { features: &options.flag_features, all_features: options.flag_all_features, no_default_features: options.flag_no_default_features, - spec: &options.flag_package, + spec: ops::Packages::Packages(&options.flag_package), mode: ops::CompileMode::Build, release: options.flag_release, filter: ops::CompileFilter::new(options.flag_lib, diff --git a/src/bin/doc.rs b/src/bin/doc.rs index f8b434247a9..c28533a89de 100644 --- a/src/bin/doc.rs +++ b/src/bin/doc.rs @@ -1,5 +1,5 @@ use cargo::core::Workspace; -use cargo::ops::{self, MessageFormat}; +use cargo::ops::{self, MessageFormat, Packages}; use cargo::util::{CliResult, Config}; use cargo::util::important_paths::{find_root_manifest_for_wd}; @@ -80,7 +80,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { features: &options.flag_features, all_features: options.flag_all_features, no_default_features: options.flag_no_default_features, - spec: &options.flag_package, + spec: Packages::Packages(&options.flag_package), filter: ops::CompileFilter::new(options.flag_lib, &options.flag_bin, &empty, diff --git a/src/bin/install.rs b/src/bin/install.rs index c27db56ffaf..e2ac62241b4 100644 --- a/src/bin/install.rs +++ b/src/bin/install.rs @@ -108,7 +108,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { features: &options.flag_features, all_features: options.flag_all_features, no_default_features: options.flag_no_default_features, - spec: &[], + spec: ops::Packages::Packages(&[]), mode: ops::CompileMode::Build, release: !options.flag_debug, filter: ops::CompileFilter::new(false, &options.flag_bin, &[], diff --git a/src/bin/run.rs b/src/bin/run.rs index 1e7089a7572..38fa657da9c 100644 --- a/src/bin/run.rs +++ b/src/bin/run.rs @@ -1,5 +1,5 @@ use cargo::core::Workspace; -use cargo::ops::{self, MessageFormat}; +use cargo::ops::{self, MessageFormat, Packages}; use cargo::util::{CliResult, CliError, Config, Human}; use cargo::util::important_paths::{find_root_manifest_for_wd}; @@ -81,7 +81,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { features: &options.flag_features, all_features: options.flag_all_features, no_default_features: options.flag_no_default_features, - spec: &[], + spec: Packages::Packages(&[]), release: options.flag_release, mode: ops::CompileMode::Build, filter: if examples.is_empty() && bins.is_empty() { diff --git a/src/bin/rustc.rs b/src/bin/rustc.rs index a73088bfd64..66369e2db93 100644 --- a/src/bin/rustc.rs +++ b/src/bin/rustc.rs @@ -1,7 +1,7 @@ use std::env; use cargo::core::Workspace; -use cargo::ops::{self, CompileOptions, CompileMode, MessageFormat}; +use cargo::ops::{self, CompileOptions, CompileMode, MessageFormat, Packages}; use cargo::util::important_paths::{find_root_manifest_for_wd}; use cargo::util::{CliResult, CliError, Config, human}; @@ -95,6 +95,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { } }; + let spec = options.flag_package.map_or_else(Vec::new, |s| vec![s]); + let opts = CompileOptions { config: config, jobs: options.flag_jobs, @@ -102,7 +104,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { features: &options.flag_features, all_features: options.flag_all_features, no_default_features: options.flag_no_default_features, - spec: &options.flag_package.map_or(Vec::new(), |s| vec![s]), + spec: Packages::Packages(&spec), mode: mode, release: options.flag_release, filter: ops::CompileFilter::new(options.flag_lib, diff --git a/src/bin/rustdoc.rs b/src/bin/rustdoc.rs index 0d159f47a8e..41c29a4e810 100644 --- a/src/bin/rustdoc.rs +++ b/src/bin/rustdoc.rs @@ -1,5 +1,5 @@ use cargo::core::Workspace; -use cargo::ops::{self, MessageFormat}; +use cargo::ops::{self, MessageFormat, Packages}; use cargo::util::{CliResult, Config}; use cargo::util::important_paths::{find_root_manifest_for_wd}; @@ -80,6 +80,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?; + let spec = options.flag_package.map_or_else(Vec::new, |s| vec![s]); + let doc_opts = ops::DocOptions { open_result: options.flag_open, compile_opts: ops::CompileOptions { @@ -89,7 +91,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { features: &options.flag_features, all_features: options.flag_all_features, no_default_features: options.flag_no_default_features, - spec: &options.flag_package.map_or(Vec::new(), |s| vec![s]), + spec: Packages::Packages(&spec), release: options.flag_release, filter: ops::CompileFilter::new(options.flag_lib, &options.flag_bin, diff --git a/src/bin/test.rs b/src/bin/test.rs index c28ff8fc431..8884e773d08 100644 --- a/src/bin/test.rs +++ b/src/bin/test.rs @@ -1,7 +1,7 @@ use cargo::core::Workspace; -use cargo::ops::{self, MessageFormat}; +use cargo::ops::{self, MessageFormat, Packages}; use cargo::util::{CliResult, CliError, Human, human, Config}; -use cargo::util::important_paths::{find_root_manifest_for_wd}; +use cargo::util::important_paths::find_root_manifest_for_wd; #[derive(RustcDecodable)] pub struct Options { @@ -28,6 +28,7 @@ pub struct Options { flag_no_fail_fast: bool, flag_frozen: bool, flag_locked: bool, + flag_all: bool, } pub const USAGE: &'static str = " @@ -46,6 +47,7 @@ Options: --bench NAME Test only the specified benchmark target --no-run Compile, but don't run tests -p SPEC, --package SPEC ... Package to run tests for + --all Test all packages in the workspace -j N, --jobs N Number of parallel jobs, defaults to # of CPUs --release Build artifacts in release mode, with optimizations --features FEATURES Space-separated list of features to also build @@ -72,6 +74,9 @@ which indicates which package should be tested. If it is not given, then the current package is tested. For more information on SPEC and its format, see the `cargo help pkgid` command. +All packages in the workspace are tested if the `--all` flag is supplied. The +`--all` flag may be supplied in the presence of a virtual manifest. + The --jobs argument affects the building of the test executable but does not affect how many jobs are used when running the tests. @@ -111,6 +116,12 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { &options.flag_bench); } + let spec = if options.flag_all { + Packages::All + } else { + Packages::Packages(&options.flag_package) + }; + let ops = ops::TestOptions { no_run: options.flag_no_run, no_fail_fast: options.flag_no_fail_fast, @@ -122,7 +133,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { features: &options.flag_features, all_features: options.flag_all_features, no_default_features: options.flag_no_default_features, - spec: &options.flag_package, + spec: spec, release: options.flag_release, mode: mode, filter: filter, @@ -139,7 +150,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { Some(err) => { Err(match err.exit.as_ref().and_then(|e| e.code()) { Some(i) => CliError::new(human("test failed"), i), - None => CliError::new(Box::new(Human(err)), 101) + None => CliError::new(Box::new(Human(err)), 101), }) } } diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index e2f62e2593b..e1bcc2ef7d9 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -22,6 +22,7 @@ //! previously compiled dependency //! +use std::borrow::Cow; use std::collections::HashMap; use std::path::PathBuf; @@ -47,8 +48,8 @@ pub struct CompileOptions<'a> { pub all_features: bool, /// Flag if the default feature should be built for the root package pub no_default_features: bool, - /// Root package to build (if None it's the current one) - pub spec: &'a [String], + /// Root package to build (if empty it's the current one) + pub spec: Packages<'a>, /// Filter to apply to the root package to select which targets will be /// built. pub filter: CompileFilter<'a>, @@ -79,6 +80,12 @@ pub enum MessageFormat { Json } +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum Packages<'a> { + All, + Packages(&'a [String]), +} + pub enum CompileFilter<'a> { Everything, Only { @@ -92,8 +99,10 @@ pub enum CompileFilter<'a> { pub fn compile<'a>(ws: &Workspace<'a>, options: &CompileOptions<'a>) -> CargoResult> { - for key in ws.current()?.manifest().warnings().iter() { - options.config.shell().warn(key)? + if let Some(root_package) = ws.current_opt() { + for key in root_package.manifest().warnings().iter() { + options.config.shell().warn(key)? + } } compile_ws(ws, None, options) } @@ -112,8 +121,9 @@ pub fn resolve_dependencies<'a>(ws: &Workspace<'a>, let mut registry = PackageRegistry::new(ws.config())?; if let Some(source) = source { - registry.add_preloaded(ws.current()?.package_id().source_id(), - source); + if let Some(root_package) = ws.current_opt() { + registry.add_preloaded(root_package.package_id().source_id(), source); + } } // First, resolve the root_package's *listed* dependencies, as well as @@ -152,7 +162,6 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>, source: Option>, options: &CompileOptions<'a>) -> CargoResult> { - let root_package = ws.current()?; let CompileOptions { config, jobs, target, spec, features, all_features, no_default_features, release, mode, message_format, @@ -166,8 +175,19 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>, bail!("jobs must be at least 1") } + let spec: Cow<'a, [String]> = match spec { + Packages::Packages(spec) => spec.into(), + Packages::All => ws.members() + .map(|package| { + let package_id = package.package_id(); + PackageIdSpec::from_package_id(package_id).to_string() + }) + .collect() + }; + let profiles = ws.profiles(); if spec.len() == 0 { + let root_package = ws.current()?; generate_targets(root_package, profiles, mode, filter, release)?; } @@ -184,10 +204,11 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>, let mut pkgids = Vec::new(); if spec.len() > 0 { - for p in spec { + for p in spec.iter() { pkgids.push(resolve_with_overrides.query(&p)?); } } else { + let root_package = ws.current()?; pkgids.push(root_package.package_id()); }; diff --git a/src/cargo/ops/cargo_doc.rs b/src/cargo/ops/cargo_doc.rs index 8c27335745e..eb1894fde0a 100644 --- a/src/cargo/ops/cargo_doc.rs +++ b/src/cargo/ops/cargo_doc.rs @@ -15,9 +15,18 @@ pub struct DocOptions<'a> { pub fn doc(ws: &Workspace, options: &DocOptions) -> CargoResult<()> { let package = ws.current()?; + let spec = match options.compile_opts.spec { + ops::Packages::Packages(packages) => packages, + _ => { + // This should not happen, because the `doc` binary is hard-coded to pass + // the `Packages::Packages` variant. + bail!("`cargo doc` does not support the `--all` flag") + }, + }; + let mut lib_names = HashSet::new(); let mut bin_names = HashSet::new(); - if options.compile_opts.spec.is_empty() { + if spec.is_empty() { for target in package.targets().iter().filter(|t| t.documented()) { if target.is_lib() { assert!(lib_names.insert(target.crate_name())); @@ -37,10 +46,10 @@ pub fn doc(ws: &Workspace, options: &DocOptions) -> CargoResult<()> { ops::compile(ws, &options.compile_opts)?; if options.open_result { - let name = if options.compile_opts.spec.len() > 1 { + let name = if spec.len() > 1 { bail!("Passing multiple packages and `open` is not supported") - } else if options.compile_opts.spec.len() == 1 { - PackageIdSpec::parse(&options.compile_opts.spec[0])? + } else if spec.len() == 1 { + PackageIdSpec::parse(&spec[0])? .name() .replace("-", "_") } else { diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs index 26841796ec8..c837e0156db 100644 --- a/src/cargo/ops/cargo_package.rs +++ b/src/cargo/ops/cargo_package.rs @@ -291,7 +291,7 @@ fn run_verify(ws: &Workspace, tar: &File, opts: &PackageOpts) -> CargoResult<()> features: &[], no_default_features: false, all_features: false, - spec: &[], + spec: ops::Packages::Packages(&[]), filter: ops::CompileFilter::Everything, release: false, message_format: ops::MessageFormat::Human, diff --git a/src/cargo/ops/cargo_rustc/context.rs b/src/cargo/ops/cargo_rustc/context.rs index 9e0cc26eb6a..de90ba89b26 100644 --- a/src/cargo/ops/cargo_rustc/context.rs +++ b/src/cargo/ops/cargo_rustc/context.rs @@ -31,7 +31,7 @@ pub struct Unit<'a> { pub struct Context<'a, 'cfg: 'a> { pub config: &'cfg Config, pub resolve: &'a Resolve, - pub current_package: PackageId, + pub current_package: Option, pub compilation: Compilation<'cfg>, pub packages: &'a PackageSet<'cfg>, pub build_state: Arc, @@ -76,7 +76,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> { None => None, }; - let current_package = ws.current()?.package_id().clone(); + let current_package = ws.current_opt().map(Package::package_id).cloned(); Ok(Context { host: host_layout, target: target_layout, @@ -450,7 +450,8 @@ impl<'a, 'cfg> Context<'a, 'cfg> { // we don't want to link it up. if src_dir.ends_with("deps") { // Don't lift up library dependencies - if unit.pkg.package_id() != &self.current_package && !unit.target.is_bin() { + if self.current_package.as_ref().map_or(false, |p| unit.pkg.package_id() != p) + && !unit.target.is_bin() { None } else { Some(( @@ -836,8 +837,9 @@ impl<'a, 'cfg> Context<'a, 'cfg> { } pub fn show_warnings(&self, pkg: &PackageId) -> bool { - pkg == &self.current_package || pkg.source_id().is_path() || - self.config.extra_verbose() + self.current_package.as_ref().map_or(false, |p| *pkg == *p) + || pkg.source_id().is_path() + || self.config.extra_verbose() } } diff --git a/src/cargo/ops/cargo_rustc/job_queue.rs b/src/cargo/ops/cargo_rustc/job_queue.rs index e69bd33cd91..6ddd002f84f 100644 --- a/src/cargo/ops/cargo_rustc/job_queue.rs +++ b/src/cargo/ops/cargo_rustc/job_queue.rs @@ -198,7 +198,9 @@ impl<'a> JobQueue<'a> { } let build_type = if self.is_release { "release" } else { "debug" }; - let profile = cx.lib_profile(&cx.current_package); + let profile = cx.current_package.as_ref().map_or_else(Profile::default, |p| { + cx.lib_profile(p).to_owned() + }); let mut opt_type = String::from(if profile.opt_level == "0" { "unoptimized" } else { "optimized" }); if profile.debuginfo { diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index 186ce0d728c..0abfe498655 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -557,7 +557,9 @@ fn build_base_args(cx: &mut Context, let prefer_dynamic = (unit.target.for_host() && !unit.target.is_custom_build()) || (crate_types.contains(&"dylib") && - unit.pkg.package_id() != &cx.current_package); + cx.current_package.as_ref().map_or(false, |p| { + *p != *unit.pkg.package_id() + })); if prefer_dynamic { cmd.arg("-C").arg("prefer-dynamic"); } diff --git a/src/cargo/ops/mod.rs b/src/cargo/ops/mod.rs index 902c72e3007..2b46cc4d26a 100644 --- a/src/cargo/ops/mod.rs +++ b/src/cargo/ops/mod.rs @@ -1,6 +1,6 @@ pub use self::cargo_clean::{clean, CleanOptions}; pub use self::cargo_compile::{compile, compile_ws, resolve_dependencies, CompileOptions}; -pub use self::cargo_compile::{CompileFilter, CompileMode, MessageFormat}; +pub use self::cargo_compile::{CompileFilter, CompileMode, MessageFormat, Packages}; pub use self::cargo_read_manifest::{read_manifest,read_package,read_packages}; pub use self::cargo_rustc::{compile_targets, Compilation, Kind, Unit}; pub use self::cargo_rustc::Context; diff --git a/tests/test.rs b/tests/test.rs index 6166a1ec651..1ed25b6f0b6 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -9,6 +9,7 @@ use std::str; use cargotest::{sleep_ms, is_nightly}; use cargotest::support::{project, execs, basic_bin_manifest, basic_lib_manifest}; use cargotest::support::paths::CargoPathExt; +use cargotest::support::registry::Package; use hamcrest::{assert_that, existing_file, is_not}; use cargo::util::process; @@ -2398,3 +2399,128 @@ fn test_many_with_features() { .arg("--features").arg("foo"), execs().with_status(0)); } + +#[test] +fn test_all_workspace() { + let p = project("foo") + .file("Cargo.toml", r#" + [project] + name = "foo" + version = "0.1.0" + + [dependencies] + bar = { path = "bar" } + + [workspace] + "#) + .file("src/main.rs", r#" + #[test] + fn foo_test() {} + "#) + .file("bar/Cargo.toml", r#" + [project] + name = "bar" + version = "0.1.0" + "#) + .file("bar/src/lib.rs", r#" + #[test] + fn bar_test() {} + "#); + p.build(); + + assert_that(p.cargo_process("test") + .arg("--all"), + execs().with_stdout_contains("\ +running 1 test +test foo_test ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured + +") + .with_stdout_contains("\ +running 1 test +test bar_test ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured + +")); +} + +#[test] +fn test_all_virtual_manifest() { + let p = project("workspace") + .file("Cargo.toml", r#" + [workspace] + members = ["a", "b"] + "#) + .file("a/Cargo.toml", r#" + [project] + name = "a" + version = "0.1.0" + "#) + .file("a/src/lib.rs", r#" + #[test] + fn a() {} + "#) + .file("b/Cargo.toml", r#" + [project] + name = "b" + version = "0.1.0" + "#) + .file("b/src/lib.rs", r#" + #[test] + fn b() {} + "#); + p.build(); + + assert_that(p.cargo_process("test") + .arg("--all"), + execs().with_stdout_contains("\ +running 1 test +test b ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured + +") + .with_stdout_contains("\ +running 1 test +test b ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured + +")); +} + +#[test] +fn test_all_member_dependency_same_name() { + let p = project("workspace") + .file("Cargo.toml", r#" + [workspace] + members = ["a"] + "#) + .file("a/Cargo.toml", r#" + [project] + name = "a" + version = "0.1.0" + + [dependencies] + a = "0.1.0" + "#) + .file("a/src/lib.rs", r#" + #[test] + fn a() {} + "#); + p.build(); + + Package::new("a", "0.1.0").publish(); + + assert_that(p.cargo_process("test") + .arg("--all"), + execs().with_stdout_contains("\ +running 1 test +test a ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured + +")); +} From 0ae3a2b4fb2c76ba30ec80740fb9cbc2d0a7ae3a Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Wed, 16 Nov 2016 14:31:06 -0500 Subject: [PATCH 03/11] remove current_package from context --- src/cargo/ops/cargo_rustc/context.rs | 13 ++++++------- src/cargo/ops/cargo_rustc/job_queue.rs | 4 ++-- src/cargo/ops/cargo_rustc/mod.rs | 4 ++-- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/cargo/ops/cargo_rustc/context.rs b/src/cargo/ops/cargo_rustc/context.rs index de90ba89b26..c53ce604072 100644 --- a/src/cargo/ops/cargo_rustc/context.rs +++ b/src/cargo/ops/cargo_rustc/context.rs @@ -29,9 +29,9 @@ pub struct Unit<'a> { } pub struct Context<'a, 'cfg: 'a> { + pub ws: &'a Workspace<'cfg>, pub config: &'cfg Config, pub resolve: &'a Resolve, - pub current_package: Option, pub compilation: Compilation<'cfg>, pub packages: &'a PackageSet<'cfg>, pub build_state: Arc, @@ -60,7 +60,7 @@ struct TargetInfo { pub struct Metadata(u64); impl<'a, 'cfg> Context<'a, 'cfg> { - pub fn new(ws: &Workspace<'cfg>, + pub fn new(ws: &'a Workspace<'cfg>, resolve: &'a Resolve, packages: &'a PackageSet<'cfg>, config: &'cfg Config, @@ -76,12 +76,11 @@ impl<'a, 'cfg> Context<'a, 'cfg> { None => None, }; - let current_package = ws.current_opt().map(Package::package_id).cloned(); Ok(Context { + ws: ws, host: host_layout, target: target_layout, resolve: resolve, - current_package: current_package, packages: packages, config: config, target_info: TargetInfo::default(), @@ -450,8 +449,8 @@ impl<'a, 'cfg> Context<'a, 'cfg> { // we don't want to link it up. if src_dir.ends_with("deps") { // Don't lift up library dependencies - if self.current_package.as_ref().map_or(false, |p| unit.pkg.package_id() != p) - && !unit.target.is_bin() { + if self.ws.current_opt().map_or(false, |p| unit.pkg.package_id() != p.package_id()) + && !unit.target.is_bin() { None } else { Some(( @@ -837,7 +836,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> { } pub fn show_warnings(&self, pkg: &PackageId) -> bool { - self.current_package.as_ref().map_or(false, |p| *pkg == *p) + self.ws.current_opt().map_or(false, |p| *pkg == *p.package_id()) || pkg.source_id().is_path() || self.config.extra_verbose() } diff --git a/src/cargo/ops/cargo_rustc/job_queue.rs b/src/cargo/ops/cargo_rustc/job_queue.rs index 6ddd002f84f..5e35a7e1030 100644 --- a/src/cargo/ops/cargo_rustc/job_queue.rs +++ b/src/cargo/ops/cargo_rustc/job_queue.rs @@ -198,8 +198,8 @@ impl<'a> JobQueue<'a> { } let build_type = if self.is_release { "release" } else { "debug" }; - let profile = cx.current_package.as_ref().map_or_else(Profile::default, |p| { - cx.lib_profile(p).to_owned() + let profile = cx.ws.current_opt().map_or_else(Profile::default, |p| { + cx.lib_profile(p.package_id()).to_owned() }); let mut opt_type = String::from(if profile.opt_level == "0" { "unoptimized" } else { "optimized" }); diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index 0abfe498655..dff80e493a7 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -557,8 +557,8 @@ fn build_base_args(cx: &mut Context, let prefer_dynamic = (unit.target.for_host() && !unit.target.is_custom_build()) || (crate_types.contains(&"dylib") && - cx.current_package.as_ref().map_or(false, |p| { - *p != *unit.pkg.package_id() + cx.ws.current_opt().map_or(false, |p| { + *p.package_id() != *unit.pkg.package_id() })); if prefer_dynamic { cmd.arg("-C").arg("prefer-dynamic"); From c368d6ad6521ddf933642f8199d710fcb4da7e8f Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Wed, 16 Nov 2016 15:26:18 -0500 Subject: [PATCH 04/11] pass `Packages` into resolve dependencies --- src/cargo/ops/cargo_compile.rs | 47 ++++++++++++-------------- src/cargo/ops/cargo_output_metadata.rs | 11 +++--- 2 files changed, 25 insertions(+), 33 deletions(-) diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index e1bcc2ef7d9..e086315936a 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -22,7 +22,6 @@ //! previously compiled dependency //! -use std::borrow::Cow; use std::collections::HashMap; use std::path::PathBuf; @@ -112,8 +111,8 @@ pub fn resolve_dependencies<'a>(ws: &Workspace<'a>, features: &[String], all_features: bool, no_default_features: bool, - specs: &[PackageIdSpec]) - -> CargoResult<(PackageSet<'a>, Resolve)> { + specs: &Packages<'a>) + -> CargoResult<(Vec, PackageSet<'a>, Resolve)> { let features = features.iter().flat_map(|s| { s.split_whitespace() }).map(|s| s.to_string()).collect::>(); @@ -147,15 +146,27 @@ pub fn resolve_dependencies<'a>(ws: &Workspace<'a>, } }; + let specs = match *specs { + Packages::All => { + ws.members() + .map(Package::package_id) + .map(PackageIdSpec::from_package_id) + .collect() + }, + Packages::Packages(packages) => { + packages.iter().map(|p| PackageIdSpec::parse(&p)).collect::>>()? + } + }; + let resolved_with_overrides = ops::resolve_with_previous(&mut registry, ws, method, Some(&resolve), None, - specs)?; + &specs)?; let packages = ops::get_resolved_packages(&resolved_with_overrides, registry); - Ok((packages, resolved_with_overrides)) + Ok((specs, packages, resolved_with_overrides)) } pub fn compile_ws<'a>(ws: &Workspace<'a>, @@ -175,40 +186,24 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>, bail!("jobs must be at least 1") } - let spec: Cow<'a, [String]> = match spec { - Packages::Packages(spec) => spec.into(), - Packages::All => ws.members() - .map(|package| { - let package_id = package.package_id(); - PackageIdSpec::from_package_id(package_id).to_string() - }) - .collect() - }; - let profiles = ws.profiles(); - if spec.len() == 0 { - let root_package = ws.current()?; - generate_targets(root_package, profiles, mode, filter, release)?; - } - let specs = spec.iter().map(|p| PackageIdSpec::parse(p)) - .collect::>>()?; - - let pair = resolve_dependencies(ws, + let resolve = resolve_dependencies(ws, source, features, all_features, no_default_features, - &specs)?; - let (packages, resolve_with_overrides) = pair; + &spec)?; + let (spec, packages, resolve_with_overrides) = resolve; let mut pkgids = Vec::new(); if spec.len() > 0 { for p in spec.iter() { - pkgids.push(resolve_with_overrides.query(&p)?); + pkgids.push(resolve_with_overrides.query(&p.to_string())?); } } else { let root_package = ws.current()?; + generate_targets(root_package, profiles, mode, filter, release)?; pkgids.push(root_package.package_id()); }; diff --git a/src/cargo/ops/cargo_output_metadata.rs b/src/cargo/ops/cargo_output_metadata.rs index bc1a04f0cfd..2856d1658c1 100644 --- a/src/cargo/ops/cargo_output_metadata.rs +++ b/src/cargo/ops/cargo_output_metadata.rs @@ -1,8 +1,8 @@ use rustc_serialize::{Encodable, Encoder}; use core::resolver::Resolve; -use core::{Package, PackageId, PackageIdSpec, Workspace}; -use ops; +use core::{Package, PackageId, Workspace}; +use ops::{self, Packages}; use util::CargoResult; const VERSION: u32 = 1; @@ -43,16 +43,13 @@ fn metadata_no_deps(ws: &Workspace, fn metadata_full(ws: &Workspace, opt: &OutputMetadataOptions) -> CargoResult { - let specs = ws.members().map(|pkg| { - PackageIdSpec::from_package_id(pkg.package_id()) - }).collect::>(); let deps = ops::resolve_dependencies(ws, None, &opt.features, opt.all_features, opt.no_default_features, - &specs)?; - let (packages, resolve) = deps; + &Packages::All)?; + let (_, packages, resolve) = deps; let packages = try!(packages.package_ids() .map(|i| packages.get(i).map(|p| p.clone())) From 81e5c764a1b962c463efd2c1feb17d4090b296f1 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Wed, 16 Nov 2016 16:04:31 -0500 Subject: [PATCH 05/11] show warnings for all members of the workspace --- src/cargo/ops/cargo_compile.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index e086315936a..a0e70e9ba3f 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -98,8 +98,8 @@ pub enum CompileFilter<'a> { pub fn compile<'a>(ws: &Workspace<'a>, options: &CompileOptions<'a>) -> CargoResult> { - if let Some(root_package) = ws.current_opt() { - for key in root_package.manifest().warnings().iter() { + for member in ws.members() { + for key in member.manifest().warnings().iter() { options.config.shell().warn(key)? } } From 6d98711b1b1ecaa9aea5a6891d219a21a6efceb2 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Fri, 2 Dec 2016 14:30:16 -0500 Subject: [PATCH 06/11] remove unnecessary match --- src/cargo/core/resolver/encode.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/cargo/core/resolver/encode.rs b/src/cargo/core/resolver/encode.rs index 6640e53e3aa..b0c6e280a37 100644 --- a/src/cargo/core/resolver/encode.rs +++ b/src/cargo/core/resolver/encode.rs @@ -286,12 +286,11 @@ impl<'a, 'cfg> Encodable for WorkspaceResolve<'a, 'cfg> { }).map(Package::package_id); let encodable = ids.iter().filter_map(|&id| { - match root { - Some(ref root) if !(self.use_root_key && *root == id) => { - Some(encodable_resolve_node(id, self.resolve)) - }, - _ => None, + if self.use_root_key && root.unwrap() == id { + return None } + + Some(encodable_resolve_node(id, self.resolve)) }).collect::>(); let mut metadata = self.resolve.metadata.clone(); From 1e0c29c2ac7c21405061b03e884b819acf5a9cd5 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Fri, 2 Dec 2016 14:40:37 -0500 Subject: [PATCH 07/11] avoid round-tripping through string --- src/cargo/ops/cargo_compile.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index a0e70e9ba3f..8a5ed55c723 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -199,7 +199,7 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>, let mut pkgids = Vec::new(); if spec.len() > 0 { for p in spec.iter() { - pkgids.push(resolve_with_overrides.query(&p.to_string())?); + pkgids.push(p.query(resolve_with_overrides.iter())?); } } else { let root_package = ws.current()?; From 621617973e701c9459211ce703b9f84826be3873 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Fri, 2 Dec 2016 15:21:31 -0500 Subject: [PATCH 08/11] remove unnecessary usage of `current_opt` --- src/cargo/ops/cargo_rustc/context.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/cargo/ops/cargo_rustc/context.rs b/src/cargo/ops/cargo_rustc/context.rs index c53ce604072..09977ca300d 100644 --- a/src/cargo/ops/cargo_rustc/context.rs +++ b/src/cargo/ops/cargo_rustc/context.rs @@ -836,9 +836,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> { } pub fn show_warnings(&self, pkg: &PackageId) -> bool { - self.ws.current_opt().map_or(false, |p| *pkg == *p.package_id()) - || pkg.source_id().is_path() - || self.config.extra_verbose() + pkg.source_id().is_path() || self.config.extra_verbose() } } From 830b8af425ed83e7d94d561ea8ad9fcb184c3cb7 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Fri, 2 Dec 2016 15:28:40 -0500 Subject: [PATCH 09/11] remove unused argument to `Context::lib_profile` --- src/cargo/ops/cargo_rustc/context.rs | 14 +++++++------- src/cargo/ops/cargo_rustc/custom_build.rs | 2 +- src/cargo/ops/cargo_rustc/job_queue.rs | 4 +--- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/cargo/ops/cargo_rustc/context.rs b/src/cargo/ops/cargo_rustc/context.rs index 09977ca300d..b1690755f96 100644 --- a/src/cargo/ops/cargo_rustc/context.rs +++ b/src/cargo/ops/cargo_rustc/context.rs @@ -597,7 +597,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> { Ok(Unit { pkg: pkg, target: t, - profile: self.lib_profile(id), + profile: self.lib_profile(), kind: unit.kind.for_target(t), }) }) @@ -630,7 +630,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> { Unit { pkg: unit.pkg, target: t, - profile: self.lib_profile(id), + profile: self.lib_profile(), kind: unit.kind.for_target(t), } })); @@ -707,7 +707,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> { ret.push(Unit { pkg: dep, target: lib, - profile: self.lib_profile(dep.package_id()), + profile: self.lib_profile(), kind: unit.kind.for_target(lib), }); if self.build_config.doc_all { @@ -753,7 +753,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> { Unit { pkg: unit.pkg, target: t, - profile: self.lib_profile(unit.pkg.package_id()), + profile: self.lib_profile(), kind: unit.kind.for_target(t), } }) @@ -808,7 +808,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> { /// Number of jobs specified for this build pub fn jobs(&self) -> u32 { self.build_config.jobs } - pub fn lib_profile(&self, _pkg: &PackageId) -> &'a Profile { + pub fn lib_profile(&self) -> &'a Profile { let (normal, test) = if self.build_config.release { (&self.profiles.release, &self.profiles.bench_deps) } else { @@ -821,10 +821,10 @@ impl<'a, 'cfg> Context<'a, 'cfg> { } } - pub fn build_script_profile(&self, pkg: &PackageId) -> &'a Profile { + pub fn build_script_profile(&self, _pkg: &PackageId) -> &'a Profile { // TODO: should build scripts always be built with the same library // profile? How is this controlled at the CLI layer? - self.lib_profile(pkg) + self.lib_profile() } pub fn rustflags_args(&self, unit: &Unit) -> CargoResult> { diff --git a/src/cargo/ops/cargo_rustc/custom_build.rs b/src/cargo/ops/cargo_rustc/custom_build.rs index e412b846ed9..5c697e92836 100644 --- a/src/cargo/ops/cargo_rustc/custom_build.rs +++ b/src/cargo/ops/cargo_rustc/custom_build.rs @@ -97,7 +97,7 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) // environment variables. Note that the profile-related environment // variables are not set with this the build script's profile but rather the // package's library profile. - let profile = cx.lib_profile(unit.pkg.package_id()); + let profile = cx.lib_profile(); let to_exec = to_exec.into_os_string(); let mut cmd = cx.compilation.host_process(to_exec, unit.pkg)?; cmd.env("OUT_DIR", &build_output) diff --git a/src/cargo/ops/cargo_rustc/job_queue.rs b/src/cargo/ops/cargo_rustc/job_queue.rs index 5e35a7e1030..f06a0bbebb6 100644 --- a/src/cargo/ops/cargo_rustc/job_queue.rs +++ b/src/cargo/ops/cargo_rustc/job_queue.rs @@ -198,9 +198,7 @@ impl<'a> JobQueue<'a> { } let build_type = if self.is_release { "release" } else { "debug" }; - let profile = cx.ws.current_opt().map_or_else(Profile::default, |p| { - cx.lib_profile(p.package_id()).to_owned() - }); + let profile = cx.lib_profile(); let mut opt_type = String::from(if profile.opt_level == "0" { "unoptimized" } else { "optimized" }); if profile.debuginfo { From 7ec9f8dbd6a435702ca65d736b4d25abe0a7777f Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Fri, 2 Dec 2016 16:03:42 -0500 Subject: [PATCH 10/11] fix formatting issues --- src/cargo/ops/cargo_compile.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 8a5ed55c723..e3b22f9d8e3 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -152,7 +152,7 @@ pub fn resolve_dependencies<'a>(ws: &Workspace<'a>, .map(Package::package_id) .map(PackageIdSpec::from_package_id) .collect() - }, + } Packages::Packages(packages) => { packages.iter().map(|p| PackageIdSpec::parse(&p)).collect::>>()? } @@ -189,11 +189,11 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>, let profiles = ws.profiles(); let resolve = resolve_dependencies(ws, - source, - features, - all_features, - no_default_features, - &spec)?; + source, + features, + all_features, + no_default_features, + &spec)?; let (spec, packages, resolve_with_overrides) = resolve; let mut pkgids = Vec::new(); From addbb7e5178d0575b6dc42436e56bbb8392f49be Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Thu, 8 Dec 2016 17:32:33 -0500 Subject: [PATCH 11/11] replace `current_opt` with membership check --- src/cargo/ops/cargo_rustc/context.rs | 3 +-- src/cargo/ops/cargo_rustc/mod.rs | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/cargo/ops/cargo_rustc/context.rs b/src/cargo/ops/cargo_rustc/context.rs index b1690755f96..e0759ad8104 100644 --- a/src/cargo/ops/cargo_rustc/context.rs +++ b/src/cargo/ops/cargo_rustc/context.rs @@ -449,8 +449,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> { // we don't want to link it up. if src_dir.ends_with("deps") { // Don't lift up library dependencies - if self.ws.current_opt().map_or(false, |p| unit.pkg.package_id() != p.package_id()) - && !unit.target.is_bin() { + if self.ws.members().find(|&p| p != unit.pkg).is_some() && !unit.target.is_bin() { None } else { Some(( diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index dff80e493a7..809437c644a 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -557,9 +557,7 @@ fn build_base_args(cx: &mut Context, let prefer_dynamic = (unit.target.for_host() && !unit.target.is_custom_build()) || (crate_types.contains(&"dylib") && - cx.ws.current_opt().map_or(false, |p| { - *p.package_id() != *unit.pkg.package_id() - })); + cx.ws.members().find(|&p| p != unit.pkg).is_some()); if prefer_dynamic { cmd.arg("-C").arg("prefer-dynamic"); }