More housekeeping and making it work that bit better

This commit is contained in:
datdenkikniet 2023-04-15 13:18:18 +02:00
parent cefb622cf8
commit df69b35c25
4 changed files with 223 additions and 22 deletions

View file

@ -209,7 +209,8 @@ pub enum Commands {
FormatCheck(PackageOpt), FormatCheck(PackageOpt),
/// Format code /// Format code
Format(PackageOpt), #[clap(alias = "fmt")]
Format(FormatOpt),
/// Run clippy /// Run clippy
Clippy(PackageOpt), Clippy(PackageOpt),
@ -265,6 +266,15 @@ pub enum Commands {
Book(Arg), Book(Arg),
} }
#[derive(Args, Debug, Clone)]
pub struct FormatOpt {
#[clap(flatten)]
pub package: PackageOpt,
/// Only check formatting, without applying fixes.
#[clap(short, long, alias = "check-only")]
pub check: bool,
}
#[derive(Args, Debug, Clone)] #[derive(Args, Debug, Clone)]
/// Restrict to package, or run on whole workspace /// Restrict to package, or run on whole workspace
pub struct PackageOpt { pub struct PackageOpt {
@ -315,3 +325,13 @@ pub enum ExtraArguments {
#[command(external_subcommand)] #[command(external_subcommand)]
Other(Vec<String>), Other(Vec<String>),
} }
impl core::fmt::Display for ExtraArguments {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ExtraArguments::Other(args) => {
write!(f, "{}", args.join(" "))
}
}
}
}

View file

@ -60,18 +60,18 @@ fn handle_results(results: Vec<FinalRunResult>) -> anyhow::Result<()> {
if !stdout.is_empty() && !stderr.is_empty() { if !stdout.is_empty() && !stderr.is_empty() {
log::log!( log::log!(
level, level,
"Command output for {command}\nStdout:\n{stdout}\nStderr:\n{stderr}" "Output for \"{command}\"\nStdout:\n{stdout}\nStderr:\n{stderr}"
); );
} else if !stdout.is_empty() { } else if !stdout.is_empty() {
log::log!( log::log!(
level, level,
"Command output for {command}\nStdout:\n{}", "Output for \"{command}\":\nStdout:\n{}",
stdout.trim_end() stdout.trim_end()
); );
} else if !stderr.is_empty() { } else if !stderr.is_empty() {
log::log!( log::log!(
level, level,
"Command output for {command}\nStderr:\n{}", "Output for \"{command}\"\nStderr:\n{}",
stderr.trim_end() stderr.trim_end()
); );
} }
@ -82,15 +82,16 @@ fn handle_results(results: Vec<FinalRunResult>) -> anyhow::Result<()> {
errors.clone().for_each(log_stdout_stderr(Level::Error)); errors.clone().for_each(log_stdout_stderr(Level::Error));
successes.for_each(|(cmd, _)| { successes.for_each(|(cmd, _)| {
info!("Succesfully executed {cmd}"); info!("Success: {cmd}");
}); });
errors.clone().for_each(|(cmd, _)| { errors.clone().for_each(|(cmd, _)| {
error!("Command {cmd} failed"); error!("Failed: {cmd}");
}); });
if errors.count() != 0 { let ecount = errors.count();
Err(anyhow::anyhow!("Some commands failed.")) if ecount != 0 {
Err(anyhow::anyhow!("{ecount} commands failed."))
} else { } else {
Ok(()) Ok(())
} }
@ -153,15 +154,6 @@ pub fn cargo(
let features = package.extract_features(target, backend); let features = package.extract_features(target, backend);
match operation {
BuildOrCheck::Check => {
log::debug!(target: "xtask::command", "Checking package: {package}")
}
BuildOrCheck::Build => {
log::debug!(target: "xtask::command", "Building package: {package}")
}
}
let command = match operation { let command = match operation {
BuildOrCheck::Check => CargoCommand::Check { BuildOrCheck::Check => CargoCommand::Check {
cargoarg, cargoarg,

View file

@ -110,9 +110,193 @@ pub enum CargoCommand<'a> {
impl core::fmt::Display for CargoCommand<'_> { impl core::fmt::Display for CargoCommand<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let executable = self.executable(); let p = |p: &Option<Package>| {
let args = self.args().join(" "); if let Some(package) = p {
write!(f, "\"{executable} {args}\"") format!("package {package}")
} else {
format!("default package")
}
};
let feat = |f: &Option<String>| {
if let Some(features) = f {
format!("\"{features}\"")
} else {
format!("no features")
}
};
let carg = |f: &&Option<&str>| {
if let Some(cargoarg) = f {
format!("{cargoarg}")
} else {
format!("no cargo args")
}
};
let details = |target: &Target,
mode: &BuildMode,
features: &Option<String>,
cargoarg: &&Option<&str>| {
let feat = feat(features);
let carg = carg(cargoarg);
if cargoarg.is_some() {
format!("({target}, {mode}, {feat}, {carg})")
} else {
format!("({target}, {mode}, {feat})")
}
};
match self {
CargoCommand::Run {
cargoarg,
example,
target,
features,
mode,
} => write!(
f,
"Run example {example} {}",
details(target, mode, features, cargoarg)
),
CargoCommand::Qemu {
cargoarg,
example,
target,
features,
mode,
} => write!(
f,
"Run example {example} in QEMU {}",
details(target, mode, features, cargoarg)
),
CargoCommand::ExampleBuild {
cargoarg,
example,
target,
features,
mode,
} => write!(
f,
"Build example {example} {}",
details(target, mode, features, cargoarg)
),
CargoCommand::ExampleCheck {
cargoarg,
example,
target,
features,
mode,
} => write!(
f,
"Check example {example} {}",
details(target, mode, features, cargoarg)
),
CargoCommand::Build {
cargoarg,
package,
target,
features,
mode,
} => {
let package = p(package);
write!(
f,
"Build {package} {}",
details(target, mode, features, cargoarg)
)
}
CargoCommand::Check {
cargoarg,
package,
target,
features,
mode,
} => {
let package = p(package);
write!(
f,
"Check {package} {}",
details(target, mode, features, cargoarg)
)
}
CargoCommand::Clippy {
cargoarg,
package,
target,
features,
} => {
let package = p(package);
let features = feat(features);
let carg = carg(cargoarg);
write!(f, "Clippy {package} ({target}, {features}, {carg})")
}
CargoCommand::Format {
cargoarg,
package,
check_only,
} => {
let package = p(package);
let carg = carg(cargoarg);
let carg = if cargoarg.is_some() {
format!("(cargo args: {carg})")
} else {
format!("")
};
if *check_only {
write!(f, "Check format for {package} {carg}")
} else {
write!(f, "Format {package} {carg}")
}
}
CargoCommand::Doc {
cargoarg,
features,
arguments,
} => {
let feat = feat(features);
let carg = carg(cargoarg);
let arguments = arguments
.clone()
.map(|a| format!("{a}"))
.unwrap_or_else(|| "No extra arguments".into());
if cargoarg.is_some() {
write!(f, "Document ({feat}, {carg}, {arguments}")
} else {
write!(f, "Document ({feat}, {arguments}")
}
}
CargoCommand::Test {
package,
features,
test,
} => {
let p = p(package);
let test = test
.clone()
.map(|t| format!("test {t}"))
.unwrap_or("all tests".into());
let feat = feat(features);
write!(f, "Run {test} in {p} ({feat})")
}
CargoCommand::Book { arguments: _ } => write!(f, "Build the book"),
CargoCommand::ExampleSize {
cargoarg,
example,
target,
features,
mode,
arguments: _,
} => {
write!(
f,
"Compute size of example {example} {}",
details(target, mode, features, cargoarg)
)
}
}
} }
} }

View file

@ -56,6 +56,12 @@ impl<'a> Target<'a> {
} }
} }
impl core::fmt::Display for Target<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.triple)
}
}
// x86_64-unknown-linux-gnu // x86_64-unknown-linux-gnu
const _X86_64: Target = Target::new("x86_64-unknown-linux-gnu", true); const _X86_64: Target = Target::new("x86_64-unknown-linux-gnu", true);
const ARMV6M: Target = Target::new("thumbv6m-none-eabi", false); const ARMV6M: Target = Target::new("thumbv6m-none-eabi", false);
@ -219,8 +225,7 @@ fn main() -> anyhow::Result<()> {
} }
Commands::Format(args) => { Commands::Format(args) => {
info!("Running cargo fmt: {args:?}"); info!("Running cargo fmt: {args:?}");
let check_only = false; cargo_format(globals, &cargologlevel, &args.package, args.check)?;
cargo_format(globals, &cargologlevel, &args, check_only)?;
} }
Commands::Clippy(args) => { Commands::Clippy(args) => {
info!("Running clippy on backend: {backend:?}"); info!("Running clippy on backend: {backend:?}");