aboutsummaryrefslogtreecommitdiff
path: root/xtask
diff options
context:
space:
mode:
authordatdenkikniet <jcdra1@gmail.com>2023-04-15 00:26:16 +0200
committerdatdenkikniet <jcdra1@gmail.com>2023-04-15 01:08:28 +0200
commit18522122f1238d7200a9c4bcc696e707385bcbb1 (patch)
treeff2ea1a90c9098b43fd477c24725383707d19a2e /xtask
parentfa92d8abe7810c8a32a37be49f162b795c226f4d (diff)
xtask: forward globals through the chain and add stderr-inheritance flag
Diffstat (limited to 'xtask')
-rw-r--r--xtask/src/argument_parsing.rs30
-rw-r--r--xtask/src/cargo_commands.rs39
-rw-r--r--xtask/src/command.rs19
-rw-r--r--xtask/src/main.rs54
4 files changed, 103 insertions, 39 deletions
diff --git a/xtask/src/argument_parsing.rs b/xtask/src/argument_parsing.rs
index c0538e2..eda0a89 100644
--- a/xtask/src/argument_parsing.rs
+++ b/xtask/src/argument_parsing.rs
@@ -130,10 +130,8 @@ pub enum BuildOrCheck {
Build,
}
-#[derive(Parser)]
-#[command(author, version, about, long_about = None)]
-/// RTIC xtask powered testing toolbox
-pub struct Cli {
+#[derive(Parser, Clone)]
+pub struct Globals {
/// For which backend to build (defaults to thumbv7)
#[arg(value_enum, short, long)]
pub backend: Option<Backends>,
@@ -160,12 +158,28 @@ pub struct Cli {
#[arg(short, long, action = clap::ArgAction::Count)]
pub verbose: u8,
+ /// Enable `stderr` inheritance on child processes.
+ ///
+ /// If this flag is enabled, the output of `stderr` produced by child
+ /// processes is printed directly to `stderr`. This will cause a lot of
+ /// clutter, but can make debugging long-running processes a lot easier.
+ #[arg(short, long)]
+ pub stderr_inherited: bool,
+}
+
+#[derive(Parser)]
+#[command(author, version, about, long_about = None)]
+/// RTIC xtask powered testing toolbox
+pub struct Cli {
+ #[clap(flatten)]
+ pub globals: Globals,
+
/// Subcommand selecting operation
#[command(subcommand)]
pub command: Commands,
}
-#[derive(Debug, Subcommand)]
+#[derive(Debug, Clone, Subcommand)]
pub enum Commands {
/// Check formatting
FormatCheck(PackageOpt),
@@ -227,7 +241,7 @@ pub enum Commands {
Book(Arg),
}
-#[derive(Args, Debug)]
+#[derive(Args, Debug, Clone)]
/// Restrict to package, or run on whole workspace
pub struct PackageOpt {
/// For which package/workspace member to operate
@@ -236,7 +250,7 @@ pub struct PackageOpt {
pub package: Option<Package>,
}
-#[derive(Args, Debug)]
+#[derive(Args, Debug, Clone)]
pub struct QemuAndRun {
/// If expected output is missing or mismatching, recreate the file
///
@@ -245,7 +259,7 @@ pub struct QemuAndRun {
pub overwrite_expected: bool,
}
-#[derive(Debug, Parser)]
+#[derive(Debug, Parser, Clone)]
pub struct Arg {
/// Options to pass to `cargo size`
#[command(subcommand)]
diff --git a/xtask/src/cargo_commands.rs b/xtask/src/cargo_commands.rs
index 7ac7aea..90a8037 100644
--- a/xtask/src/cargo_commands.rs
+++ b/xtask/src/cargo_commands.rs
@@ -1,5 +1,7 @@
use crate::{
- argument_parsing::{Backends, BuildOrCheck, ExtraArguments, Package, PackageOpt, TestMetadata},
+ argument_parsing::{
+ Backends, BuildOrCheck, ExtraArguments, Globals, Package, PackageOpt, TestMetadata,
+ },
command::{BuildMode, CargoCommand},
command_parser, package_feature_extractor, DEFAULT_FEATURES,
};
@@ -8,6 +10,7 @@ use rayon::prelude::*;
/// Cargo command to either build or check
pub fn cargo(
+ globals: &Globals,
operation: BuildOrCheck,
cargoarg: &Option<&str>,
package: &PackageOpt,
@@ -31,7 +34,7 @@ pub fn cargo(
mode: BuildMode::Release,
},
};
- command_parser(&command, false)?;
+ command_parser(globals, &command, false)?;
Ok(())
}
@@ -39,6 +42,7 @@ pub fn cargo(
///
/// The examples are in rtic/examples
pub fn cargo_example(
+ globals: &Globals,
operation: BuildOrCheck,
cargoarg: &Option<&str>,
backend: Backends,
@@ -68,7 +72,7 @@ pub fn cargo_example(
},
};
- if let Err(err) = command_parser(&command, false) {
+ if let Err(err) = command_parser(globals, &command, false) {
error!("{err}");
}
});
@@ -78,12 +82,14 @@ pub fn cargo_example(
/// Run cargo clippy on selected package
pub fn cargo_clippy(
+ globals: &Globals,
cargoarg: &Option<&str>,
package: &PackageOpt,
backend: Backends,
) -> anyhow::Result<()> {
let features = package_feature_extractor(package, backend);
command_parser(
+ globals,
&CargoCommand::Clippy {
cargoarg,
package: package.package,
@@ -97,11 +103,13 @@ pub fn cargo_clippy(
/// Run cargo fmt on selected package
pub fn cargo_format(
+ globals: &Globals,
cargoarg: &Option<&str>,
package: &PackageOpt,
check_only: bool,
) -> anyhow::Result<()> {
command_parser(
+ globals,
&CargoCommand::Format {
cargoarg,
package: package.package,
@@ -114,6 +122,7 @@ pub fn cargo_format(
/// Run cargo doc
pub fn cargo_doc(
+ globals: &Globals,
cargoarg: &Option<&str>,
backend: Backends,
arguments: &Option<ExtraArguments>,
@@ -125,6 +134,7 @@ pub fn cargo_doc(
));
command_parser(
+ globals,
&CargoCommand::Doc {
cargoarg,
features,
@@ -138,10 +148,14 @@ pub fn cargo_doc(
/// Run cargo test on the selcted package or all packages
///
/// If no package is specified, loop through all packages
-pub fn cargo_test(package: &PackageOpt, backend: Backends) -> anyhow::Result<()> {
+pub fn cargo_test(
+ globals: &Globals,
+ package: &PackageOpt,
+ backend: Backends,
+) -> anyhow::Result<()> {
if let Some(package) = package.package {
let cmd = TestMetadata::match_package(package, backend);
- command_parser(&cmd, false)?;
+ command_parser(globals, &cmd, false)?;
} else {
// Iterate over all workspace packages
for package in [
@@ -154,7 +168,7 @@ pub fn cargo_test(package: &PackageOpt, backend: Backends) -> anyhow::Result<()>
] {
let mut error_messages = vec![];
let cmd = &TestMetadata::match_package(package, backend);
- if let Err(err) = command_parser(cmd, false) {
+ if let Err(err) = command_parser(globals, cmd, false) {
error_messages.push(err);
}
@@ -169,8 +183,9 @@ pub fn cargo_test(package: &PackageOpt, backend: Backends) -> anyhow::Result<()>
}
/// Use mdbook to build the book
-pub fn cargo_book(arguments: &Option<ExtraArguments>) -> anyhow::Result<()> {
+pub fn cargo_book(globals: &Globals, arguments: &Option<ExtraArguments>) -> anyhow::Result<()> {
command_parser(
+ globals,
&CargoCommand::Book {
arguments: arguments.clone(),
},
@@ -183,6 +198,7 @@ pub fn cargo_book(arguments: &Option<ExtraArguments>) -> anyhow::Result<()> {
///
/// Supports updating the expected output via the overwrite argument
pub fn run_test(
+ globals: &Globals,
cargoarg: &Option<&str>,
backend: Backends,
examples: &[String],
@@ -200,7 +216,7 @@ pub fn run_test(
)),
mode: BuildMode::Release,
};
- if let Err(err) = command_parser(&cmd, false) {
+ if let Err(err) = command_parser(globals, &cmd, false) {
error!("{err}");
}
@@ -216,7 +232,7 @@ pub fn run_test(
mode: BuildMode::Release,
};
- if let Err(err) = command_parser(&cmd, overwrite) {
+ if let Err(err) = command_parser(globals, &cmd, overwrite) {
error!("{err}");
}
});
@@ -226,6 +242,7 @@ pub fn run_test(
/// Check the binary sizes of examples
pub fn build_and_check_size(
+ globals: &Globals,
cargoarg: &Option<&str>,
backend: Backends,
examples: &[String],
@@ -244,7 +261,7 @@ pub fn build_and_check_size(
)),
mode: BuildMode::Release,
};
- if let Err(err) = command_parser(&cmd, false) {
+ if let Err(err) = command_parser(globals, &cmd, false) {
error!("{err}");
}
@@ -260,7 +277,7 @@ pub fn build_and_check_size(
mode: BuildMode::Release,
arguments: arguments.clone(),
};
- if let Err(err) = command_parser(&cmd, false) {
+ if let Err(err) = command_parser(globals, &cmd, false) {
error!("{err}");
}
});
diff --git a/xtask/src/command.rs b/xtask/src/command.rs
index 8a2e99b..9fa5378 100644
--- a/xtask/src/command.rs
+++ b/xtask/src/command.rs
@@ -13,6 +13,21 @@ pub enum BuildMode {
Debug,
}
+#[derive(Debug, Clone, Copy, PartialEq)]
+pub enum OutputMode {
+ PipedAndCollected,
+ Inherited,
+}
+
+impl From<OutputMode> for Stdio {
+ fn from(value: OutputMode) -> Self {
+ match value {
+ OutputMode::PipedAndCollected => Stdio::piped(),
+ OutputMode::Inherited => Stdio::inherit(),
+ }
+ }
+}
+
#[derive(Debug)]
pub enum CargoCommand<'a> {
// For future embedded-ci
@@ -414,7 +429,7 @@ impl fmt::Display for BuildMode {
}
}
-pub fn run_command(command: &CargoCommand) -> anyhow::Result<RunResult> {
+pub fn run_command(command: &CargoCommand, stderr_mode: OutputMode) -> anyhow::Result<RunResult> {
let command_display = command.executable();
let args = command.args();
@@ -425,7 +440,7 @@ pub fn run_command(command: &CargoCommand) -> anyhow::Result<RunResult> {
let result = Command::new(command.executable())
.args(command.args())
.stdout(Stdio::piped())
- .stderr(Stdio::piped())
+ .stderr(stderr_mode)
.output()?;
let exit_status = result.status;
diff --git a/xtask/src/main.rs b/xtask/src/main.rs
index 30608b9..4cb38c2 100644
--- a/xtask/src/main.rs
+++ b/xtask/src/main.rs
@@ -4,8 +4,9 @@ mod cargo_commands;
mod command;
use anyhow::bail;
-use argument_parsing::{ExtraArguments, Package};
+use argument_parsing::{ExtraArguments, Globals, Package};
use clap::Parser;
+use command::OutputMode;
use core::fmt;
use diffy::{create_patch, PatchFormatter};
use std::{
@@ -109,7 +110,9 @@ fn main() -> anyhow::Result<()> {
let cli = Cli::parse();
- let env_logger_default_level = match cli.verbose {
+ let globals = &cli.globals;
+
+ let env_logger_default_level = match globals.verbose {
0 => Env::default().default_filter_or("info"),
1 => Env::default().default_filter_or("debug"),
_ => Env::default().default_filter_or("trace"),
@@ -119,16 +122,16 @@ fn main() -> anyhow::Result<()> {
.format_timestamp(None)
.init();
- trace!("default logging level: {0}", cli.verbose);
+ trace!("default logging level: {0}", globals.verbose);
- let backend = if let Some(backend) = cli.backend {
+ let backend = if let Some(backend) = globals.backend {
backend
} else {
Backends::default()
};
- let example = cli.example;
- let exampleexclude = cli.exampleexclude;
+ let example = globals.example.clone();
+ let exampleexclude = globals.exampleexclude.clone();
let examples_to_run = {
let mut examples_to_run = examples.clone();
@@ -190,28 +193,29 @@ fn main() -> anyhow::Result<()> {
Commands::FormatCheck(args) => {
info!("Running cargo fmt --check: {args:?}");
let check_only = true;
- cargo_format(&cargologlevel, &args, check_only)?;
+ cargo_format(globals, &cargologlevel, &args, check_only)?;
}
Commands::Format(args) => {
info!("Running cargo fmt: {args:?}");
let check_only = false;
- cargo_format(&cargologlevel, &args, check_only)?;
+ cargo_format(globals, &cargologlevel, &args, check_only)?;
}
Commands::Clippy(args) => {
info!("Running clippy on backend: {backend:?}");
- cargo_clippy(&cargologlevel, &args, backend)?;
+ cargo_clippy(globals, &cargologlevel, &args, backend)?;
}
Commands::Check(args) => {
info!("Checking on backend: {backend:?}");
- cargo(BuildOrCheck::Check, &cargologlevel, &args, backend)?;
+ cargo(globals, BuildOrCheck::Check, &cargologlevel, &args, backend)?;
}
Commands::Build(args) => {
info!("Building for backend: {backend:?}");
- cargo(BuildOrCheck::Build, &cargologlevel, &args, backend)?;
+ cargo(globals, BuildOrCheck::Build, &cargologlevel, &args, backend)?;
}
Commands::ExampleCheck => {
info!("Checking on backend: {backend:?}");
cargo_example(
+ globals,
BuildOrCheck::Check,
&cargologlevel,
backend,
@@ -221,6 +225,7 @@ fn main() -> anyhow::Result<()> {
Commands::ExampleBuild => {
info!("Building for backend: {backend:?}");
cargo_example(
+ globals,
BuildOrCheck::Build,
&cargologlevel,
backend,
@@ -230,12 +235,19 @@ fn main() -> anyhow::Result<()> {
Commands::Size(args) => {
// x86_64 target not valid
info!("Measuring for backend: {backend:?}");
- build_and_check_size(&cargologlevel, backend, &examples_to_run, &args.arguments)?;
+ build_and_check_size(
+ globals,
+ &cargologlevel,
+ backend,
+ &examples_to_run,
+ &args.arguments,
+ )?;
}
Commands::Qemu(args) | Commands::Run(args) => {
// x86_64 target not valid
info!("Testing for backend: {backend:?}");
run_test(
+ globals,
&cargologlevel,
backend,
&examples_to_run,
@@ -244,15 +256,15 @@ fn main() -> anyhow::Result<()> {
}
Commands::Doc(args) => {
info!("Running cargo doc on backend: {backend:?}");
- cargo_doc(&cargologlevel, backend, &args.arguments)?;
+ cargo_doc(globals, &cargologlevel, backend, &args.arguments)?;
}
Commands::Test(args) => {
info!("Running cargo test on backend: {backend:?}");
- cargo_test(&args, backend)?;
+ cargo_test(globals, &args, backend)?;
}
Commands::Book(args) => {
info!("Running mdbook");
- cargo_book(&args.arguments)?;
+ cargo_book(globals, &args.arguments)?;
}
}
@@ -283,7 +295,13 @@ fn package_feature_extractor(package: &PackageOpt, backend: Backends) -> Option<
}
// run example binary `example`
-fn command_parser(command: &CargoCommand, overwrite: bool) -> anyhow::Result<()> {
+fn command_parser(glob: &Globals, command: &CargoCommand, overwrite: bool) -> anyhow::Result<()> {
+ let output_mode = if glob.stderr_inherited {
+ OutputMode::Inherited
+ } else {
+ OutputMode::PipedAndCollected
+ };
+
match *command {
CargoCommand::Qemu { example, .. } | CargoCommand::Run { example, .. } => {
let run_file = format!("{example}.run");
@@ -296,7 +314,7 @@ fn command_parser(command: &CargoCommand, overwrite: bool) -> anyhow::Result<()>
// cargo run <..>
info!("Running example: {example}");
- let cargo_run_result = run_command(command)?;
+ let cargo_run_result = run_command(command, output_mode)?;
info!("{}", cargo_run_result.stdout);
// Create a file for the expected output if it does not exist or mismatches
@@ -329,7 +347,7 @@ fn command_parser(command: &CargoCommand, overwrite: bool) -> anyhow::Result<()>
| CargoCommand::Test { .. }
| CargoCommand::Book { .. }
| CargoCommand::ExampleSize { .. } => {
- let cargo_result = run_command(command)?;
+ let cargo_result = run_command(command, output_mode)?;
let command = cargo_result.full_command;
if let Some(exit_code) = cargo_result.exit_status.code() {
if exit_code != exitcode::OK {