mod private
{
use crate :: *;
use entity ::test :: { TestPlan, TestOptions, TestsReport, tests_run };
use collection_tools ::collection ::HashSet;
use std :: { env, fs };
use former ::Former;
use error ::
{
untyped ::
{
Error,
format_err
},
};
use iter_tools ::iter ::Itertools;
#[ derive( Debug, Former ) ]
#[ allow( clippy ::struct_excessive_bools ) ]
pub struct TestsCommandOptions
{
dir: AbsolutePath,
channels: HashSet< channel ::Channel >,
#[ former( default = 0u32 ) ]
concurrent: u32,
#[ former( default = 1u32 ) ]
power: u32,
include_features: Vec< String >,
#[ former( default = [ "full".to_string(), "default".to_string() ] ) ]
exclude_features: Vec< String >,
#[ former( default = true ) ]
temp: bool,
enabled_features: Vec< String >,
#[ former( default = true ) ]
with_all_features: bool,
#[ former( default = true ) ]
with_none_features: bool,
optimizations: HashSet< optimization ::Optimization >,
#[ former( default = 1000u32 ) ]
variants_cap: u32,
#[ cfg( feature = "progress_bar" ) ]
#[ former( default = false ) ]
with_progress: bool,
}
#[ allow( clippy ::too_many_lines ) ]
pub fn test( o: TestsCommandOptions, dry: bool )
-> ResultWithReport< TestsReport, Error >
{
let mut report = TestsReport ::default();
let channels = channel ::available_channels( o.dir.as_ref() )
.err_with_report( &report )?;
let channels_diff: Vec< _ > = o.channels.difference( &channels ).collect();
if !channels_diff.is_empty()
{
return Err
(
(
report,
format_err!
(
"Missing toolchain(-s) that was required: [{}]. \
Try to install it with `rustup install {}` command(-s)",
channels_diff.iter().join( ", " ),
channels_diff.iter().join( " " )
)
)
)
}
report.dry = dry;
let TestsCommandOptions
{
dir: _ ,
channels,
concurrent,
power,
include_features,
exclude_features,
temp,
enabled_features,
with_all_features,
with_none_features,
optimizations,
variants_cap,
#[ cfg( feature = "progress_bar" ) ]
with_progress,
} = o;
#[ cfg( not( feature = "progress_bar" ) ) ]
#[ allow( unused_variables ) ]
let with_progress = false;
let path = match EitherDirOrFile ::try_from( o.dir.as_ref() ).map_err( | e | ( report.clone(), e.into() ) )?.inner()
{
data_type ::Either ::Left( crate_dir ) => crate_dir,
data_type ::Either ::Right( manifest ) => CrateDir ::from( manifest )
};
#[ allow( clippy ::useless_conversion ) ]
let workspace = Workspace
::try_from( CrateDir ::try_from( path.clone() ).err_with_report( &report )? )
.err_with_report( &report )?
;
let packages = workspace
.packages()
.filter
(
move | p |
p
.manifest_file()
.is_ok() &&
p.
manifest_file()
.unwrap()
.starts_with( path.as_ref() )
)
;
let plan = TestPlan ::try_from
(
packages,
&channels,
power,
include_features,
exclude_features,
&optimizations,
enabled_features,
with_all_features,
with_none_features,
variants_cap,
).err_with_report( &report )?;
println!( "{plan}" );
let temp_path = if temp
{
let mut unique_name = format!
(
"temp_dir_for_test_command_{}",
path ::unique_folder_name().err_with_report( &report )?
);
let mut temp_dir = env ::temp_dir().join( unique_name );
while temp_dir.exists()
{
unique_name = format!
(
"temp_dir_for_test_command_{}",
path ::unique_folder_name().err_with_report( &report )?
);
temp_dir = env ::temp_dir().join( unique_name );
}
fs ::create_dir( &temp_dir ).err_with_report( &report )?;
Some( temp_dir )
}
else
{
None
};
let test_options_former = TestOptions ::former()
.concurrent( concurrent )
.plan( plan )
.option_temp( temp_path )
.dry( dry );
#[ cfg( feature = "progress_bar" ) ]
let test_options_former = test_options_former.with_progress( with_progress );
let options = test_options_former.form();
let result = tests_run( &options );
if temp
{
fs ::remove_dir_all( options.temp_path.unwrap() ).err_with_report( &report )?;
}
result.map_err( | ( report, e) | ( report, e.into() ) )
}
}
crate ::mod_interface!
{
orphan use test;
own use TestsCommandOptions;
}