Skip to content
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

Closed
wants to merge 2 commits into from
Closed

Add dry-run mode and --set-exit-if-changed option #106

wants to merge 2 commits into from

Conversation

sormuras
Copy link
Contributor

@sormuras sormuras commented Dec 14, 2016

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.

Copy link
Contributor

@jbduncan jbduncan left a 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
);
Copy link
Contributor

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")//
);
Copy link
Contributor

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") //
);
Copy link
Contributor

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();
Copy link
Contributor

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", //
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor

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
Copy link
Contributor Author

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
Copy link

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.

Copy link
Contributor Author

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)

@sormuras
Copy link
Contributor Author

@ronshapiro @cushon Any chance for the validation mode to get integrated?

@f2prateek
Copy link

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)

@sormuras
Copy link
Contributor Author

sormuras commented May 4, 2017

Seeing a diff is helpful in general -- but when it comes to google-java-format you just let it do its work. After a normal run, a failing validation check points to a bug in the formatter. See FormatterIntegrationTests#idempotent... methods.

@sormuras
Copy link
Contributor Author

sormuras commented May 4, 2017

@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. :)

@f2prateek
Copy link

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.

@sormuras
Copy link
Contributor Author

Rebased.

@sormuras
Copy link
Contributor Author

sormuras commented Jun 7, 2017

Rebased.

@sormuras
Copy link
Contributor Author

sormuras commented Aug 5, 2017

Rebased.

@sormuras
Copy link
Contributor Author

Rebased.

@cushon @plumpy Any news on having a validation / dry-run mode in the CLI of GJF?

@sormuras
Copy link
Contributor Author

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. 😉

@sormuras
Copy link
Contributor Author

Rebased to 1.4

@sormuras
Copy link
Contributor Author

sormuras commented Oct 9, 2017

  • Yes.
  • No.
  • Next year.

😉

@cushon
Copy link
Collaborator

cushon commented Oct 9, 2017

Sorry for neglecting this. I asked a clarifying question in #105.

@cushon cushon self-assigned this Oct 9, 2017
@sormuras
Copy link
Contributor Author

sormuras commented Oct 9, 2017

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");
Copy link
Collaborator

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.

Copy link
Contributor Author

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
Copy link
Collaborator

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));

Copy link
Contributor Author

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;
}
Copy link
Collaborator

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?

Copy link
Contributor Author

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.

Copy link
Collaborator

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;
   }

Copy link
Contributor Author

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);
  }

Copy link
Contributor Author

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?

Copy link
Collaborator

@cushon cushon Oct 11, 2017

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?

Copy link
Contributor Author

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?

Copy link
Collaborator

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.

Copy link
Contributor Author

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.",
Copy link
Collaborator

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok.

Copy link
Contributor Author

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?

Copy link
Collaborator

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.

Copy link
Contributor Author

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;
Copy link
Collaborator

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?

Copy link
Contributor Author

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?

Copy link
Contributor Author

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) {...}!

Copy link
Collaborator

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. On it.

Copy link
Contributor Author

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
Copy link
Contributor Author

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.

@sormuras sormuras changed the title Add validation mode. Add dry-run mode and --set-exit-if-changed option Oct 11, 2017
`--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.
@sormuras
Copy link
Contributor Author

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);
Copy link
Collaborator

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok.

@sormuras
Copy link
Contributor Author

Cleaned up and tests added.

cushon pushed a commit that referenced this pull request Oct 12, 2017
`--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.

See #105, #106

MOE_MIGRATED_REVID=171899496
@cushon
Copy link
Collaborator

cushon commented Oct 12, 2017

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!

@cushon cushon closed this Oct 12, 2017
@sormuras sormuras deleted the validate branch October 12, 2017 05:28
@sormuras
Copy link
Contributor Author

Build via https://jitpack.io/com/github/google/google-java-format/master-SNAPSHOT/build.log
Download all-deps from https://jitpack.io/com/github/google/google-java-format/google-java-format/master-SNAPSHOT/google-java-format-master-SNAPSHOT-all-deps.jar

java -jar google-java-format-master-SNAPSHOT-all-deps.jar --version

yields:

google-java-format: Version 1.5-SNAPSHOT

And running java -jar google-java-format-master-SNAPSHOT-all-deps.jar --dry-run --set-exit-if-changed on a tree of un-formatted sources exits with error code 1 as expected.

✔️

sormuras added a commit to sormuras/bach that referenced this pull request Oct 12, 2017
@sormuras
Copy link
Contributor Author

Updating my project to consume GJF 1.5-SNAPSHOT instead of my fork was trivial: sormuras/bach@99d48cb

@davido davido mentioned this pull request Oct 15, 2017
facebook-github-bot pushed a commit to facebook/ktfmt that referenced this pull request Oct 1, 2021
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants