Skip to content

Commit 3d382c8

Browse files
committed
refactor(runner): streamline target plan adapters
1 parent 15cf51e commit 3d382c8

2 files changed

Lines changed: 107 additions & 108 deletions

File tree

src/runner.rs

Lines changed: 98 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -529,11 +529,44 @@ pub struct MatrixOptions {
529529
pub no_prune_implied: bool,
530530
}
531531

532+
fn load_configs_for_packages(packages: &[&cargo_metadata::Package]) -> eyre::Result<Vec<Config>> {
533+
packages
534+
.iter()
535+
.map(|package| package.config())
536+
.collect::<eyre::Result<Vec<_>>>()
537+
}
538+
539+
fn single_target_plans<'a>(
540+
packages: &[&'a cargo_metadata::Package],
541+
configs: &'a [Config],
542+
target: &TargetTriple,
543+
) -> TargetPlans<'a> {
544+
let effective_target = EffectiveTarget {
545+
triple: target.clone(),
546+
source: TargetSource::Cli,
547+
};
548+
549+
TargetPlans {
550+
plans: vec![TargetPlan {
551+
target: target.clone(),
552+
packages: packages
553+
.iter()
554+
.zip(configs)
555+
.map(|(package, config)| PlannedPackage {
556+
package,
557+
config,
558+
target: effective_target.clone(),
559+
})
560+
.collect(),
561+
}],
562+
contains_configured_assignments: false,
563+
}
564+
}
565+
532566
/// Print a JSON feature matrix for the given packages to stdout.
533567
///
534-
/// The matrix is a JSON array of objects produced from each package's
535-
/// configuration and the feature combinations returned by
536-
/// [`Package::feature_matrix`].
568+
/// The matrix is a JSON array of objects produced from each package's resolved
569+
/// target-specific configuration and feature combinations.
537570
///
538571
/// # Errors
539572
///
@@ -545,56 +578,19 @@ pub fn print_feature_matrix_for_target(
545578
evaluator: &mut impl crate::cfg_eval::CfgEvaluator,
546579
options: &MatrixOptions,
547580
) -> eyre::Result<ExitCode> {
548-
let per_package_features = packages
549-
.iter()
550-
.map(|pkg| {
551-
let base_config = pkg.config()?;
552-
let config = crate::config::resolve::resolve_config(&base_config, target, evaluator)?;
553-
let features = if options.packages_only {
554-
vec!["default".to_string()]
555-
} else {
556-
let combos = pkg.feature_combinations(&config)?;
557-
let combos = crate::implication::maybe_prune(
558-
combos,
559-
&pkg.features,
560-
&config,
561-
options.no_prune_implied,
562-
);
563-
combos
564-
.keep
565-
.into_iter()
566-
.map(|combo| combo.into_iter().join(","))
567-
.collect()
568-
};
569-
Ok::<_, eyre::Report>((pkg.name.clone(), config, features))
570-
})
571-
.collect::<Result<Vec<_>, _>>()?;
572-
573-
let matrix: Vec<serde_json::Value> = per_package_features
574-
.into_iter()
575-
.flat_map(|(name, config, features)| {
576-
let target = target.as_str().to_string();
577-
features.into_iter().map(move |ft| {
578-
use serde_json_merge::{iter::dfs::Dfs, merge::Merge};
579-
580-
let mut out = serde_json::json!(config.matrix);
581-
out.merge::<Dfs>(&serde_json::json!({
582-
"name": name,
583-
"target": target,
584-
"features": ft,
585-
}));
586-
out
587-
})
588-
})
589-
.collect();
590-
591-
let matrix = if options.pretty {
592-
serde_json::to_string_pretty(&matrix)
593-
} else {
594-
serde_json::to_string(&matrix)
595-
}?;
596-
println!("{matrix}");
597-
Ok(None)
581+
let configs = load_configs_for_packages(packages)?;
582+
let target_plans = single_target_plans(packages, &configs, target);
583+
let build_options = Options {
584+
no_prune_implied: options.no_prune_implied,
585+
..Options::default()
586+
};
587+
let plan_set = build_execution_plans(
588+
&target_plans,
589+
&build_options,
590+
options.packages_only,
591+
evaluator,
592+
)?;
593+
print_matrix_for_execution_plans(&plan_set, options)
598594
}
599595

600596
/// A resolved, owned execution plan for one concrete target.
@@ -1023,30 +1019,8 @@ pub fn run_cargo_command_for_target(
10231019
target: &TargetTriple,
10241020
evaluator: &mut impl CfgEvaluator,
10251021
) -> eyre::Result<ExitCode> {
1026-
let configs: Vec<Config> = packages
1027-
.iter()
1028-
.map(|package| package.config())
1029-
.collect::<eyre::Result<Vec<_>>>()?;
1030-
1031-
let target_plans = TargetPlans {
1032-
plans: vec![TargetPlan {
1033-
target: target.clone(),
1034-
packages: packages
1035-
.iter()
1036-
.zip(&configs)
1037-
.map(|(package, config)| PlannedPackage {
1038-
package,
1039-
config,
1040-
target: EffectiveTarget {
1041-
triple: target.clone(),
1042-
source: TargetSource::Cli,
1043-
},
1044-
})
1045-
.collect(),
1046-
}],
1047-
contains_configured_assignments: false,
1048-
};
1049-
1022+
let configs = load_configs_for_packages(packages)?;
1023+
let target_plans = single_target_plans(packages, &configs, target);
10501024
let plan_set = build_execution_plans(&target_plans, options, false, evaluator)?;
10511025
run_execution_plans(
10521026
&plan_set,
@@ -1198,18 +1172,14 @@ fn execute_serial(
11981172
seen_diagnostics,
11991173
stdout,
12001174
)?;
1201-
let should_stop = ctx.options.fail_fast && !result.summary.pedantic_success;
1202-
let exit_code = result.summary.exit_code;
1203-
summary.push(result.summary);
1204-
if should_stop {
1205-
if ctx.options.summary_only {
1206-
io::copy(&mut io::Cursor::new(result.colored_output), stdout)?;
1207-
stdout.flush().ok();
1208-
}
1209-
let code =
1210-
print_summary(&summary, plan_set.show_pruned, stdout, start.elapsed())
1211-
.or(exit_code)
1212-
.unwrap_or(1);
1175+
if let Some(code) = record_result_and_maybe_stop(
1176+
&mut summary,
1177+
result,
1178+
plan_set.show_pruned,
1179+
ctx,
1180+
stdout,
1181+
start,
1182+
)? {
12131183
return Ok(Some(code));
12141184
}
12151185
}
@@ -1277,17 +1247,14 @@ fn execute_aggregate(
12771247
seen_diagnostics,
12781248
stdout,
12791249
)?;
1280-
let should_stop = ctx.options.fail_fast && !result.summary.pedantic_success;
1281-
let exit_code = result.summary.exit_code;
1282-
summary.push(result.summary);
1283-
if should_stop {
1284-
if ctx.options.summary_only {
1285-
io::copy(&mut io::Cursor::new(result.colored_output), stdout)?;
1286-
stdout.flush().ok();
1287-
}
1288-
let code = print_summary(&summary, plan_set.show_pruned, stdout, start.elapsed())
1289-
.or(exit_code)
1290-
.unwrap_or(1);
1250+
if let Some(code) = record_result_and_maybe_stop(
1251+
&mut summary,
1252+
result,
1253+
plan_set.show_pruned,
1254+
ctx,
1255+
stdout,
1256+
start,
1257+
)? {
12911258
return Ok(Some(code));
12921259
}
12931260
}
@@ -1300,6 +1267,37 @@ fn execute_aggregate(
13001267
))
13011268
}
13021269

1270+
fn record_result_and_maybe_stop(
1271+
summary: &mut Vec<Summary>,
1272+
result: CombinationResult,
1273+
show_pruned: bool,
1274+
ctx: &RunContext<'_>,
1275+
stdout: &mut StandardStream,
1276+
start: Instant,
1277+
) -> eyre::Result<ExitCode> {
1278+
let CombinationResult {
1279+
summary: result_summary,
1280+
colored_output,
1281+
} = result;
1282+
let should_stop = ctx.options.fail_fast && !result_summary.pedantic_success;
1283+
let exit_code = result_summary.exit_code;
1284+
summary.push(result_summary);
1285+
1286+
if !should_stop {
1287+
return Ok(None);
1288+
}
1289+
1290+
if ctx.options.summary_only {
1291+
io::copy(&mut io::Cursor::new(colored_output), stdout)?;
1292+
stdout.flush().ok();
1293+
}
1294+
Ok(Some(
1295+
print_summary(summary, show_pruned, stdout, start.elapsed())
1296+
.or(exit_code)
1297+
.unwrap_or(1),
1298+
))
1299+
}
1300+
13031301
/// Transpose per-target execution plans into aggregate-mode invocations.
13041302
///
13051303
/// The resulting order is package first-appearance order, sorted canonical combo

src/target_plan.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -232,12 +232,16 @@ pub fn build_target_plans<'a>(
232232
evaluator: &mut impl CfgEvaluator,
233233
) -> eyre::Result<TargetPlans<'a>> {
234234
let mut fallback_cache: Option<EffectiveTarget> = None;
235+
let workspace_targets = if cli_target.is_none() && capability_allowed {
236+
normalize_targets(&workspace_config.workspace_targets)?
237+
} else {
238+
Vec::new()
239+
};
235240

236241
let contains_configured_assignments = if cli_target.is_some() {
237242
true
238243
} else if capability_allowed {
239-
!workspace_config.workspace_targets.is_empty()
240-
|| selected.iter().any(|s| s.config.package_targets.is_some())
244+
!workspace_targets.is_empty() || selected.iter().any(|s| s.config.package_targets.is_some())
241245
} else {
242246
false
243247
};
@@ -264,7 +268,6 @@ pub fn build_target_plans<'a>(
264268
})
265269
.collect()
266270
} else if capability_allowed {
267-
let workspace_targets = normalize_targets(&workspace_config.workspace_targets)?;
268271
let mut out = Vec::with_capacity(selected.len());
269272
for s in selected {
270273
let targets = package_target_list(s, &workspace_targets, env, &mut fallback_cache)?;
@@ -295,11 +298,9 @@ pub fn build_target_plans<'a>(
295298
let mut order: Vec<TargetTriple> = Vec::new();
296299
let mut seen: HashSet<TargetTriple> = HashSet::new();
297300

298-
if cli_target.is_none() && capability_allowed {
299-
for triple in normalize_targets(&workspace_config.workspace_targets)? {
300-
if seen.insert(triple.clone()) {
301-
order.push(triple);
302-
}
301+
for triple in workspace_targets {
302+
if seen.insert(triple.clone()) {
303+
order.push(triple);
303304
}
304305
}
305306
for pt in &package_targets {

0 commit comments

Comments
 (0)