diff --git a/pom.xml b/pom.xml
index 2041543..f2fb02d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
com.theoryinpractise
googleformatter-maven-plugin
- 1.7.6-SNAPSHOT
+ 1.8.0-SNAPSHOT
maven-plugin
googleformatter-maven-plugin Maven Mojo
diff --git a/src/main/java/com/theoryinpractise/googleformatter/AbstractFormatter.java b/src/main/java/com/theoryinpractise/googleformatter/AbstractFormatter.java
new file mode 100644
index 0000000..d39f1f4
--- /dev/null
+++ b/src/main/java/com/theoryinpractise/googleformatter/AbstractFormatter.java
@@ -0,0 +1,186 @@
+package com.theoryinpractise.googleformatter;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.hash.HashCode;
+import com.google.common.hash.Hashing;
+import com.google.common.io.CharStreams;
+import com.google.googlejavaformat.java.Formatter;
+import com.google.googlejavaformat.java.JavaFormatterOptions;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.scm.ScmException;
+import org.apache.maven.scm.ScmFileSet;
+import org.apache.maven.scm.manager.ScmManager;
+import org.apache.maven.scm.repository.ScmRepository;
+import org.codehaus.plexus.compiler.util.scan.InclusionScanException;
+import org.codehaus.plexus.compiler.util.scan.SimpleSourceInclusionScanner;
+import org.codehaus.plexus.compiler.util.scan.SourceInclusionScanner;
+import org.codehaus.plexus.compiler.util.scan.StaleSourceScanner;
+import org.codehaus.plexus.compiler.util.scan.mapping.SuffixMapping;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.StandardOpenOption;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static com.theoryinpractise.googleformatter.Constants.DIRECTORY_MISSING;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+public abstract class AbstractFormatter extends AbstractMojo {
+
+ public static final SuffixMapping SOURCE_MAPPING = new SuffixMapping(".java", new HashSet<>(Arrays.asList(".java", ".class")));
+ @Component
+ ScmManager scmManager;
+
+ @Parameter(required = true, readonly = true, property = "session")
+ protected MavenSession session;
+
+ @Parameter(required = true, readonly = true, property = "project")
+ protected MavenProject project;
+
+ @Parameter(required = true, readonly = true, property = "project.build.sourceDirectory")
+ protected File sourceDirectory;
+
+ @Parameter(required = true, readonly = true, property = "project.build.testSourceDirectory")
+ protected File testSourceDirectory;
+
+ @Parameter(required = true, readonly = true, property = "project.build.outputDirectory")
+ protected File outputDirectory;
+
+ @Parameter(required = true, readonly = true, property = "project.build.testOutputDirectory")
+ protected File testOutputDirectory;
+
+ @Parameter(defaultValue = "false")
+ protected boolean includeStale;
+
+ @Parameter(defaultValue = "GOOGLE")
+ protected JavaFormatterOptions.Style style;
+
+ @Parameter(defaultValue = "false", property = "formatter.skip")
+ protected boolean skip;
+
+ @Parameter(defaultValue = "true", property = "formatter.main")
+ protected boolean formatMain;
+
+ @Parameter(defaultValue = "true", property = "formatter.test")
+ protected boolean formatTest;
+
+ @Parameter(defaultValue = "false", property = "formatter.modified")
+ protected boolean filterModified;
+
+ @Parameter(defaultValue = "false", property = "formatter.fixImports")
+ protected boolean fixImports;
+
+ @Parameter(defaultValue = "100", property = "formatter.maxLineLength")
+ protected int maxLineLength;
+
+ abstract void handleFormattedSource(File file, String formattedSource) throws MojoExecutionException;
+
+ @Override
+ public void execute() throws MojoExecutionException {
+
+ if ("pom".equals(project.getPackaging())) {
+ getLog().info("Project packaging is POM, skipping...");
+ return;
+ }
+
+ if (skip) {
+ getLog().info("Skipping source reformatting due to plugin configuration.");
+ return;
+ }
+
+ try {
+ Set sourceFiles = new HashSet<>();
+
+ if (formatMain) {
+ sourceFiles.addAll(findFilesToReformat(sourceDirectory, outputDirectory));
+ }
+ if (formatTest) {
+ sourceFiles.addAll(findFilesToReformat(testSourceDirectory, testOutputDirectory));
+ }
+
+ Set sourceFilesToProcess = filterModified ? filterUnchangedFiles(sourceFiles) : sourceFiles;
+
+ JavaFormatterOptions options = getJavaFormatterOptions();
+
+ for (File file : sourceFilesToProcess) {
+ String source = CharStreams.toString(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8));
+
+ com.google.googlejavaformat.java.Formatter formatter = new Formatter(options);
+ String formattedSource = fixImports ? formatter.formatSourceAndFixImports(source) : formatter.formatSource(source);
+
+ HashCode sourceHash = Hashing.sha256().hashString(source, StandardCharsets.UTF_8);
+ HashCode formattedHash = Hashing.sha256().hashString(formattedSource, StandardCharsets.UTF_8);
+
+ if (!formattedHash.equals(sourceHash)) {
+ handleFormattedSource(file, formattedSource);
+ }
+ }
+ } catch (Exception e) {
+ throw new MojoExecutionException(e.getMessage(), e);
+ }
+
+ }
+
+ private JavaFormatterOptions getJavaFormatterOptions() {
+ JavaFormatterOptions options = spy(JavaFormatterOptions.builder().style(style).build());
+ doReturn(maxLineLength).when(options).maxLineLength();
+ return options;
+ }
+
+ private Set filterUnchangedFiles(Set originalFiles) throws MojoExecutionException {
+ MavenProject topLevelProject = session.getTopLevelProject();
+ try {
+ if (topLevelProject.getScm().getConnection() == null && topLevelProject.getScm().getDeveloperConnection() == null) {
+ throw new MojoExecutionException(
+ "You must supply at least one of scm.connection or scm.developerConnection in your POM file if you " +
+ "specify the filterModified or filter.modified option.");
+ }
+ String connectionUrl = MoreObjects.firstNonNull(topLevelProject.getScm().getConnection(), topLevelProject.getScm().getDeveloperConnection());
+ ScmRepository repository = scmManager.makeScmRepository(connectionUrl);
+ ScmFileSet scmFileSet = new ScmFileSet(topLevelProject.getBasedir());
+ String basePath = topLevelProject.getBasedir().getAbsoluteFile().getPath();
+ List changedFiles =
+ scmManager.status(repository, scmFileSet).getChangedFiles().stream()
+ .map(f -> new File(basePath, f.getPath()).toString())
+ .collect(Collectors.toList());
+
+ return originalFiles.stream().filter(f -> changedFiles.contains(f.getPath())).collect(Collectors.toSet());
+
+ } catch (ScmException e) {
+ throw new MojoExecutionException(e.getMessage(), e);
+ }
+ }
+
+ private Set findFilesToReformat(File sourceDirectory, File outputDirectory) throws MojoExecutionException {
+ if (sourceDirectory.exists()) {
+ try {
+ SourceInclusionScanner scanner = getSourceInclusionScanner(includeStale);
+ scanner.addSourceMapping(SOURCE_MAPPING);
+ Set sourceFiles = scanner.getIncludedSources(sourceDirectory, outputDirectory);
+ getLog().info(String.format(Constants.FOUND_UNCOMPILED, sourceFiles.size(), sourceDirectory.getPath()));
+ return sourceFiles;
+ } catch (InclusionScanException e) {
+ throw new MojoExecutionException(String.format(Constants.ERROR_SCANNING_PATH, sourceDirectory.getPath()), e);
+ }
+ } else {
+ getLog().info(String.format(DIRECTORY_MISSING, sourceDirectory.getPath()));
+ return Collections.emptySet();
+ }
+ }
+
+ protected SourceInclusionScanner getSourceInclusionScanner(boolean includeStale) {
+ return includeStale ? new SimpleSourceInclusionScanner(Collections.singleton("**/*"), Collections.emptySet()) : new StaleSourceScanner(1024);
+ }
+}
diff --git a/src/main/java/com/theoryinpractise/googleformatter/GoogleFormatterMojo.java b/src/main/java/com/theoryinpractise/googleformatter/GoogleFormatterMojo.java
index baa1b33..65a7139 100644
--- a/src/main/java/com/theoryinpractise/googleformatter/GoogleFormatterMojo.java
+++ b/src/main/java/com/theoryinpractise/googleformatter/GoogleFormatterMojo.java
@@ -1,192 +1,27 @@
package com.theoryinpractise.googleformatter;
-import com.google.common.base.MoreObjects;
-import com.google.common.hash.HashCode;
-import com.google.common.hash.Hashing;
-import com.google.common.io.CharStreams;
-import com.google.googlejavaformat.java.Formatter;
-import com.google.googlejavaformat.java.JavaFormatterOptions;
-import org.apache.maven.execution.MavenSession;
-import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
-import org.apache.maven.plugins.annotations.Parameter;
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.scm.ScmException;
-import org.apache.maven.scm.ScmFileSet;
-import org.apache.maven.scm.manager.ScmManager;
-import org.apache.maven.scm.repository.ScmRepository;
-import org.codehaus.plexus.compiler.util.scan.InclusionScanException;
-import org.codehaus.plexus.compiler.util.scan.SimpleSourceInclusionScanner;
-import org.codehaus.plexus.compiler.util.scan.SourceInclusionScanner;
-import org.codehaus.plexus.compiler.util.scan.StaleSourceScanner;
-import org.codehaus.plexus.compiler.util.scan.mapping.SuffixMapping;
import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStreamReader;
+import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import static com.google.googlejavaformat.java.JavaFormatterOptions.Style;
-import static com.theoryinpractise.googleformatter.Constants.DIRECTORY_MISSING;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
/** Reformat all source files using the Google Code Formatter */
@Mojo(name = "format", defaultPhase = LifecyclePhase.PROCESS_SOURCES)
-public class GoogleFormatterMojo extends AbstractMojo {
-
- public static final SuffixMapping SOURCE_MAPPING = new SuffixMapping(".java", new HashSet<>(Arrays.asList(".java", ".class")));
- @Component ScmManager scmManager;
-
- @Parameter(required = true, readonly = true, property = "session")
- protected MavenSession session;
-
- @Parameter(required = true, readonly = true, property = "project")
- protected MavenProject project;
-
- @Parameter(required = true, readonly = true, property = "project.build.sourceDirectory")
- protected File sourceDirectory;
-
- @Parameter(required = true, readonly = true, property = "project.build.testSourceDirectory")
- protected File testSourceDirectory;
-
- @Parameter(required = true, readonly = true, property = "project.build.outputDirectory")
- protected File outputDirectory;
-
- @Parameter(required = true, readonly = true, property = "project.build.testOutputDirectory")
- protected File testOutputDirectory;
-
- @Parameter(defaultValue = "false")
- protected boolean includeStale;
-
- @Parameter(defaultValue = "GOOGLE")
- protected Style style;
-
- @Parameter(defaultValue = "false", property = "formatter.skip")
- protected boolean skip;
-
- @Parameter(defaultValue = "true", property = "formatter.main")
- protected boolean formatMain;
-
- @Parameter(defaultValue = "true", property = "formatter.test")
- protected boolean formatTest;
-
- @Parameter(defaultValue = "false", property = "formatter.modified")
- protected boolean filterModified;
-
- @Parameter(defaultValue = "false", property = "formatter.fixImports")
- protected boolean fixImports;
-
- @Parameter(defaultValue = "100", property = "formatter.maxLineLength")
- protected int maxLineLength;
-
- @Override
- public void execute() throws MojoExecutionException {
-
- if ("pom".equals(project.getPackaging())) {
- getLog().info("Project packaging is POM, skipping...");
- return;
- }
-
- if (skip) {
- getLog().info("Skipping source reformatting due to plugin configuration.");
- return;
- }
-
- try {
- Set sourceFiles = new HashSet<>();
-
- if (formatMain) {
- sourceFiles.addAll(findFilesToReformat(sourceDirectory, outputDirectory));
- }
- if (formatTest) {
- sourceFiles.addAll(findFilesToReformat(testSourceDirectory, testOutputDirectory));
- }
-
- Set sourceFilesToProcess = filterModified ? filterUnchangedFiles(sourceFiles) : sourceFiles;
-
- JavaFormatterOptions options = getJavaFormatterOptions();
-
- for (File file : sourceFilesToProcess) {
- String source = CharStreams.toString(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8));
-
- Formatter formatter = new Formatter(options);
- String formattedSource = fixImports ? formatter.formatSourceAndFixImports(source) : formatter.formatSource(source);
-
- HashCode sourceHash = Hashing.sha256().hashString(source, StandardCharsets.UTF_8);
- HashCode formattedHash = Hashing.sha256().hashString(formattedSource, StandardCharsets.UTF_8);
-
- if (!formattedHash.equals(sourceHash)) {
- // overwrite existing file
- Files.write(file.toPath(), formattedSource.getBytes(StandardCharsets.UTF_8), StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
-
- getLog().info(String.format("Reformatted file %s", file.getPath()));
+public class GoogleFormatterMojo extends AbstractFormatter {
+
+ @Override
+ public void handleFormattedSource(File file, String formattedSource) throws MojoExecutionException {
+ // overwrite existing file
+ try {
+ Files.write(file.toPath(), formattedSource.getBytes(StandardCharsets.UTF_8), StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
+ } catch (IOException e) {
+ throw new MojoExecutionException(e.getMessage(), e);
}
- }
- } catch (Exception e) {
- throw new MojoExecutionException(e.getMessage(), e);
+ getLog().info(String.format("Reformatted file %s", file.getPath()));
}
- }
-
- private JavaFormatterOptions getJavaFormatterOptions() {
- JavaFormatterOptions options = spy(JavaFormatterOptions.builder().style(style).build());
- doReturn(maxLineLength).when(options).maxLineLength();
- return options;
- }
-
- private Set filterUnchangedFiles(Set originalFiles) throws MojoExecutionException {
- MavenProject topLevelProject = session.getTopLevelProject();
- try {
- if (topLevelProject.getScm().getConnection() == null && topLevelProject.getScm().getDeveloperConnection() == null) {
- throw new MojoExecutionException(
- "You must supply at least one of scm.connection or scm.developerConnection in your POM file if you " +
- "specify the filterModified or filter.modified option.");
- }
- String connectionUrl = MoreObjects.firstNonNull(topLevelProject.getScm().getConnection(), topLevelProject.getScm().getDeveloperConnection());
- ScmRepository repository = scmManager.makeScmRepository(connectionUrl);
- ScmFileSet scmFileSet = new ScmFileSet(topLevelProject.getBasedir());
- String basePath = topLevelProject.getBasedir().getAbsoluteFile().getPath();
- List changedFiles =
- scmManager.status(repository, scmFileSet).getChangedFiles().stream()
- .map(f -> new File(basePath, f.getPath()).toString())
- .collect(Collectors.toList());
-
- return originalFiles.stream().filter(f -> changedFiles.contains(f.getPath())).collect(Collectors.toSet());
-
- } catch (ScmException e) {
- throw new MojoExecutionException(e.getMessage(), e);
- }
- }
-
- private Set findFilesToReformat(File sourceDirectory, File outputDirectory) throws MojoExecutionException {
- if (sourceDirectory.exists()) {
- try {
- SourceInclusionScanner scanner = getSourceInclusionScanner(includeStale);
- scanner.addSourceMapping(SOURCE_MAPPING);
- Set sourceFiles = scanner.getIncludedSources(sourceDirectory, outputDirectory);
- getLog().info(String.format(Constants.FOUND_UNCOMPILED, sourceFiles.size(), sourceDirectory.getPath()));
- return sourceFiles;
- } catch (InclusionScanException e) {
- throw new MojoExecutionException(String.format(Constants.ERROR_SCANNING_PATH, sourceDirectory.getPath()), e);
- }
- } else {
- getLog().info(String.format(DIRECTORY_MISSING, sourceDirectory.getPath()));
- return Collections.emptySet();
- }
- }
-
- protected SourceInclusionScanner getSourceInclusionScanner(boolean includeStale) {
- return includeStale ? new SimpleSourceInclusionScanner(Collections.singleton("**/*"), Collections.emptySet()) : new StaleSourceScanner(1024);
- }
}
diff --git a/src/main/java/com/theoryinpractise/googleformatter/ValidateCorrectFormattingMojo.java b/src/main/java/com/theoryinpractise/googleformatter/ValidateCorrectFormattingMojo.java
new file mode 100644
index 0000000..0cee264
--- /dev/null
+++ b/src/main/java/com/theoryinpractise/googleformatter/ValidateCorrectFormattingMojo.java
@@ -0,0 +1,17 @@
+package com.theoryinpractise.googleformatter;
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+
+import java.io.File;
+
+@Mojo(name = "check", defaultPhase = LifecyclePhase.VALIDATE)
+public class ValidateCorrectFormattingMojo extends AbstractFormatter {
+ @Override
+ void handleFormattedSource(File file, String formattedSource) throws MojoExecutionException {
+ throw new MojoExecutionException("Project needs formatting, please run mvn process-resources");
+ }
+}