Skip to content

Commit

Permalink
Auto merge of #3221 - euclio:test-all, r=alexcrichton
Browse files Browse the repository at this point in the history
Add `--all` flag to `cargo test`

Work towards #2878.

This flag allows a user to test all members of a workspace by using `cargo test --all`. The command is also supported when using a virtual workspace manifest.
  • Loading branch information
bors committed Dec 8, 2016
2 parents 333a798 + addbb7e commit fec03d3
Show file tree
Hide file tree
Showing 20 changed files with 260 additions and 77 deletions.
2 changes: 1 addition & 1 deletion src/bin/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
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,
Expand Down
2 changes: 1 addition & 1 deletion src/bin/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
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,
Expand Down
4 changes: 2 additions & 2 deletions src/bin/doc.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand Down Expand Up @@ -80,7 +80,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
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,
Expand Down
2 changes: 1 addition & 1 deletion src/bin/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
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, &[],
Expand Down
4 changes: 2 additions & 2 deletions src/bin/run.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand Down Expand Up @@ -81,7 +81,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
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() {
Expand Down
6 changes: 4 additions & 2 deletions src/bin/rustc.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand Down Expand Up @@ -95,14 +95,16 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
}
};

let spec = options.flag_package.map_or_else(Vec::new, |s| vec![s]);

let opts = CompileOptions {
config: config,
jobs: options.flag_jobs,
target: options.flag_target.as_ref().map(|t| &t[..]),
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,
Expand Down
6 changes: 4 additions & 2 deletions src/bin/rustdoc.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand Down Expand Up @@ -80,6 +80,8 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
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 {
Expand All @@ -89,7 +91,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
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,
Expand Down
19 changes: 15 additions & 4 deletions src/bin/test.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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 = "
Expand All @@ -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
Expand All @@ -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.
Expand Down Expand Up @@ -111,6 +116,12 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
&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,
Expand All @@ -122,7 +133,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
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,
Expand All @@ -139,7 +150,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
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),
})
}
}
Expand Down
11 changes: 5 additions & 6 deletions src/cargo/core/resolver/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,10 +283,10 @@ 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 {
if self.use_root_key && root.unwrap() == id {
return None
}

Expand All @@ -307,10 +307,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),
Expand Down
68 changes: 42 additions & 26 deletions src/cargo/ops/cargo_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,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>,
Expand Down Expand Up @@ -79,6 +79,12 @@ pub enum MessageFormat {
Json
}

#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Packages<'a> {
All,
Packages(&'a [String]),
}

pub enum CompileFilter<'a> {
Everything,
Only {
Expand All @@ -92,8 +98,10 @@ pub enum CompileFilter<'a> {

pub fn compile<'a>(ws: &Workspace<'a>, options: &CompileOptions<'a>)
-> CargoResult<ops::Compilation<'a>> {
for key in ws.current()?.manifest().warnings().iter() {
options.config.shell().warn(key)?
for member in ws.members() {
for key in member.manifest().warnings().iter() {
options.config.shell().warn(key)?
}
}
compile_ws(ws, None, options)
}
Expand All @@ -103,17 +111,18 @@ 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<PackageIdSpec>, PackageSet<'a>, Resolve)> {
let features = features.iter().flat_map(|s| {
s.split_whitespace()
}).map(|s| s.to_string()).collect::<Vec<String>>();

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
Expand All @@ -137,22 +146,33 @@ 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::<CargoResult<Vec<_>>>()?
}
};

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>,
source: Option<Box<Source + 'a>>,
options: &CompileOptions<'a>)
-> CargoResult<ops::Compilation<'a>> {
let root_package = ws.current()?;
let CompileOptions { config, jobs, target, spec, features,
all_features, no_default_features,
release, mode, message_format,
Expand All @@ -167,27 +187,23 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>,
}

let profiles = ws.profiles();
if spec.len() == 0 {
generate_targets(root_package, profiles, mode, filter, release)?;
}

let specs = spec.iter().map(|p| PackageIdSpec::parse(p))
.collect::<CargoResult<Vec<_>>>()?;

let pair = resolve_dependencies(ws,
source,
features,
all_features,
no_default_features,
&specs)?;
let (packages, resolve_with_overrides) = pair;
let resolve = resolve_dependencies(ws,
source,
features,
all_features,
no_default_features,
&spec)?;
let (spec, packages, resolve_with_overrides) = resolve;

let mut pkgids = Vec::new();
if spec.len() > 0 {
for p in spec {
pkgids.push(resolve_with_overrides.query(&p)?);
for p in spec.iter() {
pkgids.push(p.query(resolve_with_overrides.iter())?);
}
} else {
let root_package = ws.current()?;
generate_targets(root_package, profiles, mode, filter, release)?;
pkgids.push(root_package.package_id());
};

Expand Down
17 changes: 13 additions & 4 deletions src/cargo/ops/cargo_doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
Expand All @@ -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 {
Expand Down
Loading

0 comments on commit fec03d3

Please sign in to comment.