-
Notifications
You must be signed in to change notification settings - Fork 925
Implemented rough draft of check
write mode.
#2539
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
Conversation
In commit Additionally, in commit I'm not too happy with how I'm handling propagation of |
src/bin/main.rs
Outdated
@@ -342,6 +346,8 @@ fn main() { | |||
Ok(summary) => { | |||
if summary.has_operational_errors() { | |||
1 | |||
} else if summary.has_diff && summary.write_mode == Some(WriteMode::Check) { | |||
1 |
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 will probably be easier to change the other exit codes now, rather than later.
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.
Alrighty! I'll implement the stuff suggested in this comment: #1977 (comment)
src/config/options.rs
Outdated
@@ -183,6 +183,9 @@ configuration_option_enum! { WriteMode: | |||
Checkstyle, | |||
// Output the changed lines (for internal value only) | |||
Modified, | |||
// Displays how much of the input was processed, but if anything was modified, rustfmt quits | |||
// with exit code 0. This option is intended to be run as part of a CI pipeline. |
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 the exit code is backwards - it should quit with 1
if anything was changed. It displays a diff, if there is one, not progress exactly.
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.
D'oh—you're right. I'll fix in subsequent commits.
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.
Fixed/resolved.
src/config/summary.rs
Outdated
@@ -26,6 +28,9 @@ pub struct Summary { | |||
// Formatted code differs from existing code (write-mode diff only). | |||
pub has_diff: bool, | |||
|
|||
// What write mode rustfmt was invoked with, if any. | |||
pub write_mode: Option<WriteMode>, |
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 don't think this needs to be optional - even if there is no explicit write mode, then there is a default.
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.
Good point. I'll default it to overwrite?
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.
Resolved, defaults to Overwrite.
README.md
Outdated
|
||
* `overwrite` Is the default and overwrites the original files _without_ creating backups. | ||
* `replace` Overwrites the original files after creating backups of the files. | ||
* `display` Will print the formatted files to stdout. | ||
* `plain` Also writes to stdout, but with no metadata. | ||
* `diff` Will print a diff between the original files and formatted files to stdout. | ||
Will also exit with an error code if there are any differences. | ||
* `check` Similar to `diff`, but is intended to be run in during CI and returns error code 1 | ||
on failure instead of 4 as `diff` does. |
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 would document check mode in its own right, rather than comparing to diff.
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.
Good point; will do.
Thanks for the PR! The 'hard' bit of running the new write mode looks great. I agree that it would be better to avoid adding the write mode to the summary and have suggested a possible solution in a review comment. I think adding assert-cli as a dev-dependency is fine. Would be good to test a few of the exit code situations. |
Thanks! Will address shortly.
Sounds good, I'll write test cases for those. Should I move the assert-cli tests away from main.rs, or...? |
So far:
Still to do:
|
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.
Thank you the PR! I think the code handling exit code needs some update, but otherwise LGTM.
src/bin/main.rs
Outdated
@@ -342,6 +346,8 @@ fn main() { | |||
Ok(summary) => { | |||
if summary.has_operational_errors() { | |||
1 |
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.
This part is a bit wrong. IIRC in check mode, the exit code should be either 0 or 1, but this change does not seem to respect it.
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.
Thanks for the feedback! I haven't gotten around to implementing #1977 (comment), but when I do later today, this the exit code handling should be far nicer and correct, wheras with my PR, it is not.
Sorry for the delay; work happened. I correct the exit code handling as I understood #1977 (comment). I'd like to clarify—should I log cause with |
Yes, I think there should be some kind of error message. However, if we're emitting errors or warnings or whatever anyway, then I don't think we need to emit an additional message. |
src/bin/main.rs
Outdated
} else if summary.has_diff { | ||
// should only happen in diff mode | ||
4 | ||
1 |
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.
You could use ||
rather than having multiple else if
branches here.
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.
Good point, will update later today.
src/bin/main.rs
Outdated
if let Some(mode) = options.write_mode { | ||
error_summary.add_write_mode(mode) | ||
} | ||
|
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 thought I suggested a refactoring to avoid saving the write mode in the error summary, but maybe that was on another PR since I can't find any trace of it.
I think that by moving some code around in the main function so that we know the write mode (i.e., process the opts outside of execute
), then we don't need to save it into the summary.
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 thought I suggested a refactoring to avoid saving the write mode in the error summary, but maybe that was on another PR since I can't find any trace of it.
No worries.
I think that by moving some code around in the main function so that we know the write mode (i.e., process the opts outside of execute), then we don't need to save it into the summary.
I think that's a good idea. I wanted to introduce a minimally invasive change with this PR, but if exit codes are gonna change, so should this.
README.md
Outdated
|
||
* `overwrite` Is the default and overwrites the original files _without_ creating backups. | ||
* `replace` Overwrites the original files after creating backups of the files. | ||
* `display` Will print the formatted files to stdout. | ||
* `plain` Also writes to stdout, but with no metadata. | ||
* `diff` Will print a diff between the original files and formatted files to stdout. | ||
Will also exit with an error code if there are any differences. | ||
* `check` Checks if a diff can be generated. If so, rustfmt outputs a diff and quits with exit code 1. |
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 would re-word, something like: "Checks if the program's formatting matches what rustfmt would do. Silently exits with code 0 if so, emits a diff and exits with code 1 if not. This option is designed to be run in CI-like where a non-zero exit signifies incorrect formatting."
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 like that; can do.
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.
Resolved.
Sorry about the slowness on my end. I've been on-call at work, but that's over. With the coming holiday, I should be able to devote some time to landing this issue. Anyways:
That being said, the way I'm handling WriteMode isn't great. I think if I'm to refactor how exit code handling and argument parsing are handled, I'd like to use StructOpt, but I'd like to be sure that it's okay I introduce this dependency. Thoughts? |
How does using StructOpt help? I'm kind of OK (I like StructOpt), but worry it might be churn for no benefit. |
I had some more time to think about it—it won't. Oops. |
@davidbarsky How's it going on this? Got any questions I can answer? |
@nrc Hi Nick! Yes! Some guidance around changing
— (apologies for the delay.) |
Yes, I think so |
Will need to rebase on mainline, but this I'm getting errors with rustc-ap-rustc_errors. Main thing—I'm not sure how I can make the handling of WriteMode/exit codes better even with refactoring. I'd like to avoid holding up further work/progress on this, I'll post what I've got. If this isn't what y'all are looking for, feel free to take this work and build atop of it/drop it. |
# Conflicts: # Cargo.lock # src/bin/main.rs
Okay, rebased. Should be conflict-free. |
This looks great, thank you! |
Update README.md to reflect change in #2539
Per rust-lang/rustfmt#2539 I think check and diff do the same thing, except that check now returns a nonzero exit code if there are changes that rustfmt would make.
This is an attempt to address #2536. Of the items to handle in the list, this PR handles:
It does not, at press time:
I'll add the latter two this weekend.
(This PR is somewhat clunky, as I was able to propagate
WriteMode
by adding an additional field to theSummary
struct. Alternatives include returning aFmtResult<(Summary, Option<WriteMode>)>
, but that felt messy.)