Skip to content

Commit

Permalink
Emit contextual error message during incremental m2e builds (#1962)
Browse files Browse the repository at this point in the history
  • Loading branch information
nedtwigg committed Dec 15, 2023
2 parents 6440e64 + a4641ca commit 6579264
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ This document is intended for Spotless developers.
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`).

## [Unreleased]
### Added
* New static method to `DiffMessageFormatter` which allows to retrieve diffs with their line numbers ([#1960](https://github.com/diffplug/spotless/issues/1960))
### Changes
* Use palantir-java-format 2.39.0 on Java 21. ([#1948](https://github.com/diffplug/spotless/pull/1948))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@
import java.nio.file.Path;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Objects;

import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.diff.Edit;
import org.eclipse.jgit.diff.EditList;
import org.eclipse.jgit.diff.MyersDiff;
import org.eclipse.jgit.diff.RawText;
Expand Down Expand Up @@ -234,6 +236,19 @@ private void addIntendedLine(String indent, String line) {
* sequence (\n, \r, \r\n).
*/
private String diff(File file) throws IOException {
return diff(formatter, file).getValue();
}

/**
* Returns a map entry with value being a git-style diff between the contents of the given file and what those contents would
* look like if formatted using the given formatter. Does not end with any newline
* sequence (\n, \r, \r\n). The key of the map entry is the 0-based line where the first difference occurred.
*/
public static Map.Entry<Integer, String> diff(Formatter formatter, File file) throws IOException {
return diff(new CleanProviderFormatter(formatter), file);
}

private static Map.Entry<Integer, String> diff(CleanProvider formatter, File file) throws IOException {
String raw = new String(Files.readAllBytes(file.toPath()), formatter.getEncoding());
String rawUnix = LineEnding.toUnix(raw);
String formatted = formatter.getFormatted(file, rawUnix);
Expand All @@ -248,13 +263,13 @@ private String diff(File file) throws IOException {
}

/**
* Returns a git-style diff between the two unix strings.
* Returns a map entry with value being a git-style diff between the two unix strings and key being the 0-based line of the first difference (in the dirty string)
* <p>
* Output has no trailing newlines.
* <p>
* Boolean args determine whether whitespace or line endings will be visible.
*/
private static String diffWhitespaceLineEndings(String dirty, String clean, boolean whitespace, boolean lineEndings) throws IOException {
private static Map.Entry<Integer, String> diffWhitespaceLineEndings(String dirty, String clean, boolean whitespace, boolean lineEndings) throws IOException {
dirty = visibleWhitespaceLineEndings(dirty, whitespace, lineEndings);
clean = visibleWhitespaceLineEndings(clean, whitespace, lineEndings);

Expand All @@ -271,7 +286,11 @@ private static String diffWhitespaceLineEndings(String dirty, String clean, bool

// we don't need the diff to show this, since we display newlines ourselves
formatted = formatted.replace("\\ No newline at end of file\n", "");
return NEWLINE_MATCHER.trimTrailingFrom(formatted);
return Map.entry(getLineOfFirstDifference(edits), NEWLINE_MATCHER.trimTrailingFrom(formatted));
}

private static int getLineOfFirstDifference(EditList edits) {
return edits.stream().mapToInt(Edit::getBeginA).min().getAsInt();
}

private static final CharMatcher NEWLINE_MATCHER = CharMatcher.is('\n');
Expand Down
2 changes: 2 additions & 0 deletions plugin-maven/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`).

## [Unreleased]
### Added
* M2E support: Emit file specific errors during incremental build. ([#1960](https://github.com/diffplug/spotless/issues/1960))
### Changes
* Use palantir-java-format 2.39.0 on Java 21. ([#1948](https://github.com/diffplug/spotless/pull/1948))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.sonatype.plexus.build.incremental.BuildContext;

import com.diffplug.spotless.Formatter;
import com.diffplug.spotless.PaddedCell;
Expand Down Expand Up @@ -54,13 +56,17 @@ protected void process(Iterable<File> files, Formatter formatter, UpToDateChecke
PaddedCell.DirtyState dirtyState = PaddedCell.calculateDirtyState(formatter, file);
if (!dirtyState.isClean() && !dirtyState.didNotConverge()) {
problemFiles.add(file);
if (buildContext.isIncremental()) {
Map.Entry<Integer, String> diffEntry = DiffMessageFormatter.diff(formatter, file);
buildContext.addMessage(file, diffEntry.getKey() + 1, 0, diffEntry.getValue(), BuildContext.SEVERITY_ERROR, null);
}
counter.cleaned();
} else {
counter.checkedButAlreadyClean();
upToDateChecker.setUpToDate(file.toPath());
}
} catch (IOException | RuntimeException e) {
throw new MojoExecutionException("Unable to format file " + file, e);
throw new MojoExecutionException("Unable to check file " + file, e);
}
}

Expand Down

0 comments on commit 6579264

Please sign in to comment.