Skip to content

Commit 8c32e87

Browse files
committed
tidy: refactor --extra-checks parsing
1 parent 9e64506 commit 8c32e87

File tree

1 file changed

+102
-8
lines changed

1 file changed

+102
-8
lines changed

src/tools/tidy/src/ext_tool_checks.rs

Lines changed: 102 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use std::ffi::OsStr;
2121
use std::path::{Path, PathBuf};
2222
use std::process::Command;
23+
use std::str::FromStr;
2324
use std::{fmt, fs, io};
2425

2526
const MIN_PY_REV: (u32, u32) = (3, 9);
@@ -61,17 +62,32 @@ fn check_impl(
6162

6263
// Split comma-separated args up
6364
let lint_args = match extra_checks {
64-
Some(s) => s.strip_prefix("--extra-checks=").unwrap().split(',').collect(),
65+
Some(s) => s
66+
.strip_prefix("--extra-checks=")
67+
.unwrap()
68+
.split(',')
69+
.map(|s| (ExtraCheckArg::from_str(s), s))
70+
.filter_map(|(res, src)| match res {
71+
Ok(x) => Some(x),
72+
Err(err) => {
73+
eprintln!("warning: bad extra check argument {src:?}: {err:?}");
74+
None
75+
}
76+
})
77+
.collect(),
6578
None => vec![],
6679
};
6780

68-
let python_all = lint_args.contains(&"py");
69-
let python_lint = lint_args.contains(&"py:lint") || python_all;
70-
let python_fmt = lint_args.contains(&"py:fmt") || python_all;
71-
let shell_all = lint_args.contains(&"shell");
72-
let shell_lint = lint_args.contains(&"shell:lint") || shell_all;
73-
let cpp_all = lint_args.contains(&"cpp");
74-
let cpp_fmt = lint_args.contains(&"cpp:fmt") || cpp_all;
81+
macro_rules! extra_check {
82+
($lang:ident, $kind:ident) => {
83+
lint_args.iter().any(|arg| arg.matches(ExtraCheckLang::$lang, ExtraCheckKind::$kind))
84+
};
85+
}
86+
87+
let python_lint = extra_check!(Py, Lint);
88+
let python_fmt = extra_check!(Py, Fmt);
89+
let shell_lint = extra_check!(Shell, Lint);
90+
let cpp_fmt = extra_check!(Cpp, Fmt);
7591

7692
let mut py_path = None;
7793

@@ -579,3 +595,81 @@ impl From<io::Error> for Error {
579595
Self::Io(value)
580596
}
581597
}
598+
599+
#[derive(Debug)]
600+
enum ExtraCheckParseError {
601+
#[allow(dead_code, reason = "shown through Debug")]
602+
UnknownKind(String),
603+
#[allow(dead_code)]
604+
UnknownLang(String),
605+
/// Too many `:`
606+
TooManyParts,
607+
/// Tried to parse the empty string
608+
Empty,
609+
}
610+
611+
struct ExtraCheckArg {
612+
lang: ExtraCheckLang,
613+
/// None = run all extra checks for the given lang
614+
kind: Option<ExtraCheckKind>,
615+
}
616+
617+
impl ExtraCheckArg {
618+
fn matches(&self, lang: ExtraCheckLang, kind: ExtraCheckKind) -> bool {
619+
self.lang == lang && self.kind.map(|k| k == kind).unwrap_or(true)
620+
}
621+
}
622+
623+
impl FromStr for ExtraCheckArg {
624+
type Err = ExtraCheckParseError;
625+
626+
fn from_str(s: &str) -> Result<Self, Self::Err> {
627+
let mut parts = s.split(':');
628+
let Some(first) = parts.next() else {
629+
return Err(ExtraCheckParseError::Empty);
630+
};
631+
let second = parts.next();
632+
if parts.next().is_some() {
633+
return Err(ExtraCheckParseError::TooManyParts);
634+
}
635+
Ok(Self { lang: first.parse()?, kind: second.map(|s| s.parse()).transpose()? })
636+
}
637+
}
638+
639+
#[derive(PartialEq, Copy, Clone)]
640+
enum ExtraCheckLang {
641+
Py,
642+
Shell,
643+
Cpp,
644+
}
645+
646+
impl FromStr for ExtraCheckLang {
647+
type Err = ExtraCheckParseError;
648+
649+
fn from_str(s: &str) -> Result<Self, Self::Err> {
650+
Ok(match s {
651+
"py" => Self::Py,
652+
"shell" => Self::Shell,
653+
"cpp" => Self::Cpp,
654+
_ => return Err(ExtraCheckParseError::UnknownLang(s.to_string())),
655+
})
656+
}
657+
}
658+
659+
#[derive(PartialEq, Copy, Clone)]
660+
enum ExtraCheckKind {
661+
Lint,
662+
Fmt,
663+
}
664+
665+
impl FromStr for ExtraCheckKind {
666+
type Err = ExtraCheckParseError;
667+
668+
fn from_str(s: &str) -> Result<Self, Self::Err> {
669+
Ok(match s {
670+
"lint" => Self::Lint,
671+
"fmt" => Self::Fmt,
672+
_ => return Err(ExtraCheckParseError::UnknownKind(s.to_string())),
673+
})
674+
}
675+
}

0 commit comments

Comments
 (0)