make subcommand configurable

This commit is contained in:
nora 2022-12-21 20:05:30 +01:00
parent a866667545
commit c0289c65f7
6 changed files with 97 additions and 39 deletions

View file

@ -41,27 +41,46 @@ struct BuildInner {
env: Vec<EnvVar>,
allow_color: bool,
project_dir: Option<PathBuf>,
extra_args: Vec<String>,
}
#[derive(Debug)]
enum BuildMode {
Cargo { args: Option<Vec<String>> },
Cargo {
/// May be something like `miri run`.
subcommand: Vec<String>,
diag_subcommand: Vec<String>,
},
Script(PathBuf),
Rustc,
}
impl Build {
pub fn new(options: &Options) -> Self {
pub fn new(options: &Options) -> Result<Self> {
if options.rustc && options.cargo_subcmd != "build" {
bail!("Cannot specify --rustc together with --cargo-subcmd or --cargo-args");
}
let extra_args = options
.extra_args
.as_deref()
.map(split_args)
.unwrap_or_default();
let mode = if options.rustc {
BuildMode::Rustc
} else if let Some(script) = &options.script_path {
BuildMode::Script(script.clone())
} else {
let subcommand = split_args(&options.cargo_subcmd);
let diag_subcommand = options
.diagnostics_cargo_subcmd
.as_deref()
.map(split_args)
.unwrap_or_else(|| subcommand.clone());
BuildMode::Cargo {
args: options
.cargo_args
.as_ref()
.map(|cmd| cmd.split_whitespace().map(ToString::to_string).collect()),
subcommand,
diag_subcommand,
}
};
@ -73,7 +92,7 @@ impl Build {
Verify::Ice
};
Self {
Ok(Self {
inner: Rc::new(BuildInner {
mode,
input_path: options.path.clone(),
@ -81,8 +100,9 @@ impl Build {
env: options.env.clone(),
allow_color: !options.no_color,
project_dir: options.project_dir.clone(),
extra_args,
}),
}
})
}
fn cmd(&self, name: impl AsRef<OsStr>) -> Command {
@ -106,17 +126,19 @@ impl Build {
}
let (is_ice, output) = match &inner.mode {
BuildMode::Cargo { args } => {
BuildMode::Cargo {
subcommand,
diag_subcommand: _,
} => {
let mut cmd = self.cmd("cargo");
cmd.arg("build");
cmd.args(subcommand);
if inner.allow_color {
cmd.arg("--color=always");
}
for arg in args.iter().flatten() {
cmd.arg(arg);
}
cmd.args(&inner.extra_args);
for env in &inner.env {
cmd.env(&env.key, &env.value);
@ -135,6 +157,8 @@ impl Build {
BuildMode::Script(script_path) => {
let mut cmd = self.cmd(script_path);
cmd.args(&inner.extra_args);
for env in &inner.env {
cmd.env(&env.key, &env.value);
}
@ -154,6 +178,8 @@ impl Build {
cmd.arg("--color=always");
}
cmd.args(&inner.extra_args);
for env in &inner.env {
cmd.env(&env.key, &env.value);
}
@ -188,13 +214,17 @@ impl Build {
let inner = &self.inner;
let diags = match &inner.mode {
BuildMode::Cargo { args } => {
BuildMode::Cargo {
subcommand: _,
diag_subcommand,
} => {
let mut cmd = self.cmd("cargo");
cmd.args(["build", "--message-format=json"]);
for arg in args.iter().flatten() {
cmd.arg(arg);
}
cmd.args(diag_subcommand);
cmd.arg("--message-format=json");
cmd.args(&inner.extra_args);
for env in &inner.env {
cmd.env(&env.key, &env.value);
@ -295,3 +325,7 @@ pub struct CargoJsonCompileMessage {
pub reason: String,
pub message: Option<Diagnostic>,
}
fn split_args(s: &str) -> Vec<String> {
s.split_whitespace().map(ToString::to_string).collect()
}

View file

@ -31,9 +31,18 @@ pub enum Cargo {
#[derive(clap::Args, Debug)]
pub struct Options {
/// Additional arguments to pass to cargo, separated by whitespace.
/// Additional arguments to pass to cargo/rustc, separated by whitespace.
#[arg(long)]
pub cargo_args: Option<String>,
pub extra_args: Option<String>,
/// The cargo subcommand used to find the reproduction, seperated by whitespace (for example `miri run`).
#[arg(long, default_value = "build")]
pub cargo_subcmd: String,
/// The cargo subcommand used to get diagnostics like the dead_code lint from the compiler, seperated by whitespace.
/// Defaults to the value of `--cargo-subcmd`.
#[arg(long)]
pub diagnostics_cargo_subcmd: Option<String>,
/// To disable colored output.
#[arg(long)]
@ -96,7 +105,7 @@ impl FromStr for EnvVar {
}
pub fn minimize(options: Options) -> Result<()> {
let build = build::Build::new(&options);
let build = build::Build::new(&options)?;
let mut minimizer = Minimizer::new_glob_dir(options, build)?;
@ -129,7 +138,9 @@ impl Default for Options {
fn default() -> Self {
Self {
script_path: None,
cargo_args: None,
extra_args: None,
cargo_subcmd: "build".into(),
diagnostics_cargo_subcmd: None,
no_color: false,
rustc: false,
no_verify: false,