mirror of
https://github.com/rust-lang/cargo
synced 2024-10-14 03:32:39 +00:00
add --all
flag to cargo-test
This commit is contained in:
parent
25518da782
commit
62c0497912
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<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,
|
||||
|
|
|
@ -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, &[],
|
||||
|
|
|
@ -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<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() {
|
||||
|
|
|
@ -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<Option<()>> {
|
|||
}
|
||||
};
|
||||
|
||||
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<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),
|
||||
mode: mode,
|
||||
release: options.flag_release,
|
||||
filter: ops::CompileFilter::new(options.flag_lib,
|
||||
|
|
|
@ -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<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 {
|
||||
|
@ -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,
|
||||
|
|
|
@ -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<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,
|
||||
|
@ -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,
|
||||
|
@ -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),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<ops::Compilation<'a>> {
|
||||
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<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,
|
||||
|
@ -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());
|
||||
};
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<PackageId>,
|
||||
pub compilation: Compilation<'cfg>,
|
||||
pub packages: &'a PackageSet<'cfg>,
|
||||
pub build_state: Arc<BuildState>,
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
126
tests/test.rs
126
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
|
||||
|
||||
"));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue