-
-
Notifications
You must be signed in to change notification settings - Fork 14.3k
tidy: add if-installed prefix condition to extra checks system #149961
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
tidy: add if-installed prefix condition to extra checks system #149961
Conversation
This comment has been minimized.
This comment has been minimized.
85db7e7 to
69df709
Compare
|
r? @Kobzol |
|
|
This comment has been minimized.
This comment has been minimized.
58e4347 to
1c26a75
Compare
|
|
|
Basically what you are recommending is that, once I also object to adding more undocumented behavior. Even if this behavior was documented, the way it is implemented currently needlessly ups the complexity of tidy, making spellcheck both an extra-check an a regular check. I think all the spellcheck logic should be contained in the Additionally, we already have a way to control if If we do want this behavior, I think it should be opt-in, at least as far as tidy is concerned, likely through another prefix along the lines of I would also like to remind everyone that an ad-hoc implementation of typo checking has already broken CI once, so let's not repeat that mistake. |
|
I'm going to give the |
|
FWIW, we agreed to use this mechanism with @jieyouxu in #t-infra/bootstrap > Should Spellcheck check all files? @ 💬. I don't think that this would ever affect CI. Both because it will never have the binary preinstalled, and in the Tidy is inherently stateful, it depends a lot on git state and it skips some checks if the filesystem is read-only (maybe there are also some other things). The original idea hwere was to make more people use spellcheck locally. I'm not actually sure if it's needed, I don't often see spellcheck errors on CI, but it also sounded like it wouldn't do much harm. The problem is that installing the |
Yes, and I would've appreciated a ping on that honestly because you seemed to be missing a lot of context (like with opt-level, I'm pretty sure I did a bunch of manual testing about that to figure out the best level).
I still think it should have an explicit check.
I think we have different definitions to what "stateful" means. To me, all of these things (git state, fs metadata, every file in the tree) act as the "input" to tidy, and tidy merely acts as a pure function on top of these, never mutating them unless
We're already doing that for everyone on the
The cost is in code complexity and maintenance burden, as it always is. The current PR has a lot of duplicated code, and it also breaks encapsulation on the |
Fair enough, will do next time!
Sure, but in that case the
Hmm, it seems surprising to me that tidy runs so slowly for you. Well, maybe we don't really need to do anything after all. People can opt into spellcheck with Maybe to suggest a compromise: would you agree with running typos on a best effort basis (without installing it) only in the pre-push hook? That was the original-original idea.
That seems surprising to me. If anything, this PR seems to remove duplication? Also, I would prefer to actually move stuff out from the |
It's different because tidy installs typos-cli, thus modifying it.
I would not oppose that change, as long as there is a reasonable way to opt out. That's basically just a stripped down version of my
Sure, but if we do that, we should move the actual logic into the new file, not just a shim. We could also make them into individual checks without moving them out of their current module, it would just likely mean not using the existing macro. |
@Shunpoco I have strong opinions on the interface, and parsing, so I went ahead and implemented that below, but if you want to implement the actual checking logic, go ahead! If we want to refactor stuff into separate checks, I think that should be done in its own PR, we would already be doing enough here, and doing that properly would be quite involved. diff --git a/src/tools/tidy/src/extra_checks/mod.rs b/src/tools/tidy/src/extra_checks/mod.rs
index a45af7fcf15..fdae949c408 100644
--- a/src/tools/tidy/src/extra_checks/mod.rs
+++ b/src/tools/tidy/src/extra_checks/mod.rs
@@ -736,9 +739,14 @@ enum ExtraCheckParseError {
Empty,
/// `auto` specified without lang part.
AutoRequiresLang,
+ /// `if-installed` specified without lang part.
+ IfInstalledRequiresLang,
+
}
struct ExtraCheckArg {
+ /// Only run the check if the requisite software is already installed.
+ if_installed: bool,
auto: bool,
lang: ExtraCheckLang,
/// None = run all extra checks for the given lang
@@ -750,8 +758,14 @@ fn matches(&self, lang: ExtraCheckLang, kind: ExtraCheckKind) -> bool {
self.lang == lang && self.kind.map(|k| k == kind).unwrap_or(true)
}
- /// Returns `false` if this is an auto arg and the passed filename does not trigger the auto rule
- fn is_non_auto_or_matches(&self, filepath: &str) -> bool {
+ /// Returns `false` if this is an auto arg and the passed filename does not trigger the auto rule,
+ /// or if it has `if_installed` set, and the required software is not installed.
+ fn is_unconditional_or_matches(&self, filepath: &str) -> bool {
+ if self.if_installed {
+ match self.lang {
+ _ => todo!("return false here if software not found"),
+ }
+ }
if !self.auto {
return true;
}
@@ -792,22 +806,35 @@ impl FromStr for ExtraCheckArg {
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut auto = false;
+ let mut if_installed = false;
let mut parts = s.split(':');
let Some(mut first) = parts.next() else {
return Err(ExtraCheckParseError::Empty);
};
- if first == "auto" {
- let Some(part) = parts.next() else {
- return Err(ExtraCheckParseError::AutoRequiresLang);
- };
- auto = true;
- first = part;
+ loop {
+ if !auto && first == "auto" {
+ let Some(part) = parts.next() else {
+ return Err(ExtraCheckParseError::AutoRequiresLang);
+ };
+ auto = true;
+ first = part;
+ continue;
+ }
+ if !if_installed && first == "if-installed" {
+ let Some(part) = parts.next() else {
+ return Err(ExtraCheckParseError::IfInstalledRequiresLang);
+ };
+ if_installed = true;
+ first = part;
+ continue;
+ }
+ break;
}
let second = parts.next();
if parts.next().is_some() {
return Err(ExtraCheckParseError::TooManyParts);
}
- let arg = Self { auto, lang: first.parse()?, kind: second.map(|s| s.parse()).transpose()? };
+ let arg = Self { auto, if_installed, lang: first.parse()?, kind: second.map(|s| s.parse()).transpose()? };
if !arg.has_supported_kind() {
return Err(ExtraCheckParseError::UnsupportedKindForLang);
} |
Define a new function ensure_version which is extracted (and modified) from ensure_version_or_cargo_install.
1c26a75 to
05bb971
Compare
for other extra checks, it is WIP.
05bb971 to
b305a98
Compare
9fad50c to
e216dfa
Compare
e216dfa to
5642a2d
Compare
|
@rustbot review |
|
Ah, waiting-on-review was already added. @Kobzol @lolbinarycat Could you review in your spare time? |
|
I'll do my best to take a look tomorrow |
src/tools/tidy/src/spellcheck.rs
Outdated
| // If the tool is not found, do nothing. | ||
| if e.kind() != std::io::ErrorKind::NotFound { | ||
| eprintln!( | ||
| "error: spellchecker has a problem. --extra-check=specllcheck may solve the problem." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| "error: spellchecker has a problem. --extra-check=specllcheck may solve the problem." | |
| "error: spellchecker has a problem. --extra-checks=spellcheck may solve the problem." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The file was already removed from this PR since we've discussed that (at least for now) spellcheck code should be under extra_checks/
| @@ -736,10 +753,14 @@ enum ExtraCheckParseError { | |||
| Empty, | |||
| /// `auto` specified without lang part. | |||
| AutoRequiresLang, | |||
| /// `if-installed` specified without lang part. | |||
| IfInsatlledRequiresLang, | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| IfInsatlledRequiresLang, | |
| IfInstalledRequiresLang, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uh, thanks. I addressed in b49e56d
src/tools/tidy/src/lib.rs
Outdated
| }; | ||
|
|
||
| if v != version { | ||
| eprintln!( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we shouldn't print the warning here always, because we use this function just for checking the version at some places, and then it shouldn't print. Maybe we could model that with an explicit error type that specifies the result (tool not found, generic error, version doesn't match), and print a warning only in places where it makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It makes sense to me, thanks. But extra_checks/mod.rs already has such an Error enum. Do you think I can make a very similar one on lib.rs, or can I move ensure_version / ensure_version_or_cargo_install to extra_checks/ since they are only used from extra_checks for now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to move them into extra_checks/mod.rs in dfe7d8a. Please check if the change is what you expected 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few nitpicks, but also, I don't feel the best about how many untested and rarely used code paths this introduces, seems like those have some potential to bitrot.
|
@lolbinarycat Thanks for the review, I addressed your feedback in 68ea14a.
I understand your concern. We're currently not sure if |
that's the issue though, how often are people going to use Personally I would say move ahead with this and try to implement more robust testing for tidy in a followup, but ultimately it's not my decision. |
| let mut first = match parts.next() { | ||
| Some("") | None => return Err(ExtraCheckParseError::Empty), | ||
| Some(part) => part, | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: During writing a unit test, I found that parts.next() doesn't return None if the given s is empty string (""). It returns an empty string instead.
|
This looks good! I fully entrust lolbinarycat to have the final say, as they wrote the parsing code originally, but it's r+ from me. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, just some small nitpicks and a question about what OS you used to test this locally.
| @@ -120,6 +126,7 @@ fn check_impl( | |||
| ck.is_non_auto_or_matches(path) | |||
| }); | |||
| } | |||
| lint_args.retain(|ck| ck.is_non_if_installed_or_matches(root_path, outdir)); | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should check if-installed first, as a quick version check is faster than enumerating all the changed files, and by doing that first, we could potentially skip that enumeration.
|
|
||
| let tool_root_dir = build_dir.join("misc-tools"); | ||
| let tool_bin_dir = tool_root_dir.join("bin"); | ||
| let bin_path = tool_bin_dir.join(bin_name).with_extension(env::consts::EXE_EXTENSION); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh, never gave this much though since I'm not on windows... I guess it makes sense? Surprised we haven't gotten a bug report about this though. I'm assuming you're on windows? We definitely should test this on windows, if it hasn't already been.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I'm using Linux so I completely overlooked this EXE_EXTENSION 😅
But I found that the value in EXE_EXTENSION depends on the platform, so it's safe.
On Linux, it is an empty str. On the other hand, on Windows it is "exe".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whoops, yeah that's not a new addition, sorry.
| }; | ||
| if_installed = true; | ||
| first = part; | ||
| continue; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| continue; |
No longer needed.
| ]; | ||
|
|
||
| for (s, expected) in test_cases { | ||
| assert_eq!(ExtraCheckArg::from_str(s), expected); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| assert_eq!(ExtraCheckArg::from_str(s), expected); | |
| assert_eq!(ExtraCheckArg::from_str(s), Err(expected)); |
Instead of wrapping each test case in Err, you can just wrap them all here, which should hopefully make it easier to read. You can also do the same thing above with the Ok tests, though that's a bit less important due to the different formatting.
466c3a9 to
0dfff23
Compare
Ref: https://rust-lang.zulipchat.com/#narrow/channel/326414-t-infra.2Fbootstrap/topic/Should.20Spellcheck.20check.20all.20files.3F/with/543227610
tidy now runs spellcheck (typos-cli) without adding
--extra-checks=spellcheckoption if the tool is already installed under ./build/misc-tools and the version is expected.It will improve code quality without bothering engineers who doesn't want to use typos or who cleans up ./build directory frequently.