Add clang-format to the external tool check
This commit is contained in:
parent
9f1f6a3387
commit
de0ece2f29
@ -5627,6 +5627,7 @@ dependencies = [
|
|||||||
"regex",
|
"regex",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"semver",
|
"semver",
|
||||||
|
"similar",
|
||||||
"termcolor",
|
"termcolor",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
@ -15,6 +15,7 @@ semver = "1.0"
|
|||||||
termcolor = "1.1.3"
|
termcolor = "1.1.3"
|
||||||
rustc-hash = "1.1.0"
|
rustc-hash = "1.1.0"
|
||||||
fluent-syntax = "0.11.1"
|
fluent-syntax = "0.11.1"
|
||||||
|
similar = "2.5.0"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "rust-tidy"
|
name = "rust-tidy"
|
||||||
|
@ -73,6 +73,8 @@ fn check_impl(
|
|||||||
let python_fmt = lint_args.contains(&"py:fmt") || python_all;
|
let python_fmt = lint_args.contains(&"py:fmt") || python_all;
|
||||||
let shell_all = lint_args.contains(&"shell");
|
let shell_all = lint_args.contains(&"shell");
|
||||||
let shell_lint = lint_args.contains(&"shell:lint") || shell_all;
|
let shell_lint = lint_args.contains(&"shell:lint") || shell_all;
|
||||||
|
let cpp_all = lint_args.contains(&"cpp");
|
||||||
|
let cpp_fmt = lint_args.contains(&"cpp:fmt") || cpp_all;
|
||||||
|
|
||||||
let mut py_path = None;
|
let mut py_path = None;
|
||||||
|
|
||||||
@ -81,7 +83,7 @@ fn check_impl(
|
|||||||
.map(OsStr::new)
|
.map(OsStr::new)
|
||||||
.partition(|arg| arg.to_str().is_some_and(|s| s.starts_with('-')));
|
.partition(|arg| arg.to_str().is_some_and(|s| s.starts_with('-')));
|
||||||
|
|
||||||
if python_lint || python_fmt {
|
if python_lint || python_fmt || cpp_fmt {
|
||||||
let venv_path = outdir.join("venv");
|
let venv_path = outdir.join("venv");
|
||||||
let mut reqs_path = root_path.to_owned();
|
let mut reqs_path = root_path.to_owned();
|
||||||
reqs_path.extend(PIP_REQ_PATH);
|
reqs_path.extend(PIP_REQ_PATH);
|
||||||
@ -111,13 +113,13 @@ fn check_impl(
|
|||||||
|
|
||||||
let mut args = merge_args(&cfg_args_ruff, &file_args_ruff);
|
let mut args = merge_args(&cfg_args_ruff, &file_args_ruff);
|
||||||
args.insert(0, "check".as_ref());
|
args.insert(0, "check".as_ref());
|
||||||
let res = py_runner(py_path.as_ref().unwrap(), "ruff", &args);
|
let res = py_runner(py_path.as_ref().unwrap(), true, None, "ruff", &args);
|
||||||
|
|
||||||
if res.is_err() && show_diff {
|
if res.is_err() && show_diff {
|
||||||
eprintln!("\npython linting failed! Printing diff suggestions:");
|
eprintln!("\npython linting failed! Printing diff suggestions:");
|
||||||
|
|
||||||
args.insert(1, "--diff".as_ref());
|
args.insert(1, "--diff".as_ref());
|
||||||
let _ = py_runner(py_path.as_ref().unwrap(), "ruff", &args);
|
let _ = py_runner(py_path.as_ref().unwrap(), true, None, "ruff", &args);
|
||||||
}
|
}
|
||||||
// Rethrow error
|
// Rethrow error
|
||||||
let _ = res?;
|
let _ = res?;
|
||||||
@ -144,13 +146,84 @@ fn check_impl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut args = merge_args(&cfg_args_black, &file_args_black);
|
let mut args = merge_args(&cfg_args_black, &file_args_black);
|
||||||
let res = py_runner(py_path.as_ref().unwrap(), "black", &args);
|
let res = py_runner(py_path.as_ref().unwrap(), true, None, "black", &args);
|
||||||
|
|
||||||
if res.is_err() && show_diff {
|
if res.is_err() && show_diff {
|
||||||
eprintln!("\npython formatting does not match! Printing diff:");
|
eprintln!("\npython formatting does not match! Printing diff:");
|
||||||
|
|
||||||
args.insert(0, "--diff".as_ref());
|
args.insert(0, "--diff".as_ref());
|
||||||
let _ = py_runner(py_path.as_ref().unwrap(), "black", &args);
|
let _ = py_runner(py_path.as_ref().unwrap(), true, None, "black", &args);
|
||||||
|
}
|
||||||
|
// Rethrow error
|
||||||
|
let _ = res?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if cpp_fmt {
|
||||||
|
let mut cfg_args_clang_format = cfg_args.clone();
|
||||||
|
let mut file_args_clang_format = file_args.clone();
|
||||||
|
let config_path = root_path.join(".clang-format");
|
||||||
|
let config_file_arg = format!("file:{}", config_path.display());
|
||||||
|
cfg_args_clang_format.extend(&["--style".as_ref(), config_file_arg.as_ref()]);
|
||||||
|
if bless {
|
||||||
|
eprintln!("formatting C++ files");
|
||||||
|
cfg_args_clang_format.push("-i".as_ref());
|
||||||
|
} else {
|
||||||
|
eprintln!("checking C++ file formatting");
|
||||||
|
cfg_args_clang_format.extend(&["--dry-run".as_ref(), "--Werror".as_ref()]);
|
||||||
|
}
|
||||||
|
let files;
|
||||||
|
if file_args_clang_format.is_empty() {
|
||||||
|
let llvm_wrapper = root_path.join("compiler/rustc_llvm/llvm-wrapper");
|
||||||
|
files = find_with_extension(
|
||||||
|
root_path,
|
||||||
|
Some(llvm_wrapper.as_path()),
|
||||||
|
&[OsStr::new("h"), OsStr::new("cpp")],
|
||||||
|
)?;
|
||||||
|
file_args_clang_format.extend(files.iter().map(|p| p.as_os_str()));
|
||||||
|
}
|
||||||
|
let args = merge_args(&cfg_args_clang_format, &file_args_clang_format);
|
||||||
|
let res = py_runner(py_path.as_ref().unwrap(), false, None, "clang-format", &args);
|
||||||
|
|
||||||
|
if res.is_err() && show_diff {
|
||||||
|
eprintln!("\nclang-format linting failed! Printing diff suggestions:");
|
||||||
|
|
||||||
|
let mut cfg_args_clang_format_diff = cfg_args.clone();
|
||||||
|
cfg_args_clang_format_diff.extend(&["--style".as_ref(), config_file_arg.as_ref()]);
|
||||||
|
for file in file_args_clang_format {
|
||||||
|
let mut formatted = String::new();
|
||||||
|
let mut diff_args = cfg_args_clang_format_diff.clone();
|
||||||
|
diff_args.push(file);
|
||||||
|
let _ = py_runner(
|
||||||
|
py_path.as_ref().unwrap(),
|
||||||
|
false,
|
||||||
|
Some(&mut formatted),
|
||||||
|
"clang-format",
|
||||||
|
&diff_args,
|
||||||
|
);
|
||||||
|
if formatted.is_empty() {
|
||||||
|
eprintln!(
|
||||||
|
"failed to obtain the formatted content for '{}'",
|
||||||
|
file.to_string_lossy()
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let actual = std::fs::read_to_string(file).unwrap_or_else(|e| {
|
||||||
|
panic!(
|
||||||
|
"failed to read the C++ file at '{}' due to '{e}'",
|
||||||
|
file.to_string_lossy()
|
||||||
|
)
|
||||||
|
});
|
||||||
|
if formatted != actual {
|
||||||
|
let diff = similar::TextDiff::from_lines(&actual, &formatted);
|
||||||
|
eprintln!(
|
||||||
|
"{}",
|
||||||
|
diff.unified_diff().context_radius(4).header(
|
||||||
|
&format!("{} (actual)", file.to_string_lossy()),
|
||||||
|
&format!("{} (formatted)", file.to_string_lossy())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Rethrow error
|
// Rethrow error
|
||||||
let _ = res?;
|
let _ = res?;
|
||||||
@ -162,7 +235,7 @@ fn check_impl(
|
|||||||
let mut file_args_shc = file_args.clone();
|
let mut file_args_shc = file_args.clone();
|
||||||
let files;
|
let files;
|
||||||
if file_args_shc.is_empty() {
|
if file_args_shc.is_empty() {
|
||||||
files = find_with_extension(root_path, "sh")?;
|
files = find_with_extension(root_path, None, &[OsStr::new("sh")])?;
|
||||||
file_args_shc.extend(files.iter().map(|p| p.as_os_str()));
|
file_args_shc.extend(files.iter().map(|p| p.as_os_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,8 +254,31 @@ fn merge_args<'a>(cfg_args: &[&'a OsStr], file_args: &[&'a OsStr]) -> Vec<&'a Os
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Run a python command with given arguments. `py_path` should be a virtualenv.
|
/// Run a python command with given arguments. `py_path` should be a virtualenv.
|
||||||
fn py_runner(py_path: &Path, bin: &'static str, args: &[&OsStr]) -> Result<(), Error> {
|
///
|
||||||
let status = Command::new(py_path).arg("-m").arg(bin).args(args).status()?;
|
/// Captures `stdout` to a string if provided, otherwise prints the output.
|
||||||
|
fn py_runner(
|
||||||
|
py_path: &Path,
|
||||||
|
as_module: bool,
|
||||||
|
stdout: Option<&mut String>,
|
||||||
|
bin: &'static str,
|
||||||
|
args: &[&OsStr],
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let mut cmd = Command::new(py_path);
|
||||||
|
if as_module {
|
||||||
|
cmd.arg("-m").arg(bin).args(args);
|
||||||
|
} else {
|
||||||
|
let bin_path = py_path.with_file_name(bin);
|
||||||
|
cmd.arg(bin_path).args(args);
|
||||||
|
}
|
||||||
|
let status = if let Some(stdout) = stdout {
|
||||||
|
let output = cmd.output()?;
|
||||||
|
if let Ok(s) = std::str::from_utf8(&output.stdout) {
|
||||||
|
stdout.push_str(s);
|
||||||
|
}
|
||||||
|
output.status
|
||||||
|
} else {
|
||||||
|
cmd.status()?
|
||||||
|
};
|
||||||
if status.success() { Ok(()) } else { Err(Error::FailedCheck(bin)) }
|
if status.success() { Ok(()) } else { Err(Error::FailedCheck(bin)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,7 +453,11 @@ fn shellcheck_runner(args: &[&OsStr]) -> Result<(), Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Check git for tracked files matching an extension
|
/// Check git for tracked files matching an extension
|
||||||
fn find_with_extension(root_path: &Path, extension: &str) -> Result<Vec<PathBuf>, Error> {
|
fn find_with_extension(
|
||||||
|
root_path: &Path,
|
||||||
|
find_dir: Option<&Path>,
|
||||||
|
extensions: &[&OsStr],
|
||||||
|
) -> Result<Vec<PathBuf>, Error> {
|
||||||
// Untracked files show up for short status and are indicated with a leading `?`
|
// Untracked files show up for short status and are indicated with a leading `?`
|
||||||
// -C changes git to be as if run from that directory
|
// -C changes git to be as if run from that directory
|
||||||
let stat_output =
|
let stat_output =
|
||||||
@ -368,15 +468,25 @@ fn find_with_extension(root_path: &Path, extension: &str) -> Result<Vec<PathBuf>
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut output = Vec::new();
|
let mut output = Vec::new();
|
||||||
let binding = Command::new("git").arg("-C").arg(root_path).args(["ls-files"]).output()?;
|
let binding = {
|
||||||
|
let mut command = Command::new("git");
|
||||||
|
command.arg("-C").arg(root_path).args(["ls-files"]);
|
||||||
|
if let Some(find_dir) = find_dir {
|
||||||
|
command.arg(find_dir);
|
||||||
|
}
|
||||||
|
command.output()?
|
||||||
|
};
|
||||||
let tracked = String::from_utf8_lossy(&binding.stdout);
|
let tracked = String::from_utf8_lossy(&binding.stdout);
|
||||||
|
|
||||||
for line in tracked.lines() {
|
for line in tracked.lines() {
|
||||||
let line = line.trim();
|
let line = line.trim();
|
||||||
let path = Path::new(line);
|
let path = Path::new(line);
|
||||||
|
|
||||||
if path.extension() == Some(OsStr::new(extension)) {
|
let Some(ref extension) = path.extension() else {
|
||||||
output.push(path.to_owned());
|
continue;
|
||||||
|
};
|
||||||
|
if extensions.contains(extension) {
|
||||||
|
output.push(root_path.join(path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user