make cargo-miri show_error a bit nicer to use
This commit is contained in:
parent
12e3f75fd4
commit
1164815750
@ -1,10 +1,12 @@
|
|||||||
#![feature(let_else)]
|
#![feature(let_else)]
|
||||||
#![allow(clippy::useless_format, clippy::derive_partial_eq_without_eq, rustc::internal)]
|
#![allow(clippy::useless_format, clippy::derive_partial_eq_without_eq, rustc::internal)]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
mod util;
|
||||||
|
|
||||||
mod arg;
|
mod arg;
|
||||||
mod phases;
|
mod phases;
|
||||||
mod setup;
|
mod setup;
|
||||||
mod util;
|
|
||||||
mod version;
|
mod version;
|
||||||
|
|
||||||
use std::{env, iter};
|
use std::{env, iter};
|
||||||
@ -73,9 +75,9 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let Some(first) = args.next() else {
|
let Some(first) = args.next() else {
|
||||||
show_error(format!(
|
show_error!(
|
||||||
"`cargo-miri` called without first argument; please only invoke this binary through `cargo miri`"
|
"`cargo-miri` called without first argument; please only invoke this binary through `cargo miri`"
|
||||||
))
|
)
|
||||||
};
|
};
|
||||||
match first.as_str() {
|
match first.as_str() {
|
||||||
"miri" => phase_cargo_miri(args),
|
"miri" => phase_cargo_miri(args),
|
||||||
|
@ -77,15 +77,15 @@ pub fn phase_cargo_miri(mut args: impl Iterator<Item = String>) {
|
|||||||
// We cannot know which of those flags take arguments and which do not,
|
// We cannot know which of those flags take arguments and which do not,
|
||||||
// so we cannot detect subcommands later.
|
// so we cannot detect subcommands later.
|
||||||
let Some(subcommand) = args.next() else {
|
let Some(subcommand) = args.next() else {
|
||||||
show_error(format!("`cargo miri` needs to be called with a subcommand (`run`, `test`)"));
|
show_error!("`cargo miri` needs to be called with a subcommand (`run`, `test`)");
|
||||||
};
|
};
|
||||||
let subcommand = match &*subcommand {
|
let subcommand = match &*subcommand {
|
||||||
"setup" => MiriCommand::Setup,
|
"setup" => MiriCommand::Setup,
|
||||||
"test" | "t" | "run" | "r" | "nextest" => MiriCommand::Forward(subcommand),
|
"test" | "t" | "run" | "r" | "nextest" => MiriCommand::Forward(subcommand),
|
||||||
_ =>
|
_ =>
|
||||||
show_error(format!(
|
show_error!(
|
||||||
"`cargo miri` supports the following subcommands: `run`, `test`, `nextest`, and `setup`."
|
"`cargo miri` supports the following subcommands: `run`, `test`, `nextest`, and `setup`."
|
||||||
)),
|
),
|
||||||
};
|
};
|
||||||
let verbose = num_arg_flag("-v");
|
let verbose = num_arg_flag("-v");
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ pub fn phase_cargo_miri(mut args: impl Iterator<Item = String>) {
|
|||||||
match arg {
|
match arg {
|
||||||
Ok(value) => {
|
Ok(value) => {
|
||||||
if target_dir.is_some() {
|
if target_dir.is_some() {
|
||||||
show_error(format!("`--target-dir` is provided more than once"));
|
show_error!("`--target-dir` is provided more than once");
|
||||||
}
|
}
|
||||||
target_dir = Some(value.into());
|
target_dir = Some(value.into());
|
||||||
}
|
}
|
||||||
@ -456,16 +456,13 @@ pub fn phase_runner(mut binary_args: impl Iterator<Item = String>, phase: Runner
|
|||||||
|
|
||||||
let binary = binary_args.next().unwrap();
|
let binary = binary_args.next().unwrap();
|
||||||
let file = File::open(&binary)
|
let file = File::open(&binary)
|
||||||
.unwrap_or_else(|_| show_error(format!(
|
.unwrap_or_else(|_| show_error!(
|
||||||
"file {:?} not found or `cargo-miri` invoked incorrectly; please only invoke this binary through `cargo miri`", binary
|
"file {:?} not found or `cargo-miri` invoked incorrectly; please only invoke this binary through `cargo miri`", binary
|
||||||
)));
|
));
|
||||||
let file = BufReader::new(file);
|
let file = BufReader::new(file);
|
||||||
|
|
||||||
let info = serde_json::from_reader(file).unwrap_or_else(|_| {
|
let info = serde_json::from_reader(file).unwrap_or_else(|_| {
|
||||||
show_error(format!(
|
show_error!("file {:?} contains outdated or invalid JSON; try `cargo clean`", binary)
|
||||||
"file {:?} contains outdated or invalid JSON; try `cargo clean`",
|
|
||||||
binary
|
|
||||||
))
|
|
||||||
});
|
});
|
||||||
let info = match info {
|
let info = match info {
|
||||||
CrateRunInfo::RunWith(info) => info,
|
CrateRunInfo::RunWith(info) => info,
|
||||||
@ -562,7 +559,7 @@ pub fn phase_rustdoc(mut args: impl Iterator<Item = String>) {
|
|||||||
// An existing --runtool flag indicates cargo is running in cross-target mode, which we don't support.
|
// An existing --runtool flag indicates cargo is running in cross-target mode, which we don't support.
|
||||||
// Note that this is only passed when cargo is run with the unstable -Zdoctest-xcompile flag;
|
// Note that this is only passed when cargo is run with the unstable -Zdoctest-xcompile flag;
|
||||||
// otherwise, we won't be called as rustdoc at all.
|
// otherwise, we won't be called as rustdoc at all.
|
||||||
show_error(format!("cross-interpreting doctests is not currently supported by Miri."));
|
show_error!("cross-interpreting doctests is not currently supported by Miri.");
|
||||||
} else {
|
} else {
|
||||||
cmd.arg(arg);
|
cmd.arg(arg);
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ pub fn setup(subcommand: &MiriCommand, host: &str, target: &str) {
|
|||||||
if xargo_version().map_or(true, |v| v < XARGO_MIN_VERSION) {
|
if xargo_version().map_or(true, |v| v < XARGO_MIN_VERSION) {
|
||||||
if std::env::var_os("XARGO_CHECK").is_some() {
|
if std::env::var_os("XARGO_CHECK").is_some() {
|
||||||
// The user manually gave us a xargo binary; don't do anything automatically.
|
// The user manually gave us a xargo binary; don't do anything automatically.
|
||||||
show_error(format!("xargo is too old; please upgrade to the latest version"))
|
show_error!("xargo is too old; please upgrade to the latest version")
|
||||||
}
|
}
|
||||||
let mut cmd = cargo();
|
let mut cmd = cargo();
|
||||||
cmd.args(&["install", "xargo"]);
|
cmd.args(&["install", "xargo"]);
|
||||||
@ -97,10 +97,10 @@ pub fn setup(subcommand: &MiriCommand, host: &str, target: &str) {
|
|||||||
.output()
|
.output()
|
||||||
.expect("failed to determine sysroot");
|
.expect("failed to determine sysroot");
|
||||||
if !output.status.success() {
|
if !output.status.success() {
|
||||||
show_error(format!(
|
show_error!(
|
||||||
"Failed to determine sysroot; Miri said:\n{}",
|
"Failed to determine sysroot; Miri said:\n{}",
|
||||||
String::from_utf8_lossy(&output.stderr).trim_end()
|
String::from_utf8_lossy(&output.stderr).trim_end()
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
let sysroot = std::str::from_utf8(&output.stdout).unwrap();
|
let sysroot = std::str::from_utf8(&output.stdout).unwrap();
|
||||||
let sysroot = Path::new(sysroot.trim_end_matches('\n'));
|
let sysroot = Path::new(sysroot.trim_end_matches('\n'));
|
||||||
@ -121,14 +121,14 @@ pub fn setup(subcommand: &MiriCommand, host: &str, target: &str) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
if !rust_src.exists() {
|
if !rust_src.exists() {
|
||||||
show_error(format!("given Rust source directory `{}` does not exist.", rust_src.display()));
|
show_error!("given Rust source directory `{}` does not exist.", rust_src.display());
|
||||||
}
|
}
|
||||||
if rust_src.file_name().and_then(OsStr::to_str) != Some("library") {
|
if rust_src.file_name().and_then(OsStr::to_str) != Some("library") {
|
||||||
show_error(format!(
|
show_error!(
|
||||||
"given Rust source directory `{}` does not seem to be the `library` subdirectory of \
|
"given Rust source directory `{}` does not seem to be the `library` subdirectory of \
|
||||||
a Rust source checkout.",
|
a Rust source checkout.",
|
||||||
rust_src.display()
|
rust_src.display()
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next, we need our own libstd. Prepare a xargo project for that purpose.
|
// Next, we need our own libstd. Prepare a xargo project for that purpose.
|
||||||
@ -226,11 +226,9 @@ pub fn setup(subcommand: &MiriCommand, host: &str, target: &str) {
|
|||||||
// Finally run it!
|
// Finally run it!
|
||||||
if command.status().expect("failed to run xargo").success().not() {
|
if command.status().expect("failed to run xargo").success().not() {
|
||||||
if only_setup {
|
if only_setup {
|
||||||
show_error(format!("failed to run xargo, see error details above"))
|
show_error!("failed to run xargo, see error details above")
|
||||||
} else {
|
} else {
|
||||||
show_error(format!(
|
show_error!("failed to run xargo; run `cargo miri setup` to see the error details")
|
||||||
"failed to run xargo; run `cargo miri setup` to see the error details"
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,15 @@
|
|||||||
|
|
||||||
pub use crate::arg::*;
|
pub use crate::arg::*;
|
||||||
|
|
||||||
|
pub fn show_error(msg: &str) -> ! {
|
||||||
|
eprintln!("fatal error: {msg}");
|
||||||
|
std::process::exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! show_error {
|
||||||
|
($($tt:tt)*) => { show_error(&format!($($tt)*)) };
|
||||||
|
}
|
||||||
|
|
||||||
/// The information to run a crate with the given environment.
|
/// The information to run a crate with the given environment.
|
||||||
#[derive(Clone, Serialize, Deserialize)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
pub struct CrateRunEnv {
|
pub struct CrateRunEnv {
|
||||||
@ -55,10 +64,10 @@ pub enum CrateRunInfo {
|
|||||||
impl CrateRunInfo {
|
impl CrateRunInfo {
|
||||||
pub fn store(&self, filename: &Path) {
|
pub fn store(&self, filename: &Path) {
|
||||||
let file = File::create(filename)
|
let file = File::create(filename)
|
||||||
.unwrap_or_else(|_| show_error(format!("cannot create `{}`", filename.display())));
|
.unwrap_or_else(|_| show_error!("cannot create `{}`", filename.display()));
|
||||||
let file = BufWriter::new(file);
|
let file = BufWriter::new(file);
|
||||||
serde_json::ser::to_writer(file, self)
|
serde_json::ser::to_writer(file, self)
|
||||||
.unwrap_or_else(|_| show_error(format!("cannot write to `{}`", filename.display())));
|
.unwrap_or_else(|_| show_error!("cannot write to `{}`", filename.display()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,11 +79,6 @@ pub enum MiriCommand {
|
|||||||
Forward(String),
|
Forward(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show_error(msg: String) -> ! {
|
|
||||||
eprintln!("fatal error: {}", msg);
|
|
||||||
std::process::exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Escapes `s` in a way that is suitable for using it as a string literal in TOML syntax.
|
/// Escapes `s` in a way that is suitable for using it as a string literal in TOML syntax.
|
||||||
pub fn escape_for_toml(s: &str) -> String {
|
pub fn escape_for_toml(s: &str) -> String {
|
||||||
// We want to surround this string in quotes `"`. So we first escape all quotes,
|
// We want to surround this string in quotes `"`. So we first escape all quotes,
|
||||||
@ -187,15 +191,15 @@ pub fn ask_to_run(mut cmd: Command, ask: bool, text: &str) {
|
|||||||
match buf.trim().to_lowercase().as_ref() {
|
match buf.trim().to_lowercase().as_ref() {
|
||||||
// Proceed.
|
// Proceed.
|
||||||
"" | "y" | "yes" => {}
|
"" | "y" | "yes" => {}
|
||||||
"n" | "no" => show_error(format!("aborting as per your request")),
|
"n" | "no" => show_error!("aborting as per your request"),
|
||||||
a => show_error(format!("invalid answer `{}`", a)),
|
a => show_error!("invalid answer `{}`", a),
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
eprintln!("Running `{:?}` to {}.", cmd, text);
|
eprintln!("Running `{:?}` to {}.", cmd, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd.status().unwrap_or_else(|_| panic!("failed to execute {:?}", cmd)).success().not() {
|
if cmd.status().unwrap_or_else(|_| panic!("failed to execute {:?}", cmd)).success().not() {
|
||||||
show_error(format!("failed to {}", text));
|
show_error!("failed to {}", text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user