Redo command building so that we don't repeat as much, and to

make it easier to add new ones
This commit is contained in:
datdenkikniet 2023-04-16 11:00:39 +02:00
parent 404867cdf9
commit b59bf686c1
3 changed files with 270 additions and 363 deletions

View file

@ -111,6 +111,7 @@ pub fn cargo<'c>(
} }
}) })
.map(move |(package, target, features)| { .map(move |(package, target, features)| {
let target = target.into();
let command = match operation { let command = match operation {
BuildOrCheck::Check => CargoCommand::Check { BuildOrCheck::Check => CargoCommand::Check {
cargoarg, cargoarg,
@ -118,6 +119,7 @@ pub fn cargo<'c>(
target, target,
features, features,
mode: BuildMode::Release, mode: BuildMode::Release,
dir: None,
}, },
BuildOrCheck::Build => CargoCommand::Build { BuildOrCheck::Build => CargoCommand::Build {
cargoarg, cargoarg,
@ -125,6 +127,7 @@ pub fn cargo<'c>(
target, target,
features, features,
mode: BuildMode::Release, mode: BuildMode::Release,
dir: None,
}, },
}; };
@ -147,13 +150,21 @@ pub fn cargo_usage_example(
let path = format!("examples/{example}"); let path = format!("examples/{example}");
let command = match operation { let command = match operation {
BuildOrCheck::Check => CargoCommand::CheckInDir { BuildOrCheck::Check => CargoCommand::Check {
cargoarg: &None,
mode: BuildMode::Release, mode: BuildMode::Release,
dir: path.into(), dir: Some(path.into()),
package: None,
target: None,
features: None,
}, },
BuildOrCheck::Build => CargoCommand::BuildInDir { BuildOrCheck::Build => CargoCommand::Build {
cargoarg: &None,
package: None,
target: None,
features: None,
mode: BuildMode::Release, mode: BuildMode::Release,
dir: path.into(), dir: Some(path.into()),
}, },
}; };
(globals, command, false) (globals, command, false)
@ -178,14 +189,14 @@ pub fn cargo_example<'c>(
BuildOrCheck::Check => CargoCommand::ExampleCheck { BuildOrCheck::Check => CargoCommand::ExampleCheck {
cargoarg, cargoarg,
example, example,
target: backend.to_target(), target: Some(backend.to_target()),
features, features,
mode: BuildMode::Release, mode: BuildMode::Release,
}, },
BuildOrCheck::Build => CargoCommand::ExampleBuild { BuildOrCheck::Build => CargoCommand::ExampleBuild {
cargoarg, cargoarg,
example, example,
target: backend.to_target(), target: Some(backend.to_target()),
features, features,
mode: BuildMode::Release, mode: BuildMode::Release,
dir: Some(PathBuf::from("./rtic")), dir: Some(PathBuf::from("./rtic")),
@ -220,16 +231,14 @@ pub fn cargo_clippy<'c>(
} }
}) })
.map(move |(package, target, features)| { .map(move |(package, target, features)| {
( let command = CargoCommand::Clippy {
globals,
CargoCommand::Clippy {
cargoarg, cargoarg,
package: Some(package.name()), package: Some(package.name()),
target, target: target.into(),
features, features,
}, };
false,
) (globals, command, false)
}); });
runner.run_and_coalesce() runner.run_and_coalesce()
@ -317,6 +326,7 @@ pub fn qemu_run_examples<'c>(
examples_iter(examples) examples_iter(examples)
.flat_map(|example| { .flat_map(|example| {
let target = target.into();
let cmd_build = CargoCommand::ExampleBuild { let cmd_build = CargoCommand::ExampleBuild {
cargoarg: &None, cargoarg: &None,
example, example,
@ -361,6 +371,8 @@ pub fn build_and_check_size<'c>(
let features = Some(target.and_features(backend.to_rtic_feature())); let features = Some(target.and_features(backend.to_rtic_feature()));
let runner = examples_iter(examples).map(|example| { let runner = examples_iter(examples).map(|example| {
let target = target.into();
// Make sure the requested example(s) are built // Make sure the requested example(s) are built
let cmd = CargoCommand::ExampleBuild { let cmd = CargoCommand::ExampleBuild {
cargoarg: &Some("--quiet"), cargoarg: &Some("--quiet"),
@ -377,7 +389,7 @@ pub fn build_and_check_size<'c>(
let cmd = CargoCommand::ExampleSize { let cmd = CargoCommand::ExampleSize {
cargoarg, cargoarg,
example, example,
target: backend.to_target(), target,
features: features.clone(), features: features.clone(),
mode: BuildMode::Release, mode: BuildMode::Release,
arguments: arguments.clone(), arguments: arguments.clone(),

View file

@ -41,14 +41,15 @@ pub enum CargoCommand<'a> {
Run { Run {
cargoarg: &'a Option<&'a str>, cargoarg: &'a Option<&'a str>,
example: &'a str, example: &'a str,
target: Target<'a>, target: Option<Target<'a>>,
features: Option<String>, features: Option<String>,
mode: BuildMode, mode: BuildMode,
dir: Option<PathBuf>,
}, },
Qemu { Qemu {
cargoarg: &'a Option<&'a str>, cargoarg: &'a Option<&'a str>,
example: &'a str, example: &'a str,
target: Target<'a>, target: Option<Target<'a>>,
features: Option<String>, features: Option<String>,
mode: BuildMode, mode: BuildMode,
dir: Option<PathBuf>, dir: Option<PathBuf>,
@ -56,7 +57,7 @@ pub enum CargoCommand<'a> {
ExampleBuild { ExampleBuild {
cargoarg: &'a Option<&'a str>, cargoarg: &'a Option<&'a str>,
example: &'a str, example: &'a str,
target: Target<'a>, target: Option<Target<'a>>,
features: Option<String>, features: Option<String>,
mode: BuildMode, mode: BuildMode,
dir: Option<PathBuf>, dir: Option<PathBuf>,
@ -64,28 +65,30 @@ pub enum CargoCommand<'a> {
ExampleCheck { ExampleCheck {
cargoarg: &'a Option<&'a str>, cargoarg: &'a Option<&'a str>,
example: &'a str, example: &'a str,
target: Target<'a>, target: Option<Target<'a>>,
features: Option<String>, features: Option<String>,
mode: BuildMode, mode: BuildMode,
}, },
Build { Build {
cargoarg: &'a Option<&'a str>, cargoarg: &'a Option<&'a str>,
package: Option<String>, package: Option<String>,
target: Target<'a>, target: Option<Target<'a>>,
features: Option<String>, features: Option<String>,
mode: BuildMode, mode: BuildMode,
dir: Option<PathBuf>,
}, },
Check { Check {
cargoarg: &'a Option<&'a str>, cargoarg: &'a Option<&'a str>,
package: Option<String>, package: Option<String>,
target: Target<'a>, target: Option<Target<'a>>,
features: Option<String>, features: Option<String>,
mode: BuildMode, mode: BuildMode,
dir: Option<PathBuf>,
}, },
Clippy { Clippy {
cargoarg: &'a Option<&'a str>, cargoarg: &'a Option<&'a str>,
package: Option<String>, package: Option<String>,
target: Target<'a>, target: Option<Target<'a>>,
features: Option<String>, features: Option<String>,
}, },
Format { Format {
@ -109,60 +112,78 @@ pub enum CargoCommand<'a> {
ExampleSize { ExampleSize {
cargoarg: &'a Option<&'a str>, cargoarg: &'a Option<&'a str>,
example: &'a str, example: &'a str,
target: Target<'a>, target: Option<Target<'a>>,
features: Option<String>, features: Option<String>,
mode: BuildMode, mode: BuildMode,
arguments: Option<ExtraArguments>, arguments: Option<ExtraArguments>,
dir: Option<PathBuf>, dir: Option<PathBuf>,
}, },
CheckInDir {
mode: BuildMode,
dir: PathBuf,
},
BuildInDir {
mode: BuildMode,
dir: PathBuf,
},
} }
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 p = |p: &Option<String>| { fn p(p: &Option<String>) -> String {
if let Some(package) = p { if let Some(package) = p {
format!("package {package}") format!("package {package}")
} else { } else {
format!("default package") format!("default package")
} }
}; }
let feat = |f: &Option<String>| { fn feat(f: &Option<String>) -> String {
if let Some(features) = f { if let Some(features) = f {
format!("\"{features}\"") format!("\"{features}\"")
} else { } else {
format!("no features") format!("no features")
} }
}; }
let carg = |f: &&Option<&str>| { fn carg(f: &&Option<&str>) -> String {
if let Some(cargoarg) = f { if let Some(cargoarg) = f {
format!("{cargoarg}") format!("{cargoarg}")
} else { } else {
format!("no cargo args") format!("no cargo args")
} }
}; }
let details = |target: &Target, fn details(
mode: &BuildMode, target: &Option<Target>,
mode: Option<&BuildMode>,
features: &Option<String>, features: &Option<String>,
cargoarg: &&Option<&str>| { cargoarg: &&Option<&str>,
path: Option<&PathBuf>,
) -> String {
let feat = feat(features); let feat = feat(features);
let carg = carg(cargoarg); let carg = carg(cargoarg);
if cargoarg.is_some() { let in_dir = if let Some(path) = path {
let path = path.to_str().unwrap_or("<can't display>");
format!("in {path}")
} else {
format!("")
};
let target = if let Some(target) = target {
format!("{target}")
} else {
format!("<host target>")
};
let mode = if let Some(mode) = mode {
format!("{mode}")
} else {
format!("debug")
};
if cargoarg.is_some() && path.is_some() {
format!("({target}, {mode}, {feat}, {carg}, {in_dir})")
} else if cargoarg.is_some() {
format!("({target}, {mode}, {feat}, {carg})") format!("({target}, {mode}, {feat}, {carg})")
} else if path.is_some() {
format!("({target}, {mode}, {feat}, {in_dir})")
} else { } else {
format!("({target}, {mode}, {feat})") format!("({target}, {mode}, {feat})")
} }
}; }
match self { match self {
CargoCommand::Run { CargoCommand::Run {
@ -171,11 +192,14 @@ impl core::fmt::Display for CargoCommand<'_> {
target, target,
features, features,
mode, mode,
} => write!( dir,
} => {
write!(
f, f,
"Run example {example} {}", "Run example {example} {}",
details(target, mode, features, cargoarg) details(target, Some(mode), features, cargoarg, dir.as_ref())
), )
}
CargoCommand::Qemu { CargoCommand::Qemu {
cargoarg, cargoarg,
example, example,
@ -184,14 +208,9 @@ impl core::fmt::Display for CargoCommand<'_> {
mode, mode,
dir, dir,
} => { } => {
let details = details(target, mode, features, cargoarg); let details = details(target, Some(mode), features, cargoarg, dir.as_ref());
if let Some(dir) = dir {
let dir = dir.to_str().unwrap_or("Not displayable");
write!(f, "Run example {example} in QEMU from {dir} {details}",)
} else {
write!(f, "Run example {example} in QEMU {details}",) write!(f, "Run example {example} in QEMU {details}",)
} }
}
CargoCommand::ExampleBuild { CargoCommand::ExampleBuild {
cargoarg, cargoarg,
example, example,
@ -200,14 +219,9 @@ impl core::fmt::Display for CargoCommand<'_> {
mode, mode,
dir, dir,
} => { } => {
let details = details(target, mode, features, cargoarg); let details = details(target, Some(mode), features, cargoarg, dir.as_ref());
if let Some(dir) = dir {
let dir = dir.to_str().unwrap_or("Not displayable");
write!(f, "Build example {example} in {dir} {details}")
} else {
write!(f, "Build example {example} {details}",) write!(f, "Build example {example} {details}",)
} }
}
CargoCommand::ExampleCheck { CargoCommand::ExampleCheck {
cargoarg, cargoarg,
example, example,
@ -217,7 +231,7 @@ impl core::fmt::Display for CargoCommand<'_> {
} => write!( } => write!(
f, f,
"Check example {example} {}", "Check example {example} {}",
details(target, mode, features, cargoarg) details(target, Some(mode), features, cargoarg, None)
), ),
CargoCommand::Build { CargoCommand::Build {
cargoarg, cargoarg,
@ -225,50 +239,40 @@ impl core::fmt::Display for CargoCommand<'_> {
target, target,
features, features,
mode, mode,
dir,
} => { } => {
let package = p(package); let package = p(package);
write!( write!(
f, f,
"Build {package} {}", "Build {package} {}",
details(target, mode, features, cargoarg) details(target, Some(mode), features, cargoarg, dir.as_ref())
) )
} }
CargoCommand::BuildInDir { mode, dir } => {
let dir = dir.to_str().unwrap_or("Not displayable");
write!(f, "Build {dir} ({mode})")
}
CargoCommand::Check { CargoCommand::Check {
cargoarg, cargoarg,
package, package,
target, target,
features, features,
mode, mode,
dir,
} => { } => {
let package = p(package); let package = p(package);
write!( write!(
f, f,
"Check {package} {}", "Check {package} {}",
details(target, mode, features, cargoarg) details(target, Some(mode), features, cargoarg, dir.as_ref())
) )
} }
CargoCommand::CheckInDir { mode, dir } => {
let dir = dir.to_str().unwrap_or("Not displayable");
write!(f, "Check {dir} ({mode})")
}
CargoCommand::Clippy { CargoCommand::Clippy {
cargoarg, cargoarg,
package, package,
target, target,
features, features,
} => { } => {
let details = details(target, None, features, cargoarg, None);
let package = p(package); let package = p(package);
let features = feat(features); write!(f, "Clippy {package} {details}")
let carg = carg(cargoarg);
if cargoarg.is_some() {
write!(f, "Clippy {package} ({target}, {features}, {carg})")
} else {
write!(f, "Clippy {package} ({target}, {features})")
}
} }
CargoCommand::Format { CargoCommand::Format {
cargoarg, cargoarg,
@ -330,16 +334,11 @@ impl core::fmt::Display for CargoCommand<'_> {
arguments: _, arguments: _,
dir, dir,
} => { } => {
let details = details(target, mode, features, cargoarg); let details = details(target, Some(mode), features, cargoarg, dir.as_ref());
if let Some(dir) = dir {
let dir = dir.to_str().unwrap_or("Not displayable");
write!(f, "Compute size of example {example} from {dir} {details}",)
} else {
write!(f, "Compute size of example {example} {details}") write!(f, "Compute size of example {example} {details}")
} }
} }
} }
}
} }
impl<'a> CargoCommand<'a> { impl<'a> CargoCommand<'a> {
@ -358,12 +357,8 @@ impl<'a> CargoCommand<'a> {
fn command(&self) -> &'static str { fn command(&self) -> &'static str {
match self { match self {
CargoCommand::Run { .. } | CargoCommand::Qemu { .. } => "run", CargoCommand::Run { .. } | CargoCommand::Qemu { .. } => "run",
CargoCommand::ExampleCheck { .. } CargoCommand::ExampleCheck { .. } | CargoCommand::Check { .. } => "check",
| CargoCommand::Check { .. } CargoCommand::ExampleBuild { .. } | CargoCommand::Build { .. } => "build",
| CargoCommand::CheckInDir { .. } => "check",
CargoCommand::ExampleBuild { .. }
| CargoCommand::Build { .. }
| CargoCommand::BuildInDir { .. } => "build",
CargoCommand::ExampleSize { .. } => "size", CargoCommand::ExampleSize { .. } => "size",
CargoCommand::Clippy { .. } => "clippy", CargoCommand::Clippy { .. } => "clippy",
CargoCommand::Format { .. } => "fmt", CargoCommand::Format { .. } => "fmt",
@ -384,189 +379,159 @@ impl<'a> CargoCommand<'a> {
| CargoCommand::Clippy { .. } | CargoCommand::Clippy { .. }
| CargoCommand::Format { .. } | CargoCommand::Format { .. }
| CargoCommand::Test { .. } | CargoCommand::Test { .. }
| CargoCommand::Doc { .. } | CargoCommand::Doc { .. } => "cargo",
| CargoCommand::CheckInDir { .. }
| CargoCommand::BuildInDir { .. } => "cargo",
CargoCommand::Book { .. } => "mdbook", CargoCommand::Book { .. } => "mdbook",
} }
} }
/// Build args using common arguments for all commands, and the
/// specific information provided
fn build_args<'i, T: Iterator<Item = &'i str>>(
&'i self,
nightly: bool,
cargoarg: &'i Option<&'i str>,
features: &'i Option<String>,
mode: Option<&'i BuildMode>,
extra: T,
) -> Vec<&str> {
let mut args: Vec<&str> = Vec::new();
if nightly {
args.push("+nightly");
}
if let Some(cargoarg) = cargoarg.as_deref() {
args.push(cargoarg);
}
args.push(self.command());
if let Some(target) = self.target() {
args.extend_from_slice(&["--target", target.triple()])
}
if let Some(features) = features.as_ref() {
args.extend_from_slice(&["--features", features]);
}
if let Some(mode) = mode.map(|m| m.to_flag()).flatten() {
args.push(mode);
}
args.extend(extra);
args
}
/// Turn the ExtraArguments into an interator that contains the separating dashes
/// and the rest of the arguments.
///
/// NOTE: you _must_ chain this iterator at the _end_ of the extra arguments.
fn extra_args(args: Option<&ExtraArguments>) -> impl Iterator<Item = &str> {
#[allow(irrefutable_let_patterns)]
let args = if let Some(ExtraArguments::Other(arguments)) = args {
// Extra arguments must be passed after "--"
["--"]
.into_iter()
.chain(arguments.iter().map(String::as_str))
.collect()
} else {
vec![]
};
args.into_iter()
}
pub fn args(&self) -> Vec<&str> { pub fn args(&self) -> Vec<&str> {
fn p(package: &Option<String>) -> impl Iterator<Item = &str> {
if let Some(package) = package {
vec!["--package", &package].into_iter()
} else {
vec![].into_iter()
}
}
match self { match self {
// For future embedded-ci, for now the same as Qemu // For future embedded-ci, for now the same as Qemu
CargoCommand::Run { CargoCommand::Run {
cargoarg, cargoarg,
example, example,
target,
features, features,
mode, mode,
} => { // dir is exposed through `chdir`
let mut args = vec!["+nightly"]; dir: _,
if let Some(cargoarg) = cargoarg { // Target is added by build_args
args.extend_from_slice(&[cargoarg]); target: _,
} } => self.build_args(
true,
args.extend_from_slice(&[ cargoarg,
self.command(), features,
"--example", Some(mode),
example, ["--example", example].into_iter(),
"--target", ),
target.triple(),
]);
if let Some(feature) = features {
args.extend_from_slice(&["--features", feature]);
}
if let Some(flag) = mode.to_flag() {
args.push(flag);
}
args
}
CargoCommand::Qemu { CargoCommand::Qemu {
cargoarg, cargoarg,
example, example,
target,
features, features,
mode, mode,
// Dir is exposed through chdir instead // dir is exposed through `chdir`
dir: _, dir: _,
} => { // Target is added by build_args
let mut args = vec!["+nightly"]; target: _,
} => self.build_args(
if let Some(cargoarg) = cargoarg { true,
args.extend_from_slice(&[cargoarg]); cargoarg,
} features,
Some(mode),
args.extend_from_slice(&[ ["--example", example].into_iter(),
self.command(), ),
"--example",
example,
"--target",
target.triple(),
]);
if let Some(feature) = features {
args.extend_from_slice(&["--features", feature]);
}
if let Some(flag) = mode.to_flag() {
args.push(flag);
}
args
}
CargoCommand::Build { CargoCommand::Build {
cargoarg, cargoarg,
package, package,
target,
features, features,
mode, mode,
} => { // Dir is exposed through `chdir`
let mut args = vec!["+nightly"]; dir: _,
if let Some(cargoarg) = cargoarg { // Target is added by build_args
args.extend_from_slice(&[cargoarg]); target: _,
} } => self.build_args(true, cargoarg, features, Some(mode), p(package)),
args.extend_from_slice(&[self.command(), "--target", target.triple()]);
if let Some(package) = package {
args.extend_from_slice(&["--package", package]);
}
if let Some(feature) = features {
args.extend_from_slice(&["--features", feature]);
}
if let Some(flag) = mode.to_flag() {
args.push(flag);
}
args
}
CargoCommand::Check { CargoCommand::Check {
cargoarg, cargoarg,
package, package,
target: _,
features, features,
mode, mode,
} => { // Dir is exposed through `chdir`
let mut args = vec!["+nightly"]; dir: _,
if let Some(cargoarg) = cargoarg { // Target is added by build_args
args.extend_from_slice(&[cargoarg]); target: _,
} } => self.build_args(true, cargoarg, features, Some(mode), p(package)),
args.extend_from_slice(&[self.command()]);
if let Some(package) = package {
args.extend_from_slice(&["--package", package]);
}
if let Some(feature) = features {
args.extend_from_slice(&["--features", feature]);
}
if let Some(flag) = mode.to_flag() {
args.push(flag);
}
args
}
CargoCommand::Clippy { CargoCommand::Clippy {
cargoarg, cargoarg,
package, package,
target: _,
features, features,
} => { // Target is added by build_args
let mut args = vec!["+nightly"]; target: _,
if let Some(cargoarg) = cargoarg { } => self.build_args(true, cargoarg, features, None, p(package)),
args.extend_from_slice(&[cargoarg]);
}
args.extend_from_slice(&[self.command()]);
if let Some(package) = package {
args.extend_from_slice(&["--package", package]);
}
if let Some(feature) = features {
args.extend_from_slice(&["--features", feature]);
}
args
}
CargoCommand::Doc { CargoCommand::Doc {
cargoarg, cargoarg,
features, features,
arguments, arguments,
} => { } => {
let mut args = vec!["+nightly"]; let extra = Self::extra_args(arguments.as_ref());
if let Some(cargoarg) = cargoarg { self.build_args(true, cargoarg, features, None, extra)
args.extend_from_slice(&[cargoarg]);
}
args.extend_from_slice(&[self.command()]);
if let Some(feature) = features {
args.extend_from_slice(&["--features", feature]);
}
if let Some(ExtraArguments::Other(arguments)) = arguments {
for arg in arguments {
args.extend_from_slice(&[arg.as_str()]);
}
}
args
} }
CargoCommand::Test { CargoCommand::Test {
package, package,
features, features,
test, test,
} => { } => {
let mut args = vec!["+nightly"]; let extra = if let Some(test) = test {
args.extend_from_slice(&[self.command()]); vec!["--test", test]
} else {
if let Some(package) = package { vec![]
args.extend_from_slice(&["--package", package]); };
} let package = p(package);
let extra = extra.into_iter().chain(package);
if let Some(feature) = features { self.build_args(true, &None, features, None, extra)
args.extend_from_slice(&["--features", feature]);
}
if let Some(test) = test {
args.extend_from_slice(&["--test", test]);
}
args
} }
CargoCommand::Book { arguments } => { CargoCommand::Book { arguments } => {
let mut args = vec![]; let mut args = vec![];
@ -588,145 +553,89 @@ impl<'a> CargoCommand<'a> {
package, package,
check_only, check_only,
} => { } => {
let mut args = vec!["+nightly", self.command()]; let extra = if *check_only { Some("--check") } else { None };
if let Some(cargoarg) = cargoarg { let package = p(package);
args.extend_from_slice(&[cargoarg]); self.build_args(
} true,
cargoarg,
if let Some(package) = package { &None,
args.extend_from_slice(&["--package", package]); None,
} extra.into_iter().chain(package),
if *check_only { )
args.extend_from_slice(&["--check"]);
}
args
} }
CargoCommand::ExampleBuild { CargoCommand::ExampleBuild {
cargoarg, cargoarg,
example, example,
target,
features, features,
mode, mode,
// Dir is exposed through chdir instead // dir is exposed through `chdir`
dir: _, dir: _,
} => { // Target is added by build_args
let mut args = vec!["+nightly"]; target: _,
if let Some(cargoarg) = cargoarg { } => self.build_args(
args.extend_from_slice(&[cargoarg]); true,
} cargoarg,
features,
args.extend_from_slice(&[ Some(mode),
self.command(), ["--example", example].into_iter(),
"--example", ),
example,
"--target",
target.triple(),
]);
if let Some(feature) = features {
args.extend_from_slice(&["--features", feature]);
}
if let Some(flag) = mode.to_flag() {
args.push(flag);
}
args
}
CargoCommand::ExampleCheck { CargoCommand::ExampleCheck {
cargoarg, cargoarg,
example, example,
target,
features, features,
mode, mode,
} => { // Target is added by build_args
let mut args = vec!["+nightly"]; target: _,
if let Some(cargoarg) = cargoarg { } => self.build_args(
args.extend_from_slice(&[cargoarg]); true,
} cargoarg,
args.extend_from_slice(&[ features,
self.command(), Some(mode),
"--example", ["--example", example].into_iter(),
example, ),
"--target",
target.triple(),
]);
if let Some(feature) = features {
args.extend_from_slice(&["--features", feature]);
}
if let Some(flag) = mode.to_flag() {
args.push(flag);
}
args
}
CargoCommand::ExampleSize { CargoCommand::ExampleSize {
cargoarg, cargoarg,
example, example,
target,
features, features,
mode, mode,
arguments, arguments,
// Dir is exposed through chdir instead // Target is added by build_args
target: _,
// dir is exposed through `chdir`
dir: _, dir: _,
} => { } => {
let mut args = vec!["+nightly"]; let extra = ["--example", example]
if let Some(cargoarg) = cargoarg { .into_iter()
args.extend_from_slice(&[cargoarg]); .chain(Self::extra_args(arguments.as_ref()));
}
args.extend_from_slice(&[ self.build_args(true, cargoarg, features, Some(mode), extra)
self.command(),
"--example",
example,
"--target",
target.triple(),
]);
if let Some(feature_name) = features {
args.extend_from_slice(&["--features", feature_name]);
}
if let Some(flag) = mode.to_flag() {
args.push(flag);
}
if let Some(ExtraArguments::Other(arguments)) = arguments {
// Arguments to cargo size must be passed after "--"
args.extend_from_slice(&["--"]);
for arg in arguments {
args.extend_from_slice(&[arg.as_str()]);
}
}
args
}
CargoCommand::CheckInDir { mode, dir: _ } => {
let mut args = vec!["+nightly"];
args.push(self.command());
if let Some(mode) = mode.to_flag() {
args.push(mode);
}
args
}
CargoCommand::BuildInDir { mode, dir: _ } => {
let mut args = vec!["+nightly", self.command()];
if let Some(mode) = mode.to_flag() {
args.push(mode);
}
args
} }
} }
} }
/// TODO: integrate this into `args` once `-C` becomes stable.
fn chdir(&self) -> Option<&PathBuf> { fn chdir(&self) -> Option<&PathBuf> {
match self { match self {
CargoCommand::CheckInDir { dir, .. } | CargoCommand::BuildInDir { dir, .. } => {
Some(dir)
}
CargoCommand::Qemu { dir, .. } CargoCommand::Qemu { dir, .. }
| CargoCommand::ExampleBuild { dir, .. } | CargoCommand::ExampleBuild { dir, .. }
| CargoCommand::ExampleSize { dir, .. } => dir.as_ref(), | CargoCommand::ExampleSize { dir, .. }
| CargoCommand::Build { dir, .. }
| CargoCommand::Run { dir, .. }
| CargoCommand::Check { dir, .. } => dir.as_ref(),
_ => None,
}
}
fn target(&self) -> Option<&Target> {
match self {
CargoCommand::Run { target, .. }
| CargoCommand::Qemu { target, .. }
| CargoCommand::ExampleBuild { target, .. }
| CargoCommand::ExampleCheck { target, .. }
| CargoCommand::Build { target, .. }
| CargoCommand::Check { target, .. }
| CargoCommand::Clippy { target, .. }
| CargoCommand::ExampleSize { target, .. } => target.as_ref(),
_ => None, _ => None,
} }
} }
@ -863,29 +772,17 @@ pub fn handle_results(globals: &Globals, results: Vec<FinalRunResult>) -> Result
}; };
successes.for_each(|(cmd, stdout, stderr)| { successes.for_each(|(cmd, stdout, stderr)| {
let path = if let Some(dir) = cmd.chdir() {
let path = dir.to_str().unwrap_or("Not displayable");
format!(" (in {path}")
} else {
format!("")
};
if globals.verbose > 0 { if globals.verbose > 0 {
info!("✅ Success: {cmd}{path}\n {}", cmd.as_cmd_string()); info!("✅ Success: {cmd}\n {}", cmd.as_cmd_string());
} else { } else {
info!("✅ Success: {cmd}{path}"); info!("✅ Success: {cmd}");
} }
log_stdout_stderr(Level::Debug)((cmd, stdout, stderr)); log_stdout_stderr(Level::Debug)((cmd, stdout, stderr));
}); });
errors.clone().for_each(|(cmd, stdout, stderr)| { errors.clone().for_each(|(cmd, stdout, stderr)| {
if let Some(dir) = cmd.chdir() {
let path = dir.to_str().unwrap_or("Not displayable");
error!("❌ Failed: {cmd} (in {path}) \n {}", cmd.as_cmd_string());
} else {
error!("❌ Failed: {cmd}\n {}", cmd.as_cmd_string()); error!("❌ Failed: {cmd}\n {}", cmd.as_cmd_string());
}
log_stdout_stderr(Level::Error)((cmd, stdout, stderr)); log_stdout_stderr(Level::Error)((cmd, stdout, stderr));
}); });

View file

@ -356,9 +356,7 @@ fn command_parser(
| CargoCommand::Doc { .. } | CargoCommand::Doc { .. }
| CargoCommand::Test { .. } | CargoCommand::Test { .. }
| CargoCommand::Book { .. } | CargoCommand::Book { .. }
| CargoCommand::ExampleSize { .. } | CargoCommand::ExampleSize { .. } => {
| CargoCommand::BuildInDir { .. }
| CargoCommand::CheckInDir { .. } => {
let cargo_result = run_command(command, output_mode)?; let cargo_result = run_command(command, output_mode)?;
Ok(cargo_result) Ok(cargo_result)
} }