-
Notifications
You must be signed in to change notification settings - Fork 848
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
Add dry-run mode and --set-exit-if-changed option #106
Conversation
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 saw a few areas for improvement in this PR, so I decided to note my thoughts down in the hope that it will make this PR more likely to meet Google's high level of standards. :)
this.removeJavadocOnlyImports); | ||
this.removeJavadocOnlyImports, | ||
this.validationMode | ||
); |
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 this bracket should be on the previous line.
System.in); | ||
int errorCodeOk = main.format("--validate", // | ||
tempJava("Simple", "enum Simple {}\n")// | ||
); |
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.
ditto
int errorCode = main.format("--validate", // | ||
tempJava("IsFormatted", "interface IsFormatted {}\n"), // | ||
tempJava("NeedsFormatting", " class NeedsFormatting { }\n") // | ||
); |
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.
ditto
} | ||
|
||
private String tempJava(String name, String code) throws Exception { | ||
Path path = testFolder.newFile( name + ".java").toPath(); |
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.
There's an unneeded space between the bracket and name
.
May I suggest running google-java-format
on the files touched by this PR to make sure everything's nice and compliant? :)
new PrintWriter(System.out, true), | ||
new PrintWriter(System.err, true), | ||
System.in); | ||
int errorCodeOk = main.format("--validate", // |
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.
Oh, it's also not clear to me why you included blank comments at the end of this line and a few of the lines below. Could you explain why they're there? Are they even needed?
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, not needed at all. And gone.
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.
Great, current version looks good to me now. :)
continue; // no formatting needed, validate next | ||
} | ||
errWriter.print(result.getKey() + ": needs formatting"); | ||
return 1; // found first file that needs formatting - exit with error 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.
Could use allOk
flag w/ continue
to print all files failing format validation here.
continue; // no formatting needed, validate next | ||
} | ||
errWriter.print(result.getKey() + ": needs formatting"); | ||
return 1; // found first file that needs formatting - exit with error 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.
can this print all files that need formatting? It's much more useful to get a list of all files that need 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.
Aye. See comment above, at #106 (review)
@ronshapiro @cushon Any chance for the validation mode to get integrated? |
This will be great to have! One thing I'll point out is that in practice I've found it extremely helpful to explain what is expected and what it received — here's how I implemented that in the Gradle Android plugin f2prateek/gradle-android-javafmt-plugin#6 (comment) |
Seeing a diff is helpful in general -- but when it comes to |
@cushon One more ping from my side regarding the "validation" feature. Do you think it's worth to have it? I can live with a simple no ... and start using my fork of the project. :) |
That's fair, I do point out in the failure about running fmt, but I also wanted to make it easy for contributors to see what exactly was different. |
Rebased. |
Rebased. |
Rebased. |
Rebased. Using https://jitpack.io/com/github/sormuras/google-java-format/validate-SNAPSHOT/ from my fork is an option -- but any answer, be it yes or no, would release me from rebasing that branch. 😉 |
Rebased to 1.4 |
😉 |
Sorry for neglecting this. I asked a clarifying question in #105. |
Rebased to 1.5-SNAPSHOT and really like the activity here and in #105 😎 |
if (idempotent) { | ||
continue; // no formatting needed, validate next | ||
} | ||
errWriter.println(path + ": needs 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'd expect stdout for this, and dropping : needs formatting
would make this easier to use in scripts.
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.
Ok.
e.getCause().printStackTrace(errWriter); | ||
} | ||
allOk = false; | ||
continue; | ||
} | ||
boolean idempotent = formatted.equals(inputs.get(path)); // not changed |
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.
perhaps more self-documenting:
boolean changed = !formatted.equals(inputs.get(path));
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.
Ok.
outWriter.write(formatted); | ||
if (parameters.isSetExitIfChanged()) { | ||
allOk = false; | ||
} |
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.
Can you move this if
to immediately below the declaration of idempotent/changed to avoid some duplication?
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.
Not so easy. The default "stdout" is implemented as a fall-through or "catch-all-else". Will try.
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.
Sorry, what am I missing?
index 7b7c873..b331a78 100644
--- a/core/src/main/java/com/google/googlejavaformat/java/Main.java
+++ b/core/src/main/java/com/google/googlejavaformat/java/Main.java
@@ -153,14 +153,14 @@ public final class Main {
continue;
}
boolean idempotent = formatted.equals(inputs.get(path)); // not changed
+ if (!idempotent && parameters.isSetExitIfChanged()) {
+ allOk = false;
+ }
if (parameters.isValidationMode()) {
if (idempotent) {
continue; // no formatting needed, validate next
}
errWriter.println(path + ": needs formatting");
- if (parameters.isSetExitIfChanged()) {
- allOk = false;
- }
continue;
}
if (parameters.inPlace()) {
@@ -174,15 +174,9 @@ public final class Main {
allOk = false;
continue;
}
- if (parameters.isSetExitIfChanged()) {
- allOk = false;
- }
continue;
}
outWriter.write(formatted);
- if (parameters.isSetExitIfChanged() && !idempotent) {
- allOk = false;
- }
}
return allOk ? 0 : 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'll push a cleaner solution. It needs logical "is-not-running-in-special-mode" helper in CommandLineOptions
:
/** Returns true if no special run-mode (like in-place or dry-run) is selected. */
boolean stdout() {
return !(inPlace || dryRun);
}
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.
Btw. should we check for "in-place" and "dry-run" are never both set at the same time?
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.
Making the combination a usage error sounds fine.
I'm still not sure I understand what the helper is needed for?
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.
Maybe I'm assuming s/t wrong here.
Should the stdout-case always print out the potentially formatted text?
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.
google-java-format T.java
always prints formatted text to stdout, regardless of whether the input was formatted. google-java-format -n T.java
prints T.java
to stdout if the input was not already formatted.
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 current iteration behaves like this. I don't see an easy way to re-use a boolean state at the moment.
" --validate, -validate", | ||
" Validate files format only. If files need format print its path to stdout.", | ||
" --set-exit-if-changed, -set-exit-if-changed", | ||
" Validate files only, do not write anything. Error code 0 means everything's formatted.", |
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 prefer:
--dry-run -n
Prints the paths of the files whose contents would change if the formatter were run normally.
--set-exit-if-changed
Return exit code 1 if there are any formatting changes
validation isn't necessarily the only use of these flags.
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.
Ok.
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.
Support -e
as a short-cut for --set-exit-if-changed
?
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 it's fine to skip the short form for this one.
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.
Ok.
} | ||
outWriter.write(formatted); | ||
if (parameters.isSetExitIfChanged() && !idempotent) { | ||
allOk = false; | ||
} | ||
} | ||
return allOk ? 0 : 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 expected to see changes to formatStdin too?
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.
Not sure about this one.
Should an exit code of 1 be returned if changes where made for input from stdin and --set-exit-if-changed
is set to true?
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 are referring to the method private int formatStdin(CommandLineOptions parameters, JavaFormatterOptions options) {...}
!
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 expect -n
and --set-exit-if-changed
to work the same for input from stdin as it does for files. For google-java-format -n -
we can reuse STDIN_FILENAME
.
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.
Ok. On 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.
Done via:
if (parameters.isDryRun()) {
outWriter.println(STDIN_FILENAME);
} else {
outWriter.write(output);
}
if (input.equals(output)) {
return 0;
}
return parameters.isSetExitIfChanged() ? 1 : 0;
} | ||
boolean changed = !formatted.equals(inputs.get(path)); | ||
if (!changed) { | ||
continue; // preserve original file |
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.
Could be transformed to
if (changed) {
...
}
for clarity. Renders the continue
obsolete.
`--dry-run` or `-n` Prints the paths of the files whose contents would change if the formatter were run normally. `--set-exit-if-changed` Return exit code 1 if there are any formatting changes.
I'll leave the PR now as-is. If anything needs a tweak or correction, let me know. Cheers! |
outWriter.write(output); | ||
return 0; | ||
if (parameters.isDryRun()) { | ||
outWriter.println(STDIN_FILENAME); |
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.
Let's only do this if the input was unformatted, same as for file inputs.
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.
Ok.
Cleaned up and tests added. |
Merged as 13354f3. I made some adjustments but nothing that should have changed behaviour. Let me know if I missed anything, and thanks for your work on this! |
Build via https://jitpack.io/com/github/google/google-java-format/master-SNAPSHOT/build.log
yields:
And running ✔️ |
Updating my project to consume GJF 1.5-SNAPSHOT instead of my fork was trivial: sormuras/bach@99d48cb |
Summary: In --dry-run mode, ktfmt will print the file paths of files that need formatting but will not change the file contents. Also added the option to exit the program with code `1` if any changes are needed rather than just if any errors happened. These changes are in alignment with google-java-format's identical options (see google/google-java-format#106). Usage: --dry-run or -n Prints the paths of the files whose contents would change if the formatter were run normally. --set-exit-if-changed Return exit code 1 if there are any formatting changes made (or detected if running in dry mode). Reviewed By: cgrushko Differential Revision: D31286652 fbshipit-source-id: c89fb72a1411766b81c28eba66614df78b0fea0a
See #105
--dry-run
or-n
Prints the paths of the files whose contents would change if the formatter were run normally.
--set-exit-if-changed
Return exit code 1 if there are any formatting changes.