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

Make padded cell mandatory #561

Merged
merged 19 commits into from
May 3, 2020
Merged

Make padded cell mandatory #561

merged 19 commits into from
May 3, 2020

Conversation

nedtwigg
Copy link
Member

It simplifies the code quite a bit to just always do it, and it turns out that we were already doing enough of PaddedCell that it isn't slower anyway.

@nedtwigg
Copy link
Member Author

nedtwigg commented May 1, 2020

This PR does two main things:

  • the gradle plugin now forces paddedCell() to always be enabled, which simplies the code quite a bit. If users call the paddedCell(false/true) api in their scripts, they get a console warning to remove it, but no failures (or effect)
    • this means we can remove it from our documentation, but users still get all the benefits
    • this change is empowered partly by a minor change which means there's no performance penalty to always using paddedCell
  • adds a spotlessDiagnose task. It used to be that spotlessCheck would dump out files which could help diagnose a misbehaving formatter. Now it does not (a required regression to prepare for cacheability Make spotless tasks all cacheable with the Gradle Build Cache #280), so we fix that by adding a spotlessDiagnose task.
    • Normally the user never needs to know about this task, so we don't document it. But for the rare case where a formatter fails to converge, it adds a warning to the console saying that the file wasn't formatted, and recommending spotlessDiagnose to point the user towards the problem.

I think those two things are a slam dunk win. It's even more compelling because it makes enabling the buildcache much easier.

If there's going to be any contention, it is probably over this DirtyState API. Basically, in order for this change to not hurt performance, we need a method format(Formatter, File) which can return a single value that encodes any of:

  • this is clean
  • this is dirty, and this is the right answer
  • we can't tell if this is clean or dirty, because the formatter doesn't converge

This is the API I chose (with sentinel values for the isClean/didNotConverge cases).

/**
* The clean/dirty state of a single file. Intended use:
* - {@link #isClean()} means that the file is is clean, and there's nothing else to say
* - {@link #isConverged()} means that we were able to determine a clean state
* - once you've tested the above conditions and you know that it's a dirty file with a converged state,
* then you can call {@link #canonicalBytes()} to get the canonical form of the given file.
*/
public static class DirtyState {
private final byte[] canonicalBytes;
private DirtyState(byte[] canonicalBytes) {
this.canonicalBytes = canonicalBytes;
}
public boolean isClean() {
return this == isClean;
}
public boolean didNotConverge() {
return this == didNotConverge;
}
public byte[] canonicalBytes() {
return Objects.requireNonNull(canonicalBytes, "First make sure that `!isClean()` and `!didNotConverge()`");
}
}

Open to any feedback! One of the main goals of this PR is to make #560 easier to do, so there are some changes that seem arbitrary, but should plop into place for #560.

@nedtwigg nedtwigg requested review from jbduncan and fvgh May 1, 2020 06:21
Copy link
Member

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

Hi @nedtwigg, I've been following your ongoing conversation with @bigdaz in this repository on improving the performance (and maintainability) of Spotless further, which has excited me, so thanks for involving me in this!

In the README.md (in a place where GitHub's UI doesn't allow me to review it directly), there is a paragraph that says,

Spotless now has a special paddedCell() mode. If you add it to your format as such:

spotless {
  format 'cpp', {
    ...
    paddedCell()
  }
}

then it will run in the following way:

I think it should now be simplified to something like this:

Spotless now has a special "padded cell" mode, which is always enabled and runs in the following way:

I've added some more review comments below.

I've only had time to review part of this PR, so I'll let you know if I get around to looking at the rest. :)

gradle/java-setup.gradle Outdated Show resolved Hide resolved
lib/src/main/java/com/diffplug/spotless/PaddedCell.java Outdated Show resolved Hide resolved
lib/src/main/java/com/diffplug/spotless/PaddedCell.java Outdated Show resolved Hide resolved
Copy link
Member

@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've just gone through the rest of this PR, and other than my earlier comments, it looks good to me! 👍

- byte[] canonicalBytes() is now private, and IllegalStateException if called incorrectly
- access to canonicalBytes() is handled by `void writeCanonicalTo(File file)` and `void writeCanonicalTo(OutputStream out)`
Copy link
Member

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

Thanks for addressing my earlier comments! The README.md looks very good now.

I've just found one more place that could be improved, but I don't want to hold up this PR for too long, so I'll mark my review as "approved", and feel free to address my comment below at your own pace.

@@ -28,6 +29,8 @@
import java.util.Objects;
import java.util.function.Function;

import org.omg.CORBA.portable.OutputStream;
Copy link
Member

Choose a reason for hiding this comment

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

Oops, did you mean to import java.io.OutputStream rather than org.omg.CORBA.portable.OutputStream here?

Copy link
Member Author

Choose a reason for hiding this comment

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

Lol, thanks, good catch!!! The dangers of not following yagni ;-)

@nedtwigg nedtwigg merged commit 9c6b725 into master May 3, 2020
@nedtwigg nedtwigg deleted the feat/paddedcell-mandatory branch May 3, 2020 16:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants