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 ratchetFrom to maven #603

Merged
merged 13 commits into from
Jun 29, 2020
Merged

Add ratchetFrom to maven #603

merged 13 commits into from
Jun 29, 2020

Conversation

nedtwigg
Copy link
Member

@nedtwigg nedtwigg commented Jun 5, 2020

HELP WANTED. This unfinished PR implements ratchetFrom 'origin/master', which is currently only available in plugin-gradle. I am not a maven user, finishing this PR is not going to make the top of my todo list. However, I have outlined the work necessary to complete this PR, so that any interested party can take it to the finish line.

Basic implementation

In order to integrate it into maven, we need to take these two places in the maven plugin:

PaddedCell.DirtyState dirtyState = PaddedCell.calculateDirtyState(formatter, file);
if (!dirtyState.isClean() && !dirtyState.didNotConverge()) {
problemFiles.add(file);
}

PaddedCell.DirtyState dirtyState = PaddedCell.calculateDirtyState(formatter, file);
if (!dirtyState.isClean() && !dirtyState.didNotConverge()) {
dirtyState.writeCanonicalTo(file);
}

and make it look like this place in the gradle plugin (broader context in #590).

PaddedCell.DirtyState dirtyState;
if (ratchet != null && ratchet.isClean(getProject(), rootTreeSha, input)) {
dirtyState = PaddedCell.isClean();
} else {
dirtyState = PaddedCell.calculateDirtyState(formatter, input);
}

We'll also need a test, this one from gradle gets the job done pretty well:

@Test
public void singleProjectExhaustive() throws Exception {
try (Git git = Git.init().setDirectory(rootFolder()).call()) {
setFile("build.gradle").toLines(
"plugins { id 'com.diffplug.gradle.spotless' }",
"spotless {",
" ratchetFrom 'baseline'",
" format 'misc', {",
" target 'src/markdown/*.md'",
" custom 'lowercase', { str -> str.toLowerCase() }",
" bumpThisNumberIfACustomStepChanges(1)",
" }",
"}");
setFile(TEST_PATH).toContent("HELLO");
git.add().addFilepattern(TEST_PATH).call();
git.commit().setMessage("Initial state").call();
// tag this initial state as the baseline for spotless to ratchet from
git.tag().setName("baseline").call();
// so at this point we have test.md, and it would normally be dirty,
// but because it is unchanged, spotless says it is clean
assertClean();
// but if we change it so that it is not clean, spotless will now say it is dirty
setFile(TEST_PATH).toContent("HELLO WORLD");
assertDirty();
gradleRunner().withArguments("spotlessApply").build();
assertFile(TEST_PATH).hasContent("hello world");
// but if we make it unchanged again, it goes back to being clean
setFile(TEST_PATH).toContent("HELLO");
assertClean();
// and if we make the index dirty
setFile(TEST_PATH).toContent("HELLO WORLD");
git.add().addFilepattern(TEST_PATH).call();
{
// and the content dirty in the same way, then it's dirty
assertDirty();
// if we make the content something else dirty, then it's dirty
setFile(TEST_PATH).toContent("HELLO MOM");
assertDirty();
// if we make the content unchanged, even though index it and index are dirty, then it's clean
setFile(TEST_PATH).toContent("HELLO");
assertClean();
// if we delete the file, but it's still in the index, then it's clean
setFile(TEST_PATH).deleted();
assertClean();
}
// if we remove the file from the index
git.rm().addFilepattern(TEST_PATH).setCached(true).call();
{
// and it's gone in real life too, then it's clean
assertClean();
// if the content is there and unchanged, then it's clean
setFile(TEST_PATH).toContent("HELLO");
assertClean();
// if the content is dirty, then it's dirty
setFile(TEST_PATH).toContent("HELLO WORLD");
assertDirty();
}
// new files always get checked
setFile("new.md").toContent("HELLO");
{
assertDirty();
// even if they are added
git.add().addFilepattern("new.md").call();
assertDirty();
}
}
}

Integration with license

Once that is done, there's a mildly tricky bit where you really want the license step's behavior to depend on whether ratchetFrom is enabled. Here is how it is documented in gradle, and here is how it is implemented:

return FormatterStep.createLazy(LicenseHeaderStep.name(), () -> {
// by default, we should update the year if the user is using ratchetFrom
boolean updateYear = updateYearWithLatest == null ? FormatExtension.this.spotless.getRatchetFrom() != null : updateYearWithLatest;
return new LicenseHeaderStep(licenseHeader(), delimiter, yearSeparator, updateYear);
}, step -> step::format);

@nedtwigg
Copy link
Member Author

nedtwigg commented Jun 15, 2020

Will need to incorporate these commits

@nedtwigg
Copy link
Member Author

I'm working on this now.

@nedtwigg nedtwigg requested a review from lutovich June 28, 2020 06:55
@nedtwigg nedtwigg merged commit 41ed32d into master Jun 29, 2020
@nedtwigg nedtwigg deleted the feat/ratchetfrom-maven branch June 29, 2020 18:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants