Add support for "feature mixer"

This commit is contained in:
datdenkikniet 2023-04-15 14:28:24 +02:00
parent 622a58db5a
commit feb00a9755
2 changed files with 104 additions and 39 deletions

View file

@ -46,11 +46,45 @@ impl Package {
/// Without package specified the features for RTIC are required
/// With only a single package which is not RTIC, no special
/// features are needed
pub fn extract_features(&self, target: Target, backend: Backends) -> Option<String> {
pub fn features(
&self,
target: Target,
backend: Backends,
partial: bool,
) -> Vec<Option<String>> {
match self {
Package::Rtic => Some(target.and_features(backend.to_rtic_feature())),
Package::RticMacros => Some(backend.to_rtic_macros_feature().to_owned()),
_ => None,
Package::Rtic => vec![Some(target.and_features(backend.to_rtic_feature()))],
Package::RticMacros => {
vec![Some(backend.to_rtic_macros_feature().to_string())]
}
Package::RticMonotonics => {
let features = if partial {
&["cortex-m-systick", "rp2040", "nrf52840"][..]
} else {
&[
"cortex-m-systick",
"cortex-m-systick,systick-100hz",
"cortex-m-systick,systick-10khz",
"rp2040",
"nrf52810",
"nrf52811",
"nrf52832",
"nrf52833",
"nrf52840",
"nrf5340-app",
"nrf5340-net",
"nrf9160",
][..]
};
features
.into_iter()
.map(ToString::to_string)
.map(Some)
.chain(std::iter::once(None))
.collect()
}
_ => vec![None],
}
}
}
@ -189,6 +223,11 @@ pub struct Globals {
/// clutter, but can make debugging long-running processes a lot easier.
#[arg(short, long, global = true)]
pub stderr_inherited: bool,
/// Don't build/check/test all feature combinations that are available, only
/// a necessary subset.
#[arg(long, global = true)]
pub partial: bool,
}
#[derive(Parser)]

View file

@ -86,29 +86,42 @@ pub fn cargo<'c>(
package: &'c PackageOpt,
backend: Backends,
) -> Vec<FinalRunResult<'c>> {
let runner = package.packages().map(move |package| {
let target = backend.to_target();
let features = package.extract_features(target, backend);
let runner = package
.packages()
.flat_map(|package| {
let target = backend.to_target();
let features = package.features(target, backend, globals.partial);
let command = match operation {
BuildOrCheck::Check => CargoCommand::Check {
cargoarg,
package: Some(package),
target,
features,
mode: BuildMode::Release,
},
BuildOrCheck::Build => CargoCommand::Build {
cargoarg,
package: Some(package),
target,
features,
mode: BuildMode::Release,
},
};
#[cfg(feature = "rayon")]
{
features.into_par_iter().map(move |f| (package, target, f))
}
(globals, command, false)
});
#[cfg(not(feature = "rayon"))]
{
features.into_iter().map(move |f| (package, target, f))
}
})
.map(move |(package, target, features)| {
let command = match operation {
BuildOrCheck::Check => CargoCommand::Check {
cargoarg,
package: Some(package),
target,
features,
mode: BuildMode::Release,
},
BuildOrCheck::Build => CargoCommand::Build {
cargoarg,
package: Some(package),
target,
features,
mode: BuildMode::Release,
},
};
(globals, command, false)
});
runner.run_and_coalesce()
}
@ -154,21 +167,34 @@ pub fn cargo_clippy<'c>(
package: &'c PackageOpt,
backend: Backends,
) -> Vec<FinalRunResult<'c>> {
let runner = package.packages().map(|p| {
let target = backend.to_target();
let features = p.extract_features(target, backend);
let runner = package
.packages()
.flat_map(|package| {
let target = backend.to_target();
let features = package.features(target, backend, globals.partial);
(
globals,
CargoCommand::Clippy {
cargoarg,
package: Some(p),
target,
features,
},
false,
)
});
#[cfg(feature = "rayon")]
{
features.into_par_iter().map(move |f| (package, target, f))
}
#[cfg(not(feature = "rayon"))]
{
features.into_iter().map(move |f| (package, target, f))
}
})
.map(move |(package, target, features)| {
(
globals,
CargoCommand::Clippy {
cargoarg,
package: Some(package),
target,
features,
},
false,
)
});
runner.run_and_coalesce()
}