Skip to content

Commit

Permalink
Merge pull request #12 from cbourjau/add-cargo-bench
Browse files Browse the repository at this point in the history
Add support for cargo bench (Fixes #9)
  • Loading branch information
barskern authored Mar 6, 2019
2 parents b1ec779 + 4ee0b94 commit 7f3c229
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 40 deletions.
53 changes: 21 additions & 32 deletions src/cargo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const DEFAULT_CARGO_ARGS: &[&str] = &["--message-format=json", "--quiet"];
pub(crate) enum CmdKind {
Run,
Test,
Bench,
}

impl CmdKind {
Expand All @@ -21,6 +22,7 @@ impl CmdKind {
match s {
"run" => Some(Run),
"test" => Some(Test),
"bench" => Some(Bench),
_ => None,
}
}
Expand All @@ -30,6 +32,7 @@ impl CmdKind {
match self {
CmdKind::Run => "build",
CmdKind::Test => "test",
CmdKind::Bench => "bench",
}
}
}
Expand Down Expand Up @@ -194,48 +197,34 @@ pub(crate) fn select_buildopt<'a>(
opts: impl IntoIterator<Item = &'a BuildOpt>,
cmd_kind: CmdKind,
) -> Result<&'a BuildOpt, Error> {
let opts = opts.into_iter();

// Target kinds we want to look for
let look_for = &[TargetKind::Bin, TargetKind::Example, TargetKind::Test];
let is_test = cmd_kind == CmdKind::Test;

// Find candidates with the possible target types
let mut candidates = opts
let candidates: Vec<_> = opts
.into_iter()
.filter(|opt| {
// When run as a test we only care about the binary where the profile
// is set as `test`
if is_test {
opt.profile.test
} else {
opt.target
// When run as a test or bench we only care about the
// binary where the profile is set as `test`
match cmd_kind {
CmdKind::Test | CmdKind::Bench => opt.profile.test,
CmdKind::Run => opt
.target
.kind
.iter()
.any(|kind| look_for.iter().any(|lkind| lkind == kind))
.any(|kind| look_for.iter().any(|lkind| lkind == kind)),
}
})
.peekable();

// Get the first candidate
let first = candidates
.next()
.ok_or_else(|| err_msg("Found no possible candidates"))?;

// We found more than one candidate
if candidates.peek().is_some() {
// Make a error string including all the possible candidates
let candidates_str: String = iter::once(first)
.chain(candidates)
.map(|opt| format!("\t- {} ({})\n", opt.target.name, opt.target.kind[0]))
.collect();

if is_test {
Err(format_err!("Found more than one possible candidate:\n\n{}\n\nPlease use `--test`, `--example`, `--bin` or `--lib` to specify exactly what binary you want to examine", candidates_str))?
} else {
Err(format_err!("Found more than one possible candidate:\n\n{}\n\nPlease use `--example` or `--bin` to specify exactly what binary you want to examine", candidates_str))?
}
.collect();
// We expect exactly one candidate; everything else is an error
match candidates.as_slice() {
[] => Err(err_msg("No suitable build artifacts found.")),
[the_one] => Ok(the_one),
the_many => Err(format_err!(
"Found several artifact candidates: \n :{:?}",
the_many
)),
}
Ok(first)
}

impl BuildOpt {
Expand Down
21 changes: 13 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,12 @@ fn process_matches<'a>(
}

fn create_app<'a, 'b>() -> App<'a, 'b> {
let usage = concat!(
let with_usage = concat!(
"<with-cmd> 'Command executed with the cargo-created binary. ",
"Use {bin} to denote the binary. ",
"If omitted the {bin} is added as the last argument'"
"The placeholders {bin} {args} denote the path to the binary and additional arguments.",
"If omitted `{bin} {args}` is appended to `with-cmd`'"
);
let cargo_usage = "<cargo-cmd> 'The Cargo subcommand starting with `test`, `run`, or `bench`'";
App::new(COMMAND_NAME)
.about(COMMAND_DESCRIPTION)
// We have to lie about our binary name since this will be a third party
Expand All @@ -68,11 +69,15 @@ fn create_app<'a, 'b>() -> App<'a, 'b> {
.subcommand(
SubCommand::with_name(COMMAND_NAME)
.about(COMMAND_DESCRIPTION)
.arg(Arg::from_usage(&usage))
.arg(
clap::Arg::from_usage("<cargo-cmd> 'The cargo subcommand `test` or `run`'")
.raw(true),
),
.arg(Arg::from_usage(&with_usage))
.arg(clap::Arg::from_usage(cargo_usage).raw(true))
.after_help(r#"
EXAMPLES:
cargo with echo -- run
cargo with "gdb --args" -- run
cargo with "echo {args} {bin}" -- test -- myargs
"#
)
)
.settings(&[AppSettings::SubcommandRequired])
}
Expand Down

0 comments on commit 7f3c229

Please sign in to comment.