From 5ff5581d96db83c78cd471da6f1eeb7f4d3fe76d Mon Sep 17 00:00:00 2001 From: lutovich Date: Sun, 14 Jan 2018 23:49:01 +0100 Subject: [PATCH 01/91] Initial version of Spotless Maven plugin Commit introduces a prototype of the Maven plugin which is able to apply Eclipse formatter step to all java files in the project. It only takes a single parameter - 'eclipseFormatFile' which is a path to the formatter configuration. Maven plugin is build and packaged using Maven which is executed from the Gradle build script via Exec plugin. This seems to be the simplest way to get a JAR with "maven-plugin" packaging. Gradle does not have a native plugin to do this. This change just adds a bare minimum to verify the approach. --- plugin-maven/build.gradle | 64 +++++++++++ .../gradle/spotless/ArtifactResolver.java | 53 +++++++++ .../gradle/spotless/MavenProvisioner.java | 13 ++- .../gradle/spotless/SpotlessMojo.java | 92 ++++++++++++++++ plugin-maven/src/main/resources/pom.xml | 104 ++++++++++++++++++ 5 files changed, 324 insertions(+), 2 deletions(-) create mode 100644 plugin-maven/src/main/java/com/diffplug/gradle/spotless/ArtifactResolver.java create mode 100644 plugin-maven/src/main/java/com/diffplug/gradle/spotless/SpotlessMojo.java create mode 100644 plugin-maven/src/main/resources/pom.xml diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index 0c63129141..bd0a0557a3 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -7,10 +7,74 @@ dependencies { compile project(':lib') compile project(':lib-extra') compile "org.apache.maven:maven-plugin-api:3.0" + compileOnly "org.apache.maven:maven-core:3.0" compileOnly "org.apache.maven.plugin-tools:maven-plugin-annotations:3.4" + compileOnly "org.eclipse.aether:aether-api:1.1.0" + compileOnly "org.eclipse.aether:aether-util:1.1.0" testCompile project(':testlib') testCompile "junit:junit:${VER_JUNIT}" testCompile "org.assertj:assertj-core:${VER_ASSERTJ}" testCompile "com.diffplug.durian:durian-testlib:${VER_DURIAN}" } + +task copyDependencies(type: Copy) { + from configurations.runtime + include 'lib.jar', 'lib-extra.jar' + into 'build/tmpMavenProject' +} + +task installLibInLocalRepo(type: Exec) { + workingDir 'build/tmpMavenProject' + commandLine "mvn", "org.apache.maven.plugins:maven-install-plugin:2.3.1:install-file", + "-Dfile=lib.jar", + "-DgroupId=com.diffplug", + "-DartifactId=lib", + "-Dversion=1.0-SNAPSHOT", + "-Dpackaging=jar", + "-DlocalRepositoryPath=local-repo" +} + +task installLibExtraInLocalRepo(type: Exec) { + workingDir 'build/tmpMavenProject' + commandLine "mvn", "org.apache.maven.plugins:maven-install-plugin:2.3.1:install-file", + "-Dfile=lib-extra.jar", + "-DgroupId=com.diffplug", + "-DartifactId=lib-extra", + "-Dversion=1.0-SNAPSHOT", + "-Dpackaging=jar", + "-DlocalRepositoryPath=local-repo" +} + +task createLocalRepo(dependsOn: [ + copyDependencies, + installLibInLocalRepo, + installLibExtraInLocalRepo +]){ +} + +task copySourceFiles(type: Copy) { + from 'src/main/java' + into 'build/tmpMavenProject/src/main/java' +} + +task copyPomXml(type: Copy) { + from 'src/main/resources/pom.xml' + into 'build/tmpMavenProject' +} + +task runMavenBuild(type: Exec, dependsOn: [ + createLocalRepo, + copySourceFiles, + copyPomXml +]) { + workingDir 'build/tmpMavenProject' + commandLine 'mvn', 'clean', 'install' +} + +task buildMavenPlugin(type: Copy, dependsOn: runMavenBuild) { + from 'build/tmpMavenProject/target' + into 'build/libs' +} + +build.finalizedBy buildMavenPlugin diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/ArtifactResolver.java b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/ArtifactResolver.java new file mode 100644 index 0000000000..24b9213e2c --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/ArtifactResolver.java @@ -0,0 +1,53 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.gradle.spotless; + +import java.io.File; +import java.util.List; +import java.util.Objects; + +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.repository.RemoteRepository; +import org.eclipse.aether.resolution.ArtifactRequest; +import org.eclipse.aether.resolution.ArtifactResolutionException; +import org.eclipse.aether.resolution.ArtifactResult; + +public class ArtifactResolver { + + private final RepositorySystem repositorySystem; + private final RepositorySystemSession repositorySystemSession; + private final List remoteRepositories; + + public ArtifactResolver(RepositorySystem repositorySystem, RepositorySystemSession repositorySystemSession, + List remoteRepositories) { + this.repositorySystem = Objects.requireNonNull(repositorySystem); + this.repositorySystemSession = Objects.requireNonNull(repositorySystemSession); + this.remoteRepositories = Objects.requireNonNull(remoteRepositories); + } + + public File resolve(String mavenCoordinate) throws ArtifactResolutionException { + Artifact artifact = new DefaultArtifact(mavenCoordinate); + ArtifactRequest request = new ArtifactRequest(); + request.setArtifact(artifact); + request.setRepositories(remoteRepositories); + + ArtifactResult result = repositorySystem.resolveArtifact(repositorySystemSession, request); + return result.getArtifact().getFile(); + } +} diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/MavenProvisioner.java b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/MavenProvisioner.java index ab70dc8777..938e3de89f 100644 --- a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/MavenProvisioner.java +++ b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/MavenProvisioner.java @@ -15,13 +15,22 @@ */ package com.diffplug.gradle.spotless; +import static java.util.stream.Collectors.toSet; + +import java.util.Objects; + import com.diffplug.spotless.Provisioner; +import com.diffplug.spotless.ThrowingEx; /** Maven integration for Provisioner. */ public class MavenProvisioner { private MavenProvisioner() {} - public static Provisioner create() { - throw new UnsupportedOperationException(); + public static Provisioner create(ArtifactResolver artifactResolver) { + Objects.requireNonNull(artifactResolver); + + return mavenCoords -> mavenCoords.stream() + .map(ThrowingEx.wrap(artifactResolver::resolve)) + .collect(toSet()); } } diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/SpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/SpotlessMojo.java new file mode 100644 index 0000000000..c4dcfae237 --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/SpotlessMojo.java @@ -0,0 +1,92 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.gradle.spotless; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static java.util.Collections.singleton; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.Set; +import java.util.stream.Stream; + +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.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.MavenProject; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.repository.RemoteRepository; + +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.Provisioner; +import com.diffplug.spotless.extra.java.EclipseFormatterStep; + +@Mojo(name = "spotless") +public class SpotlessMojo extends AbstractMojo { + + @Component + private RepositorySystem repositorySystem; + + @Parameter(defaultValue = "${repositorySystemSession}", required = true, readonly = true) + private RepositorySystemSession repositorySystemSession; + + @Parameter(defaultValue = "${project.remotePluginRepositories}", required = true, readonly = true) + private List repositories; + + @Parameter(defaultValue = "${project}", required = true, readonly = true) + private MavenProject project; + + @Parameter(property = "eclipseFormatFile", required = true) + private String eclipseFormatFile; + + @Override + public void execute() throws MojoExecutionException, MojoFailureException { + ArtifactResolver resolver = new ArtifactResolver(repositorySystem, repositorySystemSession, repositories); + + Provisioner provisioner = MavenProvisioner.create(resolver); + Set settingFiles = singleton(new File(eclipseFormatFile)); + FormatterStep step = EclipseFormatterStep.create(settingFiles, provisioner); + + for (String compileSourceRoot : project.getCompileSourceRoots()) { + Path root = Paths.get(compileSourceRoot); + try (Stream entries = Files.walk(root)) { + entries.filter(Files::isRegularFile) + .filter(file -> file.getFileName().toString().endsWith(".java")) + .forEach(file -> format(file, step)); + } catch (Exception e) { + throw new MojoExecutionException("Unable to walk the file tree", e); + } + } + } + + private void format(Path file, FormatterStep step) { + try { + getLog().info("Formatting " + file); + String contents = new String(Files.readAllBytes(file), UTF_8); + String formatted = step.format(contents, file.toFile()); + Files.write(file, formatted.getBytes(UTF_8)); + } catch (Exception e) { + throw new RuntimeException("Unable to format " + file, e); + } + } +} diff --git a/plugin-maven/src/main/resources/pom.xml b/plugin-maven/src/main/resources/pom.xml new file mode 100644 index 0000000000..d48ee9ea13 --- /dev/null +++ b/plugin-maven/src/main/resources/pom.xml @@ -0,0 +1,104 @@ + + 4.0.0 + + com.diffplug.spotless + spotless-maven-plugin + 1.0-SNAPSHOT + maven-plugin + + Spotless Maven Plugin + + + UTF-8 + 1.8 + 1.8 + + + + + local-repo + file://${basedir}/local-repo + + true + always + ignore + + + true + always + ignore + + + + + + + org.apache.maven + maven-plugin-api + 3.0 + + + org.apache.maven + maven-core + 3.0 + + + org.apache.maven.plugin-tools + maven-plugin-annotations + 3.2 + provided + + + org.eclipse.aether + aether-api + 1.1.0 + + + org.eclipse.aether + aether-util + 1.1.0 + + + + com.diffplug + lib + ${project.version} + + + com.diffplug + lib-extra + ${project.version} + + + + + + + org.apache.maven.plugins + maven-plugin-plugin + 3.5 + + + maven-shade-plugin + 3.1.0 + + + package + + shade + + + + + com.diffplug:* + + + + + + + + + + From 9956473ba6a030b428fd0391f747095e7a60b63e Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Wed, 17 Jan 2018 11:45:19 -0800 Subject: [PATCH 02/91] Switched maven plugin over to Formatter. --- .../gradle/spotless/SpotlessMojo.java | 42 +++++++++++++------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/SpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/SpotlessMojo.java index c4dcfae237..a8d24ecf2e 100644 --- a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/SpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/SpotlessMojo.java @@ -15,13 +15,16 @@ */ package com.diffplug.gradle.spotless; -import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.Collections.singleton; import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Set; import java.util.stream.Stream; @@ -37,8 +40,11 @@ import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.repository.RemoteRepository; +import com.diffplug.spotless.Formatter; import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.LineEnding; import com.diffplug.spotless.Provisioner; +import com.diffplug.spotless.ThrowingEx; import com.diffplug.spotless.extra.java.EclipseFormatterStep; @Mojo(name = "spotless") @@ -62,31 +68,43 @@ public class SpotlessMojo extends AbstractMojo { @Override public void execute() throws MojoExecutionException, MojoFailureException { ArtifactResolver resolver = new ArtifactResolver(repositorySystem, repositorySystemSession, repositories); - Provisioner provisioner = MavenProvisioner.create(resolver); + + // create the eclipse step Set settingFiles = singleton(new File(eclipseFormatFile)); - FormatterStep step = EclipseFormatterStep.create(settingFiles, provisioner); + FormatterStep step = EclipseFormatterStep.create(EclipseFormatterStep.defaultVersion(), + settingFiles, provisioner); + // collect all the files that are going to be formatted + File rootDir = project.getFile(); + List toFormat = new ArrayList<>(); for (String compileSourceRoot : project.getCompileSourceRoots()) { Path root = Paths.get(compileSourceRoot); try (Stream entries = Files.walk(root)) { entries.filter(Files::isRegularFile) .filter(file -> file.getFileName().toString().endsWith(".java")) - .forEach(file -> format(file, step)); + .map(Path::toFile) + .forEach(toFormat::add); } catch (Exception e) { throw new MojoExecutionException("Unable to walk the file tree", e); } } - } - private void format(Path file, FormatterStep step) { + // create a formatter + Formatter formatter = Formatter.builder() + .lineEndingsPolicy(LineEnding.GIT_ATTRIBUTES.createPolicy(rootDir, () -> toFormat)) + .encoding(StandardCharsets.UTF_8) + .rootDir(rootDir.toPath()) + .steps(Collections.singletonList(step)) + .build(); + + // use the formatter to format all the files try { - getLog().info("Formatting " + file); - String contents = new String(Files.readAllBytes(file), UTF_8); - String formatted = step.format(contents, file.toFile()); - Files.write(file, formatted.getBytes(UTF_8)); - } catch (Exception e) { - throw new RuntimeException("Unable to format " + file, e); + for (File file : toFormat) { + formatter.applyTo(file); + } + } catch (IOException e) { + throw ThrowingEx.asRuntime(e); } } } From c219ef18711f6cefcadd73841ea86db64a85527f Mon Sep 17 00:00:00 2001 From: lutovich Date: Wed, 17 Jan 2018 21:55:48 +0100 Subject: [PATCH 03/91] Improved config handling in maven plugin Exposed `encoding` and `lineEndings` in the plugin xml configuration. Renamed `eclipseFormatFile` to `eclipseConfigFile` and moved it inside the `` tag. Maven plugins can handle nested configs using Plexus dependency injection and POJO objects. Thus introduced a dedicated class for all java related configuration called `Java`. Plugin xml configuration can now look like: ``` com.diffplug.spotless spotless-maven-plugin ${spotless.version} UTF-8 UNIX ${basedir}/eclipse-fmt.xml ``` Extracted an abstract `AbstractSpotlessMojo` to hold all injected dependencies. It can be potentially used in future to implement the `check` goal. Changed name of `SpotlessMojo` from "spotless" to "apply" so that it can be invoked with `mvn spotless:apply`. --- .../gradle/spotless/AbstractSpotlessMojo.java | 92 +++++++++++++++++++ .../com/diffplug/gradle/spotless/Java.java | 30 ++++++ .../gradle/spotless/SpotlessMojo.java | 89 ++++++++---------- 3 files changed, 158 insertions(+), 53 deletions(-) create mode 100644 plugin-maven/src/main/java/com/diffplug/gradle/spotless/AbstractSpotlessMojo.java create mode 100644 plugin-maven/src/main/java/com/diffplug/gradle/spotless/Java.java diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/AbstractSpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/AbstractSpotlessMojo.java new file mode 100644 index 0000000000..20aac4f1b0 --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/AbstractSpotlessMojo.java @@ -0,0 +1,92 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.gradle.spotless; + +import static java.util.stream.Collectors.toList; + +import java.io.File; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.stream.Stream; + +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugins.annotations.Component; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.MavenProject; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.repository.RemoteRepository; + +import com.diffplug.spotless.LineEnding; + +public abstract class AbstractSpotlessMojo extends AbstractMojo { + + private static final String DEFAULT_ENCODING = "UTF-8"; + private static final String DEFAULT_LINE_ENDINGS = "GIT_ATTRIBUTES"; + + @Component + private RepositorySystem repositorySystem; + + @Parameter(defaultValue = "${repositorySystemSession}", required = true, readonly = true) + private RepositorySystemSession repositorySystemSession; + + @Parameter(defaultValue = "${project.remotePluginRepositories}", required = true, readonly = true) + private List repositories; + + @Parameter(defaultValue = "${project}", required = true, readonly = true) + private MavenProject project; + + @Parameter(defaultValue = DEFAULT_ENCODING) + private String encoding; + + @Parameter(defaultValue = DEFAULT_LINE_ENDINGS) + private LineEnding lineEndings; + + @Parameter(required = true) + private Java java; + + protected ArtifactResolver createArtifactResolver() { + return new ArtifactResolver(repositorySystem, repositorySystemSession, repositories); + } + + protected List getAllSourceRoots() { + Stream compileSourceRoots = project.getCompileSourceRoots().stream(); + Stream testCompileSourceRoots = project.getTestCompileSourceRoots().stream(); + return Stream.concat(compileSourceRoots, testCompileSourceRoots) + .map(Paths::get) + .filter(Files::isDirectory) + .collect(toList()); + } + + protected Charset getEncoding() { + return Charset.forName(encoding); + } + + protected LineEnding.Policy getLineEndingsPolicy(List filesToFormat) { + return lineEndings.createPolicy(getRootDir(), () -> filesToFormat); + } + + protected File getRootDir() { + return project.getBasedir(); + } + + protected Java getJavaConfig() { + return java; + } +} diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/Java.java b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/Java.java new file mode 100644 index 0000000000..485ea89694 --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/Java.java @@ -0,0 +1,30 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.gradle.spotless; + +import java.io.File; + +public class Java { + private File eclipseConfigFile; + + public File getEclipseConfigFile() { + return eclipseConfigFile; + } + + public void setEclipseConfigFile(File eclipseConfigFile) { + this.eclipseConfigFile = eclipseConfigFile; + } +} diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/SpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/SpotlessMojo.java index a8d24ecf2e..b3cacd8631 100644 --- a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/SpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/SpotlessMojo.java @@ -16,95 +16,78 @@ package com.diffplug.gradle.spotless; import static java.util.Collections.singleton; +import static java.util.Collections.singletonList; import java.io.File; import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Set; import java.util.stream.Stream; -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.Mojo; -import org.apache.maven.plugins.annotations.Parameter; -import org.apache.maven.project.MavenProject; -import org.eclipse.aether.RepositorySystem; -import org.eclipse.aether.RepositorySystemSession; -import org.eclipse.aether.repository.RemoteRepository; +import com.diffplug.spotless.FormatExceptionPolicyStrict; import com.diffplug.spotless.Formatter; import com.diffplug.spotless.FormatterStep; -import com.diffplug.spotless.LineEnding; import com.diffplug.spotless.Provisioner; -import com.diffplug.spotless.ThrowingEx; import com.diffplug.spotless.extra.java.EclipseFormatterStep; -@Mojo(name = "spotless") -public class SpotlessMojo extends AbstractMojo { - - @Component - private RepositorySystem repositorySystem; - - @Parameter(defaultValue = "${repositorySystemSession}", required = true, readonly = true) - private RepositorySystemSession repositorySystemSession; - - @Parameter(defaultValue = "${project.remotePluginRepositories}", required = true, readonly = true) - private List repositories; - - @Parameter(defaultValue = "${project}", required = true, readonly = true) - private MavenProject project; - - @Parameter(property = "eclipseFormatFile", required = true) - private String eclipseFormatFile; +@Mojo(name = "apply") +public class SpotlessMojo extends AbstractSpotlessMojo { @Override public void execute() throws MojoExecutionException, MojoFailureException { - ArtifactResolver resolver = new ArtifactResolver(repositorySystem, repositorySystemSession, repositories); - Provisioner provisioner = MavenProvisioner.create(resolver); + List filesToFormat = collectFilesToFormat(); - // create the eclipse step - Set settingFiles = singleton(new File(eclipseFormatFile)); - FormatterStep step = EclipseFormatterStep.create(EclipseFormatterStep.defaultVersion(), - settingFiles, provisioner); + Formatter formatter = createFormatter(filesToFormat); - // collect all the files that are going to be formatted - File rootDir = project.getFile(); - List toFormat = new ArrayList<>(); - for (String compileSourceRoot : project.getCompileSourceRoots()) { - Path root = Paths.get(compileSourceRoot); + formatAll(filesToFormat, formatter); + } + + private List collectFilesToFormat() throws MojoExecutionException { + List filesToFormat = new ArrayList<>(); + for (Path root : getAllSourceRoots()) { try (Stream entries = Files.walk(root)) { entries.filter(Files::isRegularFile) .filter(file -> file.getFileName().toString().endsWith(".java")) .map(Path::toFile) - .forEach(toFormat::add); - } catch (Exception e) { + .forEach(filesToFormat::add); + } catch (IOException e) { throw new MojoExecutionException("Unable to walk the file tree", e); } } + return filesToFormat; + } - // create a formatter - Formatter formatter = Formatter.builder() - .lineEndingsPolicy(LineEnding.GIT_ATTRIBUTES.createPolicy(rootDir, () -> toFormat)) - .encoding(StandardCharsets.UTF_8) - .rootDir(rootDir.toPath()) - .steps(Collections.singletonList(step)) + private Formatter createFormatter(List filesToFormat) { + return Formatter.builder() + .encoding(getEncoding()) + .lineEndingsPolicy(getLineEndingsPolicy(filesToFormat)) + .exceptionPolicy(new FormatExceptionPolicyStrict()) + .steps(singletonList(createEclipseFormatterStep())) + .rootDir(getRootDir().toPath()) .build(); + } + + private FormatterStep createEclipseFormatterStep() { + ArtifactResolver artifactResolver = createArtifactResolver(); + Provisioner provisioner = MavenProvisioner.create(artifactResolver); + Set settingFiles = singleton(getJavaConfig().getEclipseConfigFile()); + return EclipseFormatterStep.create(EclipseFormatterStep.defaultVersion(), settingFiles, provisioner); + } - // use the formatter to format all the files - try { - for (File file : toFormat) { + private static void formatAll(List files, Formatter formatter) throws MojoExecutionException { + for (File file : files) { + try { formatter.applyTo(file); + } catch (IOException e) { + throw new MojoExecutionException("Unable to format file " + file, e); } - } catch (IOException e) { - throw ThrowingEx.asRuntime(e); } } } From a5a6cc93da63c0be1a62e4c857f07f489ddf545f Mon Sep 17 00:00:00 2001 From: lutovich Date: Wed, 17 Jan 2018 22:39:08 +0100 Subject: [PATCH 04/91] Removed dependency on maven-core Injected `MavenProject` is now replaced by injection of multiple primitive values, like `project.basedir`. --- plugin-maven/build.gradle | 1 - .../gradle/spotless/AbstractSpotlessMojo.java | 21 +++++++++++-------- .../gradle/spotless/SpotlessMojo.java | 2 +- plugin-maven/src/main/resources/pom.xml | 5 ----- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index bd0a0557a3..4cfdd8a834 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -7,7 +7,6 @@ dependencies { compile project(':lib') compile project(':lib-extra') compile "org.apache.maven:maven-plugin-api:3.0" - compileOnly "org.apache.maven:maven-core:3.0" compileOnly "org.apache.maven.plugin-tools:maven-plugin-annotations:3.4" compileOnly "org.eclipse.aether:aether-api:1.1.0" compileOnly "org.eclipse.aether:aether-util:1.1.0" diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/AbstractSpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/AbstractSpotlessMojo.java index 20aac4f1b0..87ea46981b 100644 --- a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/AbstractSpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/AbstractSpotlessMojo.java @@ -28,7 +28,6 @@ import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.Parameter; -import org.apache.maven.project.MavenProject; import org.eclipse.aether.RepositorySystem; import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.repository.RemoteRepository; @@ -49,8 +48,14 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo { @Parameter(defaultValue = "${project.remotePluginRepositories}", required = true, readonly = true) private List repositories; - @Parameter(defaultValue = "${project}", required = true, readonly = true) - private MavenProject project; + @Parameter(defaultValue = "${project.basedir}", required = true, readonly = true) + private File baseDir; + + @Parameter(defaultValue = "${project.compileSourceRoots}", required = true, readonly = true) + private List compileSourceRoots; + + @Parameter(defaultValue = "${project.testCompileSourceRoots}", required = true, readonly = true) + private List testCompileSourceRoots; @Parameter(defaultValue = DEFAULT_ENCODING) private String encoding; @@ -66,9 +71,7 @@ protected ArtifactResolver createArtifactResolver() { } protected List getAllSourceRoots() { - Stream compileSourceRoots = project.getCompileSourceRoots().stream(); - Stream testCompileSourceRoots = project.getTestCompileSourceRoots().stream(); - return Stream.concat(compileSourceRoots, testCompileSourceRoots) + return Stream.concat(compileSourceRoots.stream(), testCompileSourceRoots.stream()) .map(Paths::get) .filter(Files::isDirectory) .collect(toList()); @@ -79,11 +82,11 @@ protected Charset getEncoding() { } protected LineEnding.Policy getLineEndingsPolicy(List filesToFormat) { - return lineEndings.createPolicy(getRootDir(), () -> filesToFormat); + return lineEndings.createPolicy(getBaseDir(), () -> filesToFormat); } - protected File getRootDir() { - return project.getBasedir(); + protected File getBaseDir() { + return baseDir; } protected Java getJavaConfig() { diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/SpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/SpotlessMojo.java index b3cacd8631..8227e98ba2 100644 --- a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/SpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/SpotlessMojo.java @@ -70,7 +70,7 @@ private Formatter createFormatter(List filesToFormat) { .lineEndingsPolicy(getLineEndingsPolicy(filesToFormat)) .exceptionPolicy(new FormatExceptionPolicyStrict()) .steps(singletonList(createEclipseFormatterStep())) - .rootDir(getRootDir().toPath()) + .rootDir(getBaseDir().toPath()) .build(); } diff --git a/plugin-maven/src/main/resources/pom.xml b/plugin-maven/src/main/resources/pom.xml index d48ee9ea13..29df8842b3 100644 --- a/plugin-maven/src/main/resources/pom.xml +++ b/plugin-maven/src/main/resources/pom.xml @@ -38,11 +38,6 @@ maven-plugin-api 3.0 - - org.apache.maven - maven-core - 3.0 - org.apache.maven.plugin-tools maven-plugin-annotations From 1d63aa29b5ccee2bc5c5308ae62218178fb2c619 Mon Sep 17 00:00:00 2001 From: lutovich Date: Wed, 17 Jan 2018 23:24:37 +0100 Subject: [PATCH 05/91] Simplified maven plugin build process Removed shading & local repository for `lib` and `lib-extra`. Instead made plugin directly depend on stable version denoted by `project.stableLib`. Made all maven plugin API dependencies provided and their versions injected by the Gradle build script. --- gradle.properties | 4 ++ plugin-maven/build.gradle | 82 +++++++++---------------- plugin-maven/src/main/resources/pom.xml | 68 +++++++------------- 3 files changed, 55 insertions(+), 99 deletions(-) diff --git a/gradle.properties b/gradle.properties index 8b1316075e..beabbbf536 100644 --- a/gradle.properties +++ b/gradle.properties @@ -31,3 +31,7 @@ VER_PEGDOWN_DOCLET=1.3 VER_DURIAN=1.2.0 VER_JUNIT=4.12 VER_ASSERTJ=3.5.2 + +# Used for Maven Plugin +VER_MAVEN_API=3.0 +VER_ECLIPSE_AETHER=1.1.0 diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index 4cfdd8a834..0163b47d96 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -1,79 +1,55 @@ ext.artifactId = project.artifactIdMaven ext.version = project.versionMaven -apply from: rootProject.file('gradle/java-setup.gradle') -apply from: rootProject.file('gradle/java-publish.gradle') +apply from: rootProject.file("gradle/java-setup.gradle") +apply from: rootProject.file("gradle/java-publish.gradle") dependencies { - compile project(':lib') - compile project(':lib-extra') - compile "org.apache.maven:maven-plugin-api:3.0" - compileOnly "org.apache.maven.plugin-tools:maven-plugin-annotations:3.4" - compileOnly "org.eclipse.aether:aether-api:1.1.0" - compileOnly "org.eclipse.aether:aether-util:1.1.0" - - testCompile project(':testlib') + compile project(":lib") + compile project(":lib-extra") + compileOnly "org.apache.maven:maven-plugin-api:${VER_MAVEN_API}" + compileOnly "org.apache.maven.plugin-tools:maven-plugin-annotations:${VER_MAVEN_API}" + compileOnly "org.eclipse.aether:aether-api:${VER_ECLIPSE_AETHER}" + compileOnly "org.eclipse.aether:aether-util:${VER_ECLIPSE_AETHER}" + + testCompile project(":testlib") testCompile "junit:junit:${VER_JUNIT}" testCompile "org.assertj:assertj-core:${VER_ASSERTJ}" testCompile "com.diffplug.durian:durian-testlib:${VER_DURIAN}" } -task copyDependencies(type: Copy) { - from configurations.runtime - include 'lib.jar', 'lib-extra.jar' - into 'build/tmpMavenProject' -} - -task installLibInLocalRepo(type: Exec) { - workingDir 'build/tmpMavenProject' - commandLine "mvn", "org.apache.maven.plugins:maven-install-plugin:2.3.1:install-file", - "-Dfile=lib.jar", - "-DgroupId=com.diffplug", - "-DartifactId=lib", - "-Dversion=1.0-SNAPSHOT", - "-Dpackaging=jar", - "-DlocalRepositoryPath=local-repo" -} - -task installLibExtraInLocalRepo(type: Exec) { - workingDir 'build/tmpMavenProject' - commandLine "mvn", "org.apache.maven.plugins:maven-install-plugin:2.3.1:install-file", - "-Dfile=lib-extra.jar", - "-DgroupId=com.diffplug", - "-DartifactId=lib-extra", - "-Dversion=1.0-SNAPSHOT", - "-Dpackaging=jar", - "-DlocalRepositoryPath=local-repo" -} - -task createLocalRepo(dependsOn: [ - copyDependencies, - installLibInLocalRepo, - installLibExtraInLocalRepo -]){ -} +task cleanMavenProjectDir(type: Delete) { delete "build/tmpMavenProject" } task copySourceFiles(type: Copy) { - from 'src/main/java' - into 'build/tmpMavenProject/src/main/java' + from "src/main/java" + into "build/tmpMavenProject/src/main/java" } task copyPomXml(type: Copy) { - from 'src/main/resources/pom.xml' - into 'build/tmpMavenProject' + from "src/main/resources/pom.xml" + into "build/tmpMavenProject" + + // inject versions while copying + filter { String line -> + line.replace("VER_MAVEN_API", "${VER_MAVEN_API}") + .replace("VER_ECLIPSE_AETHER", "${VER_ECLIPSE_AETHER}") + .replace("VER_SPOTLESS_LIB", "${project.stableLib}") + } + + filteringCharset = "UTF-8" } task runMavenBuild(type: Exec, dependsOn: [ - createLocalRepo, + cleanMavenProjectDir, copySourceFiles, copyPomXml ]) { - workingDir 'build/tmpMavenProject' - commandLine 'mvn', 'clean', 'install' + workingDir "build/tmpMavenProject" + commandLine "mvn", "clean", "install" } task buildMavenPlugin(type: Copy, dependsOn: runMavenBuild) { - from 'build/tmpMavenProject/target' - into 'build/libs' + from "build/tmpMavenProject/target" + into "build/libs" } build.finalizedBy buildMavenPlugin diff --git a/plugin-maven/src/main/resources/pom.xml b/plugin-maven/src/main/resources/pom.xml index 29df8842b3..4676c8ee03 100644 --- a/plugin-maven/src/main/resources/pom.xml +++ b/plugin-maven/src/main/resources/pom.xml @@ -13,86 +13,62 @@ UTF-8 1.8 1.8 - - - - local-repo - file://${basedir}/local-repo - - true - always - ignore - - - true - always - ignore - - - + + VER_MAVEN_API + VER_ECLIPSE_AETHER + VER_SPOTLESS_LIB + org.apache.maven maven-plugin-api - 3.0 + ${maven.api.version} + provided org.apache.maven.plugin-tools maven-plugin-annotations - 3.2 + ${maven.api.version} provided org.eclipse.aether aether-api - 1.1.0 + ${eclipse.aether.version} + provided org.eclipse.aether aether-util - 1.1.0 + ${eclipse.aether.version} + provided - com.diffplug - lib - ${project.version} + com.diffplug.spotless + spotless-lib + ${spotless.lib.version} - com.diffplug - lib-extra - ${project.version} + com.diffplug.spotless + spotless-lib-extra + ${spotless.lib.version} + org.apache.maven.plugins maven-plugin-plugin 3.5 - - maven-shade-plugin - 3.1.0 - - - package - - shade - - - - - com.diffplug:* - - - - - - From af677abe83b1b84e40ed6f68cd1d88f2e416dcf1 Mon Sep 17 00:00:00 2001 From: lutovich Date: Wed, 17 Jan 2018 23:52:45 +0100 Subject: [PATCH 06/91] Set maven plugin version from gradle props --- plugin-maven/build.gradle | 3 ++- plugin-maven/src/main/resources/pom.xml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index 0163b47d96..9d4eab5ede 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -30,7 +30,8 @@ task copyPomXml(type: Copy) { // inject versions while copying filter { String line -> - line.replace("VER_MAVEN_API", "${VER_MAVEN_API}") + line.replace("VER_PLUGIN", "${project.versionMaven}") + .replace("VER_MAVEN_API", "${VER_MAVEN_API}") .replace("VER_ECLIPSE_AETHER", "${VER_ECLIPSE_AETHER}") .replace("VER_SPOTLESS_LIB", "${project.stableLib}") } diff --git a/plugin-maven/src/main/resources/pom.xml b/plugin-maven/src/main/resources/pom.xml index 4676c8ee03..05f2e4f08a 100644 --- a/plugin-maven/src/main/resources/pom.xml +++ b/plugin-maven/src/main/resources/pom.xml @@ -4,7 +4,7 @@ com.diffplug.spotless spotless-maven-plugin - 1.0-SNAPSHOT + VER_PLUGIN maven-plugin Spotless Maven Plugin From b059d536865214891d2cfc6d45b93794b21555bc Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Fri, 19 Jan 2018 12:30:24 -0800 Subject: [PATCH 07/91] Added "aspiring" docs for the maven plugin. These don't match the current implementation exactly, but I think they're close. I don't know much about maven, lets get the docs right, and then build to the docs. --- README.md | 1 + plugin-maven/CHANGES.md | 117 +---------------------------- plugin-maven/README.md | 161 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 164 insertions(+), 115 deletions(-) diff --git a/README.md b/README.md index eda5ea2919..1c9fdab66a 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,7 @@ lib('sql.DBeaverSQLFormatterStep') +'{{yes}} | {{no}} ## Acknowledgements +* Thanks to [Konstantin Lutovich](https://github.com/lutovich) for [implementing the maven plugin](https://github.com/diffplug/spotless/pull/188). * Thanks to [Baptiste Mesta](https://github.com/baptistemesta) for + porting the DBeaver formatter to Spotless, and thanks to [DBeaver](https://dbeaver.jkiss.org/) and [its authors](https://github.com/serge-rider/dbeaver/graphs/contributors) for their excellent SQL formatter. + making license headers date-aware [#180](https://github.com/diffplug/spotless/pull/180) diff --git a/plugin-maven/CHANGES.md b/plugin-maven/CHANGES.md index 9e3b891e40..3255bd7889 100644 --- a/plugin-maven/CHANGES.md +++ b/plugin-maven/CHANGES.md @@ -1,116 +1,5 @@ -# spotless-plugin-gradle releases +# spotless-plugin-maven releases -### Version 3.0.0-SNAPSHOT - TBD ([javadoc](https://diffplug.github.io/spotless/javadoc/snapshot/), [snapshot](https://oss.sonatype.org/content/repositories/snapshots/com/diffplug/spotless/spotless-plugin-maven/)) +### Version 1.0.0-SNAPSHOT - TBD ([javadoc](https://diffplug.github.io/spotless/javadoc/spotless-plugin-maven/snapshot/), [snapshot](https://oss.sonatype.org/content/repositories/snapshots/com/diffplug/spotless/spotless-plugin-maven/)) -* BREAKING CHANGE: `customReplace` and `customReplaceRegex` renamed to just `replace` and `replaceRegex`. -* BREAKING CHANGE: Plugin portal ID is still `com.diffplug.gradle.spotless`, but maven coordinate has changed to `com.diffplug.spotless:spotless-plugin-gradle`. -* HUGE SPEEDUP: Now supports incremental build / up-to-date-checking. - + If you are using `custom` or `customLazy`, you might want to take a look at [this javadoc](https://diffplug.github.io/spotless/javadoc/snapshot/spotless-gradle-plugin/snapshot/com/diffplug/gradle/spotless/FormatExtension.html#bumpThisNumberIfACustomStepChanges-int-). - -### Version 2.4.1 - January 2nd 2017 ([javadoc](https://diffplug.github.io/spotless/javadoc/2.4.1/), [jcenter](https://bintray.com/diffplug/opensource/spotless/2.4.1/view)) - -* Java files under the `src/main/groovy` folder are now formatted by default. ([Issue #59](https://github.com/diffplug/spotless/issues/59), [PR #60](https://github.com/diffplug/spotless/pull/60), thanks @ajoberstar). - -### Version 2.4.0 - November 1st 2016 ([javadoc](https://diffplug.github.io/spotless/javadoc/2.4.0/), [jcenter](https://bintray.com/diffplug/opensource/spotless/2.4.0/view)) - -* If a formatter step throws an `Error` or any of its subclasses, such as the `AssertionError`s thrown by JUnit, AssertJ, etc. that error will kill the build ([#46](https://github.com/diffplug/spotless/issues/46)) - + This allows custom rules like this: - -```gradle -custom 'no swearing', { - if (it.toLowerCase().contains('fubar')) { - throw new AssertionError('No swearing!'); - } -} -``` - -### Version 2.3.0 - October 27th 2016 ([javadoc](https://diffplug.github.io/spotless/javadoc/2.3.0/), [jcenter](https://bintray.com/diffplug/opensource/spotless/2.3.0/view)) - -* When `spotlessCheck` fails, the error message now contains a short diff of what is neccessary to fix the issue ([#10](https://github.com/diffplug/spotless/issues/10), thanks to Jonathan Bluett-Duncan). -* Added a [padded-cell mode](https://github.com/diffplug/spotless/blob/master/PADDEDCELL.md) which allows spotless to band-aid over misbehaving rules, and generate error reports for these rules (See [#37](https://github.com/diffplug/spotless/issues/37) for an example). -* Character encoding is now configurable (spotless-global or format-by-format). -* Line endings were previously only spotless-global, they now also support format-by-format. -* Upgraded eclipse formatter from 4.6.0 to 4.6.1 - -### Version 2.2.0 - October 7th 2016 ([javadoc](https://diffplug.github.io/spotless/javadoc/2.2.0/), [jcenter](https://bintray.com/diffplug/opensource/spotless/2.2.0/view)) - -* Added support for [google-java-format](https://github.com/google/google-java-format). - -``` -spotless { - java { - googleJavaFormat() // googleJavaFormat('1.1') to specify a specific version - } -} -``` - -### Version 2.1.0 - October 7th 2016 ([javadoc](https://diffplug.github.io/spotless/javadoc/2.1.0/), [jcenter](https://bintray.com/diffplug/opensource/spotless/2.1.0/view)) - -* Added the method `FormatExtension::customLazyGroovy` which fixes the Groovy closure problem. - -### Version 2.0.0 - August 16th 2016 ([javadoc](https://diffplug.github.io/spotless/javadoc/2.0.0/), [jcenter](https://bintray.com/diffplug/opensource/spotless/2.0.0/view)) - -* `spotlessApply` now writes out a file only if it needs to be changed (big performance improvement). -* Java import sorting now removes duplicate imports. -* Eclipse formatter now warns if the formatter xml contains multiple profiles. -* Updated eclipse formatter to Eclipse Neon (4.6). -* BREAKING CHANGE: Eclipse formatter now formats javadoc comments. - + You might want to look at the following settings in your `spotless.eclipseformat.xml`: - -``` -org.eclipse.jdt.core.formatter.join_lines_in_comments=true/false -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true/false -org.eclipse.jdt.core.formatter.comment.format_line_comments=true/false -org.eclipse.jdt.core.formatter.comment.format_block_comments=true/false -``` - -The most important breaking change of 2.0 is the new default line ending mode, `GIT_ATTRIBUTES`. This line ending mode copies git's behavior exactly. This change should require no intervention from users, and should be significantly easier to adopt for users who are already using `.gitattributes` or the `core.eol` property. - -If you aren't using git, you can still use `.gitattributes` files for fine-grained control of line endings. If no git information is found, it behaves the same as PLATFORM_NATIVE (the old default). - -Below is the algorithm used by git and spotless to determine the proper line ending for a file. As soon as a step succeeds in finding a line ending, the other steps will not take place. - -1. If the code is a git repository, look in the `$GIT_DIR/info/attributes` file for the `eol` attribute. -2. Look at the `.gitattributes` in the file's directory, going up the directory tree. -3. Look at the global `.gitattributes` file, if any. -4. Look at the `core.eol` property in the git config (looking first at repo-specific, then user-specific, then system-specific). -5. Use the PLATFORM_NATIVE line ending. - -### Version 1.3.3 - March 10th 2016 ([jcenter](https://bintray.com/diffplug/opensource/spotless/1.3.3/view)) - -* Upgraded Eclipse formatter to 4.5.2, which fixes [37 bugs](https://bugs.eclipse.org/bugs/buglist.cgi?query_format=advanced&resolution=FIXED&short_desc=%5Bformatter%5D&short_desc_type=allwordssubstr&target_milestone=4.5.1&target_milestone=4.5.2) compared to the previous 4.5.0. -* If you have been using `custom 'Lambda fix', { it.replace('} )', '})').replace('} ,', '},') }`, you don't need it anymore. - -### Version 1.3.2 - December 17th 2015 ([jcenter](https://bintray.com/diffplug/opensource/spotless/1.3.2/view)) - -* Spotless no longer clobbers package-info.java, fixes [#1](https://github.com/diffplug/spotless/issues/1). -* Added some infrastructure which allows `FormatterStep`s to peek at the filename if they really need to. - -### Version 1.3.1 - September 22nd 2015 ([jcenter](https://bintray.com/diffplug/opensource/spotless/1.3.1/view)) - -* Bumped the FreshMark dependency to 1.3.0, because it offers improved error reporting. - -### Version 1.3.0 - September 22nd 2015 ([jcenter](https://bintray.com/diffplug/opensource/spotless/1.3.0/view)) - -* Added native support for FreshMark. - -### Version 1.2.0 - August 25th 2015 ([jcenter](https://bintray.com/diffplug/opensource/spotless/1.2.0/view)) - -* Updated from Eclipse 4.5 M6 to the official Eclipse 4.5 release, which fixes several bugs in the formatter. -* Fixed a bug in the import sorter which made it impossible to deal with "all unmatched type imports". -* Formatting is now relative to the project directory rather than the root directory. -* Improved the logging levels. - -### Version 1.1 - May 14th 2015 ([jcenter](https://bintray.com/diffplug/opensource/spotless/1.1/view)) - -* No functional changes, probably not worth the time for an upgrade. -* First version which is available on plugins.gradle.org as well as jcenter. -* Removed some code that was copy-pasted from Durian, and added a Durian dependency. - -### Version 1.0 - April 29th 2015 ([jcenter](https://bintray.com/diffplug/opensource/spotless/1.0/view)) - -* Initial release. - -### Version 0.1 - April 28th 2015 ([jcenter](https://bintray.com/diffplug/opensource/spotless/0.1/view)) - -* First release, to test out that we can release to jcenter and whatnot. +* Maven plugin written by [Konstantin Lutovich](https://github.com/lutovich). diff --git a/plugin-maven/README.md b/plugin-maven/README.md index 0696c782c3..dc7cf676b3 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -1,3 +1,162 @@ # Spotless: Keep your code spotless with Gradle -We're looking for a contributor to build the maven plugin. See [CONTRIBUTING.md](../CONTRIBUTING.md) for more info - you'll have lots of help on hand! + +[![Maven central](https://img.shields.io/badge/mavencentral-com.diffplug.spotless%3Aspotless--plugin--maven-blue.svg)](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.diffplug.spotless%22%20AND%20a%3A%22spotless-plugin-maven%22) +[![Javadoc](https://img.shields.io/badge/javadoc-unreleased-blue.svg)](https://diffplug.github.io/spotless/javadoc/spotless-plugin-maven/unreleased/) + +[![Changelog](https://img.shields.io/badge/changelog-unreleased-brightgreen.svg)](CHANGES.md) +[![Travis CI](https://travis-ci.org/diffplug/spotless.svg?branch=master)](https://travis-ci.org/diffplug/spotless) +[![Live chat](https://img.shields.io/badge/gitter-chat-brightgreen.svg)](https://gitter.im/diffplug/spotless) +[![License Apache](https://img.shields.io/badge/license-apache-brightgreen.svg)](https://tldrlegal.com/license/apache-license-2.0-(apache-2.0)) + + + + +Spotless is a general-purpose formatting plugin. It is completely à la carte, but also includes powerful "batteries-included" if you opt-in. + +To people who use your build, it looks like this: + +``` +cmd> mvn com.diffplug.spotless:spotless-maven-plugin:spotless-check +... +:spotlessJavaCheck FAILED +> The following files had format violations: + src\main\java\com\diffplug\gradle\spotless\FormatExtension.java + @@ -109,7 +109,7 @@ + ... + -\t\t····if·(targets.length·==·0)·{ + +\t\tif·(targets.length·==·0)·{ + ... + Run 'mvn com.diffplug.spotless:spotless-maven-plugin:spotless-apply' to fix these violations. + +cmd> mvn com.diffplug.spotless:spotless-maven-plugin:spotless-apply +:spotlessApply +BUILD SUCCESSFUL + +cmd> mvn com.diffplug.spotless:spotless-maven-plugin:spotless-check +BUILD SUCCESSFUL +``` + +To use it in your pom, just [add the Spotless dependency](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.diffplug.spotless%22%20AND%20a%3A%22spotless-plugin-maven%22), and configure it like so: + +```xml + + com.diffplug.spotless + spotless-maven-plugin + ${spotless.version} + + + + ${basedir}/eclipse-fmt.xml + 4.7.1 + + + + +``` + +Spotless supports the following powerful formatters: + +* Eclipse's java code formatter (including style and import ordering) +* Google's [google-java-format](https://github.com/google/google-java-format) +* User-defined license enforcement, regex replacement, etc. + +Contributions are welcome, see [the contributing guide](../CONTRIBUTING.md) for development info. + +Spotless requires Maven to be running on JRE 8+. + + + +## Applying to Java source + +By default, all compileSourceRoots will be formatted. Each element under `` is a step, and they will be applied in the order specified. Every step is optional, and they will be applied in the order specified. It doesn't make sense to use both eclipse and google-java-format. + +```xml + + + + + /* Licensed under Apache-2.0 */ + ${basedir}/license-header + + + ${basedir}/eclipse-fmt.xml + + 4.7.1 + + + + 1.5 + + + + + java,javax,org,com,com.diffplug, + ${basedir}/importOrder + + + +``` + + + +## Line endings and encodings (invisible stuff) + +Spotless uses UTF-8 by default, but you can use [any encoding which Java supports](https://docs.oracle.com/javase/8/docs/technotes/guides/intl/encoding.doc.html). You can set it globally, and you can also set it per-format. + +```gradle + + + Cp1252 + + US-ASCII + +``` + +Line endings can also be set globally or per-format using the `lineEndings` property. Spotless supports four line ending modes: `UNIX`, `WINDOWS`, `PLATFORM_NATIVE`, and `GIT_ATTRIBUTES`. The default value is `GIT_ATTRIBUTES`, and *we highly recommend that you* ***do not change*** *this value*. Git has opinions about line endings, and if Spotless and git disagree, then you're going to have a bad time. + +You can easily set the line endings of different files using [a `.gitattributes` file](https://help.github.com/articles/dealing-with-line-endings/). Here's an example `.gitattributes` which sets all files to unix newlines: `* text eol=lf`. + + + +## Disabling warnings and error messages + +The `test` phase is Maven's built-in task for grouping all verification tasks - unit tests, static analysis, etc. By default, `spotless-check` is added as a dependency to `test`. + +You might want to disable this behavior. We [recommend against this](https://github.com/diffplug/spotless/issues/79#issuecomment-290844602), but it's easy to do if you'd like: + +```xml + + false + +``` + + + +## How do I preview what `spotless-apply` will do? + +- Save your working tree with `git add -A`, then `git commit -m "Checkpoint before spotless."` +- Run `mvn com.diffplug.spotless:spotless-maven-plugin:spotless-apply` +- View the changes with `git diff` +- If you don't like what spotless did, `git reset --hard` +- If you'd like to remove the "checkpoint" commit, `git reset --soft head~1` will make the checkpoint commit "disappear" from history, but keeps the changes in your working directory. + + + +## Example configurations (from real-world projects) + +TODO + + From a431b7103d54cd6b8c4b547b9d52c384e3481d8e Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Fri, 19 Jan 2018 12:56:59 -0800 Subject: [PATCH 08/91] Switch indent from tab to 2-space for better GitHub render. --- plugin-maven/README.md | 106 ++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/plugin-maven/README.md b/plugin-maven/README.md index dc7cf676b3..5b3cbdb82c 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -2,14 +2,14 @@ [![Maven central](https://img.shields.io/badge/mavencentral-com.diffplug.spotless%3Aspotless--plugin--maven-blue.svg)](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.diffplug.spotless%22%20AND%20a%3A%22spotless-plugin-maven%22) [![Javadoc](https://img.shields.io/badge/javadoc-unreleased-blue.svg)](https://diffplug.github.io/spotless/javadoc/spotless-plugin-maven/unreleased/) @@ -33,13 +33,13 @@ cmd> mvn com.diffplug.spotless:spotless-maven-plugin:spotless-check ... :spotlessJavaCheck FAILED > The following files had format violations: - src\main\java\com\diffplug\gradle\spotless\FormatExtension.java - @@ -109,7 +109,7 @@ - ... - -\t\t····if·(targets.length·==·0)·{ - +\t\tif·(targets.length·==·0)·{ - ... - Run 'mvn com.diffplug.spotless:spotless-maven-plugin:spotless-apply' to fix these violations. + src\main\java\com\diffplug\gradle\spotless\FormatExtension.java + @@ -109,7 +109,7 @@ + ... + -\t\t····if·(targets.length·==·0)·{ + +\t\tif·(targets.length·==·0)·{ + ... + Run 'mvn com.diffplug.spotless:spotless-maven-plugin:spotless-apply' to fix these violations. cmd> mvn com.diffplug.spotless:spotless-maven-plugin:spotless-apply :spotlessApply @@ -53,17 +53,17 @@ To use it in your pom, just [add the Spotless dependency](http://search.maven.or ```xml - com.diffplug.spotless - spotless-maven-plugin - ${spotless.version} - - - - ${basedir}/eclipse-fmt.xml - 4.7.1 - - - + com.diffplug.spotless + spotless-maven-plugin + ${spotless.version} + + + + ${basedir}/eclipse-fmt.xml + 4.7.1 + + + ``` @@ -85,28 +85,28 @@ By default, all compileSourceRoots will be formatted. Each element under ` - - - - /* Licensed under Apache-2.0 */ - ${basedir}/license-header - - - ${basedir}/eclipse-fmt.xml - - 4.7.1 - - - - 1.5 - - - - - java,javax,org,com,com.diffplug, - ${basedir}/importOrder - - + + + + /* Licensed under Apache-2.0 */ + ${basedir}/license-header + + + ${basedir}/eclipse-fmt.xml + + 4.7.1 + + + + 1.5 + + + + + java,javax,org,com,com.diffplug, + ${basedir}/importOrder + + ``` @@ -118,10 +118,10 @@ Spotless uses UTF-8 by default, but you can use [any encoding which Java support ```gradle - - Cp1252 - - US-ASCII + + Cp1252 + + US-ASCII ``` @@ -139,7 +139,7 @@ You might want to disable this behavior. We [recommend against this](https://gi ```xml - false + false ``` From 363926920ef59d056b6fbe3cbd86aad49d8b1906 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Fri, 19 Jan 2018 12:59:19 -0800 Subject: [PATCH 09/91] Update feature matrix for current maven ambitions. --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 684973ec10..7a00046190 100644 --- a/README.md +++ b/README.md @@ -34,15 +34,15 @@ output = [ '| --------------------------------------------- | ------------- | ------------ | --------|', lib('generic.EndWithNewlineStep') +'{{yes}} | {{no}} | {{no}} |', lib('generic.IndentStep') +'{{yes}} | {{no}} | {{no}} |', -lib('generic.LicenseHeaderStep') +'{{yes}} | {{no}} | {{no}} |', +lib('generic.LicenseHeaderStep') +'{{yes}} | {{yes}} | {{no}} |', lib('generic.ReplaceRegexStep') +'{{yes}} | {{no}} | {{no}} |', lib('generic.ReplaceStep') +'{{yes}} | {{no}} | {{no}} |', lib('generic.TrimTrailingWhitespaceStep') +'{{yes}} | {{no}} | {{no}} |', extra('groovy.GrEclipseFormatterStep') +'{{yes}} | {{no}} | {{no}} |', -lib('java.GoogleJavaFormatStep') +'{{yes}} | {{no}} | {{no}} |', -lib('java.ImportOrderStep') +'{{yes}} | {{no}} | {{no}} |', -lib('java.RemoveUnusedImportsStep') +'{{yes}} | {{no}} | {{no}} |', -extra('java.EclipseFormatterStep') +'{{yes}} | {{no}} | {{no}} |', +lib('java.GoogleJavaFormatStep') +'{{yes}} | {{yes}} | {{no}} |', +lib('java.ImportOrderStep') +'{{yes}} | {{yes}} | {{no}} |', +lib('java.RemoveUnusedImportsStep') +'{{yes}} | {{yes}} | {{no}} |', +extra('java.EclipseFormatterStep') +'{{yes}} | {{yes}} | {{no}} |', lib('kotlin.KtLintStep') +'{{yes}} | {{no}} | {{no}} |', lib('markdown.FreshMarkStep') +'{{yes}} | {{no}} | {{no}} |', lib('scala.ScalaFmtStep') +'{{yes}} | {{no}} | {{no}} |', @@ -57,15 +57,15 @@ lib('sql.DBeaverSQLFormatterStep') +'{{yes}} | {{no}} | --------------------------------------------- | ------------- | ------------ | --------| | [`generic.EndWithNewlineStep`](lib/src/main/java/com/diffplug/spotless/generic/EndWithNewlineStep.java) | :+1: | :white_large_square: | :white_large_square: | | [`generic.IndentStep`](lib/src/main/java/com/diffplug/spotless/generic/IndentStep.java) | :+1: | :white_large_square: | :white_large_square: | -| [`generic.LicenseHeaderStep`](lib/src/main/java/com/diffplug/spotless/generic/LicenseHeaderStep.java) | :+1: | :white_large_square: | :white_large_square: | +| [`generic.LicenseHeaderStep`](lib/src/main/java/com/diffplug/spotless/generic/LicenseHeaderStep.java) | :+1: | :+1: | :white_large_square: | | [`generic.ReplaceRegexStep`](lib/src/main/java/com/diffplug/spotless/generic/ReplaceRegexStep.java) | :+1: | :white_large_square: | :white_large_square: | | [`generic.ReplaceStep`](lib/src/main/java/com/diffplug/spotless/generic/ReplaceStep.java) | :+1: | :white_large_square: | :white_large_square: | | [`generic.TrimTrailingWhitespaceStep`](lib/src/main/java/com/diffplug/spotless/generic/TrimTrailingWhitespaceStep.java) | :+1: | :white_large_square: | :white_large_square: | | [`groovy.GrEclipseFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/groovy/GrEclipseFormatterStep.java) | :+1: | :white_large_square: | :white_large_square: | -| [`java.GoogleJavaFormatStep`](lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java) | :+1: | :white_large_square: | :white_large_square: | -| [`java.ImportOrderStep`](lib/src/main/java/com/diffplug/spotless/java/ImportOrderStep.java) | :+1: | :white_large_square: | :white_large_square: | -| [`java.RemoveUnusedImportsStep`](lib/src/main/java/com/diffplug/spotless/java/RemoveUnusedImportsStep.java) | :+1: | :white_large_square: | :white_large_square: | -| [`java.EclipseFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/java/EclipseFormatterStep.java) | :+1: | :white_large_square: | :white_large_square: | +| [`java.GoogleJavaFormatStep`](lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java) | :+1: | :+1: | :white_large_square: | +| [`java.ImportOrderStep`](lib/src/main/java/com/diffplug/spotless/java/ImportOrderStep.java) | :+1: | :+1: | :white_large_square: | +| [`java.RemoveUnusedImportsStep`](lib/src/main/java/com/diffplug/spotless/java/RemoveUnusedImportsStep.java) | :+1: | :+1: | :white_large_square: | +| [`java.EclipseFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/java/EclipseFormatterStep.java) | :+1: | :+1: | :white_large_square: | | [`kotlin.KtLintStep`](lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java) | :+1: | :white_large_square: | :white_large_square: | | [`markdown.FreshMarkStep`](lib/src/main/java/com/diffplug/spotless/markdown/FreshMarkStep.java) | :+1: | :white_large_square: | :white_large_square: | | [`scala.ScalaFmtStep`](lib/src/main/java/com/diffplug/spotless/scala/ScalaFmtStep.java) | :+1: | :white_large_square: | :white_large_square: | From 240f87c1ba6eb0685ba2b354a9b2682ae6337efe Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Fri, 19 Jan 2018 13:07:47 -0800 Subject: [PATCH 10/91] Fixed some typos in README. --- plugin-maven/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugin-maven/README.md b/plugin-maven/README.md index 5b3cbdb82c..f1e1a081e8 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -29,7 +29,7 @@ Spotless is a general-purpose formatting plugin. It is completely à la carte, To people who use your build, it looks like this: ``` -cmd> mvn com.diffplug.spotless:spotless-maven-plugin:spotless-check +cmd> mvn com.diffplug.spotless:spotless-plugin-maven:spotless-check ... :spotlessJavaCheck FAILED > The following files had format violations: @@ -39,13 +39,13 @@ cmd> mvn com.diffplug.spotless:spotless-maven-plugin:spotless-check -\t\t····if·(targets.length·==·0)·{ +\t\tif·(targets.length·==·0)·{ ... - Run 'mvn com.diffplug.spotless:spotless-maven-plugin:spotless-apply' to fix these violations. + Run 'mvn com.diffplug.spotless:spotless-plugin-maven:spotless-apply' to fix these violations. -cmd> mvn com.diffplug.spotless:spotless-maven-plugin:spotless-apply +cmd> mvn com.diffplug.spotless:spotless-plugin-maven:spotless-apply :spotlessApply BUILD SUCCESSFUL -cmd> mvn com.diffplug.spotless:spotless-maven-plugin:spotless-check +cmd> mvn com.diffplug.spotless:spotless-plugin-maven:spotless-check BUILD SUCCESSFUL ``` @@ -54,7 +54,7 @@ To use it in your pom, just [add the Spotless dependency](http://search.maven.or ```xml com.diffplug.spotless - spotless-maven-plugin + spotless-plugin-maven ${spotless.version} @@ -148,7 +148,7 @@ You might want to disable this behavior. We [recommend against this](https://gi ## How do I preview what `spotless-apply` will do? - Save your working tree with `git add -A`, then `git commit -m "Checkpoint before spotless."` -- Run `mvn com.diffplug.spotless:spotless-maven-plugin:spotless-apply` +- Run `mvn com.diffplug.spotless:spotless-plugin-maven:spotless-apply` - View the changes with `git diff` - If you don't like what spotless did, `git reset --hard` - If you'd like to remove the "checkpoint" commit, `git reset --soft head~1` will make the checkpoint commit "disappear" from history, but keeps the changes in your working directory. From 8570064e54f4470294318a5f94df6ef6c8d6be0d Mon Sep 17 00:00:00 2001 From: lutovich Date: Fri, 19 Jan 2018 23:36:59 +0100 Subject: [PATCH 11/91] Made maven plugin build use template for pom Gradle build script will now use Mustache template to create pom.xml with needed versions. This should be more reliable and future-proof than previously used `String#replace()`. --- plugin-maven/build.gradle | 63 +++++++++++++------ .../resources/{pom.xml => pom.xml.mustache} | 8 +-- 2 files changed, 49 insertions(+), 22 deletions(-) rename plugin-maven/src/main/resources/{pom.xml => pom.xml.mustache} (90%) diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index 9d4eab5ede..c8de944932 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -1,8 +1,29 @@ +import com.github.mustachejava.DefaultMustacheFactory + +import java.nio.file.Files +import java.nio.file.Paths + +import static java.nio.charset.StandardCharsets.UTF_8 +import static java.nio.file.StandardOpenOption.CREATE_NEW +import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING + ext.artifactId = project.artifactIdMaven ext.version = project.versionMaven apply from: rootProject.file("gradle/java-setup.gradle") apply from: rootProject.file("gradle/java-publish.gradle") +final MAVEN_PROJECT_DIR = "mavenProject" +final PROJECT_DIR = project.projectDir.toString() + +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath "com.github.spullara.mustache.java:compiler:0.9.5" + } +} + dependencies { compile project(":lib") compile project(":lib-extra") @@ -17,39 +38,45 @@ dependencies { testCompile "com.diffplug.durian:durian-testlib:${VER_DURIAN}" } -task cleanMavenProjectDir(type: Delete) { delete "build/tmpMavenProject" } +task cleanMavenProjectDir(type: Delete) { delete "build/${MAVEN_PROJECT_DIR}" } task copySourceFiles(type: Copy) { from "src/main/java" - into "build/tmpMavenProject/src/main/java" + into "build/${MAVEN_PROJECT_DIR}/src/main/java" } -task copyPomXml(type: Copy) { - from "src/main/resources/pom.xml" - into "build/tmpMavenProject" +task createPomXml { + doLast { + def versions = [ + SpotlessMavenPluginVersion: project.versionMaven, + MavenApiVersion : VER_MAVEN_API, + EclipseAetherVersion : VER_ECLIPSE_AETHER, + SpotlessLibVersion : project.stableLib + ] - // inject versions while copying - filter { String line -> - line.replace("VER_PLUGIN", "${project.versionMaven}") - .replace("VER_MAVEN_API", "${VER_MAVEN_API}") - .replace("VER_ECLIPSE_AETHER", "${VER_ECLIPSE_AETHER}") - .replace("VER_SPOTLESS_LIB", "${project.stableLib}") - } + def pomXmlTemplate = Paths.get(PROJECT_DIR, "src", "main", "resources", "pom.xml.mustache") + def newPomXml = Paths.get(PROJECT_DIR, "build", MAVEN_PROJECT_DIR, "pom.xml") - filteringCharset = "UTF-8" + Files.newBufferedReader(pomXmlTemplate).withCloseable { reader -> + Files.newBufferedWriter(newPomXml, UTF_8, CREATE_NEW, TRUNCATE_EXISTING).withCloseable { writer -> + def mustache = new DefaultMustacheFactory().compile(reader, "pom") + mustache.execute(writer, versions) + } + } + } } task runMavenBuild(type: Exec, dependsOn: [ - cleanMavenProjectDir, - copySourceFiles, - copyPomXml + cleanMavenProjectDir, + copySourceFiles, + createPomXml ]) { - workingDir "build/tmpMavenProject" + workingDir "build/${MAVEN_PROJECT_DIR}" commandLine "mvn", "clean", "install" } task buildMavenPlugin(type: Copy, dependsOn: runMavenBuild) { - from "build/tmpMavenProject/target" + from "build/${MAVEN_PROJECT_DIR}/target" into "build/libs" } diff --git a/plugin-maven/src/main/resources/pom.xml b/plugin-maven/src/main/resources/pom.xml.mustache similarity index 90% rename from plugin-maven/src/main/resources/pom.xml rename to plugin-maven/src/main/resources/pom.xml.mustache index 05f2e4f08a..7bf25866ac 100644 --- a/plugin-maven/src/main/resources/pom.xml +++ b/plugin-maven/src/main/resources/pom.xml.mustache @@ -4,7 +4,7 @@ com.diffplug.spotless spotless-maven-plugin - VER_PLUGIN + {{SpotlessMavenPluginVersion}} maven-plugin Spotless Maven Plugin @@ -15,9 +15,9 @@ 1.8 - VER_MAVEN_API - VER_ECLIPSE_AETHER - VER_SPOTLESS_LIB + {{MavenApiVersion}} + {{EclipseAetherVersion}} + {{SpotlessLibVersion}} From 75f02047afe178792cf9018f6c571f5c8c6ee92d Mon Sep 17 00:00:00 2001 From: lutovich Date: Fri, 19 Jan 2018 23:45:03 +0100 Subject: [PATCH 12/91] Fixed code formatting and build dir reference --- plugin-maven/build.gradle | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index c8de944932..517b18bebb 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -12,16 +12,13 @@ ext.version = project.versionMaven apply from: rootProject.file("gradle/java-setup.gradle") apply from: rootProject.file("gradle/java-publish.gradle") -final MAVEN_PROJECT_DIR = "mavenProject" final PROJECT_DIR = project.projectDir.toString() +final BUILD_DIR = project.buildDir.toString() +final MAVEN_PROJECT_DIR = "${BUILD_DIR}/mavenProject" buildscript { - repositories { - mavenCentral() - } - dependencies { - classpath "com.github.spullara.mustache.java:compiler:0.9.5" - } + repositories { mavenCentral() } + dependencies { classpath "com.github.spullara.mustache.java:compiler:0.9.5" } } dependencies { @@ -38,24 +35,24 @@ dependencies { testCompile "com.diffplug.durian:durian-testlib:${VER_DURIAN}" } -task cleanMavenProjectDir(type: Delete) { delete "build/${MAVEN_PROJECT_DIR}" } +task cleanMavenProjectDir(type: Delete) { delete MAVEN_PROJECT_DIR } task copySourceFiles(type: Copy) { from "src/main/java" - into "build/${MAVEN_PROJECT_DIR}/src/main/java" + into "${MAVEN_PROJECT_DIR}/src/main/java" } task createPomXml { doLast { def versions = [ - SpotlessMavenPluginVersion: project.versionMaven, - MavenApiVersion : VER_MAVEN_API, - EclipseAetherVersion : VER_ECLIPSE_AETHER, - SpotlessLibVersion : project.stableLib + SpotlessMavenPluginVersion: project.versionMaven, + MavenApiVersion : VER_MAVEN_API, + EclipseAetherVersion : VER_ECLIPSE_AETHER, + SpotlessLibVersion : project.stableLib ] def pomXmlTemplate = Paths.get(PROJECT_DIR, "src", "main", "resources", "pom.xml.mustache") - def newPomXml = Paths.get(PROJECT_DIR, "build", MAVEN_PROJECT_DIR, "pom.xml") + def newPomXml = Paths.get(MAVEN_PROJECT_DIR, "pom.xml") Files.newBufferedReader(pomXmlTemplate).withCloseable { reader -> Files.newBufferedWriter(newPomXml, UTF_8, CREATE_NEW, TRUNCATE_EXISTING).withCloseable { writer -> @@ -67,17 +64,17 @@ task createPomXml { } task runMavenBuild(type: Exec, dependsOn: [ - cleanMavenProjectDir, - copySourceFiles, - createPomXml + cleanMavenProjectDir, + copySourceFiles, + createPomXml ]) { - workingDir "build/${MAVEN_PROJECT_DIR}" + workingDir MAVEN_PROJECT_DIR commandLine "mvn", "clean", "install" } task buildMavenPlugin(type: Copy, dependsOn: runMavenBuild) { - from "build/${MAVEN_PROJECT_DIR}/target" - into "build/libs" + from "${MAVEN_PROJECT_DIR}/target" + into "${BUILD_DIR}/libs" } build.finalizedBy buildMavenPlugin From 40da7f537fa7ddfe196c1db16e62d9ec625fb1cf Mon Sep 17 00:00:00 2001 From: lutovich Date: Sun, 21 Jan 2018 12:50:41 +0100 Subject: [PATCH 13/91] Improve maven plugin configuration Restructured code to better support addition of new formatter steps and formatters. Spotless mojo now accepts java configuration with list of steps. It is also possible to specify global encoding, line endings and override them for java. New `pom.xml` config looks like: ``` UTF-8 UNIX US-ASCII WINDOWS ${basedir}/build/eclipse-format.xml 4.7.1 ``` --- .../gradle/spotless/AbstractSpotlessMojo.java | 24 ++---- .../com/diffplug/gradle/spotless/Eclipse.java | 43 ++++++++++ .../gradle/spotless/FormatterFactory.java | 28 +++++++ .../gradle/spotless/FormatterStepFactory.java | 23 ++++++ .../com/diffplug/gradle/spotless/Java.java | 49 +++++++++-- .../diffplug/gradle/spotless/MojoConfig.java | 52 ++++++++++++ .../gradle/spotless/SpotlessMojo.java | 81 ++++++++++--------- 7 files changed, 239 insertions(+), 61 deletions(-) create mode 100644 plugin-maven/src/main/java/com/diffplug/gradle/spotless/Eclipse.java create mode 100644 plugin-maven/src/main/java/com/diffplug/gradle/spotless/FormatterFactory.java create mode 100644 plugin-maven/src/main/java/com/diffplug/gradle/spotless/FormatterStepFactory.java create mode 100644 plugin-maven/src/main/java/com/diffplug/gradle/spotless/MojoConfig.java diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/AbstractSpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/AbstractSpotlessMojo.java index 87ea46981b..2cb77ed8b1 100644 --- a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/AbstractSpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/AbstractSpotlessMojo.java @@ -18,7 +18,6 @@ import static java.util.stream.Collectors.toList; import java.io.File; -import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -33,6 +32,7 @@ import org.eclipse.aether.repository.RemoteRepository; import com.diffplug.spotless.LineEnding; +import com.diffplug.spotless.Provisioner; public abstract class AbstractSpotlessMojo extends AbstractMojo { @@ -63,13 +63,9 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo { @Parameter(defaultValue = DEFAULT_LINE_ENDINGS) private LineEnding lineEndings; - @Parameter(required = true) + @Parameter private Java java; - protected ArtifactResolver createArtifactResolver() { - return new ArtifactResolver(repositorySystem, repositorySystemSession, repositories); - } - protected List getAllSourceRoots() { return Stream.concat(compileSourceRoots.stream(), testCompileSourceRoots.stream()) .map(Paths::get) @@ -77,19 +73,13 @@ protected List getAllSourceRoots() { .collect(toList()); } - protected Charset getEncoding() { - return Charset.forName(encoding); - } - - protected LineEnding.Policy getLineEndingsPolicy(List filesToFormat) { - return lineEndings.createPolicy(getBaseDir(), () -> filesToFormat); - } - - protected File getBaseDir() { - return baseDir; + protected MojoConfig getMojoConfig() { + ArtifactResolver resolver = new ArtifactResolver(repositorySystem, repositorySystemSession, repositories); + Provisioner provisioner = MavenProvisioner.create(resolver); + return new MojoConfig(baseDir, encoding, lineEndings, provisioner); } - protected Java getJavaConfig() { + protected Java getJava() { return java; } } diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/Eclipse.java b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/Eclipse.java new file mode 100644 index 0000000000..1dafc43705 --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/Eclipse.java @@ -0,0 +1,43 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.gradle.spotless; + +import static com.diffplug.spotless.extra.java.EclipseFormatterStep.defaultVersion; +import static java.util.Collections.singleton; + +import java.io.File; +import java.util.Set; + +import org.apache.maven.plugins.annotations.Parameter; + +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.extra.java.EclipseFormatterStep; + +public class Eclipse implements FormatterStepFactory { + + @Parameter(required = true) + private File file; + + @Parameter + private String version; + + @Override + public FormatterStep newFormatterStep(MojoConfig mojoConfig) { + String formatterVersion = version == null ? defaultVersion() : version; + Set settingsFiles = singleton(file); + return EclipseFormatterStep.create(formatterVersion, settingsFiles, mojoConfig.getProvisioner()); + } +} diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/FormatterFactory.java b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/FormatterFactory.java new file mode 100644 index 0000000000..db227993ee --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/FormatterFactory.java @@ -0,0 +1,28 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.gradle.spotless; + +import java.io.File; +import java.util.List; + +import com.diffplug.spotless.Formatter; + +public interface FormatterFactory { + + String fileExtension(); + + Formatter newFormatter(List filesToFormat, MojoConfig mojoConfig); +} diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/FormatterStepFactory.java b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/FormatterStepFactory.java new file mode 100644 index 0000000000..6af2f2658f --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/FormatterStepFactory.java @@ -0,0 +1,23 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.gradle.spotless; + +import com.diffplug.spotless.FormatterStep; + +public interface FormatterStepFactory { + + FormatterStep newFormatterStep(MojoConfig mojoConfig); +} diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/Java.java b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/Java.java index 485ea89694..c53fd38513 100644 --- a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/Java.java +++ b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/Java.java @@ -15,16 +15,53 @@ */ package com.diffplug.gradle.spotless; +import static java.util.stream.Collectors.toList; + import java.io.File; +import java.nio.charset.Charset; +import java.util.List; + +import org.apache.maven.plugins.annotations.Parameter; + +import com.diffplug.spotless.FormatExceptionPolicyStrict; +import com.diffplug.spotless.Formatter; +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.LineEnding; + +public class Java implements FormatterFactory { + + private static final String EXTENSION = "java"; -public class Java { - private File eclipseConfigFile; + @Parameter + private String encoding; - public File getEclipseConfigFile() { - return eclipseConfigFile; + @Parameter + private LineEnding lineEndings; + + @Parameter + private List steps; + + @Override + public String fileExtension() { + return EXTENSION; } - public void setEclipseConfigFile(File eclipseConfigFile) { - this.eclipseConfigFile = eclipseConfigFile; + @Override + public Formatter newFormatter(List filesToFormat, MojoConfig mojoConfig) { + Charset formatterEncoding = encoding == null ? Charset.forName(mojoConfig.getEncoding()) : Charset.forName(encoding); + LineEnding formatterLineEndings = lineEndings == null ? mojoConfig.getLineEndings() : lineEndings; + LineEnding.Policy formatterLineEndingPolicy = formatterLineEndings.createPolicy(mojoConfig.getBaseDir(), () -> filesToFormat); + + List formatterSteps = steps.stream() + .map(factory -> factory.newFormatterStep(mojoConfig)) + .collect(toList()); + + return Formatter.builder() + .encoding(formatterEncoding) + .lineEndingsPolicy(formatterLineEndingPolicy) + .exceptionPolicy(new FormatExceptionPolicyStrict()) + .steps(formatterSteps) + .rootDir(mojoConfig.getBaseDir().toPath()) + .build(); } } diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/MojoConfig.java b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/MojoConfig.java new file mode 100644 index 0000000000..7ab3209913 --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/MojoConfig.java @@ -0,0 +1,52 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.gradle.spotless; + +import java.io.File; + +import com.diffplug.spotless.LineEnding; +import com.diffplug.spotless.Provisioner; + +public class MojoConfig { + + private final File baseDir; + private final String encoding; + private final LineEnding lineEndings; + private final Provisioner provisioner; + + public MojoConfig(File baseDir, String encoding, LineEnding lineEndings, Provisioner provisioner) { + this.baseDir = baseDir; + this.encoding = encoding; + this.lineEndings = lineEndings; + this.provisioner = provisioner; + } + + public File getBaseDir() { + return baseDir; + } + + public String getEncoding() { + return encoding; + } + + public LineEnding getLineEndings() { + return lineEndings; + } + + public Provisioner getProvisioner() { + return provisioner; + } +} diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/SpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/SpotlessMojo.java index 8227e98ba2..330e431f32 100644 --- a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/SpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/gradle/spotless/SpotlessMojo.java @@ -15,70 +15,55 @@ */ package com.diffplug.gradle.spotless; -import static java.util.Collections.singleton; import static java.util.Collections.singletonList; +import static java.util.stream.Collectors.toList; import java.io.File; import java.io.IOException; +import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Path; -import java.util.ArrayList; import java.util.List; -import java.util.Set; import java.util.stream.Stream; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Mojo; -import com.diffplug.spotless.FormatExceptionPolicyStrict; import com.diffplug.spotless.Formatter; -import com.diffplug.spotless.FormatterStep; -import com.diffplug.spotless.Provisioner; -import com.diffplug.spotless.extra.java.EclipseFormatterStep; @Mojo(name = "apply") public class SpotlessMojo extends AbstractSpotlessMojo { + private static final String FILE_EXTENSION_SEPARATOR = "."; + @Override public void execute() throws MojoExecutionException, MojoFailureException { - List filesToFormat = collectFilesToFormat(); - - Formatter formatter = createFormatter(filesToFormat); - - formatAll(filesToFormat, formatter); - } + List formatterFactories = singletonList(getJava()); - private List collectFilesToFormat() throws MojoExecutionException { - List filesToFormat = new ArrayList<>(); - for (Path root : getAllSourceRoots()) { - try (Stream entries = Files.walk(root)) { - entries.filter(Files::isRegularFile) - .filter(file -> file.getFileName().toString().endsWith(".java")) - .map(Path::toFile) - .forEach(filesToFormat::add); - } catch (IOException e) { - throw new MojoExecutionException("Unable to walk the file tree", e); - } + for (FormatterFactory formatterFactory : formatterFactories) { + execute(formatterFactory); } - return filesToFormat; } - private Formatter createFormatter(List filesToFormat) { - return Formatter.builder() - .encoding(getEncoding()) - .lineEndingsPolicy(getLineEndingsPolicy(filesToFormat)) - .exceptionPolicy(new FormatExceptionPolicyStrict()) - .steps(singletonList(createEclipseFormatterStep())) - .rootDir(getBaseDir().toPath()) - .build(); + private void execute(FormatterFactory formatterFactory) throws MojoExecutionException { + MojoConfig mojoConfig = getMojoConfig(); + List filesToFormat = collectFilesToFormat(formatterFactory.fileExtension()); + + Formatter formatter = formatterFactory.newFormatter(filesToFormat, mojoConfig); + + formatAll(filesToFormat, formatter); } - private FormatterStep createEclipseFormatterStep() { - ArtifactResolver artifactResolver = createArtifactResolver(); - Provisioner provisioner = MavenProvisioner.create(artifactResolver); - Set settingFiles = singleton(getJavaConfig().getEclipseConfigFile()); - return EclipseFormatterStep.create(EclipseFormatterStep.defaultVersion(), settingFiles, provisioner); + private List collectFilesToFormat(String extension) throws MojoExecutionException { + try { + return getAllSourceRoots().stream() + .flatMap(root -> collectFilesToFormat(root, extension).stream()) + .map(Path::toFile) + .collect(toList()); + } catch (Exception e) { + throw new MojoExecutionException("Unable to collect files to format", e); + } } private static void formatAll(List files, Formatter formatter) throws MojoExecutionException { @@ -90,4 +75,24 @@ private static void formatAll(List files, Formatter formatter) throws Mojo } } } + + private static List collectFilesToFormat(Path root, String extension) { + try (Stream entries = Files.walk(root)) { + return entries.filter(Files::isRegularFile) + .filter(file -> hasExtension(file, extension)) + .collect(toList()); + } catch (IOException e) { + throw new UncheckedIOException("Unable to walk the file tree rooted at " + root, e); + } + } + + private static boolean hasExtension(Path file, String extension) { + Path fileName = file.getFileName(); + if (fileName == null) { + return false; + } else { + String fileNameString = fileName.toString(); + return fileNameString.endsWith(FILE_EXTENSION_SEPARATOR + extension); + } + } } From 3696310c3d8ad294bfc9aeddd026c12ae32f2738 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sun, 21 Jan 2018 10:24:17 -0800 Subject: [PATCH 14/91] Changed maven artifactId to spotless-maven-plugin, but kept project folder location as 'plugin-maven'. --- gradle.properties | 3 ++- plugin-maven/README.md | 18 +++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/gradle.properties b/gradle.properties index beabbbf536..e12d475853 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,8 @@ artifactIdTestLib=spotless-testlib versionMaven=1.0.0-SNAPSHOT stableMaven=unreleased -artifactIdMaven=spotless-plugin-maven +# naming convention '-maven-plugin' allows mvn 'spotless:check' instead of 'spotless-plugin-maven:check' +artifactIdMaven=spotless-maven-plugin versionGradle=3.9.0-SNAPSHOT stableGradle=3.8.0 diff --git a/plugin-maven/README.md b/plugin-maven/README.md index f1e1a081e8..16234569f7 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -2,7 +2,7 @@ -[![Maven central](https://img.shields.io/badge/mavencentral-com.diffplug.spotless%3Aspotless--plugin--maven-blue.svg)](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.diffplug.spotless%22%20AND%20a%3A%22spotless-plugin-maven%22) +[![Maven central](https://img.shields.io/badge/mavencentral-com.diffplug.spotless%3Aspotless--maven--plugin-blue.svg)](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.diffplug.spotless%22%20AND%20a%3A%22spotless-maven-plugin%22) [![Javadoc](https://img.shields.io/badge/javadoc-unreleased-blue.svg)](https://diffplug.github.io/spotless/javadoc/spotless-plugin-maven/unreleased/) [![Changelog](https://img.shields.io/badge/changelog-unreleased-brightgreen.svg)](CHANGES.md) @@ -29,7 +29,7 @@ Spotless is a general-purpose formatting plugin. It is completely à la carte, To people who use your build, it looks like this: ``` -cmd> mvn com.diffplug.spotless:spotless-plugin-maven:spotless-check +cmd> mvn spotless:spotless-check ... :spotlessJavaCheck FAILED > The following files had format violations: @@ -39,22 +39,22 @@ cmd> mvn com.diffplug.spotless:spotless-plugin-maven:spotless-check -\t\t····if·(targets.length·==·0)·{ +\t\tif·(targets.length·==·0)·{ ... - Run 'mvn com.diffplug.spotless:spotless-plugin-maven:spotless-apply' to fix these violations. + Run 'mvn spotless:spotless-apply' to fix these violations. -cmd> mvn com.diffplug.spotless:spotless-plugin-maven:spotless-apply +cmd> mvn spotless:spotless-apply :spotlessApply BUILD SUCCESSFUL -cmd> mvn com.diffplug.spotless:spotless-plugin-maven:spotless-check +cmd> mvn spotless:spotless-check BUILD SUCCESSFUL ``` -To use it in your pom, just [add the Spotless dependency](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.diffplug.spotless%22%20AND%20a%3A%22spotless-plugin-maven%22), and configure it like so: +To use it in your pom, just [add the Spotless dependency](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.diffplug.spotless%22%20AND%20a%3A%22spotless-maven-plugin%22), and configure it like so: ```xml com.diffplug.spotless - spotless-plugin-maven + spotless-maven-plugin ${spotless.version} @@ -148,7 +148,7 @@ You might want to disable this behavior. We [recommend against this](https://gi ## How do I preview what `spotless-apply` will do? - Save your working tree with `git add -A`, then `git commit -m "Checkpoint before spotless."` -- Run `mvn com.diffplug.spotless:spotless-plugin-maven:spotless-apply` +- Run `mvn spotless:spotless-apply` - View the changes with `git diff` - If you don't like what spotless did, `git reset --hard` - If you'd like to remove the "checkpoint" commit, `git reset --soft head~1` will make the checkpoint commit "disappear" from history, but keeps the changes in your working directory. From 49c275311a2138cbe15473c784fa792010a9075f Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sun, 21 Jan 2018 10:28:04 -0800 Subject: [PATCH 15/91] Added an explicit steps container inside each "java" configuration. --- plugin-maven/README.md | 53 +++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/plugin-maven/README.md b/plugin-maven/README.md index 16234569f7..de896fc3ed 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -58,10 +58,12 @@ To use it in your pom, just [add the Spotless dependency](http://search.maven.or ${spotless.version} - - ${basedir}/eclipse-fmt.xml - 4.7.1 - + + + ${basedir}/eclipse-fmt.xml + 4.7.1 + + @@ -86,26 +88,28 @@ By default, all compileSourceRoots will be formatted. Each element under ` - - - /* Licensed under Apache-2.0 */ - ${basedir}/license-header - - - ${basedir}/eclipse-fmt.xml - - 4.7.1 - - - - 1.5 - - - - - java,javax,org,com,com.diffplug, - ${basedir}/importOrder - + + + + /* Licensed under Apache-2.0 */ + ${basedir}/license-header + + + ${basedir}/eclipse-fmt.xml + + 4.7.1 + + + + 1.5 + + + + + java,javax,org,com,com.diffplug, + ${basedir}/importOrder + + ``` @@ -120,6 +124,7 @@ Spotless uses UTF-8 by default, but you can use [any encoding which Java support Cp1252 + ... US-ASCII From 35da59acfac6e3a010fc842041c7c71a1ca9c690 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sun, 21 Jan 2018 10:29:36 -0800 Subject: [PATCH 16/91] Change task names from "spotless-{check|apply}" to just "check|apply". --- plugin-maven/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugin-maven/README.md b/plugin-maven/README.md index de896fc3ed..d8af9caadc 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -29,7 +29,7 @@ Spotless is a general-purpose formatting plugin. It is completely à la carte, To people who use your build, it looks like this: ``` -cmd> mvn spotless:spotless-check +cmd> mvn spotless:check ... :spotlessJavaCheck FAILED > The following files had format violations: @@ -39,13 +39,13 @@ cmd> mvn spotless:spotless-check -\t\t····if·(targets.length·==·0)·{ +\t\tif·(targets.length·==·0)·{ ... - Run 'mvn spotless:spotless-apply' to fix these violations. + Run 'mvn spotless:apply' to fix these violations. -cmd> mvn spotless:spotless-apply +cmd> mvn spotless:apply :spotlessApply BUILD SUCCESSFUL -cmd> mvn spotless:spotless-check +cmd> mvn spotless:check BUILD SUCCESSFUL ``` @@ -150,10 +150,10 @@ You might want to disable this behavior. We [recommend against this](https://gi -## How do I preview what `spotless-apply` will do? +## How do I preview what `mvn spotless:apply` will do? - Save your working tree with `git add -A`, then `git commit -m "Checkpoint before spotless."` -- Run `mvn spotless:spotless-apply` +- Run `mvn spotless:apply` - View the changes with `git diff` - If you don't like what spotless did, `git reset --hard` - If you'd like to remove the "checkpoint" commit, `git reset --soft head~1` will make the checkpoint commit "disappear" from history, but keeps the changes in your working directory. From fd38755fc9fffbe2144faf3a9c48f672db047b47 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sun, 21 Jan 2018 12:46:19 -0800 Subject: [PATCH 17/91] First cut at an integration test system for the maven plugin. --- .../spotless/GradleIntegrationTest.java | 14 + .../spotless/EclipseFormatStepTest.java | 54 ++++ .../gradle/spotless/MavenIntegrationTest.java | 102 +++++++ .../diffplug/gradle/spotless/MavenRunner.java | 155 ++++++++++ .../eclipse/format/JavaCodeFormatted.test | 5 + .../eclipse/format/JavaCodeUnformatted.test | 5 + .../java/eclipse/format/formatter.xml | 264 ++++++++++++++++++ 7 files changed, 599 insertions(+) create mode 100644 plugin-maven/src/test/java/com/diffplug/gradle/spotless/EclipseFormatStepTest.java create mode 100644 plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenIntegrationTest.java create mode 100644 plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenRunner.java create mode 100644 plugin-maven/src/test/resources/java/eclipse/format/JavaCodeFormatted.test create mode 100644 plugin-maven/src/test/resources/java/eclipse/format/JavaCodeUnformatted.test create mode 100644 plugin-maven/src/test/resources/java/eclipse/format/formatter.xml diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GradleIntegrationTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GradleIntegrationTest.java index ec504dcd4b..aad54bc045 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GradleIntegrationTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GradleIntegrationTest.java @@ -37,6 +37,20 @@ import com.diffplug.spotless.ResourceHarness; public class GradleIntegrationTest extends ResourceHarness { + /** + * Each test gets its own temp folder, and we create a gradle + * build there and run it. + * + * Because those test folders don't have a .gitattributes file, + * git (on windows) will default to \r\n. So now if you read a + * test file from the spotless test resources, and compare it + * to a build result, the line endings won't match. + * + * By sticking this .gitattributes file into the test directory, + * we ensure that the default Spotless line endings policy of + * GIT_ATTRIBUTES will use \n, so that tests match the test + * resources on win and linux. + */ @Before public void gitAttributes() throws IOException { write(".gitattributes", "* text eol=lf"); diff --git a/plugin-maven/src/test/java/com/diffplug/gradle/spotless/EclipseFormatStepTest.java b/plugin-maven/src/test/java/com/diffplug/gradle/spotless/EclipseFormatStepTest.java new file mode 100644 index 0000000000..7796d4ab3f --- /dev/null +++ b/plugin-maven/src/test/java/com/diffplug/gradle/spotless/EclipseFormatStepTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.gradle.spotless; + +import java.io.IOException; + +import org.assertj.core.api.Assertions; +import org.junit.Ignore; +import org.junit.Test; + +/** + * This test is ignored because it doesn't work. + * To make it work, we'll need something like the following: + * + * build.gradle + * task publishTestToLocalRepo() + * test.dependsOn(publishTestToLocalRepo) + * + * Then in MavenIntegratonTest.POM_HEADER, set appropriately + * + * Would also be good if we had mvnw setup, so that + * the test harness used mvnw to control the verison + * of maven that was used. + */ +@Ignore +public class EclipseFormatStepTest extends MavenIntegrationTest { + @Test + public void testEclipse() throws IOException, InterruptedException { + // write the pom + writePomJavaSteps( + "", + " ${basedir}/eclipse-fmt.xml", + " 4.7.1", + ""); + write("src/main/java/test.java", getTestResource("java/eclipse/format/JavaCodeUnformatted.test")); + mavenRunner().withArguments("spotless:apply").runNoError(); + + String actual = read("src/main/java/test.java"); + Assertions.assertThat(actual).isEqualTo(getTestResource("java/eclipse/format/JavaCodeFormatted.test")); + } +} diff --git a/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenIntegrationTest.java b/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenIntegrationTest.java new file mode 100644 index 0000000000..5247b5b8c0 --- /dev/null +++ b/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenIntegrationTest.java @@ -0,0 +1,102 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.gradle.spotless; + +import java.io.IOException; +import java.util.Arrays; +import java.util.stream.Collectors; + +import org.junit.Before; + +import com.diffplug.spotless.ResourceHarness; + +public class MavenIntegrationTest extends ResourceHarness { + /** + * Each test gets its own temp folder, and we create a maven + * build there and run it. + * + * Because those test folders don't have a .gitattributes file, + * git on windows will default to \r\n. So now if you read a + * test file from the spotless test resources, and compare it + * to a build result, the line endings won't match. + * + * By sticking this .gitattributes file into the test directory, + * we ensure that the default Spotless line endings policy of + * GIT_ATTRIBUTES will use \n, so that tests match the test + * resources on win and linux. + */ + @Before + public void gitAttributes() throws IOException { + write(".gitattributes", "* text eol=lf"); + } + + private static final String POM_HEADER = "" + + "\n" + + " 4.0.0\n" + + " \n" + + " \n" + + " central\n" + + " Central Repository\n" + + " http://repo.maven.apache.org/maven2\n" + + " default\n" + + " \n" + + " false\n" + + " \n" + + " \n" + + " \n" + + " \n" + // TODO: setup test so that the plugin gets compiled first, and put into this repository + " \n" + + " central\n" + + " Central Repository\n" + + " http://repo.maven.apache.org/maven2\n" + + " default\n" + + " \n" + + " false\n" + + " \n" + + " \n" + + " never\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " com.diffplug.spotless\n" + + " spotless-maven-plugin\n" + + " +\n" + + " \n"; + + private static final String POM_FOOTER = "" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n"; + + protected void writePomJavaSteps(String... steps) throws IOException { + write("pom.xml", + POM_HEADER, + "", + Arrays.stream(steps).collect(Collectors.joining("\n")), + "", + POM_FOOTER); + } + + protected MavenRunner mavenRunner() throws IOException { + return MavenRunner.create() + .withProjectDir(rootFolder()); + } +} diff --git a/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenRunner.java b/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenRunner.java new file mode 100644 index 0000000000..929ac2fce2 --- /dev/null +++ b/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenRunner.java @@ -0,0 +1,155 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.gradle.spotless; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.Objects; +import java.util.stream.Collectors; + +import org.assertj.core.api.Assertions; + +import com.diffplug.common.base.Throwables; + +/** + * Harness for running a maven build, same idea as the + * [GradleRunner from the gradle testkit](https://docs.gradle.org/current/javadoc/org/gradle/testkit/runner/GradleRunner.html). + */ +public class MavenRunner { + public static MavenRunner create() { + return new MavenRunner(); + } + + private MavenRunner() {} + + private File projectDir; + private String[] args; + + public MavenRunner withProjectDir(File projectDir) { + this.projectDir = Objects.requireNonNull(projectDir); + return this; + } + + public MavenRunner withArguments(String... args) { + this.args = Objects.requireNonNull(args); + return this; + } + + private Result run() throws IOException, InterruptedException { + Objects.requireNonNull(projectDir, "Need to call withProjectDir() first"); + Objects.requireNonNull(args, "Need to call withArguments() first"); + // run maven with the given args in the given directory + List cmds = getPlatformCmds("mvn " + Arrays.stream(args).collect(Collectors.joining(" "))); + ProcessBuilder builder = new ProcessBuilder(cmds); + builder.directory(projectDir); + Process process = builder.start(); + // slurp and return the stdout, stderr, and exitValue + Slurper output = new Slurper(process.getInputStream()); + Slurper error = new Slurper(process.getErrorStream()); + int exitValue = process.waitFor(); + output.join(); + error.join(); + return new Result(exitValue, output.result(), error.result()); + } + + /** Runs the command and asserts that nothing was printed to stderr. */ + public Result runNoError() throws IOException, InterruptedException { + Result result = run(); + Assertions.assertThat(result.error()).isEmpty(); + return result; + } + + /** Runs the command and asserts that something was printed to stderr. */ + public Result runHasError() throws IOException, InterruptedException { + Result result = run(); + Assertions.assertThat(result.error()).isNotEmpty(); + return result; + } + + public static class Result { + private final int exitValue; + private final String output; + private final String error; + + public Result(int exitValue, String output, String error) { + super(); + this.exitValue = exitValue; + this.output = Objects.requireNonNull(output); + this.error = Objects.requireNonNull(error); + } + + public int exitValue() { + return exitValue; + } + + public String output() { + return output; + } + + public String error() { + return error; + } + } + + /** Prepends any arguments necessary to run a console command. */ + private static List getPlatformCmds(String cmd) { + if (isWin()) { + return Arrays.asList("cmd", "/c", cmd); + } else { + return Arrays.asList("/bin/sh", "-c", cmd); + } + } + + private static boolean isWin() { + String os_name = System.getProperty("os.name").toLowerCase(Locale.getDefault()); + return os_name.contains("win"); + } + + private static class Slurper extends Thread { + private final InputStream input; + private volatile String result; + + Slurper(InputStream input) { + this.input = Objects.requireNonNull(input); + start(); + } + + @Override + public void run() { + try { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int numRead; + while ((numRead = input.read(buffer)) != -1) { + output.write(buffer, 0, numRead); + } + result = output.toString(Charset.defaultCharset().name()); + } catch (Exception e) { + result = Throwables.getStackTraceAsString(e); + } + } + + public String result() { + return result; + } + } +} diff --git a/plugin-maven/src/test/resources/java/eclipse/format/JavaCodeFormatted.test b/plugin-maven/src/test/resources/java/eclipse/format/JavaCodeFormatted.test new file mode 100644 index 0000000000..fc8b92a1ea --- /dev/null +++ b/plugin-maven/src/test/resources/java/eclipse/format/JavaCodeFormatted.test @@ -0,0 +1,5 @@ +public class Java { + public static void main(String[] args) { + System.out.println("hello"); + } +} \ No newline at end of file diff --git a/plugin-maven/src/test/resources/java/eclipse/format/JavaCodeUnformatted.test b/plugin-maven/src/test/resources/java/eclipse/format/JavaCodeUnformatted.test new file mode 100644 index 0000000000..5589c792d8 --- /dev/null +++ b/plugin-maven/src/test/resources/java/eclipse/format/JavaCodeUnformatted.test @@ -0,0 +1,5 @@ +public class Java { +public static void main(String[] args) { +System.out.println("hello"); +} +} \ No newline at end of file diff --git a/plugin-maven/src/test/resources/java/eclipse/format/formatter.xml b/plugin-maven/src/test/resources/java/eclipse/format/formatter.xml new file mode 100644 index 0000000000..365c79b2a3 --- /dev/null +++ b/plugin-maven/src/test/resources/java/eclipse/format/formatter.xml @@ -0,0 +1,264 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 38641789ae50395b86b0715d38aa5eb8977157fb Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sun, 21 Jan 2018 22:02:02 -0800 Subject: [PATCH 18/91] Use ByteStreams.copy to reduce boilerplate. --- .../java/com/diffplug/gradle/spotless/MavenRunner.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenRunner.java b/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenRunner.java index 929ac2fce2..8313af683f 100644 --- a/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenRunner.java +++ b/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenRunner.java @@ -29,6 +29,7 @@ import org.assertj.core.api.Assertions; import com.diffplug.common.base.Throwables; +import com.diffplug.common.io.ByteStreams; /** * Harness for running a maven build, same idea as the @@ -137,11 +138,7 @@ private static class Slurper extends Thread { public void run() { try { ByteArrayOutputStream output = new ByteArrayOutputStream(); - byte[] buffer = new byte[1024]; - int numRead; - while ((numRead = input.read(buffer)) != -1) { - output.write(buffer, 0, numRead); - } + ByteStreams.copy(input, output); result = output.toString(Charset.defaultCharset().name()); } catch (Exception e) { result = Throwables.getStackTraceAsString(e); From d54b183dd95247abbf060914df1bf516925d231b Mon Sep 17 00:00:00 2001 From: lutovich Date: Mon, 22 Jan 2018 21:20:46 +0100 Subject: [PATCH 19/91] Made maven plugin ITs runnable Gradle build script creates builds spotless maven plugin by shelling out to maven. It then installs the plugin JAR into a local maven repo that's later used for tests. Task "test" depends on all these steps. Maven integration tests generate pom.xml based on a template. This pom references the previously created local maven repo to locate spotless plugin. Tests then invoke maven via Process API and compare formatter with unformatted files. --- gradle.properties | 2 + plugin-maven/build.gradle | 26 ++++- .../spotless/EclipseFormatStepTest.java | 22 +--- .../gradle/spotless/MavenIntegrationTest.java | 107 +++++++++--------- .../gradle/spotless/MavenProvisionerTest.java | 53 ++++++++- .../eclipse/format/JavaCodeFormatted.test | 2 +- .../src/test/resources/pom.xml.mustache | 53 +++++++++ 7 files changed, 194 insertions(+), 71 deletions(-) create mode 100644 plugin-maven/src/test/resources/pom.xml.mustache diff --git a/gradle.properties b/gradle.properties index e12d475853..a75bdca5aa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -32,7 +32,9 @@ VER_PEGDOWN_DOCLET=1.3 VER_DURIAN=1.2.0 VER_JUNIT=4.12 VER_ASSERTJ=3.5.2 +VER_MOCKITO=2.13.0 # Used for Maven Plugin VER_MAVEN_API=3.0 VER_ECLIPSE_AETHER=1.1.0 +VER_MUSTACHE=0.9.5 diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index 517b18bebb..fdcc423cba 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -15,10 +15,11 @@ apply from: rootProject.file("gradle/java-publish.gradle") final PROJECT_DIR = project.projectDir.toString() final BUILD_DIR = project.buildDir.toString() final MAVEN_PROJECT_DIR = "${BUILD_DIR}/mavenProject" +final LOCAL_MAVEN_REPO_DIR = "${BUILD_DIR}/localMavenRepository" buildscript { repositories { mavenCentral() } - dependencies { classpath "com.github.spullara.mustache.java:compiler:0.9.5" } + dependencies { classpath "com.github.spullara.mustache.java:compiler:${VER_MUSTACHE}" } } dependencies { @@ -32,7 +33,10 @@ dependencies { testCompile project(":testlib") testCompile "junit:junit:${VER_JUNIT}" testCompile "org.assertj:assertj-core:${VER_ASSERTJ}" + testCompile "org.mockito:mockito-core:${VER_MOCKITO}" testCompile "com.diffplug.durian:durian-testlib:${VER_DURIAN}" + testCompile "com.github.spullara.mustache.java:compiler:${VER_MUSTACHE}" + testCompile "org.eclipse.aether:aether-api:${VER_ECLIPSE_AETHER}" } task cleanMavenProjectDir(type: Delete) { delete MAVEN_PROJECT_DIR } @@ -77,4 +81,22 @@ task buildMavenPlugin(type: Copy, dependsOn: runMavenBuild) { into "${BUILD_DIR}/libs" } -build.finalizedBy buildMavenPlugin +task createLocalMavenRepositoryForTests(type: Exec, dependsOn: buildMavenPlugin) { + workingDir "${BUILD_DIR}/libs" + commandLine "mvn", "org.apache.maven.plugins:maven-install-plugin:2.3.1:install-file", + "-Dfile=spotless-maven-plugin-${project.versionMaven}.jar", + "-DgroupId=com.diffplug.spotless", + "-DartifactId=spotless", + "-Dversion=${project.versionMaven}", + "-Dpackaging=paven-plugin", + "-DlocalRepositoryPath=${LOCAL_MAVEN_REPO_DIR}" +} + +test { + // pass location of the local maven repository and plugin version to junit tests + systemProperty "localMavenRepositoryDir", "${LOCAL_MAVEN_REPO_DIR}" + systemProperty "spotlessMavenPluginVersion", project.versionMaven +} + +test.dependsOn createLocalMavenRepositoryForTests +build.dependsOn buildMavenPlugin diff --git a/plugin-maven/src/test/java/com/diffplug/gradle/spotless/EclipseFormatStepTest.java b/plugin-maven/src/test/java/com/diffplug/gradle/spotless/EclipseFormatStepTest.java index 7796d4ab3f..13f137a64a 100644 --- a/plugin-maven/src/test/java/com/diffplug/gradle/spotless/EclipseFormatStepTest.java +++ b/plugin-maven/src/test/java/com/diffplug/gradle/spotless/EclipseFormatStepTest.java @@ -15,37 +15,27 @@ */ package com.diffplug.gradle.spotless; -import java.io.IOException; - import org.assertj.core.api.Assertions; -import org.junit.Ignore; import org.junit.Test; /** - * This test is ignored because it doesn't work. - * To make it work, we'll need something like the following: - * - * build.gradle - * task publishTestToLocalRepo() - * test.dependsOn(publishTestToLocalRepo) - * - * Then in MavenIntegratonTest.POM_HEADER, set appropriately - * * Would also be good if we had mvnw setup, so that * the test harness used mvnw to control the verison * of maven that was used. */ -@Ignore public class EclipseFormatStepTest extends MavenIntegrationTest { + @Test - public void testEclipse() throws IOException, InterruptedException { + public void testEclipse() throws Exception { // write the pom - writePomJavaSteps( + writePomWithJavaSteps( "", - " ${basedir}/eclipse-fmt.xml", + " ${basedir}/formatter.xml", " 4.7.1", ""); + write("src/main/java/test.java", getTestResource("java/eclipse/format/JavaCodeUnformatted.test")); + write("formatter.xml", getTestResource("java/eclipse/format/formatter.xml")); mavenRunner().withArguments("spotless:apply").runNoError(); String actual = read("src/main/java/test.java"); diff --git a/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenIntegrationTest.java b/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenIntegrationTest.java index 5247b5b8c0..89ba644fe0 100644 --- a/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenIntegrationTest.java +++ b/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenIntegrationTest.java @@ -15,15 +15,36 @@ */ package com.diffplug.gradle.spotless; +import static com.diffplug.common.base.Strings.isNullOrEmpty; +import static java.util.stream.Collectors.joining; +import static org.junit.Assert.fail; + +import java.io.BufferedReader; import java.io.IOException; +import java.io.StringWriter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Arrays; -import java.util.stream.Collectors; +import java.util.HashMap; +import java.util.Map; import org.junit.Before; +import com.github.mustachejava.DefaultMustacheFactory; +import com.github.mustachejava.Mustache; +import com.github.mustachejava.MustacheFactory; + import com.diffplug.spotless.ResourceHarness; public class MavenIntegrationTest extends ResourceHarness { + + private static final String LOCAL_MAVEN_REPOSITORY_DIR = "localMavenRepositoryDir"; + private static final String SPOTLESS_MAVEN_PLUGIN_VERSION = "spotlessMavenPluginVersion"; + private static final String JAVA_CONFIGURATION = "javaConfiguration"; + + private final MustacheFactory mustacheFactory = new DefaultMustacheFactory(); + /** * Each test gets its own temp folder, and we create a maven * build there and run it. @@ -43,60 +64,44 @@ public void gitAttributes() throws IOException { write(".gitattributes", "* text eol=lf"); } - private static final String POM_HEADER = "" + - "\n" + - " 4.0.0\n" + - " \n" + - " \n" + - " central\n" + - " Central Repository\n" + - " http://repo.maven.apache.org/maven2\n" + - " default\n" + - " \n" + - " false\n" + - " \n" + - " \n" + - " \n" + - " \n" + // TODO: setup test so that the plugin gets compiled first, and put into this repository - " \n" + - " central\n" + - " Central Repository\n" + - " http://repo.maven.apache.org/maven2\n" + - " default\n" + - " \n" + - " false\n" + - " \n" + - " \n" + - " never\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " com.diffplug.spotless\n" + - " spotless-maven-plugin\n" + - " +\n" + - " \n"; - - private static final String POM_FOOTER = "" + - " \n" + - " \n" + - " \n" + - " \n" + - "\n"; - - protected void writePomJavaSteps(String... steps) throws IOException { - write("pom.xml", - POM_HEADER, - "", - Arrays.stream(steps).collect(Collectors.joining("\n")), - "", - POM_FOOTER); + protected void writePomWithJavaSteps(String... steps) throws IOException { + String pomXmlContent = createPomXmlContent(steps); + write("pom.xml", pomXmlContent); } protected MavenRunner mavenRunner() throws IOException { return MavenRunner.create() .withProjectDir(rootFolder()); } + + private String createPomXmlContent(String... steps) throws IOException { + Path pomXml = Paths.get("src", "test", "resources", "pom.xml.mustache"); + + try (BufferedReader reader = Files.newBufferedReader(pomXml)) { + Mustache mustache = mustacheFactory.compile(reader, "pom"); + StringWriter writer = new StringWriter(); + Map params = buildPomXmlParams(steps); + mustache.execute(writer, params); + return writer.toString(); + } + } + + private static Map buildPomXmlParams(String... steps) { + Map params = new HashMap<>(); + params.put(LOCAL_MAVEN_REPOSITORY_DIR, getSystemProperty(LOCAL_MAVEN_REPOSITORY_DIR)); + params.put(SPOTLESS_MAVEN_PLUGIN_VERSION, getSystemProperty(SPOTLESS_MAVEN_PLUGIN_VERSION)); + + String stepsXml = Arrays.stream(steps).collect(joining("\n", "\n", "\n")); + params.put(JAVA_CONFIGURATION, stepsXml); + + return params; + } + + private static String getSystemProperty(String name) { + String value = System.getProperty(name); + if (isNullOrEmpty(value)) { + fail("System property '" + name + "' is not defined"); + } + return value; + } } diff --git a/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenProvisionerTest.java b/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenProvisionerTest.java index 4ecda7c061..6d0a606ccb 100644 --- a/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenProvisionerTest.java +++ b/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenProvisionerTest.java @@ -15,11 +15,62 @@ */ package com.diffplug.gradle.spotless; +import static java.util.Collections.emptyList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.util.Set; + +import org.eclipse.aether.resolution.ArtifactResolutionException; import org.junit.Test; +import com.diffplug.spotless.Provisioner; + public class MavenProvisionerTest { + + @Test + public void testProvisionWithDependencies() throws Exception { + ArtifactResolver resolver = mock(ArtifactResolver.class); + when(resolver.resolve("foo")).thenReturn(new File("foo")); + when(resolver.resolve("bar")).thenReturn(new File("bar")); + when(resolver.resolve("baz")).thenReturn(new File("baz")); + Provisioner provisioner = MavenProvisioner.create(resolver); + + Set files = provisioner.provisionWithDependencies("foo", "bar", "baz"); + + assertThat(files).containsOnly(new File("foo"), new File("bar"), new File("baz")); + } + @Test - public void test() { + public void testProvisionWithDependenciesThrowsCheckedException() throws Exception { + ArtifactResolver resolver = mock(ArtifactResolver.class); + when(resolver.resolve("foo")).thenThrow(new ArtifactResolutionException(emptyList(), "Error!")); + Provisioner provisioner = MavenProvisioner.create(resolver); + + try { + provisioner.provisionWithDependencies("foo"); + fail("Exception expected"); + } catch (RuntimeException e) { + assertThat(e.getCause()).isInstanceOf(ArtifactResolutionException.class); + assertThat(e.getCause().getMessage()).isEqualTo("Error!"); + } + } + + @Test + public void testProvisionWithDependenciesThrowsUncheckedException() throws Exception { + ArtifactResolver resolver = mock(ArtifactResolver.class); + when(resolver.resolve("foo")).thenThrow(new RuntimeException("Wrong coordinate!")); + + Provisioner provisioner = MavenProvisioner.create(resolver); + try { + provisioner.provisionWithDependencies("foo"); + fail("Exception expected"); + } catch (RuntimeException e) { + assertThat(e.getMessage()).isEqualTo("Wrong coordinate!"); + } } } diff --git a/plugin-maven/src/test/resources/java/eclipse/format/JavaCodeFormatted.test b/plugin-maven/src/test/resources/java/eclipse/format/JavaCodeFormatted.test index fc8b92a1ea..b43ebf6edf 100644 --- a/plugin-maven/src/test/resources/java/eclipse/format/JavaCodeFormatted.test +++ b/plugin-maven/src/test/resources/java/eclipse/format/JavaCodeFormatted.test @@ -2,4 +2,4 @@ public class Java { public static void main(String[] args) { System.out.println("hello"); } -} \ No newline at end of file +} diff --git a/plugin-maven/src/test/resources/pom.xml.mustache b/plugin-maven/src/test/resources/pom.xml.mustache new file mode 100644 index 0000000000..9410301bd5 --- /dev/null +++ b/plugin-maven/src/test/resources/pom.xml.mustache @@ -0,0 +1,53 @@ + + 4.0.0 + + com.diffplug.spotless + spotless-maven-plugin-tests + 1.0.0-SNAPSHOT + + Spotless Maven Plugin Tests + + + UTF-8 + + + + + local-repo + file://{{localMavenRepositoryDir}} + + true + always + ignore + + + true + always + ignore + + + + + + + + com.diffplug.spotless + spotless-maven-plugin + {{spotlessMavenPluginVersion}} + + {{#pluginConfiguration}} + {{{pluginConfiguration}}} + {{/pluginConfiguration}} + + {{#javaConfiguration}} + + {{{javaConfiguration}}} + + {{/javaConfiguration}} + + + + + + From ddbf0eb986a928ec05ae7d10ae095a71f027e814 Mon Sep 17 00:00:00 2001 From: lutovich Date: Mon, 22 Jan 2018 21:35:30 +0100 Subject: [PATCH 20/91] Better package name for maven plugin --- .../{gradle => maven}/spotless/AbstractSpotlessMojo.java | 2 +- .../diffplug/{gradle => maven}/spotless/ArtifactResolver.java | 2 +- .../java/com/diffplug/{gradle => maven}/spotless/Eclipse.java | 2 +- .../diffplug/{gradle => maven}/spotless/FormatterFactory.java | 2 +- .../{gradle => maven}/spotless/FormatterStepFactory.java | 2 +- .../main/java/com/diffplug/{gradle => maven}/spotless/Java.java | 2 +- .../diffplug/{gradle => maven}/spotless/MavenProvisioner.java | 2 +- .../com/diffplug/{gradle => maven}/spotless/MojoConfig.java | 2 +- .../com/diffplug/{gradle => maven}/spotless/SpotlessMojo.java | 2 +- .../{gradle => maven}/spotless/EclipseFormatStepTest.java | 2 +- .../{gradle => maven}/spotless/MavenIntegrationTest.java | 2 +- .../{gradle => maven}/spotless/MavenProvisionerTest.java | 2 +- .../com/diffplug/{gradle => maven}/spotless/MavenRunner.java | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) rename plugin-maven/src/main/java/com/diffplug/{gradle => maven}/spotless/AbstractSpotlessMojo.java (98%) rename plugin-maven/src/main/java/com/diffplug/{gradle => maven}/spotless/ArtifactResolver.java (98%) rename plugin-maven/src/main/java/com/diffplug/{gradle => maven}/spotless/Eclipse.java (97%) rename plugin-maven/src/main/java/com/diffplug/{gradle => maven}/spotless/FormatterFactory.java (95%) rename plugin-maven/src/main/java/com/diffplug/{gradle => maven}/spotless/FormatterStepFactory.java (95%) rename plugin-maven/src/main/java/com/diffplug/{gradle => maven}/spotless/Java.java (98%) rename plugin-maven/src/main/java/com/diffplug/{gradle => maven}/spotless/MavenProvisioner.java (96%) rename plugin-maven/src/main/java/com/diffplug/{gradle => maven}/spotless/MojoConfig.java (97%) rename plugin-maven/src/main/java/com/diffplug/{gradle => maven}/spotless/SpotlessMojo.java (98%) rename plugin-maven/src/test/java/com/diffplug/{gradle => maven}/spotless/EclipseFormatStepTest.java (97%) rename plugin-maven/src/test/java/com/diffplug/{gradle => maven}/spotless/MavenIntegrationTest.java (98%) rename plugin-maven/src/test/java/com/diffplug/{gradle => maven}/spotless/MavenProvisionerTest.java (98%) rename plugin-maven/src/test/java/com/diffplug/{gradle => maven}/spotless/MavenRunner.java (99%) diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/AbstractSpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/AbstractSpotlessMojo.java similarity index 98% rename from plugin-maven/src/main/java/com/diffplug/gradle/spotless/AbstractSpotlessMojo.java rename to plugin-maven/src/main/java/com/diffplug/maven/spotless/AbstractSpotlessMojo.java index 2cb77ed8b1..34127426c7 100644 --- a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/AbstractSpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/maven/spotless/AbstractSpotlessMojo.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.gradle.spotless; +package com.diffplug.maven.spotless; import static java.util.stream.Collectors.toList; diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/ArtifactResolver.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/ArtifactResolver.java similarity index 98% rename from plugin-maven/src/main/java/com/diffplug/gradle/spotless/ArtifactResolver.java rename to plugin-maven/src/main/java/com/diffplug/maven/spotless/ArtifactResolver.java index 24b9213e2c..a1e19d7728 100644 --- a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/ArtifactResolver.java +++ b/plugin-maven/src/main/java/com/diffplug/maven/spotless/ArtifactResolver.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.gradle.spotless; +package com.diffplug.maven.spotless; import java.io.File; import java.util.List; diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/Eclipse.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/Eclipse.java similarity index 97% rename from plugin-maven/src/main/java/com/diffplug/gradle/spotless/Eclipse.java rename to plugin-maven/src/main/java/com/diffplug/maven/spotless/Eclipse.java index 1dafc43705..109545a713 100644 --- a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/Eclipse.java +++ b/plugin-maven/src/main/java/com/diffplug/maven/spotless/Eclipse.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.gradle.spotless; +package com.diffplug.maven.spotless; import static com.diffplug.spotless.extra.java.EclipseFormatterStep.defaultVersion; import static java.util.Collections.singleton; diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/FormatterFactory.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/FormatterFactory.java similarity index 95% rename from plugin-maven/src/main/java/com/diffplug/gradle/spotless/FormatterFactory.java rename to plugin-maven/src/main/java/com/diffplug/maven/spotless/FormatterFactory.java index db227993ee..9d951fdace 100644 --- a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/FormatterFactory.java +++ b/plugin-maven/src/main/java/com/diffplug/maven/spotless/FormatterFactory.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.gradle.spotless; +package com.diffplug.maven.spotless; import java.io.File; import java.util.List; diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/FormatterStepFactory.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/FormatterStepFactory.java similarity index 95% rename from plugin-maven/src/main/java/com/diffplug/gradle/spotless/FormatterStepFactory.java rename to plugin-maven/src/main/java/com/diffplug/maven/spotless/FormatterStepFactory.java index 6af2f2658f..1386efb584 100644 --- a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/FormatterStepFactory.java +++ b/plugin-maven/src/main/java/com/diffplug/maven/spotless/FormatterStepFactory.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.gradle.spotless; +package com.diffplug.maven.spotless; import com.diffplug.spotless.FormatterStep; diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/Java.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/Java.java similarity index 98% rename from plugin-maven/src/main/java/com/diffplug/gradle/spotless/Java.java rename to plugin-maven/src/main/java/com/diffplug/maven/spotless/Java.java index c53fd38513..9fa1e00b05 100644 --- a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/Java.java +++ b/plugin-maven/src/main/java/com/diffplug/maven/spotless/Java.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.gradle.spotless; +package com.diffplug.maven.spotless; import static java.util.stream.Collectors.toList; diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/MavenProvisioner.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/MavenProvisioner.java similarity index 96% rename from plugin-maven/src/main/java/com/diffplug/gradle/spotless/MavenProvisioner.java rename to plugin-maven/src/main/java/com/diffplug/maven/spotless/MavenProvisioner.java index 938e3de89f..3d289c9994 100644 --- a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/MavenProvisioner.java +++ b/plugin-maven/src/main/java/com/diffplug/maven/spotless/MavenProvisioner.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.gradle.spotless; +package com.diffplug.maven.spotless; import static java.util.stream.Collectors.toSet; diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/MojoConfig.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/MojoConfig.java similarity index 97% rename from plugin-maven/src/main/java/com/diffplug/gradle/spotless/MojoConfig.java rename to plugin-maven/src/main/java/com/diffplug/maven/spotless/MojoConfig.java index 7ab3209913..7c123b537d 100644 --- a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/MojoConfig.java +++ b/plugin-maven/src/main/java/com/diffplug/maven/spotless/MojoConfig.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.gradle.spotless; +package com.diffplug.maven.spotless; import java.io.File; diff --git a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/SpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessMojo.java similarity index 98% rename from plugin-maven/src/main/java/com/diffplug/gradle/spotless/SpotlessMojo.java rename to plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessMojo.java index 330e431f32..74a02357fa 100644 --- a/plugin-maven/src/main/java/com/diffplug/gradle/spotless/SpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessMojo.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.gradle.spotless; +package com.diffplug.maven.spotless; import static java.util.Collections.singletonList; import static java.util.stream.Collectors.toList; diff --git a/plugin-maven/src/test/java/com/diffplug/gradle/spotless/EclipseFormatStepTest.java b/plugin-maven/src/test/java/com/diffplug/maven/spotless/EclipseFormatStepTest.java similarity index 97% rename from plugin-maven/src/test/java/com/diffplug/gradle/spotless/EclipseFormatStepTest.java rename to plugin-maven/src/test/java/com/diffplug/maven/spotless/EclipseFormatStepTest.java index 13f137a64a..cb96ce9a28 100644 --- a/plugin-maven/src/test/java/com/diffplug/gradle/spotless/EclipseFormatStepTest.java +++ b/plugin-maven/src/test/java/com/diffplug/maven/spotless/EclipseFormatStepTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.gradle.spotless; +package com.diffplug.maven.spotless; import org.assertj.core.api.Assertions; import org.junit.Test; diff --git a/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenIntegrationTest.java b/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenIntegrationTest.java similarity index 98% rename from plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenIntegrationTest.java rename to plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenIntegrationTest.java index 89ba644fe0..841bc64525 100644 --- a/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenIntegrationTest.java +++ b/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenIntegrationTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.gradle.spotless; +package com.diffplug.maven.spotless; import static com.diffplug.common.base.Strings.isNullOrEmpty; import static java.util.stream.Collectors.joining; diff --git a/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenProvisionerTest.java b/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenProvisionerTest.java similarity index 98% rename from plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenProvisionerTest.java rename to plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenProvisionerTest.java index 6d0a606ccb..aa07a7c90e 100644 --- a/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenProvisionerTest.java +++ b/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenProvisionerTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.gradle.spotless; +package com.diffplug.maven.spotless; import static java.util.Collections.emptyList; import static org.assertj.core.api.Assertions.assertThat; diff --git a/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenRunner.java b/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenRunner.java similarity index 99% rename from plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenRunner.java rename to plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenRunner.java index 8313af683f..35c31abc79 100644 --- a/plugin-maven/src/test/java/com/diffplug/gradle/spotless/MavenRunner.java +++ b/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenRunner.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.gradle.spotless; +package com.diffplug.maven.spotless; import java.io.ByteArrayOutputStream; import java.io.File; From 4754a8f738e478ce452edbcec1296cdaf2ef719f Mon Sep 17 00:00:00 2001 From: lutovich Date: Mon, 22 Jan 2018 22:55:20 +0100 Subject: [PATCH 21/91] Include stdout and stderr in maven plugin test failures Make test task print assertion failures. --- plugin-maven/build.gradle | 1 + .../com/diffplug/maven/spotless/MavenRunner.java | 13 +++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index fdcc423cba..1b9694db5a 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -93,6 +93,7 @@ task createLocalMavenRepositoryForTests(type: Exec, dependsOn: buildMavenPlugin) } test { + testLogging { exceptionFormat = 'full' } // pass location of the local maven repository and plugin version to junit tests systemProperty "localMavenRepositoryDir", "${LOCAL_MAVEN_REPO_DIR}" systemProperty "spotlessMavenPluginVersion", project.versionMaven diff --git a/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenRunner.java b/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenRunner.java index 35c31abc79..f17ff5a704 100644 --- a/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenRunner.java +++ b/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenRunner.java @@ -75,14 +75,14 @@ private Result run() throws IOException, InterruptedException { /** Runs the command and asserts that nothing was printed to stderr. */ public Result runNoError() throws IOException, InterruptedException { Result result = run(); - Assertions.assertThat(result.error()).isEmpty(); + Assertions.assertThat(result.error()).as("Run without error %s", result).isEmpty(); return result; } /** Runs the command and asserts that something was printed to stderr. */ public Result runHasError() throws IOException, InterruptedException { Result result = run(); - Assertions.assertThat(result.error()).isNotEmpty(); + Assertions.assertThat(result.error()).as("Run with error %s", result).isNotEmpty(); return result; } @@ -109,6 +109,15 @@ public String output() { public String error() { return error; } + + @Override + public String toString() { + return "Result{" + + "exitValue=" + exitValue + + ", output='" + output + '\'' + + ", error='" + error + '\'' + + '}'; + } } /** Prepends any arguments necessary to run a console command. */ From 88bcd1976f6211c30f470f4ad9a1de252a0733ec Mon Sep 17 00:00:00 2001 From: lutovich Date: Mon, 22 Jan 2018 23:29:26 +0100 Subject: [PATCH 22/91] Assert on exit code, not stderr In maven plugin integration tests. Previous assertion on string obtained from stderr failed on CI. There build agents print "Picked up _JAVA_OPTIONS: -Xmx2048m -Xms512m" to stderr when java is launched. --- .../java/com/diffplug/maven/spotless/MavenRunner.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenRunner.java b/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenRunner.java index f17ff5a704..9766c4693e 100644 --- a/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenRunner.java +++ b/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenRunner.java @@ -15,6 +15,8 @@ */ package com.diffplug.maven.spotless; +import static org.assertj.core.api.Assertions.assertThat; + import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; @@ -26,8 +28,6 @@ import java.util.Objects; import java.util.stream.Collectors; -import org.assertj.core.api.Assertions; - import com.diffplug.common.base.Throwables; import com.diffplug.common.io.ByteStreams; @@ -75,14 +75,14 @@ private Result run() throws IOException, InterruptedException { /** Runs the command and asserts that nothing was printed to stderr. */ public Result runNoError() throws IOException, InterruptedException { Result result = run(); - Assertions.assertThat(result.error()).as("Run without error %s", result).isEmpty(); + assertThat(result.exitValue()).as("Run without error %s", result).isEqualTo(0); return result; } /** Runs the command and asserts that something was printed to stderr. */ public Result runHasError() throws IOException, InterruptedException { Result result = run(); - Assertions.assertThat(result.error()).as("Run with error %s", result).isNotEmpty(); + assertThat(result.exitValue()).as("Run with error %s", result).isEqualTo(1); return result; } From c84becf7f515b3fc42355f857dabf120c39a3fcf Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Tue, 23 Jan 2018 00:45:57 -0800 Subject: [PATCH 23/91] Refactored DiffMessageFormatter out of gradle and into lib-extra. --- .../integration}/DiffMessageFormatter.java | 99 ++++++++++++++----- .../extra/integration/package-info.java | 10 ++ .../gradle/spotless/SpotlessTask.java | 12 ++- .../spotless/DiffMessageFormatterTest.java | 1 + 4 files changed, 93 insertions(+), 29 deletions(-) rename {plugin-gradle/src/main/java/com/diffplug/gradle/spotless => lib-extra/src/main/java/com/diffplug/spotless/extra/integration}/DiffMessageFormatter.java (70%) create mode 100644 lib-extra/src/main/java/com/diffplug/spotless/extra/integration/package-info.java diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/DiffMessageFormatter.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/integration/DiffMessageFormatter.java similarity index 70% rename from plugin-gradle/src/main/java/com/diffplug/gradle/spotless/DiffMessageFormatter.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/integration/DiffMessageFormatter.java index d70cf3ab4e..e62781d498 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/DiffMessageFormatter.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/integration/DiffMessageFormatter.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.gradle.spotless; +package com.diffplug.spotless.extra.integration; import java.io.ByteArrayOutputStream; import java.io.File; @@ -23,6 +23,7 @@ import java.nio.file.Path; import java.util.List; import java.util.ListIterator; +import java.util.Objects; import org.eclipse.jgit.diff.DiffFormatter; import org.eclipse.jgit.diff.EditList; @@ -31,6 +32,7 @@ import org.eclipse.jgit.diff.RawTextComparator; import com.diffplug.common.base.CharMatcher; +import com.diffplug.common.base.Errors; import com.diffplug.common.base.Preconditions; import com.diffplug.common.base.Splitter; import com.diffplug.spotless.Formatter; @@ -38,35 +40,80 @@ import com.diffplug.spotless.PaddedCell; /** Formats the messages of failed spotlessCheck invocations with a nice diff message. */ -final class DiffMessageFormatter { - private static final int MAX_CHECK_MESSAGE_LINES = 50; - static final int MAX_FILES_TO_LIST = 10; - - static String messageFor(SpotlessTask task, Formatter formatter, List problemFiles) throws IOException { - DiffMessageFormatter diffFormater = new DiffMessageFormatter(task, formatter, problemFiles); - return "The following files had format violations:\n" - + diffFormater.buffer - + "Run 'gradlew " - + SpotlessPlugin.EXTENSION - + SpotlessPlugin.APPLY - + "' to fix these violations."; +public final class DiffMessageFormatter { + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private Builder() {} + + private String runToFix; + private File rootDir; + private boolean isPaddedCell; + private Formatter formatter; + private List problemFiles; + + /** "Run 'gradlew spotlessApply' to fix these violations." */ + public Builder runToFix(String runToFix) { + this.runToFix = Objects.requireNonNull(runToFix); + return this; + } + + public Builder rootDir(File rootDir) { + this.rootDir = Objects.requireNonNull(rootDir); + return this; + } + + public Builder isPaddedCell(boolean isPaddedCell) { + this.isPaddedCell = isPaddedCell; + return this; + } + + public Builder formatter(Formatter formatter) { + this.formatter = Objects.requireNonNull(formatter); + return this; + } + + public Builder problemFiles(List problemFiles) { + this.problemFiles = Objects.requireNonNull(problemFiles); + Preconditions.checkArgument(!problemFiles.isEmpty(), "cannot be empty"); + return this; + } + + /** Returns the error message. */ + public String getMessage() { + try { + Objects.requireNonNull(runToFix, "runToFix"); + Objects.requireNonNull(rootDir, "rootDir"); + Objects.requireNonNull(formatter, "formatter"); + Objects.requireNonNull(problemFiles, "problemFiles"); + DiffMessageFormatter diffFormater = new DiffMessageFormatter(this); + return "The following files had format violations:\n" + + diffFormater.buffer + + runToFix; + } catch (IOException e) { + throw Errors.asRuntime(e); + } + } } + private static final int MAX_CHECK_MESSAGE_LINES = 50; + public static final int MAX_FILES_TO_LIST = 10; + private final StringBuilder buffer = new StringBuilder(MAX_CHECK_MESSAGE_LINES * 64); private int numLines = 0; - private DiffMessageFormatter(SpotlessTask task, Formatter formatter, List problemFiles) throws IOException { - Preconditions.checkArgument(!problemFiles.isEmpty(), "Problem files must not be empty"); - - Path rootDir = task.getProject().getRootDir().toPath(); - ListIterator problemIter = problemFiles.listIterator(); + private DiffMessageFormatter(Builder builder) throws IOException { + Path rootDir = builder.rootDir.toPath(); + ListIterator problemIter = builder.problemFiles.listIterator(); while (problemIter.hasNext() && numLines < MAX_CHECK_MESSAGE_LINES) { File file = problemIter.next(); addFile(rootDir.relativize(file.toPath()) + "\n" + - DiffMessageFormatter.diff(task, formatter, file)); + DiffMessageFormatter.diff(builder, file)); } if (problemIter.hasNext()) { - int remainingFiles = problemFiles.size() - problemIter.nextIndex(); + int remainingFiles = builder.problemFiles.size() - problemIter.nextIndex(); if (remainingFiles >= MAX_FILES_TO_LIST) { buffer.append("Violations also present in ").append(remainingFiles).append(" other files.\n"); } else { @@ -126,19 +173,19 @@ private void addIntendedLine(String indent, String line) { * look like if formatted using the given formatter. Does not end with any newline * sequence (\n, \r, \r\n). */ - private static String diff(SpotlessTask task, Formatter formatter, File file) throws IOException { - String raw = new String(Files.readAllBytes(file.toPath()), formatter.getEncoding()); + private static String diff(Builder builder, File file) throws IOException { + String raw = new String(Files.readAllBytes(file.toPath()), builder.formatter.getEncoding()); String rawUnix = LineEnding.toUnix(raw); String formattedUnix; - if (task.isPaddedCell()) { - formattedUnix = PaddedCell.check(formatter, file, rawUnix).canonical(); + if (builder.isPaddedCell) { + formattedUnix = PaddedCell.check(builder.formatter, file, rawUnix).canonical(); } else { - formattedUnix = formatter.compute(rawUnix, file); + formattedUnix = builder.formatter.compute(rawUnix, file); } if (rawUnix.equals(formattedUnix)) { // the formatting is fine, so it's a line-ending issue - String formatted = formatter.computeLineEndings(formattedUnix, file); + String formatted = builder.formatter.computeLineEndings(formattedUnix, file); return diffWhitespaceLineEndings(raw, formatted, false, true); } else { return diffWhitespaceLineEndings(rawUnix, formattedUnix, true, false); diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/integration/package-info.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/integration/package-info.java new file mode 100644 index 0000000000..7d152c9079 --- /dev/null +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/integration/package-info.java @@ -0,0 +1,10 @@ +/** + * Integration code for plugins. + */ +@ParametersAreNonnullByDefault +@ReturnValuesAreNonnullByDefault +package com.diffplug.spotless.extra.integration; + +import javax.annotation.ParametersAreNonnullByDefault; + +import com.diffplug.spotless.annotations.ReturnValuesAreNonnullByDefault; diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTask.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTask.java index a8ac8ea725..2eb4786949 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTask.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTask.java @@ -18,7 +18,6 @@ import static com.diffplug.gradle.spotless.PluginGradlePreconditions.requireElementsNonNull; import java.io.File; -import java.io.IOException; import java.io.Serializable; import java.nio.charset.Charset; import java.nio.file.Files; @@ -45,6 +44,7 @@ import com.diffplug.spotless.LineEnding; import com.diffplug.spotless.PaddedCell; import com.diffplug.spotless.PaddedCellBulk; +import com.diffplug.spotless.extra.integration.DiffMessageFormatter; public class SpotlessTask extends DefaultTask { // set by SpotlessExtension, but possibly overridden by FormatExtension @@ -279,7 +279,13 @@ private void check(Formatter formatter, List outOfDate) throws Exception { } /** Returns an exception which indicates problem files nicely. */ - GradleException formatViolationsFor(Formatter formatter, List problemFiles) throws IOException { - return new GradleException(DiffMessageFormatter.messageFor(this, formatter, problemFiles)); + GradleException formatViolationsFor(Formatter formatter, List problemFiles) { + return new GradleException(DiffMessageFormatter.builder() + .runToFix("Run 'gradlew spotlessApply' to fix these violations.") + .rootDir(getProject().getRootDir()) + .isPaddedCell(paddedCell) + .formatter(formatter) + .problemFiles(problemFiles) + .getMessage()); } } diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/DiffMessageFormatterTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/DiffMessageFormatterTest.java index 27acc3feb1..1c47c0621c 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/DiffMessageFormatterTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/DiffMessageFormatterTest.java @@ -33,6 +33,7 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.LineEnding; import com.diffplug.spotless.ResourceHarness; +import com.diffplug.spotless.extra.integration.DiffMessageFormatter; public class DiffMessageFormatterTest extends ResourceHarness { private SpotlessTask create(File... files) throws IOException { From 012b1186a101b2091cfe3b4d0285fabe6a919d9b Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Tue, 23 Jan 2018 00:46:48 -0800 Subject: [PATCH 24/91] Added "check" to the maven plugin, but not properly integrated. --- .../diffplug/maven/spotless/SpotlessMojo.java | 51 +++++++++++++++---- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessMojo.java index 74a02357fa..081f240f00 100644 --- a/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessMojo.java @@ -23,6 +23,7 @@ import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; @@ -31,6 +32,7 @@ import org.apache.maven.plugins.annotations.Mojo; import com.diffplug.spotless.Formatter; +import com.diffplug.spotless.extra.integration.DiffMessageFormatter; @Mojo(name = "apply") public class SpotlessMojo extends AbstractSpotlessMojo { @@ -52,17 +54,11 @@ private void execute(FormatterFactory formatterFactory) throws MojoExecutionExce Formatter formatter = formatterFactory.newFormatter(filesToFormat, mojoConfig); - formatAll(filesToFormat, formatter); - } - - private List collectFilesToFormat(String extension) throws MojoExecutionException { - try { - return getAllSourceRoots().stream() - .flatMap(root -> collectFilesToFormat(root, extension).stream()) - .map(Path::toFile) - .collect(toList()); - } catch (Exception e) { - throw new MojoExecutionException("Unable to collect files to format", e); + boolean check = false; + if (!check) { + formatAll(filesToFormat, formatter); + } else { + checkAll(filesToFormat, formatter); } } @@ -76,6 +72,39 @@ private static void formatAll(List files, Formatter formatter) throws Mojo } } + private static void checkAll(List files, Formatter formatter) throws MojoExecutionException { + List problemFiles = new ArrayList<>(); + for (File file : files) { + try { + if (!formatter.isClean(file)) { + problemFiles.add(file); + } + } catch (IOException e) { + throw new MojoExecutionException("Unable to format file " + file, e); + } + } + if (!problemFiles.isEmpty()) { + throw new MojoExecutionException(DiffMessageFormatter.builder() + .runToFix("Run 'gradlew spotless:apply' to fix these violations.") + .rootDir(null) + .isPaddedCell(false) + .formatter(formatter) + .problemFiles(problemFiles) + .getMessage()); + } + } + + private List collectFilesToFormat(String extension) throws MojoExecutionException { + try { + return getAllSourceRoots().stream() + .flatMap(root -> collectFilesToFormat(root, extension).stream()) + .map(Path::toFile) + .collect(toList()); + } catch (Exception e) { + throw new MojoExecutionException("Unable to collect files to format", e); + } + } + private static List collectFilesToFormat(Path root, String extension) { try (Stream entries = Files.walk(root)) { return entries.filter(Files::isRegularFile) From 0c01e6459b2fc950c6af36050a9d9adbead646e4 Mon Sep 17 00:00:00 2001 From: lutovich Date: Wed, 24 Jan 2018 00:39:36 +0100 Subject: [PATCH 25/91] Made maven plugin use all dependencies from local repo So that it is able to depend on snapshot version of lib and lib-extra. All compile dependencies with transitives are now installed into local maven repo. This repo is used both for building and testing the plugin. --- plugin-maven/build.gradle | 53 +++++++++++++++++-- .../src/main/resources/pom.xml.mustache | 20 +++++++ 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index 1b9694db5a..d9acd2ad22 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -17,6 +17,8 @@ final BUILD_DIR = project.buildDir.toString() final MAVEN_PROJECT_DIR = "${BUILD_DIR}/mavenProject" final LOCAL_MAVEN_REPO_DIR = "${BUILD_DIR}/localMavenRepository" +final SPOTLESS_LIB_VERSION = "1.0.0-SNAPSHOT" // should be project.stableLib once maven plugin stabilizes + buildscript { repositories { mavenCentral() } dependencies { classpath "com.github.spullara.mustache.java:compiler:${VER_MUSTACHE}" } @@ -46,13 +48,58 @@ task copySourceFiles(type: Copy) { into "${MAVEN_PROJECT_DIR}/src/main/java" } -task createPomXml { +// this task is temporary, it should be removed once maven plugin stabilizes +// and can depend on released version of lib and lib-extra +task installAllCompileDependenciesInLocalMavenRepo + +project.configurations.compile.resolvedConfiguration.resolvedArtifacts.each { + def groupId = it.moduleVersion.id.group + def artifactId = it.moduleVersion.id.name + def version = it.moduleVersion.id.version + def file = it.file + + if (artifactId == "lib" || artifactId == "lib-extra") { + artifactId = "spotless-" + artifactId + version = SPOTLESS_LIB_VERSION + } + + def installDependency = task "install_${artifactId}"(type: Exec) { + commandLine "mvn", "org.apache.maven.plugins:maven-install-plugin:2.3.1:install-file", + "-Dfile=${file}", + "-DgroupId=${groupId}", + "-DartifactId=${artifactId}", + "-Dversion=${version}", + "-Dpackaging=jar", + "-DlocalRepositoryPath=${LOCAL_MAVEN_REPO_DIR}" + } + + installAllCompileDependenciesInLocalMavenRepo.dependsOn installDependency +} + +task createPomXml(dependsOn: installAllCompileDependenciesInLocalMavenRepo) { doLast { + def additionalDependencies = project.configurations.compile.resolvedConfiguration.resolvedArtifacts.findAll { + def artifactId = it.moduleVersion.id.name + return artifactId != "lib" && artifactId != "lib-extra" + }.collect { + def groupId = it.moduleVersion.id.group + def artifactId = it.moduleVersion.id.name + def version = it.moduleVersion.id.version + + return "\n" + + " ${groupId}\n" + + " ${artifactId}\n" + + " ${version}\n" + + " \n" + }.join("\n") + def versions = [ SpotlessMavenPluginVersion: project.versionMaven, MavenApiVersion : VER_MAVEN_API, EclipseAetherVersion : VER_ECLIPSE_AETHER, - SpotlessLibVersion : project.stableLib + SpotlessLibVersion : SPOTLESS_LIB_VERSION, + additionalDependencies : additionalDependencies, + localMavenRepositoryDir : LOCAL_MAVEN_REPO_DIR ] def pomXmlTemplate = Paths.get(PROJECT_DIR, "src", "main", "resources", "pom.xml.mustache") @@ -88,7 +135,7 @@ task createLocalMavenRepositoryForTests(type: Exec, dependsOn: buildMavenPlugin) "-DgroupId=com.diffplug.spotless", "-DartifactId=spotless", "-Dversion=${project.versionMaven}", - "-Dpackaging=paven-plugin", + "-Dpackaging=maven-plugin", "-DlocalRepositoryPath=${LOCAL_MAVEN_REPO_DIR}" } diff --git a/plugin-maven/src/main/resources/pom.xml.mustache b/plugin-maven/src/main/resources/pom.xml.mustache index 7bf25866ac..2ecaa0499c 100644 --- a/plugin-maven/src/main/resources/pom.xml.mustache +++ b/plugin-maven/src/main/resources/pom.xml.mustache @@ -20,6 +20,23 @@ {{SpotlessLibVersion}} + + + local-repo + file://{{localMavenRepositoryDir}} + + true + always + ignore + + + true + always + ignore + + + + org.apache.maven @@ -56,6 +73,9 @@ spotless-lib-extra ${spotless.lib.version} + + {{{additionalDependencies}}} + From c43ed45c2edb07781dbc300a6218158de9ed8701 Mon Sep 17 00:00:00 2001 From: lutovich Date: Wed, 24 Jan 2018 00:43:12 +0100 Subject: [PATCH 26/91] Consistent naming of mustache variables --- plugin-maven/build.gradle | 8 ++++---- plugin-maven/src/main/resources/pom.xml.mustache | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index d9acd2ad22..aa2562cbbd 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -94,10 +94,10 @@ task createPomXml(dependsOn: installAllCompileDependenciesInLocalMavenRepo) { }.join("\n") def versions = [ - SpotlessMavenPluginVersion: project.versionMaven, - MavenApiVersion : VER_MAVEN_API, - EclipseAetherVersion : VER_ECLIPSE_AETHER, - SpotlessLibVersion : SPOTLESS_LIB_VERSION, + spotlessMavenPluginVersion: project.versionMaven, + mavenApiVersion : VER_MAVEN_API, + eclipseAetherVersion : VER_ECLIPSE_AETHER, + spotlessLibVersion : SPOTLESS_LIB_VERSION, additionalDependencies : additionalDependencies, localMavenRepositoryDir : LOCAL_MAVEN_REPO_DIR ] diff --git a/plugin-maven/src/main/resources/pom.xml.mustache b/plugin-maven/src/main/resources/pom.xml.mustache index 2ecaa0499c..64c671f550 100644 --- a/plugin-maven/src/main/resources/pom.xml.mustache +++ b/plugin-maven/src/main/resources/pom.xml.mustache @@ -4,7 +4,7 @@ com.diffplug.spotless spotless-maven-plugin - {{SpotlessMavenPluginVersion}} + {{spotlessMavenPluginVersion}} maven-plugin Spotless Maven Plugin @@ -15,9 +15,9 @@ 1.8 - {{MavenApiVersion}} - {{EclipseAetherVersion}} - {{SpotlessLibVersion}} + {{mavenApiVersion}} + {{eclipseAetherVersion}} + {{spotlessLibVersion}} From 66bb67e8de7f71293582d77b278ea4af9ea7e5b9 Mon Sep 17 00:00:00 2001 From: lutovich Date: Wed, 24 Jan 2018 01:02:40 +0100 Subject: [PATCH 27/91] Use correct root dir for DiffMessageFormatter --- .../src/main/java/com/diffplug/maven/spotless/SpotlessMojo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessMojo.java index 081f240f00..69a95ff5e9 100644 --- a/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessMojo.java @@ -86,7 +86,7 @@ private static void checkAll(List files, Formatter formatter) throws MojoE if (!problemFiles.isEmpty()) { throw new MojoExecutionException(DiffMessageFormatter.builder() .runToFix("Run 'gradlew spotless:apply' to fix these violations.") - .rootDir(null) + .rootDir(formatter.getRootDir().toFile()) .isPaddedCell(false) .formatter(formatter) .problemFiles(problemFiles) From 31d5357281c1df551390b2836a5f3464aedfd5ca Mon Sep 17 00:00:00 2001 From: lutovich Date: Wed, 24 Jan 2018 23:26:33 +0100 Subject: [PATCH 28/91] Fix maven provisioner to resolve transitive dependencies Previously it only resolved given coordinates to a single artifact. --- plugin-maven/build.gradle | 1 + .../maven/spotless/AbstractSpotlessMojo.java | 2 +- .../spotless/ArtifactResolutionException.java | 23 +++++++ .../maven/spotless/ArtifactResolver.java | 60 ++++++++++++++----- .../maven/spotless/MavenProvisioner.java | 3 +- .../maven/spotless/MavenProvisionerTest.java | 57 ++++++++---------- 6 files changed, 97 insertions(+), 49 deletions(-) create mode 100644 plugin-maven/src/main/java/com/diffplug/maven/spotless/ArtifactResolutionException.java diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index aa2562cbbd..ec6c2dd9a2 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -38,6 +38,7 @@ dependencies { testCompile "org.mockito:mockito-core:${VER_MOCKITO}" testCompile "com.diffplug.durian:durian-testlib:${VER_DURIAN}" testCompile "com.github.spullara.mustache.java:compiler:${VER_MUSTACHE}" + testCompile "org.apache.maven:maven-plugin-api:${VER_MAVEN_API}" testCompile "org.eclipse.aether:aether-api:${VER_ECLIPSE_AETHER}" } diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/AbstractSpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/AbstractSpotlessMojo.java index 34127426c7..ee22125075 100644 --- a/plugin-maven/src/main/java/com/diffplug/maven/spotless/AbstractSpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/maven/spotless/AbstractSpotlessMojo.java @@ -74,7 +74,7 @@ protected List getAllSourceRoots() { } protected MojoConfig getMojoConfig() { - ArtifactResolver resolver = new ArtifactResolver(repositorySystem, repositorySystemSession, repositories); + ArtifactResolver resolver = new ArtifactResolver(repositorySystem, repositorySystemSession, repositories, getLog()); Provisioner provisioner = MavenProvisioner.create(resolver); return new MojoConfig(baseDir, encoding, lineEndings, provisioner); } diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/ArtifactResolutionException.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/ArtifactResolutionException.java new file mode 100644 index 0000000000..eb98a2c730 --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/maven/spotless/ArtifactResolutionException.java @@ -0,0 +1,23 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.maven.spotless; + +public class ArtifactResolutionException extends RuntimeException { + + public ArtifactResolutionException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/ArtifactResolver.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/ArtifactResolver.java index a1e19d7728..6f285b03a6 100644 --- a/plugin-maven/src/main/java/com/diffplug/maven/spotless/ArtifactResolver.java +++ b/plugin-maven/src/main/java/com/diffplug/maven/spotless/ArtifactResolver.java @@ -15,39 +15,71 @@ */ package com.diffplug.maven.spotless; +import static java.util.stream.Collectors.toSet; + import java.io.File; import java.util.List; import java.util.Objects; +import java.util.Set; +import org.apache.maven.plugin.logging.Log; import org.eclipse.aether.RepositorySystem; import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.collection.CollectRequest; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.graph.DependencyFilter; import org.eclipse.aether.repository.RemoteRepository; -import org.eclipse.aether.resolution.ArtifactRequest; -import org.eclipse.aether.resolution.ArtifactResolutionException; import org.eclipse.aether.resolution.ArtifactResult; +import org.eclipse.aether.resolution.DependencyRequest; +import org.eclipse.aether.resolution.DependencyResolutionException; +import org.eclipse.aether.resolution.DependencyResult; public class ArtifactResolver { + private static final DependencyFilter ACCEPT_ALL_FILTER = (node, parents) -> true; + private final RepositorySystem repositorySystem; - private final RepositorySystemSession repositorySystemSession; - private final List remoteRepositories; + private final RepositorySystemSession session; + private final List repositories; + private final Log log; - public ArtifactResolver(RepositorySystem repositorySystem, RepositorySystemSession repositorySystemSession, - List remoteRepositories) { + public ArtifactResolver(RepositorySystem repositorySystem, RepositorySystemSession session, + List repositories, Log log) { this.repositorySystem = Objects.requireNonNull(repositorySystem); - this.repositorySystemSession = Objects.requireNonNull(repositorySystemSession); - this.remoteRepositories = Objects.requireNonNull(remoteRepositories); + this.session = Objects.requireNonNull(session); + this.repositories = Objects.requireNonNull(repositories); + this.log = Objects.requireNonNull(log); } - public File resolve(String mavenCoordinate) throws ArtifactResolutionException { + public Set resolve(String mavenCoordinate) { Artifact artifact = new DefaultArtifact(mavenCoordinate); - ArtifactRequest request = new ArtifactRequest(); - request.setArtifact(artifact); - request.setRepositories(remoteRepositories); + Dependency dependency = new Dependency(artifact, null); + CollectRequest collectRequest = new CollectRequest(dependency, repositories); + DependencyRequest dependencyRequest = new DependencyRequest(collectRequest, ACCEPT_ALL_FILTER); + + DependencyResult dependencyResult = resolveDependencies(dependencyRequest); + + return dependencyResult.getArtifactResults() + .stream() + .peek(this::logResolved) + .map(ArtifactResult::getArtifact) + .map(Artifact::getFile) + .collect(toSet()); + } + + private DependencyResult resolveDependencies(DependencyRequest dependencyRequest) { + try { + return repositorySystem.resolveDependencies(session, dependencyRequest); + } catch (DependencyResolutionException e) { + throw new ArtifactResolutionException("Unable to resolve dependencies", e); + } + } - ArtifactResult result = repositorySystem.resolveArtifact(repositorySystemSession, request); - return result.getArtifact().getFile(); + private void logResolved(ArtifactResult artifactResult) { + if (log.isDebugEnabled()) { + log.debug("Resolved artifact: " + artifactResult); + } } } diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/MavenProvisioner.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/MavenProvisioner.java index 3d289c9994..e82361ad13 100644 --- a/plugin-maven/src/main/java/com/diffplug/maven/spotless/MavenProvisioner.java +++ b/plugin-maven/src/main/java/com/diffplug/maven/spotless/MavenProvisioner.java @@ -20,7 +20,6 @@ import java.util.Objects; import com.diffplug.spotless.Provisioner; -import com.diffplug.spotless.ThrowingEx; /** Maven integration for Provisioner. */ public class MavenProvisioner { @@ -30,7 +29,7 @@ public static Provisioner create(ArtifactResolver artifactResolver) { Objects.requireNonNull(artifactResolver); return mavenCoords -> mavenCoords.stream() - .map(ThrowingEx.wrap(artifactResolver::resolve)) + .flatMap(coord -> artifactResolver.resolve(coord).stream()) .collect(toSet()); } } diff --git a/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenProvisionerTest.java b/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenProvisionerTest.java index aa07a7c90e..64fbd28c64 100644 --- a/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenProvisionerTest.java +++ b/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenProvisionerTest.java @@ -15,62 +15,55 @@ */ package com.diffplug.maven.spotless; -import static java.util.Collections.emptyList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import com.diffplug.spotless.Provisioner; +import org.junit.Test; import java.io.File; import java.util.Set; -import org.eclipse.aether.resolution.ArtifactResolutionException; -import org.junit.Test; - -import com.diffplug.spotless.Provisioner; +import static com.diffplug.common.collect.Sets.newHashSet; +import static java.util.Collections.emptySet; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class MavenProvisionerTest { @Test - public void testProvisionWithDependencies() throws Exception { + public void testProvisionWithDependenciesWhenNothingResolved() throws Exception { ArtifactResolver resolver = mock(ArtifactResolver.class); - when(resolver.resolve("foo")).thenReturn(new File("foo")); - when(resolver.resolve("bar")).thenReturn(new File("bar")); - when(resolver.resolve("baz")).thenReturn(new File("baz")); + when(resolver.resolve(anyString())).thenReturn(emptySet()); Provisioner provisioner = MavenProvisioner.create(resolver); Set files = provisioner.provisionWithDependencies("foo", "bar", "baz"); - assertThat(files).containsOnly(new File("foo"), new File("bar"), new File("baz")); + assertThat(files).isEmpty(); } @Test - public void testProvisionWithDependenciesThrowsCheckedException() throws Exception { + public void testProvisionWithDependencies() throws Exception { ArtifactResolver resolver = mock(ArtifactResolver.class); - when(resolver.resolve("foo")).thenThrow(new ArtifactResolutionException(emptyList(), "Error!")); + when(resolver.resolve("foo")).thenReturn(newHashSet(new File("foo-1"), new File("foo-2"))); + when(resolver.resolve("bar")).thenReturn(newHashSet(new File("bar-1"))); + when(resolver.resolve("baz")).thenReturn(newHashSet(new File("baz-1"), new File("baz-2"))); Provisioner provisioner = MavenProvisioner.create(resolver); - try { - provisioner.provisionWithDependencies("foo"); - fail("Exception expected"); - } catch (RuntimeException e) { - assertThat(e.getCause()).isInstanceOf(ArtifactResolutionException.class); - assertThat(e.getCause().getMessage()).isEqualTo("Error!"); - } + Set files = provisioner.provisionWithDependencies("foo", "bar", "baz"); + + assertThat(files).containsOnly(new File("foo-1"), new File("foo-2"), new File("bar-1"), new File("baz-1"), new File("baz-2")); } @Test - public void testProvisionWithDependenciesThrowsUncheckedException() throws Exception { + public void testProvisionWithDependenciesWithDuplicates() throws Exception { ArtifactResolver resolver = mock(ArtifactResolver.class); - when(resolver.resolve("foo")).thenThrow(new RuntimeException("Wrong coordinate!")); - + when(resolver.resolve("foo")).thenReturn(newHashSet(new File("foo-1"), new File("foo-2"))); + when(resolver.resolve("bar")).thenReturn(newHashSet(new File("foo-2"))); + when(resolver.resolve("baz")).thenReturn(newHashSet(new File("foo-1"), new File("baz-2"))); Provisioner provisioner = MavenProvisioner.create(resolver); - try { - provisioner.provisionWithDependencies("foo"); - fail("Exception expected"); - } catch (RuntimeException e) { - assertThat(e.getMessage()).isEqualTo("Wrong coordinate!"); - } + Set files = provisioner.provisionWithDependencies("foo", "bar", "baz"); + + assertThat(files).containsOnly(new File("foo-1"), new File("foo-2"), new File("baz-2")); } } From 4b032eb8ac98f3ef42f68c7eba6eb88467beae7f Mon Sep 17 00:00:00 2001 From: lutovich Date: Thu, 25 Jan 2018 00:14:55 +0100 Subject: [PATCH 29/91] Support RemoveUnusedImports in maven plugin --- .../com/diffplug/maven/spotless/Java.java | 2 ++ .../maven/spotless/RemoveUnusedImports.java | 27 +++++++++++++++ .../maven/spotless/EclipseFormatStepTest.java | 12 +++---- .../maven/spotless/MavenProvisionerTest.java | 13 +++---- .../diffplug/maven/spotless/MavenRunner.java | 6 ++-- .../spotless/RemoveUnusedImportsStepTest.java | 34 +++++++++++++++++++ .../eclipse/format/JavaCodeUnformatted.test | 2 +- .../JavaCodeWithPackageFormatted.test | 12 +++++++ .../JavaCodeWithPackageUnformatted.test | 13 +++++++ 9 files changed, 103 insertions(+), 18 deletions(-) create mode 100644 plugin-maven/src/main/java/com/diffplug/maven/spotless/RemoveUnusedImports.java create mode 100644 plugin-maven/src/test/java/com/diffplug/maven/spotless/RemoveUnusedImportsStepTest.java create mode 100644 plugin-maven/src/test/resources/java/removeunusedimports/JavaCodeWithPackageFormatted.test create mode 100644 plugin-maven/src/test/resources/java/removeunusedimports/JavaCodeWithPackageUnformatted.test diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/Java.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/Java.java index 9fa1e00b05..c8bb6c7ced 100644 --- a/plugin-maven/src/main/java/com/diffplug/maven/spotless/Java.java +++ b/plugin-maven/src/main/java/com/diffplug/maven/spotless/Java.java @@ -20,6 +20,7 @@ import java.io.File; import java.nio.charset.Charset; import java.util.List; +import java.util.Objects; import org.apache.maven.plugins.annotations.Parameter; @@ -53,6 +54,7 @@ public Formatter newFormatter(List filesToFormat, MojoConfig mojoConfig) { LineEnding.Policy formatterLineEndingPolicy = formatterLineEndings.createPolicy(mojoConfig.getBaseDir(), () -> filesToFormat); List formatterSteps = steps.stream() + .filter(Objects::nonNull) // all unrecognized steps from XML config appear as nulls in the list .map(factory -> factory.newFormatterStep(mojoConfig)) .collect(toList()); diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/RemoveUnusedImports.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/RemoveUnusedImports.java new file mode 100644 index 0000000000..1d967a1150 --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/maven/spotless/RemoveUnusedImports.java @@ -0,0 +1,27 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.maven.spotless; + +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.java.RemoveUnusedImportsStep; + +public class RemoveUnusedImports implements FormatterStepFactory { + + @Override + public FormatterStep newFormatterStep(MojoConfig mojoConfig) { + return RemoveUnusedImportsStep.create(mojoConfig.getProvisioner()); + } +} diff --git a/plugin-maven/src/test/java/com/diffplug/maven/spotless/EclipseFormatStepTest.java b/plugin-maven/src/test/java/com/diffplug/maven/spotless/EclipseFormatStepTest.java index cb96ce9a28..7bdaf841c0 100644 --- a/plugin-maven/src/test/java/com/diffplug/maven/spotless/EclipseFormatStepTest.java +++ b/plugin-maven/src/test/java/com/diffplug/maven/spotless/EclipseFormatStepTest.java @@ -15,19 +15,14 @@ */ package com.diffplug.maven.spotless; -import org.assertj.core.api.Assertions; +import static org.assertj.core.api.Assertions.assertThat; + import org.junit.Test; -/** - * Would also be good if we had mvnw setup, so that - * the test harness used mvnw to control the verison - * of maven that was used. - */ public class EclipseFormatStepTest extends MavenIntegrationTest { @Test public void testEclipse() throws Exception { - // write the pom writePomWithJavaSteps( "", " ${basedir}/formatter.xml", @@ -36,9 +31,10 @@ public void testEclipse() throws Exception { write("src/main/java/test.java", getTestResource("java/eclipse/format/JavaCodeUnformatted.test")); write("formatter.xml", getTestResource("java/eclipse/format/formatter.xml")); + mavenRunner().withArguments("spotless:apply").runNoError(); String actual = read("src/main/java/test.java"); - Assertions.assertThat(actual).isEqualTo(getTestResource("java/eclipse/format/JavaCodeFormatted.test")); + assertThat(actual).isEqualTo(getTestResource("java/eclipse/format/JavaCodeFormatted.test")); } } diff --git a/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenProvisionerTest.java b/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenProvisionerTest.java index 64fbd28c64..ff3af15fcb 100644 --- a/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenProvisionerTest.java +++ b/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenProvisionerTest.java @@ -15,12 +15,6 @@ */ package com.diffplug.maven.spotless; -import com.diffplug.spotless.Provisioner; -import org.junit.Test; - -import java.io.File; -import java.util.Set; - import static com.diffplug.common.collect.Sets.newHashSet; import static java.util.Collections.emptySet; import static org.assertj.core.api.Assertions.assertThat; @@ -28,6 +22,13 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import java.io.File; +import java.util.Set; + +import org.junit.Test; + +import com.diffplug.spotless.Provisioner; + public class MavenProvisionerTest { @Test diff --git a/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenRunner.java b/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenRunner.java index 9766c4693e..db469c11f9 100644 --- a/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenRunner.java +++ b/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenRunner.java @@ -72,17 +72,17 @@ private Result run() throws IOException, InterruptedException { return new Result(exitValue, output.result(), error.result()); } - /** Runs the command and asserts that nothing was printed to stderr. */ + /** Runs the command and asserts that exit code is 0. */ public Result runNoError() throws IOException, InterruptedException { Result result = run(); assertThat(result.exitValue()).as("Run without error %s", result).isEqualTo(0); return result; } - /** Runs the command and asserts that something was printed to stderr. */ + /** Runs the command and asserts that exit code is not 0. */ public Result runHasError() throws IOException, InterruptedException { Result result = run(); - assertThat(result.exitValue()).as("Run with error %s", result).isEqualTo(1); + assertThat(result.exitValue()).as("Run with error %s", result).isNotEqualTo(0); return result; } diff --git a/plugin-maven/src/test/java/com/diffplug/maven/spotless/RemoveUnusedImportsStepTest.java b/plugin-maven/src/test/java/com/diffplug/maven/spotless/RemoveUnusedImportsStepTest.java new file mode 100644 index 0000000000..0af3476c71 --- /dev/null +++ b/plugin-maven/src/test/java/com/diffplug/maven/spotless/RemoveUnusedImportsStepTest.java @@ -0,0 +1,34 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.maven.spotless; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; + +public class RemoveUnusedImportsStepTest extends MavenIntegrationTest { + + @Test + public void testRemoveUnusedInports() throws Exception { + writePomWithJavaSteps(""); + write("src/main/java/test.java", getTestResource("java/removeunusedimports/JavaCodeWithPackageUnformatted.test")); + + mavenRunner().withArguments("spotless:apply").runNoError(); + + String actual = read("src/main/java/test.java"); + assertThat(actual).isEqualTo(getTestResource("java/removeunusedimports/JavaCodeWithPackageFormatted.test")); + } +} diff --git a/plugin-maven/src/test/resources/java/eclipse/format/JavaCodeUnformatted.test b/plugin-maven/src/test/resources/java/eclipse/format/JavaCodeUnformatted.test index 5589c792d8..f673abb3be 100644 --- a/plugin-maven/src/test/resources/java/eclipse/format/JavaCodeUnformatted.test +++ b/plugin-maven/src/test/resources/java/eclipse/format/JavaCodeUnformatted.test @@ -2,4 +2,4 @@ public class Java { public static void main(String[] args) { System.out.println("hello"); } -} \ No newline at end of file +} diff --git a/plugin-maven/src/test/resources/java/removeunusedimports/JavaCodeWithPackageFormatted.test b/plugin-maven/src/test/resources/java/removeunusedimports/JavaCodeWithPackageFormatted.test new file mode 100644 index 0000000000..f30facd835 --- /dev/null +++ b/plugin-maven/src/test/resources/java/removeunusedimports/JavaCodeWithPackageFormatted.test @@ -0,0 +1,12 @@ +package hello.world; + +import mylib.UsedB; +import mylib.UsedA; + +public class Java { +public static void main(String[] args) { +System.out.println("hello"); +UsedB.someMethod(); +UsedA.someMethod(); +} +} diff --git a/plugin-maven/src/test/resources/java/removeunusedimports/JavaCodeWithPackageUnformatted.test b/plugin-maven/src/test/resources/java/removeunusedimports/JavaCodeWithPackageUnformatted.test new file mode 100644 index 0000000000..f0dbfb0ef9 --- /dev/null +++ b/plugin-maven/src/test/resources/java/removeunusedimports/JavaCodeWithPackageUnformatted.test @@ -0,0 +1,13 @@ +package hello.world; + +import mylib.Unused; +import mylib.UsedB; +import mylib.UsedA; + +public class Java { +public static void main(String[] args) { +System.out.println("hello"); +UsedB.someMethod(); +UsedA.someMethod(); +} +} \ No newline at end of file From 4cf839ae4945ee5d8be2aaaff23688c8bd2f3198 Mon Sep 17 00:00:00 2001 From: lutovich Date: Thu, 25 Jan 2018 00:37:45 +0100 Subject: [PATCH 30/91] Use correct artifactId for maven plugin in tests --- plugin-maven/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index ec6c2dd9a2..beccc3b646 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -134,7 +134,7 @@ task createLocalMavenRepositoryForTests(type: Exec, dependsOn: buildMavenPlugin) commandLine "mvn", "org.apache.maven.plugins:maven-install-plugin:2.3.1:install-file", "-Dfile=spotless-maven-plugin-${project.versionMaven}.jar", "-DgroupId=com.diffplug.spotless", - "-DartifactId=spotless", + "-DartifactId=spotless-maven-plugin", "-Dversion=${project.versionMaven}", "-Dpackaging=maven-plugin", "-DlocalRepositoryPath=${LOCAL_MAVEN_REPO_DIR}" From 622d2dfc75030ffd212ef753897ba41a0ebf157f Mon Sep 17 00:00:00 2001 From: lutovich Date: Thu, 25 Jan 2018 00:59:08 +0100 Subject: [PATCH 31/91] Extracted check MOJO To make goal `spotless:check` accessible. Moved all functionality common for "apply" and "check" into `AbstractSpotlessMojo`. Now command `mvn spotless:check` will result in all formatting violations being printed and build being failed. --- .../maven/spotless/AbstractSpotlessMojo.java | 64 ++++++++- .../maven/spotless/SpotlessApplyMojo.java | 40 ++++++ .../maven/spotless/SpotlessCheckMojo.java | 55 ++++++++ .../diffplug/maven/spotless/SpotlessMojo.java | 127 ------------------ 4 files changed, 153 insertions(+), 133 deletions(-) create mode 100644 plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessApplyMojo.java create mode 100644 plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessCheckMojo.java delete mode 100644 plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessMojo.java diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/AbstractSpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/AbstractSpotlessMojo.java index ee22125075..11ded46a78 100644 --- a/plugin-maven/src/main/java/com/diffplug/maven/spotless/AbstractSpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/maven/spotless/AbstractSpotlessMojo.java @@ -15,9 +15,12 @@ */ package com.diffplug.maven.spotless; +import static java.util.Collections.singletonList; import static java.util.stream.Collectors.toList; import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -25,12 +28,15 @@ import java.util.stream.Stream; 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.eclipse.aether.RepositorySystem; import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.repository.RemoteRepository; +import com.diffplug.spotless.Formatter; import com.diffplug.spotless.LineEnding; import com.diffplug.spotless.Provisioner; @@ -39,6 +45,8 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo { private static final String DEFAULT_ENCODING = "UTF-8"; private static final String DEFAULT_LINE_ENDINGS = "GIT_ATTRIBUTES"; + private static final String FILE_EXTENSION_SEPARATOR = "."; + @Component private RepositorySystem repositorySystem; @@ -66,20 +74,64 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo { @Parameter private Java java; - protected List getAllSourceRoots() { + protected abstract void process(List files, Formatter formatter) throws MojoExecutionException; + + @Override + public final void execute() throws MojoExecutionException, MojoFailureException { + List formatterFactories = singletonList(java); + + for (FormatterFactory formatterFactory : formatterFactories) { + execute(formatterFactory); + } + } + + private void execute(FormatterFactory formatterFactory) throws MojoExecutionException { + List files = collectFiles(formatterFactory.fileExtension()); + Formatter formatter = formatterFactory.newFormatter(files, getMojoConfig()); + process(files, formatter); + } + + private List collectFiles(String extension) throws MojoExecutionException { + try { + return getAllSourceRoots().stream() + .flatMap(root -> collectFiles(root, extension).stream()) + .map(Path::toFile) + .collect(toList()); + } catch (Exception e) { + throw new MojoExecutionException("Unable to collect files to format", e); + } + } + + private static List collectFiles(Path root, String extension) { + try (Stream entries = Files.walk(root)) { + return entries.filter(Files::isRegularFile) + .filter(file -> hasExtension(file, extension)) + .collect(toList()); + } catch (IOException e) { + throw new UncheckedIOException("Unable to walk the file tree rooted at " + root, e); + } + } + + private static boolean hasExtension(Path file, String extension) { + Path fileName = file.getFileName(); + if (fileName == null) { + return false; + } else { + String fileNameString = fileName.toString(); + return fileNameString.endsWith(FILE_EXTENSION_SEPARATOR + extension); + } + } + + private List getAllSourceRoots() { return Stream.concat(compileSourceRoots.stream(), testCompileSourceRoots.stream()) .map(Paths::get) .filter(Files::isDirectory) .collect(toList()); } - protected MojoConfig getMojoConfig() { + private MojoConfig getMojoConfig() { ArtifactResolver resolver = new ArtifactResolver(repositorySystem, repositorySystemSession, repositories, getLog()); Provisioner provisioner = MavenProvisioner.create(resolver); return new MojoConfig(baseDir, encoding, lineEndings, provisioner); } - - protected Java getJava() { - return java; - } } diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessApplyMojo.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessApplyMojo.java new file mode 100644 index 0000000000..5f5509462a --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessApplyMojo.java @@ -0,0 +1,40 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.maven.spotless; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.Mojo; + +import com.diffplug.spotless.Formatter; + +@Mojo(name = "apply") +public class SpotlessApplyMojo extends AbstractSpotlessMojo { + + @Override + protected void process(List files, Formatter formatter) throws MojoExecutionException { + for (File file : files) { + try { + formatter.applyTo(file); + } catch (IOException e) { + throw new MojoExecutionException("Unable to format file " + file, e); + } + } + } +} diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessCheckMojo.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessCheckMojo.java new file mode 100644 index 0000000000..0a62efc42b --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessCheckMojo.java @@ -0,0 +1,55 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.maven.spotless; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.Mojo; + +import com.diffplug.spotless.Formatter; +import com.diffplug.spotless.extra.integration.DiffMessageFormatter; + +@Mojo(name = "check") +public class SpotlessCheckMojo extends AbstractSpotlessMojo { + + @Override + protected void process(List files, Formatter formatter) throws MojoExecutionException { + List problemFiles = new ArrayList<>(); + for (File file : files) { + try { + if (!formatter.isClean(file)) { + problemFiles.add(file); + } + } catch (IOException e) { + throw new MojoExecutionException("Unable to format file " + file, e); + } + } + + if (!problemFiles.isEmpty()) { + throw new MojoExecutionException(DiffMessageFormatter.builder() + .runToFix("Run 'mvn spotless:apply' to fix these violations.") + .rootDir(formatter.getRootDir().toFile()) + .isPaddedCell(false) + .formatter(formatter) + .problemFiles(problemFiles) + .getMessage()); + } + } +} diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessMojo.java deleted file mode 100644 index 69a95ff5e9..0000000000 --- a/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessMojo.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2016 DiffPlug - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.diffplug.maven.spotless; - -import static java.util.Collections.singletonList; -import static java.util.stream.Collectors.toList; - -import java.io.File; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Stream; - -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.Mojo; - -import com.diffplug.spotless.Formatter; -import com.diffplug.spotless.extra.integration.DiffMessageFormatter; - -@Mojo(name = "apply") -public class SpotlessMojo extends AbstractSpotlessMojo { - - private static final String FILE_EXTENSION_SEPARATOR = "."; - - @Override - public void execute() throws MojoExecutionException, MojoFailureException { - List formatterFactories = singletonList(getJava()); - - for (FormatterFactory formatterFactory : formatterFactories) { - execute(formatterFactory); - } - } - - private void execute(FormatterFactory formatterFactory) throws MojoExecutionException { - MojoConfig mojoConfig = getMojoConfig(); - List filesToFormat = collectFilesToFormat(formatterFactory.fileExtension()); - - Formatter formatter = formatterFactory.newFormatter(filesToFormat, mojoConfig); - - boolean check = false; - if (!check) { - formatAll(filesToFormat, formatter); - } else { - checkAll(filesToFormat, formatter); - } - } - - private static void formatAll(List files, Formatter formatter) throws MojoExecutionException { - for (File file : files) { - try { - formatter.applyTo(file); - } catch (IOException e) { - throw new MojoExecutionException("Unable to format file " + file, e); - } - } - } - - private static void checkAll(List files, Formatter formatter) throws MojoExecutionException { - List problemFiles = new ArrayList<>(); - for (File file : files) { - try { - if (!formatter.isClean(file)) { - problemFiles.add(file); - } - } catch (IOException e) { - throw new MojoExecutionException("Unable to format file " + file, e); - } - } - if (!problemFiles.isEmpty()) { - throw new MojoExecutionException(DiffMessageFormatter.builder() - .runToFix("Run 'gradlew spotless:apply' to fix these violations.") - .rootDir(formatter.getRootDir().toFile()) - .isPaddedCell(false) - .formatter(formatter) - .problemFiles(problemFiles) - .getMessage()); - } - } - - private List collectFilesToFormat(String extension) throws MojoExecutionException { - try { - return getAllSourceRoots().stream() - .flatMap(root -> collectFilesToFormat(root, extension).stream()) - .map(Path::toFile) - .collect(toList()); - } catch (Exception e) { - throw new MojoExecutionException("Unable to collect files to format", e); - } - } - - private static List collectFilesToFormat(Path root, String extension) { - try (Stream entries = Files.walk(root)) { - return entries.filter(Files::isRegularFile) - .filter(file -> hasExtension(file, extension)) - .collect(toList()); - } catch (IOException e) { - throw new UncheckedIOException("Unable to walk the file tree rooted at " + root, e); - } - } - - private static boolean hasExtension(Path file, String extension) { - Path fileName = file.getFileName(); - if (fileName == null) { - return false; - } else { - String fileNameString = fileName.toString(); - return fileNameString.endsWith(FILE_EXTENSION_SEPARATOR + extension); - } - } -} From e759a0b49908740506f2a83c24d4020b600f7aaf Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Fri, 26 Jan 2018 18:41:29 -0800 Subject: [PATCH 32/91] Removed DiffMessageFormatter::rootDir() because Formatter has it already. --- .../integration/DiffMessageFormatter.java | 18 ++++++------------ .../diffplug/gradle/spotless/SpotlessTask.java | 3 +-- .../maven/spotless/SpotlessCheckMojo.java | 1 - 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/integration/DiffMessageFormatter.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/integration/DiffMessageFormatter.java index e62781d498..398ccca1ad 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/integration/DiffMessageFormatter.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/integration/DiffMessageFormatter.java @@ -20,7 +20,6 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.nio.file.Path; import java.util.List; import java.util.ListIterator; import java.util.Objects; @@ -49,7 +48,6 @@ public static class Builder { private Builder() {} private String runToFix; - private File rootDir; private boolean isPaddedCell; private Formatter formatter; private List problemFiles; @@ -60,11 +58,6 @@ public Builder runToFix(String runToFix) { return this; } - public Builder rootDir(File rootDir) { - this.rootDir = Objects.requireNonNull(rootDir); - return this; - } - public Builder isPaddedCell(boolean isPaddedCell) { this.isPaddedCell = isPaddedCell; return this; @@ -85,7 +78,6 @@ public Builder problemFiles(List problemFiles) { public String getMessage() { try { Objects.requireNonNull(runToFix, "runToFix"); - Objects.requireNonNull(rootDir, "rootDir"); Objects.requireNonNull(formatter, "formatter"); Objects.requireNonNull(problemFiles, "problemFiles"); DiffMessageFormatter diffFormater = new DiffMessageFormatter(this); @@ -96,6 +88,10 @@ public String getMessage() { throw Errors.asRuntime(e); } } + + String relativePath(File file) { + return formatter.getRootDir().relativize(file.toPath()).toString(); + } } private static final int MAX_CHECK_MESSAGE_LINES = 50; @@ -105,12 +101,10 @@ public String getMessage() { private int numLines = 0; private DiffMessageFormatter(Builder builder) throws IOException { - Path rootDir = builder.rootDir.toPath(); ListIterator problemIter = builder.problemFiles.listIterator(); while (problemIter.hasNext() && numLines < MAX_CHECK_MESSAGE_LINES) { File file = problemIter.next(); - addFile(rootDir.relativize(file.toPath()) + "\n" + - DiffMessageFormatter.diff(builder, file)); + addFile(builder.relativePath(file) + "\n" + DiffMessageFormatter.diff(builder, file)); } if (problemIter.hasNext()) { int remainingFiles = builder.problemFiles.size() - problemIter.nextIndex(); @@ -119,7 +113,7 @@ private DiffMessageFormatter(Builder builder) throws IOException { } else { buffer.append("Violations also present in:\n"); while (problemIter.hasNext()) { - addIntendedLine(NORMAL_INDENT, rootDir.relativize(problemIter.next().toPath()).toString()); + addIntendedLine(NORMAL_INDENT, builder.relativePath(problemIter.next())); } } } diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTask.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTask.java index 2eb4786949..801e45f17d 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTask.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTask.java @@ -164,7 +164,7 @@ public void performAction(IncrementalTaskInputs inputs) throws Exception { Formatter formatter = Formatter.builder() .lineEndingsPolicy(lineEndingsPolicy) .encoding(Charset.forName(encoding)) - .rootDir(getProject().getProjectDir().toPath()) + .rootDir(getProject().getRootDir().toPath()) .steps(steps) .exceptionPolicy(exceptionPolicy) .build(); @@ -282,7 +282,6 @@ private void check(Formatter formatter, List outOfDate) throws Exception { GradleException formatViolationsFor(Formatter formatter, List problemFiles) { return new GradleException(DiffMessageFormatter.builder() .runToFix("Run 'gradlew spotlessApply' to fix these violations.") - .rootDir(getProject().getRootDir()) .isPaddedCell(paddedCell) .formatter(formatter) .problemFiles(problemFiles) diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessCheckMojo.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessCheckMojo.java index 0a62efc42b..e81c4d4f04 100644 --- a/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessCheckMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessCheckMojo.java @@ -45,7 +45,6 @@ protected void process(List files, Formatter formatter) throws MojoExecuti if (!problemFiles.isEmpty()) { throw new MojoExecutionException(DiffMessageFormatter.builder() .runToFix("Run 'mvn spotless:apply' to fix these violations.") - .rootDir(formatter.getRootDir().toFile()) .isPaddedCell(false) .formatter(formatter) .problemFiles(problemFiles) From 0185af611e5f1b2f66ecd929650c484db9d5a2d6 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sat, 27 Jan 2018 02:29:14 -0800 Subject: [PATCH 33/91] The local dependencies repo now contains only our local deps, and it has up-to-date checking. --- plugin-maven/build.gradle | 53 +++++++++---------- .../src/main/resources/pom.xml.mustache | 2 +- 2 files changed, 25 insertions(+), 30 deletions(-) diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index beccc3b646..ffff074a98 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -17,8 +17,6 @@ final BUILD_DIR = project.buildDir.toString() final MAVEN_PROJECT_DIR = "${BUILD_DIR}/mavenProject" final LOCAL_MAVEN_REPO_DIR = "${BUILD_DIR}/localMavenRepository" -final SPOTLESS_LIB_VERSION = "1.0.0-SNAPSHOT" // should be project.stableLib once maven plugin stabilizes - buildscript { repositories { mavenCentral() } dependencies { classpath "com.github.spullara.mustache.java:compiler:${VER_MUSTACHE}" } @@ -49,22 +47,23 @@ task copySourceFiles(type: Copy) { into "${MAVEN_PROJECT_DIR}/src/main/java" } -// this task is temporary, it should be removed once maven plugin stabilizes -// and can depend on released version of lib and lib-extra -task installAllCompileDependenciesInLocalMavenRepo - -project.configurations.compile.resolvedConfiguration.resolvedArtifacts.each { - def groupId = it.moduleVersion.id.group - def artifactId = it.moduleVersion.id.name - def version = it.moduleVersion.id.version - def file = it.file - if (artifactId == "lib" || artifactId == "lib-extra") { - artifactId = "spotless-" + artifactId - version = SPOTLESS_LIB_VERSION - } +task installLocalDependencies +def libs = [ + 'lib', + 'lib-extra', + 'testlib' +] +libs.each { + def groupId = 'com.diffplug.spotless' + def artifactId = "spotless-${it}" + def version = project.versionLib + def jarTask = tasks.getByPath(":${it}:jar") + def file = jarTask.archivePath def installDependency = task "install_${artifactId}"(type: Exec) { + inputs.file(file) + outputs.dir(project.file("${LOCAL_MAVEN_REPO_DIR}/${groupId.replace('.', '/')}/${artifactId}/${version}")) commandLine "mvn", "org.apache.maven.plugins:maven-install-plugin:2.3.1:install-file", "-Dfile=${file}", "-DgroupId=${groupId}", @@ -73,32 +72,28 @@ project.configurations.compile.resolvedConfiguration.resolvedArtifacts.each { "-Dpackaging=jar", "-DlocalRepositoryPath=${LOCAL_MAVEN_REPO_DIR}" } + installDependency.dependsOn(jarTask) - installAllCompileDependenciesInLocalMavenRepo.dependsOn installDependency + installLocalDependencies.dependsOn installDependency } -task createPomXml(dependsOn: installAllCompileDependenciesInLocalMavenRepo) { +task createPomXml(dependsOn: installLocalDependencies) { doLast { def additionalDependencies = project.configurations.compile.resolvedConfiguration.resolvedArtifacts.findAll { - def artifactId = it.moduleVersion.id.name - return artifactId != "lib" && artifactId != "lib-extra" + return !libs.contains(it.moduleVersion.id.name) }.collect { - def groupId = it.moduleVersion.id.group - def artifactId = it.moduleVersion.id.name - def version = it.moduleVersion.id.version - - return "\n" + - " ${groupId}\n" + - " ${artifactId}\n" + - " ${version}\n" + + return " \n" + + " ${it.moduleVersion.id.group}\n" + + " ${it.moduleVersion.id.name}\n" + + " ${it.moduleVersion.id.version}\n" + " \n" - }.join("\n") + }.join() def versions = [ spotlessMavenPluginVersion: project.versionMaven, mavenApiVersion : VER_MAVEN_API, eclipseAetherVersion : VER_ECLIPSE_AETHER, - spotlessLibVersion : SPOTLESS_LIB_VERSION, + spotlessLibVersion : project.versionLib, additionalDependencies : additionalDependencies, localMavenRepositoryDir : LOCAL_MAVEN_REPO_DIR ] diff --git a/plugin-maven/src/main/resources/pom.xml.mustache b/plugin-maven/src/main/resources/pom.xml.mustache index 64c671f550..df64cdb6b0 100644 --- a/plugin-maven/src/main/resources/pom.xml.mustache +++ b/plugin-maven/src/main/resources/pom.xml.mustache @@ -74,7 +74,7 @@ ${spotless.lib.version} - {{{additionalDependencies}}} +{{{additionalDependencies}}} From 0dba10ca2cc18fbd764933d2757b703f966946da Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sat, 27 Jan 2018 03:43:44 -0800 Subject: [PATCH 34/91] Forced buildMavenPlugin to act like the standard jar task, so that publishing works automatically. --- plugin-maven/build.gradle | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index ffff074a98..6ee1bcc2f4 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -42,7 +42,7 @@ dependencies { task cleanMavenProjectDir(type: Delete) { delete MAVEN_PROJECT_DIR } -task copySourceFiles(type: Copy) { +task copySourceFiles(type: Sync) { from "src/main/java" into "${MAVEN_PROJECT_DIR}/src/main/java" } @@ -119,20 +119,13 @@ task runMavenBuild(type: Exec, dependsOn: [ commandLine "mvn", "clean", "install" } -task buildMavenPlugin(type: Copy, dependsOn: runMavenBuild) { - from "${MAVEN_PROJECT_DIR}/target" - into "${BUILD_DIR}/libs" -} - -task createLocalMavenRepositoryForTests(type: Exec, dependsOn: buildMavenPlugin) { - workingDir "${BUILD_DIR}/libs" - commandLine "mvn", "org.apache.maven.plugins:maven-install-plugin:2.3.1:install-file", - "-Dfile=spotless-maven-plugin-${project.versionMaven}.jar", - "-DgroupId=com.diffplug.spotless", - "-DartifactId=spotless-maven-plugin", - "-Dversion=${project.versionMaven}", - "-Dpackaging=maven-plugin", - "-DlocalRepositoryPath=${LOCAL_MAVEN_REPO_DIR}" +jar.deleteAllActions() +jar.dependsOn(runMavenBuild) +jar.doLast { + Files.copy( + file("${MAVEN_PROJECT_DIR}/target/spotless-maven-plugin-${project.versionMaven}.jar").toPath(), + jar.archivePath.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING + ) } test { @@ -141,6 +134,3 @@ test { systemProperty "localMavenRepositoryDir", "${LOCAL_MAVEN_REPO_DIR}" systemProperty "spotlessMavenPluginVersion", project.versionMaven } - -test.dependsOn createLocalMavenRepositoryForTests -build.dependsOn buildMavenPlugin From 9bb5bbcac650ded53fa5110cb4cfbd014c26b498 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sat, 27 Jan 2018 04:10:30 -0800 Subject: [PATCH 35/91] Added a GoogleJavaFormat step. --- .../maven/spotless/GoogleJavaFormat.java | 32 ++++++++++++++++ .../maven/spotless/GoogleJavaFormatTest.java | 38 +++++++++++++++++++ .../googlejavaformat/JavaCodeFormatted.test | 11 ++++++ .../googlejavaformat/JavaCodeUnformatted.test | 12 ++++++ 4 files changed, 93 insertions(+) create mode 100644 plugin-maven/src/main/java/com/diffplug/maven/spotless/GoogleJavaFormat.java create mode 100644 plugin-maven/src/test/java/com/diffplug/maven/spotless/GoogleJavaFormatTest.java create mode 100644 plugin-maven/src/test/resources/java/googlejavaformat/JavaCodeFormatted.test create mode 100644 plugin-maven/src/test/resources/java/googlejavaformat/JavaCodeUnformatted.test diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/GoogleJavaFormat.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/GoogleJavaFormat.java new file mode 100644 index 0000000000..e299b7cad3 --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/maven/spotless/GoogleJavaFormat.java @@ -0,0 +1,32 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.maven.spotless; + +import org.apache.maven.plugins.annotations.Parameter; + +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.java.GoogleJavaFormatStep; + +public class GoogleJavaFormat implements FormatterStepFactory { + @Parameter + private String version; + + @Override + public FormatterStep newFormatterStep(MojoConfig mojoConfig) { + String formatterVersion = version == null ? GoogleJavaFormatStep.defaultVersion() : version; + return GoogleJavaFormatStep.create(formatterVersion, mojoConfig.getProvisioner()); + } +} diff --git a/plugin-maven/src/test/java/com/diffplug/maven/spotless/GoogleJavaFormatTest.java b/plugin-maven/src/test/java/com/diffplug/maven/spotless/GoogleJavaFormatTest.java new file mode 100644 index 0000000000..34f81f0b6d --- /dev/null +++ b/plugin-maven/src/test/java/com/diffplug/maven/spotless/GoogleJavaFormatTest.java @@ -0,0 +1,38 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.maven.spotless; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; + +public class GoogleJavaFormatTest extends MavenIntegrationTest { + @Test + public void defaultVersion() throws Exception { + writePomWithJavaSteps( + "", + " 1.2", + ""); + + write("src/main/java/test.java", getTestResource("java/googlejavaformat/JavaCodeUnformatted.test")); + write("formatter.xml", getTestResource("java/eclipse/format/formatter.xml")); + + mavenRunner().withArguments("spotless:apply").runNoError(); + + String actual = read("src/main/java/test.java"); + assertThat(actual).isEqualTo(getTestResource("java/googlejavaformat/JavaCodeFormatted.test")); + } +} diff --git a/plugin-maven/src/test/resources/java/googlejavaformat/JavaCodeFormatted.test b/plugin-maven/src/test/resources/java/googlejavaformat/JavaCodeFormatted.test new file mode 100644 index 0000000000..de7710d80c --- /dev/null +++ b/plugin-maven/src/test/resources/java/googlejavaformat/JavaCodeFormatted.test @@ -0,0 +1,11 @@ + +import mylib.UsedA; +import mylib.UsedB; + +public class Java { + public static void main(String[] args) { + System.out.println("hello"); + UsedB.someMethod(); + UsedA.someMethod(); + } +} diff --git a/plugin-maven/src/test/resources/java/googlejavaformat/JavaCodeUnformatted.test b/plugin-maven/src/test/resources/java/googlejavaformat/JavaCodeUnformatted.test new file mode 100644 index 0000000000..a9a957c9c2 --- /dev/null +++ b/plugin-maven/src/test/resources/java/googlejavaformat/JavaCodeUnformatted.test @@ -0,0 +1,12 @@ + +import mylib.Unused; +import mylib.UsedB; +import mylib.UsedA; + +public class Java { +public static void main(String[] args) { +System.out.println("hello"); +UsedB.someMethod(); +UsedA.someMethod(); +} +} \ No newline at end of file From 3189d7ddd8effaaa6b8d9d0286d5ea2d98ce2b4c Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sat, 27 Jan 2018 04:11:22 -0800 Subject: [PATCH 36/91] Added an ImportOrder step. --- .../diffplug/maven/spotless/ImportOrder.java | 44 +++++++++++++++++ .../maven/spotless/ImportOrderTest.java | 48 +++++++++++++++++++ .../importsorter/JavaCodeSortedImports.test | 9 ++++ .../importsorter/JavaCodeUnsortedImports.test | 7 +++ .../java/importsorter/import.properties | 6 +++ 5 files changed, 114 insertions(+) create mode 100644 plugin-maven/src/main/java/com/diffplug/maven/spotless/ImportOrder.java create mode 100644 plugin-maven/src/test/java/com/diffplug/maven/spotless/ImportOrderTest.java create mode 100644 plugin-maven/src/test/resources/java/importsorter/JavaCodeSortedImports.test create mode 100644 plugin-maven/src/test/resources/java/importsorter/JavaCodeUnsortedImports.test create mode 100644 plugin-maven/src/test/resources/java/importsorter/import.properties diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/ImportOrder.java b/plugin-maven/src/main/java/com/diffplug/maven/spotless/ImportOrder.java new file mode 100644 index 0000000000..c36b14cdea --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/maven/spotless/ImportOrder.java @@ -0,0 +1,44 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.maven.spotless; + +import java.io.File; + +import org.apache.maven.plugins.annotations.Parameter; + +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.java.ImportOrderStep; + +public class ImportOrder implements FormatterStepFactory { + @Parameter + private File file; + + @Parameter + private String order; + + @Override + public FormatterStep newFormatterStep(MojoConfig mojoConfig) { + if (file != null ^ order != null) { + if (file != null) { + return ImportOrderStep.createFromFile(file); + } else { + return ImportOrderStep.createFromOrder(order.split(",")); + } + } else { + throw new IllegalArgumentException("Must specify exactly one of 'file' or 'order'."); + } + } +} diff --git a/plugin-maven/src/test/java/com/diffplug/maven/spotless/ImportOrderTest.java b/plugin-maven/src/test/java/com/diffplug/maven/spotless/ImportOrderTest.java new file mode 100644 index 0000000000..53ff98d4d3 --- /dev/null +++ b/plugin-maven/src/test/java/com/diffplug/maven/spotless/ImportOrderTest.java @@ -0,0 +1,48 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.maven.spotless; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; + +public class ImportOrderTest extends MavenIntegrationTest { + @Test + public void file() throws Exception { + write("import.properties", getTestResource("java/importsorter/import.properties")); + writePomWithJavaSteps( + "", + " ${basedir}/import.properties", + ""); + runTest(); + } + + @Test + public void order() throws Exception { + writePomWithJavaSteps( + "", + " java,javax,org,\\#com", + ""); + runTest(); + } + + private void runTest() throws Exception { + write("src/main/java/test.java", getTestResource("java/importsorter/JavaCodeUnsortedImports.test")); + mavenRunner().withArguments("spotless:apply").runNoError(); + String actual = read("src/main/java/test.java"); + assertThat(actual).isEqualTo(getTestResource("java/importsorter/JavaCodeSortedImports.test")); + } +} diff --git a/plugin-maven/src/test/resources/java/importsorter/JavaCodeSortedImports.test b/plugin-maven/src/test/resources/java/importsorter/JavaCodeSortedImports.test new file mode 100644 index 0000000000..e20a555950 --- /dev/null +++ b/plugin-maven/src/test/resources/java/importsorter/JavaCodeSortedImports.test @@ -0,0 +1,9 @@ +import java.lang.Runnable; +import java.lang.Thread; + +import org.dooda.Didoo; + +import static java.lang.Exception.*; +import static java.lang.Runnable.*; + +import static com.foo.Bar; diff --git a/plugin-maven/src/test/resources/java/importsorter/JavaCodeUnsortedImports.test b/plugin-maven/src/test/resources/java/importsorter/JavaCodeUnsortedImports.test new file mode 100644 index 0000000000..50d052d456 --- /dev/null +++ b/plugin-maven/src/test/resources/java/importsorter/JavaCodeUnsortedImports.test @@ -0,0 +1,7 @@ +import static java.lang.Exception.*; +import org.dooda.Didoo; +import java.lang.Thread; +import java.lang.Runnable; + +import static java.lang.Runnable.*; +import static com.foo.Bar diff --git a/plugin-maven/src/test/resources/java/importsorter/import.properties b/plugin-maven/src/test/resources/java/importsorter/import.properties new file mode 100644 index 0000000000..24e9660a4e --- /dev/null +++ b/plugin-maven/src/test/resources/java/importsorter/import.properties @@ -0,0 +1,6 @@ +#Organize Import Order +#Mon Jan 14 17:18:26 BRST 2013 +3=\#com +2=org +1=javax +0=java \ No newline at end of file From 6568440d1bddbc99946e4b2d441ffaf3d9eaf422 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sat, 27 Jan 2018 04:16:05 -0800 Subject: [PATCH 37/91] Reorganized packages. --- .../spotless => spotless/maven}/AbstractSpotlessMojo.java | 3 ++- .../maven}/ArtifactResolutionException.java | 2 +- .../{maven/spotless => spotless/maven}/ArtifactResolver.java | 2 +- .../{maven/spotless => spotless/maven}/FormatterFactory.java | 2 +- .../spotless => spotless/maven}/FormatterStepFactory.java | 2 +- .../{maven/spotless => spotless/maven}/MavenProvisioner.java | 2 +- .../{maven/spotless => spotless/maven}/MojoConfig.java | 2 +- .../spotless => spotless/maven}/SpotlessApplyMojo.java | 2 +- .../spotless => spotless/maven}/SpotlessCheckMojo.java | 2 +- .../{maven/spotless => spotless/maven/java}/Eclipse.java | 4 +++- .../spotless => spotless/maven/java}/GoogleJavaFormat.java | 4 +++- .../{maven/spotless => spotless/maven/java}/ImportOrder.java | 4 +++- .../{maven/spotless => spotless/maven/java}/Java.java | 5 ++++- .../maven/java}/RemoveUnusedImports.java | 4 +++- .../spotless => spotless/maven}/MavenIntegrationTest.java | 2 +- .../spotless => spotless/maven}/MavenProvisionerTest.java | 2 +- .../{maven/spotless => spotless/maven}/MavenRunner.java | 2 +- .../maven/java}/EclipseFormatStepTest.java | 4 +++- .../maven/java}/GoogleJavaFormatTest.java | 4 +++- .../spotless => spotless/maven/java}/ImportOrderTest.java | 4 +++- .../maven/java}/RemoveUnusedImportsStepTest.java | 4 +++- 21 files changed, 41 insertions(+), 21 deletions(-) rename plugin-maven/src/main/java/com/diffplug/{maven/spotless => spotless/maven}/AbstractSpotlessMojo.java (98%) rename plugin-maven/src/main/java/com/diffplug/{maven/spotless => spotless/maven}/ArtifactResolutionException.java (95%) rename plugin-maven/src/main/java/com/diffplug/{maven/spotless => spotless/maven}/ArtifactResolver.java (98%) rename plugin-maven/src/main/java/com/diffplug/{maven/spotless => spotless/maven}/FormatterFactory.java (95%) rename plugin-maven/src/main/java/com/diffplug/{maven/spotless => spotless/maven}/FormatterStepFactory.java (95%) rename plugin-maven/src/main/java/com/diffplug/{maven/spotless => spotless/maven}/MavenProvisioner.java (96%) rename plugin-maven/src/main/java/com/diffplug/{maven/spotless => spotless/maven}/MojoConfig.java (97%) rename plugin-maven/src/main/java/com/diffplug/{maven/spotless => spotless/maven}/SpotlessApplyMojo.java (96%) rename plugin-maven/src/main/java/com/diffplug/{maven/spotless => spotless/maven}/SpotlessCheckMojo.java (97%) rename plugin-maven/src/main/java/com/diffplug/{maven/spotless => spotless/maven/java}/Eclipse.java (90%) rename plugin-maven/src/main/java/com/diffplug/{maven/spotless => spotless/maven/java}/GoogleJavaFormat.java (88%) rename plugin-maven/src/main/java/com/diffplug/{maven/spotless => spotless/maven/java}/ImportOrder.java (89%) rename plugin-maven/src/main/java/com/diffplug/{maven/spotless => spotless/maven/java}/Java.java (91%) rename plugin-maven/src/main/java/com/diffplug/{maven/spotless => spotless/maven/java}/RemoveUnusedImports.java (86%) rename plugin-maven/src/test/java/com/diffplug/{maven/spotless => spotless/maven}/MavenIntegrationTest.java (99%) rename plugin-maven/src/test/java/com/diffplug/{maven/spotless => spotless/maven}/MavenProvisionerTest.java (98%) rename plugin-maven/src/test/java/com/diffplug/{maven/spotless => spotless/maven}/MavenRunner.java (99%) rename plugin-maven/src/test/java/com/diffplug/{maven/spotless => spotless/maven/java}/EclipseFormatStepTest.java (93%) rename plugin-maven/src/test/java/com/diffplug/{maven/spotless => spotless/maven/java}/GoogleJavaFormatTest.java (92%) rename plugin-maven/src/test/java/com/diffplug/{maven/spotless => spotless/maven/java}/ImportOrderTest.java (93%) rename plugin-maven/src/test/java/com/diffplug/{maven/spotless => spotless/maven/java}/RemoveUnusedImportsStepTest.java (92%) diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/AbstractSpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java similarity index 98% rename from plugin-maven/src/main/java/com/diffplug/maven/spotless/AbstractSpotlessMojo.java rename to plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java index 11ded46a78..d4fbde21cc 100644 --- a/plugin-maven/src/main/java/com/diffplug/maven/spotless/AbstractSpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.maven.spotless; +package com.diffplug.spotless.maven; import static java.util.Collections.singletonList; import static java.util.stream.Collectors.toList; @@ -39,6 +39,7 @@ import com.diffplug.spotless.Formatter; import com.diffplug.spotless.LineEnding; import com.diffplug.spotless.Provisioner; +import com.diffplug.spotless.maven.java.Java; public abstract class AbstractSpotlessMojo extends AbstractMojo { diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/ArtifactResolutionException.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/ArtifactResolutionException.java similarity index 95% rename from plugin-maven/src/main/java/com/diffplug/maven/spotless/ArtifactResolutionException.java rename to plugin-maven/src/main/java/com/diffplug/spotless/maven/ArtifactResolutionException.java index eb98a2c730..398b357a62 100644 --- a/plugin-maven/src/main/java/com/diffplug/maven/spotless/ArtifactResolutionException.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/ArtifactResolutionException.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.maven.spotless; +package com.diffplug.spotless.maven; public class ArtifactResolutionException extends RuntimeException { diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/ArtifactResolver.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/ArtifactResolver.java similarity index 98% rename from plugin-maven/src/main/java/com/diffplug/maven/spotless/ArtifactResolver.java rename to plugin-maven/src/main/java/com/diffplug/spotless/maven/ArtifactResolver.java index 6f285b03a6..35508905e2 100644 --- a/plugin-maven/src/main/java/com/diffplug/maven/spotless/ArtifactResolver.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/ArtifactResolver.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.maven.spotless; +package com.diffplug.spotless.maven; import static java.util.stream.Collectors.toSet; diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/FormatterFactory.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java similarity index 95% rename from plugin-maven/src/main/java/com/diffplug/maven/spotless/FormatterFactory.java rename to plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java index 9d951fdace..8866ed3c23 100644 --- a/plugin-maven/src/main/java/com/diffplug/maven/spotless/FormatterFactory.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.maven.spotless; +package com.diffplug.spotless.maven; import java.io.File; import java.util.List; diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/FormatterStepFactory.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepFactory.java similarity index 95% rename from plugin-maven/src/main/java/com/diffplug/maven/spotless/FormatterStepFactory.java rename to plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepFactory.java index 1386efb584..89e650acc2 100644 --- a/plugin-maven/src/main/java/com/diffplug/maven/spotless/FormatterStepFactory.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepFactory.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.maven.spotless; +package com.diffplug.spotless.maven; import com.diffplug.spotless.FormatterStep; diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/MavenProvisioner.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/MavenProvisioner.java similarity index 96% rename from plugin-maven/src/main/java/com/diffplug/maven/spotless/MavenProvisioner.java rename to plugin-maven/src/main/java/com/diffplug/spotless/maven/MavenProvisioner.java index e82361ad13..902aa1e1e6 100644 --- a/plugin-maven/src/main/java/com/diffplug/maven/spotless/MavenProvisioner.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/MavenProvisioner.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.maven.spotless; +package com.diffplug.spotless.maven; import static java.util.stream.Collectors.toSet; diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/MojoConfig.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/MojoConfig.java similarity index 97% rename from plugin-maven/src/main/java/com/diffplug/maven/spotless/MojoConfig.java rename to plugin-maven/src/main/java/com/diffplug/spotless/maven/MojoConfig.java index 7c123b537d..771ff2dc88 100644 --- a/plugin-maven/src/main/java/com/diffplug/maven/spotless/MojoConfig.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/MojoConfig.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.maven.spotless; +package com.diffplug.spotless.maven; import java.io.File; diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessApplyMojo.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessApplyMojo.java similarity index 96% rename from plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessApplyMojo.java rename to plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessApplyMojo.java index 5f5509462a..42b5eda7ea 100644 --- a/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessApplyMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessApplyMojo.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.maven.spotless; +package com.diffplug.spotless.maven; import java.io.File; import java.io.IOException; diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessCheckMojo.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java similarity index 97% rename from plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessCheckMojo.java rename to plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java index e81c4d4f04..8abba5c9fa 100644 --- a/plugin-maven/src/main/java/com/diffplug/maven/spotless/SpotlessCheckMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.maven.spotless; +package com.diffplug.spotless.maven; import java.io.File; import java.io.IOException; diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/Eclipse.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Eclipse.java similarity index 90% rename from plugin-maven/src/main/java/com/diffplug/maven/spotless/Eclipse.java rename to plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Eclipse.java index 109545a713..b0e6ab1f9b 100644 --- a/plugin-maven/src/main/java/com/diffplug/maven/spotless/Eclipse.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Eclipse.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.maven.spotless; +package com.diffplug.spotless.maven.java; import static com.diffplug.spotless.extra.java.EclipseFormatterStep.defaultVersion; import static java.util.Collections.singleton; @@ -25,6 +25,8 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.extra.java.EclipseFormatterStep; +import com.diffplug.spotless.maven.FormatterStepFactory; +import com.diffplug.spotless.maven.MojoConfig; public class Eclipse implements FormatterStepFactory { diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/GoogleJavaFormat.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/GoogleJavaFormat.java similarity index 88% rename from plugin-maven/src/main/java/com/diffplug/maven/spotless/GoogleJavaFormat.java rename to plugin-maven/src/main/java/com/diffplug/spotless/maven/java/GoogleJavaFormat.java index e299b7cad3..8db99d115d 100644 --- a/plugin-maven/src/main/java/com/diffplug/maven/spotless/GoogleJavaFormat.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/GoogleJavaFormat.java @@ -13,12 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.maven.spotless; +package com.diffplug.spotless.maven.java; import org.apache.maven.plugins.annotations.Parameter; import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.java.GoogleJavaFormatStep; +import com.diffplug.spotless.maven.FormatterStepFactory; +import com.diffplug.spotless.maven.MojoConfig; public class GoogleJavaFormat implements FormatterStepFactory { @Parameter diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/ImportOrder.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/ImportOrder.java similarity index 89% rename from plugin-maven/src/main/java/com/diffplug/maven/spotless/ImportOrder.java rename to plugin-maven/src/main/java/com/diffplug/spotless/maven/java/ImportOrder.java index c36b14cdea..e861f9cc42 100644 --- a/plugin-maven/src/main/java/com/diffplug/maven/spotless/ImportOrder.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/ImportOrder.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.maven.spotless; +package com.diffplug.spotless.maven.java; import java.io.File; @@ -21,6 +21,8 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.java.ImportOrderStep; +import com.diffplug.spotless.maven.FormatterStepFactory; +import com.diffplug.spotless.maven.MojoConfig; public class ImportOrder implements FormatterStepFactory { @Parameter diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/Java.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java similarity index 91% rename from plugin-maven/src/main/java/com/diffplug/maven/spotless/Java.java rename to plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java index c8bb6c7ced..3bf9499d85 100644 --- a/plugin-maven/src/main/java/com/diffplug/maven/spotless/Java.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.maven.spotless; +package com.diffplug.spotless.maven.java; import static java.util.stream.Collectors.toList; @@ -28,6 +28,9 @@ import com.diffplug.spotless.Formatter; import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.LineEnding; +import com.diffplug.spotless.maven.FormatterFactory; +import com.diffplug.spotless.maven.FormatterStepFactory; +import com.diffplug.spotless.maven.MojoConfig; public class Java implements FormatterFactory { diff --git a/plugin-maven/src/main/java/com/diffplug/maven/spotless/RemoveUnusedImports.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/RemoveUnusedImports.java similarity index 86% rename from plugin-maven/src/main/java/com/diffplug/maven/spotless/RemoveUnusedImports.java rename to plugin-maven/src/main/java/com/diffplug/spotless/maven/java/RemoveUnusedImports.java index 1d967a1150..75f7e05320 100644 --- a/plugin-maven/src/main/java/com/diffplug/maven/spotless/RemoveUnusedImports.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/RemoveUnusedImports.java @@ -13,10 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.maven.spotless; +package com.diffplug.spotless.maven.java; import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.java.RemoveUnusedImportsStep; +import com.diffplug.spotless.maven.FormatterStepFactory; +import com.diffplug.spotless.maven.MojoConfig; public class RemoveUnusedImports implements FormatterStepFactory { diff --git a/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenIntegrationTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java similarity index 99% rename from plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenIntegrationTest.java rename to plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java index 841bc64525..d70af1dc5f 100644 --- a/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenIntegrationTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.maven.spotless; +package com.diffplug.spotless.maven; import static com.diffplug.common.base.Strings.isNullOrEmpty; import static java.util.stream.Collectors.joining; diff --git a/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenProvisionerTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenProvisionerTest.java similarity index 98% rename from plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenProvisionerTest.java rename to plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenProvisionerTest.java index ff3af15fcb..9430402ac8 100644 --- a/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenProvisionerTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenProvisionerTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.maven.spotless; +package com.diffplug.spotless.maven; import static com.diffplug.common.collect.Sets.newHashSet; import static java.util.Collections.emptySet; diff --git a/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenRunner.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java similarity index 99% rename from plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenRunner.java rename to plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java index db469c11f9..73e7689637 100644 --- a/plugin-maven/src/test/java/com/diffplug/maven/spotless/MavenRunner.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.maven.spotless; +package com.diffplug.spotless.maven; import static org.assertj.core.api.Assertions.assertThat; diff --git a/plugin-maven/src/test/java/com/diffplug/maven/spotless/EclipseFormatStepTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/EclipseFormatStepTest.java similarity index 93% rename from plugin-maven/src/test/java/com/diffplug/maven/spotless/EclipseFormatStepTest.java rename to plugin-maven/src/test/java/com/diffplug/spotless/maven/java/EclipseFormatStepTest.java index 7bdaf841c0..cc2202b9d5 100644 --- a/plugin-maven/src/test/java/com/diffplug/maven/spotless/EclipseFormatStepTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/EclipseFormatStepTest.java @@ -13,12 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.maven.spotless; +package com.diffplug.spotless.maven.java; import static org.assertj.core.api.Assertions.assertThat; import org.junit.Test; +import com.diffplug.spotless.maven.MavenIntegrationTest; + public class EclipseFormatStepTest extends MavenIntegrationTest { @Test diff --git a/plugin-maven/src/test/java/com/diffplug/maven/spotless/GoogleJavaFormatTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/GoogleJavaFormatTest.java similarity index 92% rename from plugin-maven/src/test/java/com/diffplug/maven/spotless/GoogleJavaFormatTest.java rename to plugin-maven/src/test/java/com/diffplug/spotless/maven/java/GoogleJavaFormatTest.java index 34f81f0b6d..e384fd7941 100644 --- a/plugin-maven/src/test/java/com/diffplug/maven/spotless/GoogleJavaFormatTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/GoogleJavaFormatTest.java @@ -13,12 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.maven.spotless; +package com.diffplug.spotless.maven.java; import static org.assertj.core.api.Assertions.assertThat; import org.junit.Test; +import com.diffplug.spotless.maven.MavenIntegrationTest; + public class GoogleJavaFormatTest extends MavenIntegrationTest { @Test public void defaultVersion() throws Exception { diff --git a/plugin-maven/src/test/java/com/diffplug/maven/spotless/ImportOrderTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/ImportOrderTest.java similarity index 93% rename from plugin-maven/src/test/java/com/diffplug/maven/spotless/ImportOrderTest.java rename to plugin-maven/src/test/java/com/diffplug/spotless/maven/java/ImportOrderTest.java index 53ff98d4d3..26bc618452 100644 --- a/plugin-maven/src/test/java/com/diffplug/maven/spotless/ImportOrderTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/ImportOrderTest.java @@ -13,12 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.maven.spotless; +package com.diffplug.spotless.maven.java; import static org.assertj.core.api.Assertions.assertThat; import org.junit.Test; +import com.diffplug.spotless.maven.MavenIntegrationTest; + public class ImportOrderTest extends MavenIntegrationTest { @Test public void file() throws Exception { diff --git a/plugin-maven/src/test/java/com/diffplug/maven/spotless/RemoveUnusedImportsStepTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/RemoveUnusedImportsStepTest.java similarity index 92% rename from plugin-maven/src/test/java/com/diffplug/maven/spotless/RemoveUnusedImportsStepTest.java rename to plugin-maven/src/test/java/com/diffplug/spotless/maven/java/RemoveUnusedImportsStepTest.java index 0af3476c71..c57ff55476 100644 --- a/plugin-maven/src/test/java/com/diffplug/maven/spotless/RemoveUnusedImportsStepTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/RemoveUnusedImportsStepTest.java @@ -13,12 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.maven.spotless; +package com.diffplug.spotless.maven.java; import static org.assertj.core.api.Assertions.assertThat; import org.junit.Test; +import com.diffplug.spotless.maven.MavenIntegrationTest; + public class RemoveUnusedImportsStepTest extends MavenIntegrationTest { @Test From 21f8d00ebae3cfbfe0b2ffa7414801f98819284e Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sat, 27 Jan 2018 04:27:05 -0800 Subject: [PATCH 38/91] Make the parent FormatterFactory available to the FormatterStepFactory. --- .../java/com/diffplug/spotless/maven/FormatterStepFactory.java | 2 +- .../main/java/com/diffplug/spotless/maven/java/Eclipse.java | 3 ++- .../com/diffplug/spotless/maven/java/GoogleJavaFormat.java | 3 ++- .../java/com/diffplug/spotless/maven/java/ImportOrder.java | 3 ++- .../src/main/java/com/diffplug/spotless/maven/java/Java.java | 2 +- .../com/diffplug/spotless/maven/java/RemoveUnusedImports.java | 3 ++- 6 files changed, 10 insertions(+), 6 deletions(-) diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepFactory.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepFactory.java index 89e650acc2..d663e9ae75 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepFactory.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepFactory.java @@ -19,5 +19,5 @@ public interface FormatterStepFactory { - FormatterStep newFormatterStep(MojoConfig mojoConfig); + FormatterStep newFormatterStep(FormatterFactory parent, MojoConfig mojoConfig); } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Eclipse.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Eclipse.java index b0e6ab1f9b..f41ba32a1e 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Eclipse.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Eclipse.java @@ -25,6 +25,7 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.extra.java.EclipseFormatterStep; +import com.diffplug.spotless.maven.FormatterFactory; import com.diffplug.spotless.maven.FormatterStepFactory; import com.diffplug.spotless.maven.MojoConfig; @@ -37,7 +38,7 @@ public class Eclipse implements FormatterStepFactory { private String version; @Override - public FormatterStep newFormatterStep(MojoConfig mojoConfig) { + public FormatterStep newFormatterStep(FormatterFactory parent, MojoConfig mojoConfig) { String formatterVersion = version == null ? defaultVersion() : version; Set settingsFiles = singleton(file); return EclipseFormatterStep.create(formatterVersion, settingsFiles, mojoConfig.getProvisioner()); diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/GoogleJavaFormat.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/GoogleJavaFormat.java index 8db99d115d..bef4c7077e 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/GoogleJavaFormat.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/GoogleJavaFormat.java @@ -19,6 +19,7 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.java.GoogleJavaFormatStep; +import com.diffplug.spotless.maven.FormatterFactory; import com.diffplug.spotless.maven.FormatterStepFactory; import com.diffplug.spotless.maven.MojoConfig; @@ -27,7 +28,7 @@ public class GoogleJavaFormat implements FormatterStepFactory { private String version; @Override - public FormatterStep newFormatterStep(MojoConfig mojoConfig) { + public FormatterStep newFormatterStep(FormatterFactory parent, MojoConfig mojoConfig) { String formatterVersion = version == null ? GoogleJavaFormatStep.defaultVersion() : version; return GoogleJavaFormatStep.create(formatterVersion, mojoConfig.getProvisioner()); } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/ImportOrder.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/ImportOrder.java index e861f9cc42..270f45e8f0 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/ImportOrder.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/ImportOrder.java @@ -21,6 +21,7 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.java.ImportOrderStep; +import com.diffplug.spotless.maven.FormatterFactory; import com.diffplug.spotless.maven.FormatterStepFactory; import com.diffplug.spotless.maven.MojoConfig; @@ -32,7 +33,7 @@ public class ImportOrder implements FormatterStepFactory { private String order; @Override - public FormatterStep newFormatterStep(MojoConfig mojoConfig) { + public FormatterStep newFormatterStep(FormatterFactory parent, MojoConfig mojoConfig) { if (file != null ^ order != null) { if (file != null) { return ImportOrderStep.createFromFile(file); diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java index 3bf9499d85..3ea0fc9e2e 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java @@ -58,7 +58,7 @@ public Formatter newFormatter(List filesToFormat, MojoConfig mojoConfig) { List formatterSteps = steps.stream() .filter(Objects::nonNull) // all unrecognized steps from XML config appear as nulls in the list - .map(factory -> factory.newFormatterStep(mojoConfig)) + .map(factory -> factory.newFormatterStep(this, mojoConfig)) .collect(toList()); return Formatter.builder() diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/RemoveUnusedImports.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/RemoveUnusedImports.java index 75f7e05320..b447b23c01 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/RemoveUnusedImports.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/RemoveUnusedImports.java @@ -17,13 +17,14 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.java.RemoveUnusedImportsStep; +import com.diffplug.spotless.maven.FormatterFactory; import com.diffplug.spotless.maven.FormatterStepFactory; import com.diffplug.spotless.maven.MojoConfig; public class RemoveUnusedImports implements FormatterStepFactory { @Override - public FormatterStep newFormatterStep(MojoConfig mojoConfig) { + public FormatterStep newFormatterStep(FormatterFactory parent, MojoConfig mojoConfig) { return RemoveUnusedImportsStep.create(mojoConfig.getProvisioner()); } } From 8ebdbfc62807940195ca0ac63b04b11a48e6befc Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sat, 27 Jan 2018 04:36:21 -0800 Subject: [PATCH 39/91] Refactored non-java stuff out of FormatterFactory. --- .../spotless/maven/FormatterFactory.java | 48 +++++++++++++++++-- .../diffplug/spotless/maven/java/Java.java | 47 +----------------- 2 files changed, 46 insertions(+), 49 deletions(-) diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java index 8866ed3c23..99f426562f 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java @@ -15,14 +15,56 @@ */ package com.diffplug.spotless.maven; +import static java.util.stream.Collectors.toList; + import java.io.File; +import java.nio.charset.Charset; import java.util.List; +import java.util.Objects; + +import org.apache.maven.plugins.annotations.Parameter; +import com.diffplug.spotless.FormatExceptionPolicyStrict; import com.diffplug.spotless.Formatter; +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.LineEnding; + +public abstract class FormatterFactory { + @Parameter + protected String encoding; + + @Parameter + protected LineEnding lineEndings; + + @Parameter + protected List steps; + + public abstract String fileExtension(); + + public Formatter newFormatter(List filesToFormat, MojoConfig mojoConfig) { + Charset formatterEncoding = encoding(mojoConfig); + LineEnding formatterLineEndings = lineEndings(mojoConfig); + LineEnding.Policy formatterLineEndingPolicy = formatterLineEndings.createPolicy(mojoConfig.getBaseDir(), () -> filesToFormat); + + List formatterSteps = steps.stream() + .filter(Objects::nonNull) // all unrecognized steps from XML config appear as nulls in the list + .map(factory -> factory.newFormatterStep(this, mojoConfig)) + .collect(toList()); -public interface FormatterFactory { + return Formatter.builder() + .encoding(formatterEncoding) + .lineEndingsPolicy(formatterLineEndingPolicy) + .exceptionPolicy(new FormatExceptionPolicyStrict()) + .steps(formatterSteps) + .rootDir(mojoConfig.getBaseDir().toPath()) + .build(); + } - String fileExtension(); + public Charset encoding(MojoConfig mojoConfig) { + return Charset.forName(encoding == null ? mojoConfig.getEncoding() : encoding); + } - Formatter newFormatter(List filesToFormat, MojoConfig mojoConfig); + public LineEnding lineEndings(MojoConfig mojoConfig) { + return lineEndings == null ? mojoConfig.getLineEndings() : lineEndings; + } } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java index 3ea0fc9e2e..81eacea8de 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java @@ -15,58 +15,13 @@ */ package com.diffplug.spotless.maven.java; -import static java.util.stream.Collectors.toList; - -import java.io.File; -import java.nio.charset.Charset; -import java.util.List; -import java.util.Objects; - -import org.apache.maven.plugins.annotations.Parameter; - -import com.diffplug.spotless.FormatExceptionPolicyStrict; -import com.diffplug.spotless.Formatter; -import com.diffplug.spotless.FormatterStep; -import com.diffplug.spotless.LineEnding; import com.diffplug.spotless.maven.FormatterFactory; -import com.diffplug.spotless.maven.FormatterStepFactory; -import com.diffplug.spotless.maven.MojoConfig; - -public class Java implements FormatterFactory { +public class Java extends FormatterFactory { private static final String EXTENSION = "java"; - @Parameter - private String encoding; - - @Parameter - private LineEnding lineEndings; - - @Parameter - private List steps; - @Override public String fileExtension() { return EXTENSION; } - - @Override - public Formatter newFormatter(List filesToFormat, MojoConfig mojoConfig) { - Charset formatterEncoding = encoding == null ? Charset.forName(mojoConfig.getEncoding()) : Charset.forName(encoding); - LineEnding formatterLineEndings = lineEndings == null ? mojoConfig.getLineEndings() : lineEndings; - LineEnding.Policy formatterLineEndingPolicy = formatterLineEndings.createPolicy(mojoConfig.getBaseDir(), () -> filesToFormat); - - List formatterSteps = steps.stream() - .filter(Objects::nonNull) // all unrecognized steps from XML config appear as nulls in the list - .map(factory -> factory.newFormatterStep(this, mojoConfig)) - .collect(toList()); - - return Formatter.builder() - .encoding(formatterEncoding) - .lineEndingsPolicy(formatterLineEndingPolicy) - .exceptionPolicy(new FormatExceptionPolicyStrict()) - .steps(formatterSteps) - .rootDir(mojoConfig.getBaseDir().toPath()) - .build(); - } } From 24f7096ada1339773379adf230c0144fc1140bdc Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sat, 27 Jan 2018 04:43:55 -0800 Subject: [PATCH 40/91] Added a License step. --- .../spotless/maven/generic/LicenseHeader.java | 61 +++++++++++++++++++ .../maven/generic/LicenseHeaderTest.java | 52 ++++++++++++++++ .../test/resources/license/HasLicense.test | 30 +++++++++ .../resources/license/MissingLicense.test | 28 +++++++++ .../src/test/resources/license/TestLicense | 2 + 5 files changed, 173 insertions(+) create mode 100644 plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/LicenseHeader.java create mode 100644 plugin-maven/src/test/java/com/diffplug/spotless/maven/generic/LicenseHeaderTest.java create mode 100644 plugin-maven/src/test/resources/license/HasLicense.test create mode 100644 plugin-maven/src/test/resources/license/MissingLicense.test create mode 100644 plugin-maven/src/test/resources/license/TestLicense diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/LicenseHeader.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/LicenseHeader.java new file mode 100644 index 0000000000..3c8280db93 --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/LicenseHeader.java @@ -0,0 +1,61 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.spotless.maven.generic; + +import java.io.File; + +import org.apache.maven.plugins.annotations.Parameter; + +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.generic.LicenseHeaderStep; +import com.diffplug.spotless.maven.FormatterFactory; +import com.diffplug.spotless.maven.FormatterStepFactory; +import com.diffplug.spotless.maven.MojoConfig; +import com.diffplug.spotless.maven.java.Java; + +public class LicenseHeader implements FormatterStepFactory { + @Parameter + private File file; + + @Parameter + private String content; + + @Parameter + private String delimiter; + + @Override + public FormatterStep newFormatterStep(FormatterFactory parent, MojoConfig mojoConfig) { + String delimiterString; + if (delimiter != null) { + delimiterString = delimiter; + } else { + if (parent instanceof Java) { + delimiterString = "package "; + } else { + throw new IllegalArgumentException("You need to specify 'delimiter'."); + } + } + if (file != null ^ content != null) { + if (file != null) { + return LicenseHeaderStep.createFromFile(file, parent.encoding(mojoConfig), delimiterString); + } else { + return LicenseHeaderStep.createFromHeader(content, delimiterString); + } + } else { + throw new IllegalArgumentException("Must specify exactly one of 'file' or 'content'."); + } + } +} diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/generic/LicenseHeaderTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/generic/LicenseHeaderTest.java new file mode 100644 index 0000000000..eb28e37db4 --- /dev/null +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/generic/LicenseHeaderTest.java @@ -0,0 +1,52 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.spotless.maven.generic; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.diffplug.spotless.maven.MavenIntegrationTest; + +public class LicenseHeaderTest extends MavenIntegrationTest { + private static final String KEY_LICENSE = "license/TestLicense"; + + public void fromFile() throws Exception { + write("license.java", getTestResource(KEY_LICENSE)); + writePomWithJavaSteps( + "", + " ${basedir}/license.java", + ""); + runTest(); + } + + public void fromContent() throws Exception { + write("license.java", getTestResource(KEY_LICENSE)); + writePomWithJavaSteps( + "", + " ", + "// If you can't trust a man's word", + "// Does it help to have it in writing?", + " ", + ""); + runTest(); + } + + private void runTest() throws Exception { + write("src/main/java/test.java", getTestResource("license/MissingLicense.test")); + mavenRunner().withArguments("spotless:apply").runNoError(); + String actual = read("src/main/java/test.java"); + assertThat(actual).isEqualTo(getTestResource("license/HasLicense.test")); + } +} diff --git a/plugin-maven/src/test/resources/license/HasLicense.test b/plugin-maven/src/test/resources/license/HasLicense.test new file mode 100644 index 0000000000..775a25028d --- /dev/null +++ b/plugin-maven/src/test/resources/license/HasLicense.test @@ -0,0 +1,30 @@ +// If you can't trust a man's word +// Does it help to have it in writing? +package com.github.youribonnaffe.gradle.format; + +import java.util.function.Function; + + +public class Java8Test { + public void doStuff() throws Exception { + Function example = Integer::parseInt; + example.andThen(val -> { + return val + 2; + } ); + SimpleEnum val = SimpleEnum.A; + switch (val) { + case A: + break; + case B: + break; + case C: + break; + default: + throw new Exception(); + } + } + + public enum SimpleEnum { + A, B, C; + } +} diff --git a/plugin-maven/src/test/resources/license/MissingLicense.test b/plugin-maven/src/test/resources/license/MissingLicense.test new file mode 100644 index 0000000000..38f9541b2c --- /dev/null +++ b/plugin-maven/src/test/resources/license/MissingLicense.test @@ -0,0 +1,28 @@ +package com.github.youribonnaffe.gradle.format; + +import java.util.function.Function; + + +public class Java8Test { + public void doStuff() throws Exception { + Function example = Integer::parseInt; + example.andThen(val -> { + return val + 2; + } ); + SimpleEnum val = SimpleEnum.A; + switch (val) { + case A: + break; + case B: + break; + case C: + break; + default: + throw new Exception(); + } + } + + public enum SimpleEnum { + A, B, C; + } +} diff --git a/plugin-maven/src/test/resources/license/TestLicense b/plugin-maven/src/test/resources/license/TestLicense new file mode 100644 index 0000000000..4c832cf0a9 --- /dev/null +++ b/plugin-maven/src/test/resources/license/TestLicense @@ -0,0 +1,2 @@ +// If you can't trust a man's word +// Does it help to have it in writing? \ No newline at end of file From 5e9fce6b7a39a677cfca298d7a6ef10409d4bb7f Mon Sep 17 00:00:00 2001 From: lutovich Date: Sat, 27 Jan 2018 20:33:42 +0100 Subject: [PATCH 41/91] Refactor formatter and step configuration Split configuration into two - one for `FormatterFactory` and other for `FormatterStepFactory`. --- .../spotless/maven/AbstractSpotlessMojo.java | 6 +-- .../{MojoConfig.java => FormatterConfig.java} | 4 +- .../spotless/maven/FormatterFactory.java | 28 +++++++----- .../spotless/maven/FormatterStepConfig.java | 45 +++++++++++++++++++ .../spotless/maven/FormatterStepFactory.java | 2 +- .../spotless/maven/generic/LicenseHeader.java | 21 +++------ .../diffplug/spotless/maven/java/Eclipse.java | 7 ++- .../spotless/maven/java/GoogleJavaFormat.java | 7 ++- .../spotless/maven/java/ImportOrder.java | 5 +-- .../diffplug/spotless/maven/java/Java.java | 6 +++ .../maven/java/RemoveUnusedImports.java | 7 ++- 11 files changed, 93 insertions(+), 45 deletions(-) rename plugin-maven/src/main/java/com/diffplug/spotless/maven/{MojoConfig.java => FormatterConfig.java} (90%) create mode 100644 plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepConfig.java diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java index d4fbde21cc..5c1f512e26 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java @@ -88,7 +88,7 @@ public final void execute() throws MojoExecutionException, MojoFailureException private void execute(FormatterFactory formatterFactory) throws MojoExecutionException { List files = collectFiles(formatterFactory.fileExtension()); - Formatter formatter = formatterFactory.newFormatter(files, getMojoConfig()); + Formatter formatter = formatterFactory.newFormatter(files, getFormatterConfig()); process(files, formatter); } @@ -130,9 +130,9 @@ private List getAllSourceRoots() { .collect(toList()); } - private MojoConfig getMojoConfig() { + private FormatterConfig getFormatterConfig() { ArtifactResolver resolver = new ArtifactResolver(repositorySystem, repositorySystemSession, repositories, getLog()); Provisioner provisioner = MavenProvisioner.create(resolver); - return new MojoConfig(baseDir, encoding, lineEndings, provisioner); + return new FormatterConfig(baseDir, encoding, lineEndings, provisioner); } } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/MojoConfig.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java similarity index 90% rename from plugin-maven/src/main/java/com/diffplug/spotless/maven/MojoConfig.java rename to plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java index 771ff2dc88..a31ac47ab3 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/MojoConfig.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java @@ -20,14 +20,14 @@ import com.diffplug.spotless.LineEnding; import com.diffplug.spotless.Provisioner; -public class MojoConfig { +public class FormatterConfig { private final File baseDir; private final String encoding; private final LineEnding lineEndings; private final Provisioner provisioner; - public MojoConfig(File baseDir, String encoding, LineEnding lineEndings, Provisioner provisioner) { + public FormatterConfig(File baseDir, String encoding, LineEnding lineEndings, Provisioner provisioner) { this.baseDir = baseDir; this.encoding = encoding; this.lineEndings = lineEndings; diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java index 99f426562f..c97b8010f6 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java @@ -41,14 +41,18 @@ public abstract class FormatterFactory { public abstract String fileExtension(); - public Formatter newFormatter(List filesToFormat, MojoConfig mojoConfig) { - Charset formatterEncoding = encoding(mojoConfig); - LineEnding formatterLineEndings = lineEndings(mojoConfig); - LineEnding.Policy formatterLineEndingPolicy = formatterLineEndings.createPolicy(mojoConfig.getBaseDir(), () -> filesToFormat); + public abstract String licenseHeaderDelimiter(); + + public final Formatter newFormatter(List filesToFormat, FormatterConfig config) { + Charset formatterEncoding = encoding(config); + LineEnding formatterLineEndings = lineEndings(config); + LineEnding.Policy formatterLineEndingPolicy = formatterLineEndings.createPolicy(config.getBaseDir(), () -> filesToFormat); + + FormatterStepConfig stepConfig = stepConfig(formatterEncoding, config); List formatterSteps = steps.stream() .filter(Objects::nonNull) // all unrecognized steps from XML config appear as nulls in the list - .map(factory -> factory.newFormatterStep(this, mojoConfig)) + .map(factory -> factory.newFormatterStep(stepConfig)) .collect(toList()); return Formatter.builder() @@ -56,15 +60,19 @@ public Formatter newFormatter(List filesToFormat, MojoConfig mojoConfig) { .lineEndingsPolicy(formatterLineEndingPolicy) .exceptionPolicy(new FormatExceptionPolicyStrict()) .steps(formatterSteps) - .rootDir(mojoConfig.getBaseDir().toPath()) + .rootDir(config.getBaseDir().toPath()) .build(); } - public Charset encoding(MojoConfig mojoConfig) { - return Charset.forName(encoding == null ? mojoConfig.getEncoding() : encoding); + private Charset encoding(FormatterConfig config) { + return Charset.forName(encoding == null ? config.getEncoding() : encoding); + } + + private LineEnding lineEndings(FormatterConfig config) { + return lineEndings == null ? config.getLineEndings() : lineEndings; } - public LineEnding lineEndings(MojoConfig mojoConfig) { - return lineEndings == null ? mojoConfig.getLineEndings() : lineEndings; + private FormatterStepConfig stepConfig(Charset encoding, FormatterConfig config) { + return new FormatterStepConfig(encoding, licenseHeaderDelimiter(), config.getProvisioner()); } } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepConfig.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepConfig.java new file mode 100644 index 0000000000..0a2fbde018 --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepConfig.java @@ -0,0 +1,45 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.spotless.maven; + +import java.nio.charset.Charset; + +import com.diffplug.spotless.Provisioner; + +public class FormatterStepConfig { + + private final Charset encoding; + private final String licenseHeaderDelimiter; + private final Provisioner provisioner; + + public FormatterStepConfig(Charset encoding, String licenseHeaderDelimiter, Provisioner provisioner) { + this.encoding = encoding; + this.licenseHeaderDelimiter = licenseHeaderDelimiter; + this.provisioner = provisioner; + } + + public Charset getEncoding() { + return encoding; + } + + public String getLicenseHeaderDelimiter() { + return licenseHeaderDelimiter; + } + + public Provisioner getProvisioner() { + return provisioner; + } +} diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepFactory.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepFactory.java index d663e9ae75..119aa56961 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepFactory.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepFactory.java @@ -19,5 +19,5 @@ public interface FormatterStepFactory { - FormatterStep newFormatterStep(FormatterFactory parent, MojoConfig mojoConfig); + FormatterStep newFormatterStep(FormatterStepConfig config); } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/LicenseHeader.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/LicenseHeader.java index 3c8280db93..0ce5f14b0b 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/LicenseHeader.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/LicenseHeader.java @@ -21,10 +21,8 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.generic.LicenseHeaderStep; -import com.diffplug.spotless.maven.FormatterFactory; +import com.diffplug.spotless.maven.FormatterStepConfig; import com.diffplug.spotless.maven.FormatterStepFactory; -import com.diffplug.spotless.maven.MojoConfig; -import com.diffplug.spotless.maven.java.Java; public class LicenseHeader implements FormatterStepFactory { @Parameter @@ -37,20 +35,15 @@ public class LicenseHeader implements FormatterStepFactory { private String delimiter; @Override - public FormatterStep newFormatterStep(FormatterFactory parent, MojoConfig mojoConfig) { - String delimiterString; - if (delimiter != null) { - delimiterString = delimiter; - } else { - if (parent instanceof Java) { - delimiterString = "package "; - } else { - throw new IllegalArgumentException("You need to specify 'delimiter'."); - } + public FormatterStep newFormatterStep(FormatterStepConfig config) { + String delimiterString = delimiter != null ? delimiter : config.getLicenseHeaderDelimiter(); + if (delimiterString == null) { + throw new IllegalArgumentException("You need to specify 'delimiter'."); } + if (file != null ^ content != null) { if (file != null) { - return LicenseHeaderStep.createFromFile(file, parent.encoding(mojoConfig), delimiterString); + return LicenseHeaderStep.createFromFile(file, config.getEncoding(), delimiterString); } else { return LicenseHeaderStep.createFromHeader(content, delimiterString); } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Eclipse.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Eclipse.java index f41ba32a1e..7a8dbeb331 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Eclipse.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Eclipse.java @@ -25,9 +25,8 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.extra.java.EclipseFormatterStep; -import com.diffplug.spotless.maven.FormatterFactory; +import com.diffplug.spotless.maven.FormatterStepConfig; import com.diffplug.spotless.maven.FormatterStepFactory; -import com.diffplug.spotless.maven.MojoConfig; public class Eclipse implements FormatterStepFactory { @@ -38,9 +37,9 @@ public class Eclipse implements FormatterStepFactory { private String version; @Override - public FormatterStep newFormatterStep(FormatterFactory parent, MojoConfig mojoConfig) { + public FormatterStep newFormatterStep(FormatterStepConfig config) { String formatterVersion = version == null ? defaultVersion() : version; Set settingsFiles = singleton(file); - return EclipseFormatterStep.create(formatterVersion, settingsFiles, mojoConfig.getProvisioner()); + return EclipseFormatterStep.create(formatterVersion, settingsFiles, config.getProvisioner()); } } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/GoogleJavaFormat.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/GoogleJavaFormat.java index bef4c7077e..afa8f3dedd 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/GoogleJavaFormat.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/GoogleJavaFormat.java @@ -19,17 +19,16 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.java.GoogleJavaFormatStep; -import com.diffplug.spotless.maven.FormatterFactory; +import com.diffplug.spotless.maven.FormatterStepConfig; import com.diffplug.spotless.maven.FormatterStepFactory; -import com.diffplug.spotless.maven.MojoConfig; public class GoogleJavaFormat implements FormatterStepFactory { @Parameter private String version; @Override - public FormatterStep newFormatterStep(FormatterFactory parent, MojoConfig mojoConfig) { + public FormatterStep newFormatterStep(FormatterStepConfig config) { String formatterVersion = version == null ? GoogleJavaFormatStep.defaultVersion() : version; - return GoogleJavaFormatStep.create(formatterVersion, mojoConfig.getProvisioner()); + return GoogleJavaFormatStep.create(formatterVersion, config.getProvisioner()); } } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/ImportOrder.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/ImportOrder.java index 270f45e8f0..3be6897679 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/ImportOrder.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/ImportOrder.java @@ -21,9 +21,8 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.java.ImportOrderStep; -import com.diffplug.spotless.maven.FormatterFactory; +import com.diffplug.spotless.maven.FormatterStepConfig; import com.diffplug.spotless.maven.FormatterStepFactory; -import com.diffplug.spotless.maven.MojoConfig; public class ImportOrder implements FormatterStepFactory { @Parameter @@ -33,7 +32,7 @@ public class ImportOrder implements FormatterStepFactory { private String order; @Override - public FormatterStep newFormatterStep(FormatterFactory parent, MojoConfig mojoConfig) { + public FormatterStep newFormatterStep(FormatterStepConfig config) { if (file != null ^ order != null) { if (file != null) { return ImportOrderStep.createFromFile(file); diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java index 81eacea8de..98b98e3fd5 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java @@ -19,9 +19,15 @@ public class Java extends FormatterFactory { private static final String EXTENSION = "java"; + private static final String LICENSE_HEADER_DELIMITER = "package "; @Override public String fileExtension() { return EXTENSION; } + + @Override + public String licenseHeaderDelimiter() { + return LICENSE_HEADER_DELIMITER; + } } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/RemoveUnusedImports.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/RemoveUnusedImports.java index b447b23c01..54fd30a167 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/RemoveUnusedImports.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/RemoveUnusedImports.java @@ -17,14 +17,13 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.java.RemoveUnusedImportsStep; -import com.diffplug.spotless.maven.FormatterFactory; +import com.diffplug.spotless.maven.FormatterStepConfig; import com.diffplug.spotless.maven.FormatterStepFactory; -import com.diffplug.spotless.maven.MojoConfig; public class RemoveUnusedImports implements FormatterStepFactory { @Override - public FormatterStep newFormatterStep(FormatterFactory parent, MojoConfig mojoConfig) { - return RemoveUnusedImportsStep.create(mojoConfig.getProvisioner()); + public FormatterStep newFormatterStep(FormatterStepConfig config) { + return RemoveUnusedImportsStep.create(config.getProvisioner()); } } From d95f76d2088a0aab3e987fb2a92f6622b8a2e2a2 Mon Sep 17 00:00:00 2001 From: lutovich Date: Sat, 27 Jan 2018 20:44:04 +0100 Subject: [PATCH 42/91] Allow multiple file extension for formatters Previously each `FormatterFactory` had to return only a single extension. This worked fine for Java but does not hold for other languages, like Scala. --- .../spotless/maven/AbstractSpotlessMojo.java | 20 ++++++++++++------- .../spotless/maven/FormatterFactory.java | 3 ++- .../diffplug/spotless/maven/java/Java.java | 8 ++++++-- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java index 5c1f512e26..3654a5350f 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java @@ -25,6 +25,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; +import java.util.Set; import java.util.stream.Stream; import org.apache.maven.plugin.AbstractMojo; @@ -87,15 +88,15 @@ public final void execute() throws MojoExecutionException, MojoFailureException } private void execute(FormatterFactory formatterFactory) throws MojoExecutionException { - List files = collectFiles(formatterFactory.fileExtension()); + List files = collectFiles(formatterFactory.fileExtensions()); Formatter formatter = formatterFactory.newFormatter(files, getFormatterConfig()); process(files, formatter); } - private List collectFiles(String extension) throws MojoExecutionException { + private List collectFiles(Set extensions) throws MojoExecutionException { try { return getAllSourceRoots().stream() - .flatMap(root -> collectFiles(root, extension).stream()) + .flatMap(root -> collectFiles(root, extensions).stream()) .map(Path::toFile) .collect(toList()); } catch (Exception e) { @@ -103,23 +104,28 @@ private List collectFiles(String extension) throws MojoExecutionException } } - private static List collectFiles(Path root, String extension) { + private static List collectFiles(Path root, Set extensions) { try (Stream entries = Files.walk(root)) { return entries.filter(Files::isRegularFile) - .filter(file -> hasExtension(file, extension)) + .filter(file -> hasExtension(file, extensions)) .collect(toList()); } catch (IOException e) { throw new UncheckedIOException("Unable to walk the file tree rooted at " + root, e); } } - private static boolean hasExtension(Path file, String extension) { + private static boolean hasExtension(Path file, Set extensions) { Path fileName = file.getFileName(); if (fileName == null) { return false; } else { String fileNameString = fileName.toString(); - return fileNameString.endsWith(FILE_EXTENSION_SEPARATOR + extension); + for (String extension : extensions) { + if (fileNameString.endsWith(FILE_EXTENSION_SEPARATOR + extension)) { + return true; + } + } + return false; } } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java index c97b8010f6..057b19d91d 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java @@ -21,6 +21,7 @@ import java.nio.charset.Charset; import java.util.List; import java.util.Objects; +import java.util.Set; import org.apache.maven.plugins.annotations.Parameter; @@ -39,7 +40,7 @@ public abstract class FormatterFactory { @Parameter protected List steps; - public abstract String fileExtension(); + public abstract Set fileExtensions(); public abstract String licenseHeaderDelimiter(); diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java index 98b98e3fd5..14ac9bac61 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java @@ -15,6 +15,10 @@ */ package com.diffplug.spotless.maven.java; +import static java.util.Collections.singleton; + +import java.util.Set; + import com.diffplug.spotless.maven.FormatterFactory; public class Java extends FormatterFactory { @@ -22,8 +26,8 @@ public class Java extends FormatterFactory { private static final String LICENSE_HEADER_DELIMITER = "package "; @Override - public String fileExtension() { - return EXTENSION; + public Set fileExtensions() { + return singleton(EXTENSION); } @Override From 4f2952c20ed5f31bab36b3543a2f845b3586eccb Mon Sep 17 00:00:00 2001 From: lutovich Date: Sun, 28 Jan 2018 19:47:27 +0100 Subject: [PATCH 43/91] Made spotless mojo scan for files starting at basedir Maven by default allows only a single compile root dir. Plugins can add more or override at runtime but by default it's only `src/main/java`. When single plugin goal, like `spotless:check` is executed this single source root is what it can access. Previously spotless mojo scanned only compile source roots. This made it only see java files. It wasn't able to see for example scala files that usually live at `src/main/scala`. This happened because `src/main/scala` source root can be added by other plugins (like scala-maven-plugin http://davidb.github.io/scala-maven-plugin/add-source-mojo.html) and such plugins are not executed when single spotless mojo is invoked. This commit makes spotless mojo start scanning files from project root directory. It will only skip `target` directory right now. --- .../spotless/maven/AbstractSpotlessMojo.java | 36 +++++-------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java index 3654a5350f..dd4a6269f7 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java @@ -20,10 +20,8 @@ import java.io.File; import java.io.IOException; -import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.List; import java.util.Set; import java.util.stream.Stream; @@ -61,11 +59,8 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo { @Parameter(defaultValue = "${project.basedir}", required = true, readonly = true) private File baseDir; - @Parameter(defaultValue = "${project.compileSourceRoots}", required = true, readonly = true) - private List compileSourceRoots; - - @Parameter(defaultValue = "${project.testCompileSourceRoots}", required = true, readonly = true) - private List testCompileSourceRoots; + @Parameter(defaultValue = "${project.build.directory}", required = true, readonly = true) + private File targetDir; @Parameter(defaultValue = DEFAULT_ENCODING) private String encoding; @@ -94,23 +89,17 @@ private void execute(FormatterFactory formatterFactory) throws MojoExecutionExce } private List collectFiles(Set extensions) throws MojoExecutionException { - try { - return getAllSourceRoots().stream() - .flatMap(root -> collectFiles(root, extensions).stream()) - .map(Path::toFile) - .collect(toList()); - } catch (Exception e) { - throw new MojoExecutionException("Unable to collect files to format", e); - } - } + Path projectDir = baseDir.toPath(); + Path outputDir = targetDir.toPath(); - private static List collectFiles(Path root, Set extensions) { - try (Stream entries = Files.walk(root)) { - return entries.filter(Files::isRegularFile) + try (Stream entries = Files.walk(projectDir)) { + return entries.filter(entry -> !entry.startsWith(outputDir)) + .filter(Files::isRegularFile) .filter(file -> hasExtension(file, extensions)) + .map(Path::toFile) .collect(toList()); } catch (IOException e) { - throw new UncheckedIOException("Unable to walk the file tree rooted at " + root, e); + throw new MojoExecutionException("Unable to walk the file tree rooted at " + projectDir, e); } } @@ -129,13 +118,6 @@ private static boolean hasExtension(Path file, Set extensions) { } } - private List getAllSourceRoots() { - return Stream.concat(compileSourceRoots.stream(), testCompileSourceRoots.stream()) - .map(Paths::get) - .filter(Files::isDirectory) - .collect(toList()); - } - private FormatterConfig getFormatterConfig() { ArtifactResolver resolver = new ArtifactResolver(repositorySystem, repositorySystemSession, repositories, getLog()); Provisioner provisioner = MavenProvisioner.create(resolver); From 1d82ba9f17cd21d9b96d4c2ee4e679f6612cee78 Mon Sep 17 00:00:00 2001 From: lutovich Date: Sun, 28 Jan 2018 20:06:30 +0100 Subject: [PATCH 44/91] Added scalafmt step It allows scalafmt version and configuration file to be configured. --- .../spotless/maven/AbstractSpotlessMojo.java | 12 +++-- .../diffplug/spotless/maven/scala/Scala.java | 39 ++++++++++++++ .../spotless/maven/scala/Scalafmt.java | 40 +++++++++++++++ .../spotless/maven/MavenIntegrationTest.java | 26 +++++++--- .../spotless/maven/scala/ScalafmtTest.java | 51 +++++++++++++++++++ .../src/test/resources/pom.xml.mustache | 10 +--- .../test/resources/scala/scalafmt/basic.clean | 16 ++++++ .../scala/scalafmt/basic.cleanWithCustomConf | 24 +++++++++ .../test/resources/scala/scalafmt/basic.dirty | 21 ++++++++ .../resources/scala/scalafmt/scalafmt.conf | 2 + 10 files changed, 221 insertions(+), 20 deletions(-) create mode 100644 plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scala.java create mode 100644 plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scalafmt.java create mode 100644 plugin-maven/src/test/java/com/diffplug/spotless/maven/scala/ScalafmtTest.java create mode 100644 plugin-maven/src/test/resources/scala/scalafmt/basic.clean create mode 100644 plugin-maven/src/test/resources/scala/scalafmt/basic.cleanWithCustomConf create mode 100644 plugin-maven/src/test/resources/scala/scalafmt/basic.dirty create mode 100644 plugin-maven/src/test/resources/scala/scalafmt/scalafmt.conf diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java index dd4a6269f7..f574ac0ee7 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java @@ -15,13 +15,13 @@ */ package com.diffplug.spotless.maven; -import static java.util.Collections.singletonList; import static java.util.stream.Collectors.toList; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.stream.Stream; @@ -39,6 +39,7 @@ import com.diffplug.spotless.LineEnding; import com.diffplug.spotless.Provisioner; import com.diffplug.spotless.maven.java.Java; +import com.diffplug.spotless.maven.scala.Scala; public abstract class AbstractSpotlessMojo extends AbstractMojo { @@ -71,14 +72,19 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo { @Parameter private Java java; + @Parameter + private Scala scala; + protected abstract void process(List files, Formatter formatter) throws MojoExecutionException; @Override public final void execute() throws MojoExecutionException, MojoFailureException { - List formatterFactories = singletonList(java); + List formatterFactories = Arrays.asList(java, scala); for (FormatterFactory formatterFactory : formatterFactories) { - execute(formatterFactory); + if (formatterFactory != null) { + execute(formatterFactory); + } } } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scala.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scala.java new file mode 100644 index 0000000000..32b13267b9 --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scala.java @@ -0,0 +1,39 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.spotless.maven.scala; + +import static com.diffplug.common.collect.Sets.newHashSet; +import static java.util.Collections.unmodifiableSet; + +import java.util.Set; + +import com.diffplug.spotless.maven.FormatterFactory; + +public class Scala extends FormatterFactory { + + private static final Set FILE_EXTENSIONS = unmodifiableSet(newHashSet("scala", "sc")); + private static final String LICENSE_HEADER_DELIMITER = "package "; + + @Override + public Set fileExtensions() { + return FILE_EXTENSIONS; + } + + @Override + public String licenseHeaderDelimiter() { + return LICENSE_HEADER_DELIMITER; + } +} diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scalafmt.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scalafmt.java new file mode 100644 index 0000000000..ce28bd4813 --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scalafmt.java @@ -0,0 +1,40 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.spotless.maven.scala; + +import java.io.File; + +import org.apache.maven.plugins.annotations.Parameter; + +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.maven.FormatterStepConfig; +import com.diffplug.spotless.maven.FormatterStepFactory; +import com.diffplug.spotless.scala.ScalaFmtStep; + +public class Scalafmt implements FormatterStepFactory { + + @Parameter + private File file; + + @Parameter + private String version; + + @Override + public FormatterStep newFormatterStep(FormatterStepConfig config) { + String scalafmtVersion = version != null ? version : ScalaFmtStep.defaultVersion(); + return ScalaFmtStep.create(scalafmtVersion, config.getProvisioner(), file); + } +} diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java index d70af1dc5f..e44ba7f9a8 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java @@ -41,7 +41,7 @@ public class MavenIntegrationTest extends ResourceHarness { private static final String LOCAL_MAVEN_REPOSITORY_DIR = "localMavenRepositoryDir"; private static final String SPOTLESS_MAVEN_PLUGIN_VERSION = "spotlessMavenPluginVersion"; - private static final String JAVA_CONFIGURATION = "javaConfiguration"; + private static final String CONFIGURATION = "configuration"; private final MustacheFactory mustacheFactory = new DefaultMustacheFactory(); @@ -65,8 +65,11 @@ public void gitAttributes() throws IOException { } protected void writePomWithJavaSteps(String... steps) throws IOException { - String pomXmlContent = createPomXmlContent(steps); - write("pom.xml", pomXmlContent); + writePomWithSteps("java", steps); + } + + protected void writePomWithScalaSteps(String... steps) throws IOException { + writePomWithSteps("scala", steps); } protected MavenRunner mavenRunner() throws IOException { @@ -74,25 +77,32 @@ protected MavenRunner mavenRunner() throws IOException { .withProjectDir(rootFolder()); } - private String createPomXmlContent(String... steps) throws IOException { + private void writePomWithSteps(String group, String... steps) throws IOException { + String pomXmlContent = createPomXmlContent(group, steps); + write("pom.xml", pomXmlContent); + } + + private String createPomXmlContent(String group, String... steps) throws IOException { Path pomXml = Paths.get("src", "test", "resources", "pom.xml.mustache"); try (BufferedReader reader = Files.newBufferedReader(pomXml)) { Mustache mustache = mustacheFactory.compile(reader, "pom"); StringWriter writer = new StringWriter(); - Map params = buildPomXmlParams(steps); + Map params = buildPomXmlParams(group, steps); mustache.execute(writer, params); return writer.toString(); } } - private static Map buildPomXmlParams(String... steps) { + private static Map buildPomXmlParams(String group, String... steps) { Map params = new HashMap<>(); params.put(LOCAL_MAVEN_REPOSITORY_DIR, getSystemProperty(LOCAL_MAVEN_REPOSITORY_DIR)); params.put(SPOTLESS_MAVEN_PLUGIN_VERSION, getSystemProperty(SPOTLESS_MAVEN_PLUGIN_VERSION)); - String stepsXml = Arrays.stream(steps).collect(joining("\n", "\n", "\n")); - params.put(JAVA_CONFIGURATION, stepsXml); + String prefix = String.format("<%s>\n\n", group); + String suffix = String.format("\n\n", group); + String stepsXml = Arrays.stream(steps).collect(joining("\n", prefix, suffix)); + params.put(CONFIGURATION, stepsXml); return params; } diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/scala/ScalafmtTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/scala/ScalafmtTest.java new file mode 100644 index 0000000000..b9a4c85e8a --- /dev/null +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/scala/ScalafmtTest.java @@ -0,0 +1,51 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.spotless.maven.scala; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; + +import com.diffplug.spotless.maven.MavenIntegrationTest; + +public class ScalafmtTest extends MavenIntegrationTest { + + @Test + public void testScalafmtWithDefaultConfig() throws Exception { + writePomWithScalaSteps(""); + + write("src/main/scala/test.scala", getTestResource("scala/scalafmt/basic.dirty")); + mavenRunner().withArguments("spotless:apply").runNoError(); + + String actual = read("src/main/scala/test.scala"); + assertThat(actual).isEqualTo(getTestResource("scala/scalafmt/basic.clean")); + } + + @Test + public void testScalafmtWithCustomConfig() throws Exception { + writePomWithScalaSteps( + "", + " ${project.basedir}/scalafmt.conf", + ""); + + write("src/main/scala/test.scala", getTestResource("scala/scalafmt/basic.dirty")); + write("scalafmt.conf", getTestResource("scala/scalafmt/scalafmt.conf")); + mavenRunner().withArguments("spotless:apply").runNoError(); + + String actual = read("src/main/scala/test.scala"); + assertThat(actual).isEqualTo(getTestResource("scala/scalafmt/basic.cleanWithCustomConf")); + } +} diff --git a/plugin-maven/src/test/resources/pom.xml.mustache b/plugin-maven/src/test/resources/pom.xml.mustache index 9410301bd5..d24c7e3975 100644 --- a/plugin-maven/src/test/resources/pom.xml.mustache +++ b/plugin-maven/src/test/resources/pom.xml.mustache @@ -36,15 +36,7 @@ spotless-maven-plugin {{spotlessMavenPluginVersion}} - {{#pluginConfiguration}} - {{{pluginConfiguration}}} - {{/pluginConfiguration}} - - {{#javaConfiguration}} - - {{{javaConfiguration}}} - - {{/javaConfiguration}} + {{{configuration}}} diff --git a/plugin-maven/src/test/resources/scala/scalafmt/basic.clean b/plugin-maven/src/test/resources/scala/scalafmt/basic.clean new file mode 100644 index 0000000000..922a2ccbb9 --- /dev/null +++ b/plugin-maven/src/test/resources/scala/scalafmt/basic.clean @@ -0,0 +1,16 @@ +@foobar("annot", { + val x = 2 + val y = 2 // y=2 + x + y +}) +object a extends b with c { + def foo[T: Int#Double#Triple, R <% String](@annot1 + x: Int @annot2 = 2, + y: Int = 3): Int = { + "match" match { + case 1 | 2 => + 3 + case 2 => 2 + } + } +} diff --git a/plugin-maven/src/test/resources/scala/scalafmt/basic.cleanWithCustomConf b/plugin-maven/src/test/resources/scala/scalafmt/basic.cleanWithCustomConf new file mode 100644 index 0000000000..98bf69b7af --- /dev/null +++ b/plugin-maven/src/test/resources/scala/scalafmt/basic.cleanWithCustomConf @@ -0,0 +1,24 @@ +@foobar("annot", { + val x = 2 + val y = 2 // y=2 + x + y +}) +object a + extends b + with c { + def foo[ + T: Int#Double#Triple, + R <% String]( + @annot1 + x: Int @annot2 = + 2, + y: Int = 3) + : Int = { + "match" match { + case 1 | 2 => + 3 + case 2 => + 2 + } + } +} diff --git a/plugin-maven/src/test/resources/scala/scalafmt/basic.dirty b/plugin-maven/src/test/resources/scala/scalafmt/basic.dirty new file mode 100644 index 0000000000..2844c84555 --- /dev/null +++ b/plugin-maven/src/test/resources/scala/scalafmt/basic.dirty @@ -0,0 +1,21 @@ +@ foobar("annot", { + val x = 2 + val y = 2 // y=2 + x + y +}) + object + a extends b with c { + def + foo[T:Int#Double#Triple, + R <% String]( + @annot1 + x + : Int @annot2 = 2 + , y: Int = 3): Int = { + "match" match { + case 1 | 2 => + 3 + case 2 => 2 + } + } +} \ No newline at end of file diff --git a/plugin-maven/src/test/resources/scala/scalafmt/scalafmt.conf b/plugin-maven/src/test/resources/scala/scalafmt/scalafmt.conf new file mode 100644 index 0000000000..5007f5e8ff --- /dev/null +++ b/plugin-maven/src/test/resources/scala/scalafmt/scalafmt.conf @@ -0,0 +1,2 @@ +style = defaultWithAlign # For pretty alignment. +maxColumn = 20 # For my teensy narrow display From 4b34991469ba3f408a1e0d7cf4491b0e4e786c94 Mon Sep 17 00:00:00 2001 From: lutovich Date: Sun, 28 Jan 2018 21:54:25 +0100 Subject: [PATCH 45/91] Fixed license header tests They were previously not executed because of missing `@Test` annotation. When enabled, they failed because maven was not able to find `LicenseHeader` implementation. Looks like Maven is only able to locate classes for injection when they live in the same package or in subpackages of the current package. For example step `Java` lives in package `com.diffplug.spotless.maven.java` and to be able to inject implementation of `licenseHeader` step it should also live in `com.diffplug.spotless.maven.java` or any of it's subpackages, like `com.diffplug.spotless.maven.java.hello`. This commit makes generic license header an abstract class and adds implementor for Java in the correct package. Such implementations are now also responsible for default delimiter. This feels cleaner than putting delimiter in `FormatterFactory` implementations. --- .../spotless/maven/FormatterFactory.java | 6 ++-- .../spotless/maven/FormatterStepConfig.java | 8 +----- ...Header.java => AbstractLicenseHeader.java} | 14 ++++++++-- .../diffplug/spotless/maven/java/Java.java | 6 ---- .../spotless/maven/java/LicenseHeader.java | 28 +++++++++++++++++++ .../diffplug/spotless/maven/scala/Scala.java | 6 ---- .../maven/generic/LicenseHeaderTest.java | 9 ++++-- .../resources/license/MissingLicense.test | 2 +- 8 files changed, 49 insertions(+), 30 deletions(-) rename plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/{LicenseHeader.java => AbstractLicenseHeader.java} (71%) create mode 100644 plugin-maven/src/main/java/com/diffplug/spotless/maven/java/LicenseHeader.java diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java index 057b19d91d..87c37ef785 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java @@ -42,8 +42,6 @@ public abstract class FormatterFactory { public abstract Set fileExtensions(); - public abstract String licenseHeaderDelimiter(); - public final Formatter newFormatter(List filesToFormat, FormatterConfig config) { Charset formatterEncoding = encoding(config); LineEnding formatterLineEndings = lineEndings(config); @@ -73,7 +71,7 @@ private LineEnding lineEndings(FormatterConfig config) { return lineEndings == null ? config.getLineEndings() : lineEndings; } - private FormatterStepConfig stepConfig(Charset encoding, FormatterConfig config) { - return new FormatterStepConfig(encoding, licenseHeaderDelimiter(), config.getProvisioner()); + private static FormatterStepConfig stepConfig(Charset encoding, FormatterConfig config) { + return new FormatterStepConfig(encoding, config.getProvisioner()); } } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepConfig.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepConfig.java index 0a2fbde018..03599ec362 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepConfig.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepConfig.java @@ -22,12 +22,10 @@ public class FormatterStepConfig { private final Charset encoding; - private final String licenseHeaderDelimiter; private final Provisioner provisioner; - public FormatterStepConfig(Charset encoding, String licenseHeaderDelimiter, Provisioner provisioner) { + public FormatterStepConfig(Charset encoding, Provisioner provisioner) { this.encoding = encoding; - this.licenseHeaderDelimiter = licenseHeaderDelimiter; this.provisioner = provisioner; } @@ -35,10 +33,6 @@ public Charset getEncoding() { return encoding; } - public String getLicenseHeaderDelimiter() { - return licenseHeaderDelimiter; - } - public Provisioner getProvisioner() { return provisioner; } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/LicenseHeader.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/AbstractLicenseHeader.java similarity index 71% rename from plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/LicenseHeader.java rename to plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/AbstractLicenseHeader.java index 0ce5f14b0b..7021747cda 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/LicenseHeader.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/AbstractLicenseHeader.java @@ -21,10 +21,16 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.generic.LicenseHeaderStep; +import com.diffplug.spotless.maven.FormatterFactory; import com.diffplug.spotless.maven.FormatterStepConfig; import com.diffplug.spotless.maven.FormatterStepFactory; -public class LicenseHeader implements FormatterStepFactory { +/** + * Base class for license header formatting. + * Implementations should be located in the same package tree as the implementation of {@link FormatterFactory}. + * It is important because Maven's parameter injection framework looks for implementations in the same package tree. + */ +public abstract class AbstractLicenseHeader implements FormatterStepFactory { @Parameter private File file; @@ -34,9 +40,11 @@ public class LicenseHeader implements FormatterStepFactory { @Parameter private String delimiter; + protected abstract String defaultDelimiter(); + @Override - public FormatterStep newFormatterStep(FormatterStepConfig config) { - String delimiterString = delimiter != null ? delimiter : config.getLicenseHeaderDelimiter(); + public final FormatterStep newFormatterStep(FormatterStepConfig config) { + String delimiterString = delimiter != null ? delimiter : defaultDelimiter(); if (delimiterString == null) { throw new IllegalArgumentException("You need to specify 'delimiter'."); } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java index 14ac9bac61..81da753d11 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java @@ -23,15 +23,9 @@ public class Java extends FormatterFactory { private static final String EXTENSION = "java"; - private static final String LICENSE_HEADER_DELIMITER = "package "; @Override public Set fileExtensions() { return singleton(EXTENSION); } - - @Override - public String licenseHeaderDelimiter() { - return LICENSE_HEADER_DELIMITER; - } } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/LicenseHeader.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/LicenseHeader.java new file mode 100644 index 0000000000..5dbe3c5a1f --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/LicenseHeader.java @@ -0,0 +1,28 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.spotless.maven.java; + +import com.diffplug.spotless.maven.generic.AbstractLicenseHeader; + +public class LicenseHeader extends AbstractLicenseHeader { + + private static final String DELIMITER = "package "; + + @Override + protected String defaultDelimiter() { + return DELIMITER; + } +} diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scala.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scala.java index 32b13267b9..802c34c874 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scala.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scala.java @@ -25,15 +25,9 @@ public class Scala extends FormatterFactory { private static final Set FILE_EXTENSIONS = unmodifiableSet(newHashSet("scala", "sc")); - private static final String LICENSE_HEADER_DELIMITER = "package "; @Override public Set fileExtensions() { return FILE_EXTENSIONS; } - - @Override - public String licenseHeaderDelimiter() { - return LICENSE_HEADER_DELIMITER; - } } diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/generic/LicenseHeaderTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/generic/LicenseHeaderTest.java index eb28e37db4..80986d0311 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/generic/LicenseHeaderTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/generic/LicenseHeaderTest.java @@ -17,22 +17,25 @@ import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + import com.diffplug.spotless.maven.MavenIntegrationTest; public class LicenseHeaderTest extends MavenIntegrationTest { private static final String KEY_LICENSE = "license/TestLicense"; + @Test public void fromFile() throws Exception { - write("license.java", getTestResource(KEY_LICENSE)); + write("license.txt", getTestResource(KEY_LICENSE)); writePomWithJavaSteps( "", - " ${basedir}/license.java", + " ${basedir}/license.txt", ""); runTest(); } + @Test public void fromContent() throws Exception { - write("license.java", getTestResource(KEY_LICENSE)); writePomWithJavaSteps( "", " ", diff --git a/plugin-maven/src/test/resources/license/MissingLicense.test b/plugin-maven/src/test/resources/license/MissingLicense.test index 38f9541b2c..c81a2412b7 100644 --- a/plugin-maven/src/test/resources/license/MissingLicense.test +++ b/plugin-maven/src/test/resources/license/MissingLicense.test @@ -25,4 +25,4 @@ public class Java8Test { public enum SimpleEnum { A, B, C; } -} +} \ No newline at end of file From 7db3759157d97300f1e82383c94a0de64063a8ed Mon Sep 17 00:00:00 2001 From: lutovich Date: Sun, 28 Jan 2018 23:32:13 +0100 Subject: [PATCH 46/91] Mark check and apply MOJOs as thread safe They do not keep any internal state. Every field is injected by Maven. --- .../java/com/diffplug/spotless/maven/SpotlessApplyMojo.java | 2 +- .../java/com/diffplug/spotless/maven/SpotlessCheckMojo.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessApplyMojo.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessApplyMojo.java index 42b5eda7ea..99c04d55f6 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessApplyMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessApplyMojo.java @@ -24,7 +24,7 @@ import com.diffplug.spotless.Formatter; -@Mojo(name = "apply") +@Mojo(name = "apply", threadSafe = true) public class SpotlessApplyMojo extends AbstractSpotlessMojo { @Override diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java index 8abba5c9fa..ebe99154b9 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java @@ -26,7 +26,7 @@ import com.diffplug.spotless.Formatter; import com.diffplug.spotless.extra.integration.DiffMessageFormatter; -@Mojo(name = "check") +@Mojo(name = "check", threadSafe = true) public class SpotlessCheckMojo extends AbstractSpotlessMojo { @Override From d8258bd658a2d299f8c9cb812ba37cfe35090406 Mon Sep 17 00:00:00 2001 From: lutovich Date: Tue, 30 Jan 2018 23:13:31 +0100 Subject: [PATCH 47/91] Removed need for "" config element And need to restructure packages. Turns out Maven (underlying Eclipse sisu container) requires injected classes be in the same package as the class that's being configured. That's only in case of direct field injection. With setter/adder is class can be in any package because it's `Class` will be determined based on the type of setter/adder parameter. It is also guaraneteed that setters and adders will be invoked in the order of corresponding xml elements. This removes the need for `` and makes it possible to place classes in nice packages. One drawback is that explicit adder methods are required. At the same time they provide an ability to explicitly define which steps are supported for the given formatter. This makes error messages a bit prettier when for example "googleJavaFormat" is configured for Scala. Eclipse sisu doc for adder/setter: https://www.eclipse.org/sisu/docs/api/org.eclipse.sisu.plexus/reference/org/eclipse/sisu/plexus/CompositeBeanHelper.html --- plugin-maven/README.md | 56 +++++++++---------- .../spotless/maven/FormatterFactory.java | 21 ++++--- .../spotless/maven/FormatterStepConfig.java | 8 ++- ...tLicenseHeader.java => LicenseHeader.java} | 12 +--- .../diffplug/spotless/maven/java/Java.java | 27 +++++++++ .../spotless/maven/java/LicenseHeader.java | 28 ---------- .../diffplug/spotless/maven/scala/Scala.java | 16 +++++- .../spotless/maven/MavenIntegrationTest.java | 4 +- 8 files changed, 93 insertions(+), 79 deletions(-) rename plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/{AbstractLicenseHeader.java => LicenseHeader.java} (74%) delete mode 100644 plugin-maven/src/main/java/com/diffplug/spotless/maven/java/LicenseHeader.java diff --git a/plugin-maven/README.md b/plugin-maven/README.md index d8af9caadc..c9926a8692 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -58,12 +58,10 @@ To use it in your pom, just [add the Spotless dependency](http://search.maven.or ${spotless.version} - - - ${basedir}/eclipse-fmt.xml - 4.7.1 - - + + ${basedir}/eclipse-fmt.xml + 4.7.1 + @@ -88,28 +86,26 @@ By default, all compileSourceRoots will be formatted. Each element under ` - - - - /* Licensed under Apache-2.0 */ - ${basedir}/license-header - - - ${basedir}/eclipse-fmt.xml - - 4.7.1 - - - - 1.5 - - - - - java,javax,org,com,com.diffplug, - ${basedir}/importOrder - - + + + /* Licensed under Apache-2.0 */ + ${basedir}/license-header + + + ${basedir}/eclipse-fmt.xml + + 4.7.1 + + + + 1.5 + + + + + java,javax,org,com,com.diffplug, + ${basedir}/importOrder + ``` @@ -120,11 +116,11 @@ By default, all compileSourceRoots will be formatted. Each element under ` Cp1252 - ... + US-ASCII diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java index 87c37ef785..aef9e27ad3 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java @@ -19,6 +19,7 @@ import java.io.File; import java.nio.charset.Charset; +import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Set; @@ -32,16 +33,17 @@ public abstract class FormatterFactory { @Parameter - protected String encoding; + private String encoding; @Parameter - protected LineEnding lineEndings; + private LineEnding lineEndings; - @Parameter - protected List steps; + private final List stepFactories = new ArrayList<>(); public abstract Set fileExtensions(); + public abstract String licenseHeaderDelimiter(); + public final Formatter newFormatter(List filesToFormat, FormatterConfig config) { Charset formatterEncoding = encoding(config); LineEnding formatterLineEndings = lineEndings(config); @@ -49,7 +51,7 @@ public final Formatter newFormatter(List filesToFormat, FormatterConfig co FormatterStepConfig stepConfig = stepConfig(formatterEncoding, config); - List formatterSteps = steps.stream() + List formatterSteps = stepFactories.stream() .filter(Objects::nonNull) // all unrecognized steps from XML config appear as nulls in the list .map(factory -> factory.newFormatterStep(stepConfig)) .collect(toList()); @@ -63,6 +65,11 @@ public final Formatter newFormatter(List filesToFormat, FormatterConfig co .build(); } + protected void addStepFactory(FormatterStepFactory stepFactory) { + Objects.requireNonNull(stepFactory); + stepFactories.add(stepFactory); + } + private Charset encoding(FormatterConfig config) { return Charset.forName(encoding == null ? config.getEncoding() : encoding); } @@ -71,7 +78,7 @@ private LineEnding lineEndings(FormatterConfig config) { return lineEndings == null ? config.getLineEndings() : lineEndings; } - private static FormatterStepConfig stepConfig(Charset encoding, FormatterConfig config) { - return new FormatterStepConfig(encoding, config.getProvisioner()); + private FormatterStepConfig stepConfig(Charset encoding, FormatterConfig config) { + return new FormatterStepConfig(encoding, licenseHeaderDelimiter(), config.getProvisioner()); } } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepConfig.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepConfig.java index 03599ec362..0a2fbde018 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepConfig.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepConfig.java @@ -22,10 +22,12 @@ public class FormatterStepConfig { private final Charset encoding; + private final String licenseHeaderDelimiter; private final Provisioner provisioner; - public FormatterStepConfig(Charset encoding, Provisioner provisioner) { + public FormatterStepConfig(Charset encoding, String licenseHeaderDelimiter, Provisioner provisioner) { this.encoding = encoding; + this.licenseHeaderDelimiter = licenseHeaderDelimiter; this.provisioner = provisioner; } @@ -33,6 +35,10 @@ public Charset getEncoding() { return encoding; } + public String getLicenseHeaderDelimiter() { + return licenseHeaderDelimiter; + } + public Provisioner getProvisioner() { return provisioner; } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/AbstractLicenseHeader.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/LicenseHeader.java similarity index 74% rename from plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/AbstractLicenseHeader.java rename to plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/LicenseHeader.java index 7021747cda..aa9317616e 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/AbstractLicenseHeader.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/LicenseHeader.java @@ -21,16 +21,10 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.generic.LicenseHeaderStep; -import com.diffplug.spotless.maven.FormatterFactory; import com.diffplug.spotless.maven.FormatterStepConfig; import com.diffplug.spotless.maven.FormatterStepFactory; -/** - * Base class for license header formatting. - * Implementations should be located in the same package tree as the implementation of {@link FormatterFactory}. - * It is important because Maven's parameter injection framework looks for implementations in the same package tree. - */ -public abstract class AbstractLicenseHeader implements FormatterStepFactory { +public class LicenseHeader implements FormatterStepFactory { @Parameter private File file; @@ -40,11 +34,9 @@ public abstract class AbstractLicenseHeader implements FormatterStepFactory { @Parameter private String delimiter; - protected abstract String defaultDelimiter(); - @Override public final FormatterStep newFormatterStep(FormatterStepConfig config) { - String delimiterString = delimiter != null ? delimiter : defaultDelimiter(); + String delimiterString = delimiter != null ? delimiter : config.getLicenseHeaderDelimiter(); if (delimiterString == null) { throw new IllegalArgumentException("You need to specify 'delimiter'."); } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java index 81da753d11..8f9f4fb582 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java @@ -20,12 +20,39 @@ import java.util.Set; import com.diffplug.spotless.maven.FormatterFactory; +import com.diffplug.spotless.maven.generic.LicenseHeader; public class Java extends FormatterFactory { private static final String EXTENSION = "java"; + private static final String LICENSE_HEADER_DELIMITER = "package "; @Override public Set fileExtensions() { return singleton(EXTENSION); } + + @Override + public String licenseHeaderDelimiter() { + return LICENSE_HEADER_DELIMITER; + } + + public void addLicenseHeader(LicenseHeader licenseHeader) { + addStepFactory(licenseHeader); + } + + public void addEclipse(Eclipse eclipse) { + addStepFactory(eclipse); + } + + public void addGoogleJavaFormat(GoogleJavaFormat googleJavaFormat) { + addStepFactory(googleJavaFormat); + } + + public void addImportOrder(ImportOrder importOrder) { + addStepFactory(importOrder); + } + + public void addRemoveUnusedImports(RemoveUnusedImports removeUnusedImports) { + addStepFactory(removeUnusedImports); + } } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/LicenseHeader.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/LicenseHeader.java deleted file mode 100644 index 5dbe3c5a1f..0000000000 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/LicenseHeader.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2016 DiffPlug - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.diffplug.spotless.maven.java; - -import com.diffplug.spotless.maven.generic.AbstractLicenseHeader; - -public class LicenseHeader extends AbstractLicenseHeader { - - private static final String DELIMITER = "package "; - - @Override - protected String defaultDelimiter() { - return DELIMITER; - } -} diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scala.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scala.java index 802c34c874..e1df191946 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scala.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scala.java @@ -21,13 +21,27 @@ import java.util.Set; import com.diffplug.spotless.maven.FormatterFactory; +import com.diffplug.spotless.maven.generic.LicenseHeader; public class Scala extends FormatterFactory { - private static final Set FILE_EXTENSIONS = unmodifiableSet(newHashSet("scala", "sc")); + private static final String LICENSE_HEADER_DELIMITER = "package "; @Override public Set fileExtensions() { return FILE_EXTENSIONS; } + + @Override + public String licenseHeaderDelimiter() { + return LICENSE_HEADER_DELIMITER; + } + + public void addLicenseHeader(LicenseHeader licenseHeader) { + addStepFactory(licenseHeader); + } + + public void addScalafmt(Scalafmt scalafmt) { + addStepFactory(scalafmt); + } } diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java index e44ba7f9a8..163ac891ab 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java @@ -99,8 +99,8 @@ private static Map buildPomXmlParams(String group, String... ste params.put(LOCAL_MAVEN_REPOSITORY_DIR, getSystemProperty(LOCAL_MAVEN_REPOSITORY_DIR)); params.put(SPOTLESS_MAVEN_PLUGIN_VERSION, getSystemProperty(SPOTLESS_MAVEN_PLUGIN_VERSION)); - String prefix = String.format("<%s>\n\n", group); - String suffix = String.format("\n\n", group); + String prefix = String.format("<%s>\n", group); + String suffix = String.format("\n", group); String stepsXml = Arrays.stream(steps).collect(joining("\n", prefix, suffix)); params.put(CONFIGURATION, stepsXml); From a8de57d78d91ebfad6b192293d5f0a61dacf5e07 Mon Sep 17 00:00:00 2001 From: lutovich Date: Tue, 30 Jan 2018 23:47:50 +0100 Subject: [PATCH 48/91] Added property to skip 'spotless:check' Property is `spotless.check.skip` and takes a boolean value. Can either be specified in POM `` section or in command like like `-Dspotless.check.skip=true`. --- .../spotless/maven/SpotlessCheckMojo.java | 9 +++ .../spotless/maven/SpotlessCheckMojoTest.java | 62 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 plugin-maven/src/test/java/com/diffplug/spotless/maven/SpotlessCheckMojoTest.java diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java index ebe99154b9..69a88640be 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java @@ -22,6 +22,7 @@ import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; import com.diffplug.spotless.Formatter; import com.diffplug.spotless.extra.integration.DiffMessageFormatter; @@ -29,8 +30,16 @@ @Mojo(name = "check", threadSafe = true) public class SpotlessCheckMojo extends AbstractSpotlessMojo { + @Parameter(property = "spotless.check.skip", defaultValue = "false") + private boolean skip; + @Override protected void process(List files, Formatter formatter) throws MojoExecutionException { + if (skip) { + getLog().info("Spotless check skipped"); + return; + } + List problemFiles = new ArrayList<>(); for (File file : files) { try { diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/SpotlessCheckMojoTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/SpotlessCheckMojoTest.java new file mode 100644 index 0000000000..ea18de21fb --- /dev/null +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/SpotlessCheckMojoTest.java @@ -0,0 +1,62 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.spotless.maven; + +import org.junit.Test; + +public class SpotlessCheckMojoTest extends MavenIntegrationTest { + + private static final String UNFORMATTED_FILE = "license/MissingLicense.test"; + private static final String FORMATTED_FILE = "license/HasLicense.test"; + + @Test + public void testSpotlessCheckWithFormattingViolations() throws Exception { + testSpotlessCheck(UNFORMATTED_FILE, null, true); + } + + @Test + public void testSpotlessCheckWithoutFormattingViolations() throws Exception { + testSpotlessCheck(FORMATTED_FILE, null, false); + } + + @Test + public void testSkipSpotlessCheckWithFormattingViolations() throws Exception { + testSpotlessCheck(UNFORMATTED_FILE, "-Dspotless.check.skip", false); + } + + private void testSpotlessCheck(String fileName, String additionalMvnArg, boolean expectError) throws Exception { + writePomWithJavaSteps( + "", + " ${basedir}/license.txt", + ""); + + write("license.txt", getTestResource("license/TestLicense")); + write("src/main/java/test.java", getTestResource(fileName)); + + MavenRunner mavenRunner = mavenRunner(); + if (additionalMvnArg == null) { + mavenRunner.withArguments("spotless:check"); + } else { + mavenRunner.withArguments("spotless:check", additionalMvnArg); + } + + if (expectError) { + mavenRunner.runHasError(); + } else { + mavenRunner.runNoError(); + } + } +} From 3ca2bf75060dcbb74c45be06da3a38fbf9626279 Mon Sep 17 00:00:00 2001 From: lutovich Date: Tue, 30 Jan 2018 23:53:11 +0100 Subject: [PATCH 49/91] Added javadoc to check and apply MOJOs It will be shown as MOJO description. --- .../java/com/diffplug/spotless/maven/SpotlessApplyMojo.java | 3 +++ .../java/com/diffplug/spotless/maven/SpotlessCheckMojo.java | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessApplyMojo.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessApplyMojo.java index 99c04d55f6..e108ea7d90 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessApplyMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessApplyMojo.java @@ -24,6 +24,9 @@ import com.diffplug.spotless.Formatter; +/** + * Performs formatting of all source files according to configured formatters. + */ @Mojo(name = "apply", threadSafe = true) public class SpotlessApplyMojo extends AbstractSpotlessMojo { diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java index 69a88640be..e31cf46c34 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java @@ -27,6 +27,10 @@ import com.diffplug.spotless.Formatter; import com.diffplug.spotless.extra.integration.DiffMessageFormatter; +/** + * Performs code formatting analysis and prints all violations to the console. + * Fails the build if violations are discovered. + */ @Mojo(name = "check", threadSafe = true) public class SpotlessCheckMojo extends AbstractSpotlessMojo { From 807291e66243767e59ee0ca30a31ad43e0a92ee0 Mon Sep 17 00:00:00 2001 From: lutovich Date: Wed, 31 Jan 2018 00:36:28 +0100 Subject: [PATCH 50/91] Bind 'spotless:check' to verify phase by default Which makes `verify` unneeded in plugin execution configuration. Example to bing 'check' to verify phase: ``` com.diffplug.spotless spotless-maven-plugin ${spotless.version} check check ``` --- .../spotless/maven/SpotlessCheckMojo.java | 3 +- .../spotless/maven/MavenIntegrationTest.java | 25 +++++---- .../spotless/maven/SpotlessCheckMojoTest.java | 55 +++++++++++++------ .../src/test/resources/pom.xml.mustache | 5 ++ 4 files changed, 61 insertions(+), 27 deletions(-) diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java index e31cf46c34..2511a09114 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java @@ -21,6 +21,7 @@ import java.util.List; import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; @@ -31,7 +32,7 @@ * Performs code formatting analysis and prints all violations to the console. * Fails the build if violations are discovered. */ -@Mojo(name = "check", threadSafe = true) +@Mojo(name = "check", defaultPhase = LifecyclePhase.VERIFY, threadSafe = true) public class SpotlessCheckMojo extends AbstractSpotlessMojo { @Parameter(property = "spotless.check.skip", defaultValue = "false") diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java index 163ac891ab..cf55a4c46c 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java @@ -42,6 +42,7 @@ public class MavenIntegrationTest extends ResourceHarness { private static final String LOCAL_MAVEN_REPOSITORY_DIR = "localMavenRepositoryDir"; private static final String SPOTLESS_MAVEN_PLUGIN_VERSION = "spotlessMavenPluginVersion"; private static final String CONFIGURATION = "configuration"; + private static final String EXECUTIONS = "executions"; private final MustacheFactory mustacheFactory = new DefaultMustacheFactory(); @@ -65,11 +66,16 @@ public void gitAttributes() throws IOException { } protected void writePomWithJavaSteps(String... steps) throws IOException { - writePomWithSteps("java", steps); + writePom("java", null, steps); } protected void writePomWithScalaSteps(String... steps) throws IOException { - writePomWithSteps("scala", steps); + writePom("scala", null, steps); + } + + protected void writePom(String group, String[] executions, String[] steps) throws IOException { + String pomXmlContent = createPomXmlContent(group, executions, steps); + write("pom.xml", pomXmlContent); } protected MavenRunner mavenRunner() throws IOException { @@ -77,24 +83,19 @@ protected MavenRunner mavenRunner() throws IOException { .withProjectDir(rootFolder()); } - private void writePomWithSteps(String group, String... steps) throws IOException { - String pomXmlContent = createPomXmlContent(group, steps); - write("pom.xml", pomXmlContent); - } - - private String createPomXmlContent(String group, String... steps) throws IOException { + private String createPomXmlContent(String group, String[] executions, String[] steps) throws IOException { Path pomXml = Paths.get("src", "test", "resources", "pom.xml.mustache"); try (BufferedReader reader = Files.newBufferedReader(pomXml)) { Mustache mustache = mustacheFactory.compile(reader, "pom"); StringWriter writer = new StringWriter(); - Map params = buildPomXmlParams(group, steps); + Map params = buildPomXmlParams(group, executions, steps); mustache.execute(writer, params); return writer.toString(); } } - private static Map buildPomXmlParams(String group, String... steps) { + private static Map buildPomXmlParams(String group, String[] executions, String[] steps) { Map params = new HashMap<>(); params.put(LOCAL_MAVEN_REPOSITORY_DIR, getSystemProperty(LOCAL_MAVEN_REPOSITORY_DIR)); params.put(SPOTLESS_MAVEN_PLUGIN_VERSION, getSystemProperty(SPOTLESS_MAVEN_PLUGIN_VERSION)); @@ -104,6 +105,10 @@ private static Map buildPomXmlParams(String group, String... ste String stepsXml = Arrays.stream(steps).collect(joining("\n", prefix, suffix)); params.put(CONFIGURATION, stepsXml); + if (executions != null) { + params.put(EXECUTIONS, String.join("\n", executions)); + } + return params; } diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/SpotlessCheckMojoTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/SpotlessCheckMojoTest.java index ea18de21fb..7db1bafcde 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/SpotlessCheckMojoTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/SpotlessCheckMojoTest.java @@ -15,6 +15,10 @@ */ package com.diffplug.spotless.maven; +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; + import org.junit.Test; public class SpotlessCheckMojoTest extends MavenIntegrationTest { @@ -24,39 +28,58 @@ public class SpotlessCheckMojoTest extends MavenIntegrationTest { @Test public void testSpotlessCheckWithFormattingViolations() throws Exception { - testSpotlessCheck(UNFORMATTED_FILE, null, true); + writePomWithJavaLicenseHeaderStep(); + testSpotlessCheck(UNFORMATTED_FILE, "spotless:check", true); } @Test public void testSpotlessCheckWithoutFormattingViolations() throws Exception { - testSpotlessCheck(FORMATTED_FILE, null, false); + writePomWithJavaLicenseHeaderStep(); + testSpotlessCheck(FORMATTED_FILE, "spotless:check", false); } @Test public void testSkipSpotlessCheckWithFormattingViolations() throws Exception { - testSpotlessCheck(UNFORMATTED_FILE, "-Dspotless.check.skip", false); + writePomWithJavaLicenseHeaderStep(); + testSpotlessCheck(UNFORMATTED_FILE, "spotless:check -Dspotless.check.skip", false); } - private void testSpotlessCheck(String fileName, String additionalMvnArg, boolean expectError) throws Exception { - writePomWithJavaSteps( - "", - " ${basedir}/license.txt", - ""); + @Test + public void testSpotlessCheckBindingToVerifyPhase() throws Exception { + writePom("java", + new String[]{ + "", + " check", + " ", + " check", + " ", + ""}, + new String[]{ + "", + " ${basedir}/license.txt", + ""}); + + testSpotlessCheck(UNFORMATTED_FILE, "verify", true); + } + private void testSpotlessCheck(String fileName, String command, boolean expectError) throws Exception { write("license.txt", getTestResource("license/TestLicense")); - write("src/main/java/test.java", getTestResource(fileName)); + write("src/main/java/com.github.youribonnaffe.gradle.format/Java8Test.java", getTestResource(fileName)); - MavenRunner mavenRunner = mavenRunner(); - if (additionalMvnArg == null) { - mavenRunner.withArguments("spotless:check"); - } else { - mavenRunner.withArguments("spotless:check", additionalMvnArg); - } + MavenRunner mavenRunner = mavenRunner().withArguments(command); if (expectError) { - mavenRunner.runHasError(); + MavenRunner.Result result = mavenRunner.runHasError(); + assertThat(result.output()).contains("The following files had format violations"); } else { mavenRunner.runNoError(); } } + + private void writePomWithJavaLicenseHeaderStep() throws IOException { + writePomWithJavaSteps( + "", + " ${basedir}/license.txt", + ""); + } } diff --git a/plugin-maven/src/test/resources/pom.xml.mustache b/plugin-maven/src/test/resources/pom.xml.mustache index d24c7e3975..f907160d67 100644 --- a/plugin-maven/src/test/resources/pom.xml.mustache +++ b/plugin-maven/src/test/resources/pom.xml.mustache @@ -10,6 +10,8 @@ UTF-8 + 1.8 + 1.8 @@ -38,6 +40,9 @@ {{{configuration}}} + + {{{executions}}} + From 48cb4c9ad086e7074c51d5f9572bf1da71a64ae1 Mon Sep 17 00:00:00 2001 From: lutovich Date: Wed, 31 Jan 2018 00:57:54 +0100 Subject: [PATCH 51/91] Run maven plugin tests with full stacktrace logging --- .../src/test/java/com/diffplug/spotless/maven/MavenRunner.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java index 73e7689637..f9588624b5 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java @@ -59,7 +59,7 @@ private Result run() throws IOException, InterruptedException { Objects.requireNonNull(projectDir, "Need to call withProjectDir() first"); Objects.requireNonNull(args, "Need to call withArguments() first"); // run maven with the given args in the given directory - List cmds = getPlatformCmds("mvn " + Arrays.stream(args).collect(Collectors.joining(" "))); + List cmds = getPlatformCmds("mvn -e " + Arrays.stream(args).collect(Collectors.joining(" "))); ProcessBuilder builder = new ProcessBuilder(cmds); builder.directory(projectDir); Process process = builder.start(); From 08f90d2017842c9420aa859fbccc27ea310128b9 Mon Sep 17 00:00:00 2001 From: lutovich Date: Wed, 31 Jan 2018 22:54:07 +0100 Subject: [PATCH 52/91] Use mvnw to build maven plugin Maven wrapper makes it easy to control version of maven and it's installation. Version can be changed in `.mvn/wrapper/maven-wrapper.properties` file. --- plugin-maven/build.gradle | 15 +- .../resources/.mvn/wrapper/maven-wrapper.jar | Bin 0 -> 48336 bytes .../.mvn/wrapper/maven-wrapper.properties | 1 + plugin-maven/src/main/resources/mvnw | 227 ++++++++++++++++++ plugin-maven/src/main/resources/mvnw.cmd | 145 +++++++++++ 5 files changed, 386 insertions(+), 2 deletions(-) create mode 100755 plugin-maven/src/main/resources/.mvn/wrapper/maven-wrapper.jar create mode 100755 plugin-maven/src/main/resources/.mvn/wrapper/maven-wrapper.properties create mode 100755 plugin-maven/src/main/resources/mvnw create mode 100755 plugin-maven/src/main/resources/mvnw.cmd diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index 6ee1bcc2f4..529c03fc1f 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -16,6 +16,7 @@ final PROJECT_DIR = project.projectDir.toString() final BUILD_DIR = project.buildDir.toString() final MAVEN_PROJECT_DIR = "${BUILD_DIR}/mavenProject" final LOCAL_MAVEN_REPO_DIR = "${BUILD_DIR}/localMavenRepository" +final MVNW = System.getProperty('os.name').toLowerCase().contains('win') ? 'mvnw.cmd' : './mvnw' buildscript { repositories { mavenCentral() } @@ -47,6 +48,13 @@ task copySourceFiles(type: Sync) { into "${MAVEN_PROJECT_DIR}/src/main/java" } +task copyMvnw(type: Copy) { + from 'src/main/resources' + include 'mvnw' + include 'mvnw.cmd' + include '.mvn/**' + into MAVEN_PROJECT_DIR +} task installLocalDependencies def libs = [ @@ -62,9 +70,11 @@ libs.each { def file = jarTask.archivePath def installDependency = task "install_${artifactId}"(type: Exec) { + workingDir MAVEN_PROJECT_DIR + inputs.file(file) outputs.dir(project.file("${LOCAL_MAVEN_REPO_DIR}/${groupId.replace('.', '/')}/${artifactId}/${version}")) - commandLine "mvn", "org.apache.maven.plugins:maven-install-plugin:2.3.1:install-file", + commandLine MVNW, "org.apache.maven.plugins:maven-install-plugin:2.3.1:install-file", "-Dfile=${file}", "-DgroupId=${groupId}", "-DartifactId=${artifactId}", @@ -113,10 +123,11 @@ task createPomXml(dependsOn: installLocalDependencies) { task runMavenBuild(type: Exec, dependsOn: [ cleanMavenProjectDir, copySourceFiles, + copyMvnw, createPomXml ]) { workingDir MAVEN_PROJECT_DIR - commandLine "mvn", "clean", "install" + commandLine MVNW, "clean", "install" } jar.deleteAllActions() diff --git a/plugin-maven/src/main/resources/.mvn/wrapper/maven-wrapper.jar b/plugin-maven/src/main/resources/.mvn/wrapper/maven-wrapper.jar new file mode 100755 index 0000000000000000000000000000000000000000..f775b1c04cf89b25c7814d3a8a7c810301092e57 GIT binary patch literal 48336 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 \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/plugin-maven/src/main/resources/mvnw.cmd b/plugin-maven/src/main/resources/mvnw.cmd new file mode 100755 index 0000000000..6a6eec39ba --- /dev/null +++ b/plugin-maven/src/main/resources/mvnw.cmd @@ -0,0 +1,145 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" + +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% From 5ccbd098685ba69395112dc53f3c952cf1f08791 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 1 Feb 2018 12:23:16 -0800 Subject: [PATCH 53/91] Cache the .m2 directory on Travis. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index a2a78181ca..4e03c33888 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,3 +9,4 @@ cache: directories: - $HOME/.gradle/caches/ - $HOME/.gradle/wrapper/ + - $HOME/.m2/ From 7df61917e87132f97e54d921d86e0d71650a3b89 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 1 Feb 2018 14:10:43 -0800 Subject: [PATCH 54/91] Use mvnw to run tests. --- .../spotless/maven/MavenIntegrationTest.java | 15 +++++++++++++++ .../com/diffplug/spotless/maven/MavenRunner.java | 6 +++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java index cf55a4c46c..d8966aab50 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java @@ -20,6 +20,7 @@ import static org.junit.Assert.fail; import java.io.BufferedReader; +import java.io.File; import java.io.IOException; import java.io.StringWriter; import java.nio.file.Files; @@ -35,6 +36,7 @@ import com.github.mustachejava.Mustache; import com.github.mustachejava.MustacheFactory; +import com.diffplug.common.io.Resources; import com.diffplug.spotless.ResourceHarness; public class MavenIntegrationTest extends ResourceHarness { @@ -63,6 +65,19 @@ public class MavenIntegrationTest extends ResourceHarness { @Before public void gitAttributes() throws IOException { write(".gitattributes", "* text eol=lf"); + // copy the mvnw resources + copy("mvnw").setExecutable(true); + copy("mvnw.cmd"); + copy(".mvn/wrapper/maven-wrapper.jar"); + copy(".mvn/wrapper/maven-wrapper.properties"); + } + + private File copy(String path) throws IOException { + byte[] bytes = Resources.toByteArray(ResourceHarness.class.getResource("/" + path)); + Path target = newFile(path).toPath(); + Files.createDirectories(target.getParent()); + Files.write(target, bytes); + return target.toFile(); } protected void writePomWithJavaSteps(String... steps) throws IOException { diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java index f9588624b5..ecb984918e 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java @@ -59,7 +59,7 @@ private Result run() throws IOException, InterruptedException { Objects.requireNonNull(projectDir, "Need to call withProjectDir() first"); Objects.requireNonNull(args, "Need to call withArguments() first"); // run maven with the given args in the given directory - List cmds = getPlatformCmds("mvn -e " + Arrays.stream(args).collect(Collectors.joining(" "))); + List cmds = getPlatformCmds("-e " + Arrays.stream(args).collect(Collectors.joining(" "))); ProcessBuilder builder = new ProcessBuilder(cmds); builder.directory(projectDir); Process process = builder.start(); @@ -123,9 +123,9 @@ public String toString() { /** Prepends any arguments necessary to run a console command. */ private static List getPlatformCmds(String cmd) { if (isWin()) { - return Arrays.asList("cmd", "/c", cmd); + return Arrays.asList("cmd", "/c", "mvnw " + cmd); } else { - return Arrays.asList("/bin/sh", "-c", cmd); + return Arrays.asList("/bin/sh", "-c", "./mvnw " + cmd); } } From a676bc415f9cd4f250b5eeef1b5b446870c20934 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 1 Feb 2018 14:23:04 -0800 Subject: [PATCH 55/91] Moved mvnw out of src/main/resources into the project route. Everything in src/main/resources will get shipped to users inside the jar. No need to ship mvnw. Also appears that some of the plugin installation tasks might be failing on the buildserver, perhaps because the install tasks didn't depend on copyMvnw. --- .../resources => }/.mvn/wrapper/maven-wrapper.jar | Bin .../.mvn/wrapper/maven-wrapper.properties | 0 plugin-maven/build.gradle | 9 --------- plugin-maven/{src/main/resources => }/mvnw | 0 plugin-maven/{src/main/resources => }/mvnw.cmd | 0 .../{src/main/resources => }/pom.xml.mustache | 0 .../spotless/maven/MavenIntegrationTest.java | 10 ++++------ 7 files changed, 4 insertions(+), 15 deletions(-) rename plugin-maven/{src/main/resources => }/.mvn/wrapper/maven-wrapper.jar (100%) rename plugin-maven/{src/main/resources => }/.mvn/wrapper/maven-wrapper.properties (100%) rename plugin-maven/{src/main/resources => }/mvnw (100%) rename plugin-maven/{src/main/resources => }/mvnw.cmd (100%) rename plugin-maven/{src/main/resources => }/pom.xml.mustache (100%) diff --git a/plugin-maven/src/main/resources/.mvn/wrapper/maven-wrapper.jar b/plugin-maven/.mvn/wrapper/maven-wrapper.jar similarity index 100% rename from plugin-maven/src/main/resources/.mvn/wrapper/maven-wrapper.jar rename to plugin-maven/.mvn/wrapper/maven-wrapper.jar diff --git a/plugin-maven/src/main/resources/.mvn/wrapper/maven-wrapper.properties b/plugin-maven/.mvn/wrapper/maven-wrapper.properties similarity index 100% rename from plugin-maven/src/main/resources/.mvn/wrapper/maven-wrapper.properties rename to plugin-maven/.mvn/wrapper/maven-wrapper.properties diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index 529c03fc1f..67a48a9607 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -48,14 +48,6 @@ task copySourceFiles(type: Sync) { into "${MAVEN_PROJECT_DIR}/src/main/java" } -task copyMvnw(type: Copy) { - from 'src/main/resources' - include 'mvnw' - include 'mvnw.cmd' - include '.mvn/**' - into MAVEN_PROJECT_DIR -} - task installLocalDependencies def libs = [ 'lib', @@ -123,7 +115,6 @@ task createPomXml(dependsOn: installLocalDependencies) { task runMavenBuild(type: Exec, dependsOn: [ cleanMavenProjectDir, copySourceFiles, - copyMvnw, createPomXml ]) { workingDir MAVEN_PROJECT_DIR diff --git a/plugin-maven/src/main/resources/mvnw b/plugin-maven/mvnw similarity index 100% rename from plugin-maven/src/main/resources/mvnw rename to plugin-maven/mvnw diff --git a/plugin-maven/src/main/resources/mvnw.cmd b/plugin-maven/mvnw.cmd similarity index 100% rename from plugin-maven/src/main/resources/mvnw.cmd rename to plugin-maven/mvnw.cmd diff --git a/plugin-maven/src/main/resources/pom.xml.mustache b/plugin-maven/pom.xml.mustache similarity index 100% rename from plugin-maven/src/main/resources/pom.xml.mustache rename to plugin-maven/pom.xml.mustache diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java index d8966aab50..09687b222b 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java @@ -36,7 +36,6 @@ import com.github.mustachejava.Mustache; import com.github.mustachejava.MustacheFactory; -import com.diffplug.common.io.Resources; import com.diffplug.spotless.ResourceHarness; public class MavenIntegrationTest extends ResourceHarness { @@ -73,11 +72,10 @@ public void gitAttributes() throws IOException { } private File copy(String path) throws IOException { - byte[] bytes = Resources.toByteArray(ResourceHarness.class.getResource("/" + path)); - Path target = newFile(path).toPath(); - Files.createDirectories(target.getParent()); - Files.write(target, bytes); - return target.toFile(); + File dst = newFile(path); + dst.getParentFile().mkdirs(); + Files.copy(Paths.get(path), dst.toPath()); + return dst; } protected void writePomWithJavaSteps(String... steps) throws IOException { From d4cddc0825644905f6801e5b21e5d6ffb958a9ab Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 1 Feb 2018 14:48:16 -0800 Subject: [PATCH 56/91] Revert "Moved mvnw out of src/main/resources into the project route." This reverts commit a676bc415f9cd4f250b5eeef1b5b446870c20934. --- plugin-maven/build.gradle | 9 +++++++++ .../main/resources}/.mvn/wrapper/maven-wrapper.jar | Bin .../.mvn/wrapper/maven-wrapper.properties | 0 plugin-maven/{ => src/main/resources}/mvnw | 0 plugin-maven/{ => src/main/resources}/mvnw.cmd | 0 .../{ => src/main/resources}/pom.xml.mustache | 0 .../spotless/maven/MavenIntegrationTest.java | 10 ++++++---- 7 files changed, 15 insertions(+), 4 deletions(-) rename plugin-maven/{ => src/main/resources}/.mvn/wrapper/maven-wrapper.jar (100%) rename plugin-maven/{ => src/main/resources}/.mvn/wrapper/maven-wrapper.properties (100%) rename plugin-maven/{ => src/main/resources}/mvnw (100%) rename plugin-maven/{ => src/main/resources}/mvnw.cmd (100%) rename plugin-maven/{ => src/main/resources}/pom.xml.mustache (100%) diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index 67a48a9607..529c03fc1f 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -48,6 +48,14 @@ task copySourceFiles(type: Sync) { into "${MAVEN_PROJECT_DIR}/src/main/java" } +task copyMvnw(type: Copy) { + from 'src/main/resources' + include 'mvnw' + include 'mvnw.cmd' + include '.mvn/**' + into MAVEN_PROJECT_DIR +} + task installLocalDependencies def libs = [ 'lib', @@ -115,6 +123,7 @@ task createPomXml(dependsOn: installLocalDependencies) { task runMavenBuild(type: Exec, dependsOn: [ cleanMavenProjectDir, copySourceFiles, + copyMvnw, createPomXml ]) { workingDir MAVEN_PROJECT_DIR diff --git a/plugin-maven/.mvn/wrapper/maven-wrapper.jar b/plugin-maven/src/main/resources/.mvn/wrapper/maven-wrapper.jar similarity index 100% rename from plugin-maven/.mvn/wrapper/maven-wrapper.jar rename to plugin-maven/src/main/resources/.mvn/wrapper/maven-wrapper.jar diff --git a/plugin-maven/.mvn/wrapper/maven-wrapper.properties b/plugin-maven/src/main/resources/.mvn/wrapper/maven-wrapper.properties similarity index 100% rename from plugin-maven/.mvn/wrapper/maven-wrapper.properties rename to plugin-maven/src/main/resources/.mvn/wrapper/maven-wrapper.properties diff --git a/plugin-maven/mvnw b/plugin-maven/src/main/resources/mvnw similarity index 100% rename from plugin-maven/mvnw rename to plugin-maven/src/main/resources/mvnw diff --git a/plugin-maven/mvnw.cmd b/plugin-maven/src/main/resources/mvnw.cmd similarity index 100% rename from plugin-maven/mvnw.cmd rename to plugin-maven/src/main/resources/mvnw.cmd diff --git a/plugin-maven/pom.xml.mustache b/plugin-maven/src/main/resources/pom.xml.mustache similarity index 100% rename from plugin-maven/pom.xml.mustache rename to plugin-maven/src/main/resources/pom.xml.mustache diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java index 09687b222b..d8966aab50 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java @@ -36,6 +36,7 @@ import com.github.mustachejava.Mustache; import com.github.mustachejava.MustacheFactory; +import com.diffplug.common.io.Resources; import com.diffplug.spotless.ResourceHarness; public class MavenIntegrationTest extends ResourceHarness { @@ -72,10 +73,11 @@ public void gitAttributes() throws IOException { } private File copy(String path) throws IOException { - File dst = newFile(path); - dst.getParentFile().mkdirs(); - Files.copy(Paths.get(path), dst.toPath()); - return dst; + byte[] bytes = Resources.toByteArray(ResourceHarness.class.getResource("/" + path)); + Path target = newFile(path).toPath(); + Files.createDirectories(target.getParent()); + Files.write(target, bytes); + return target.toFile(); } protected void writePomWithJavaSteps(String... steps) throws IOException { From b9a4fa4c30e08d6aefd82332b45b175f4bb8947a Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 1 Feb 2018 14:48:07 -0800 Subject: [PATCH 57/91] Added task graph vis, which shows problem in build. --- plugin-maven/build.gradle | 26 +++++++++++++++++++++----- plugin-maven/taskGraph.pdf | Bin 0 -> 17464 bytes 2 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 plugin-maven/taskGraph.pdf diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index 529c03fc1f..695af87d52 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -1,3 +1,24 @@ +buildscript { + repositories { mavenCentral() } + dependencies { classpath "com.github.spullara.mustache.java:compiler:${VER_MUSTACHE}" } +} +plugins { + id 'cz.malohlava' version '1.0.3' // https://github.com/mmalohlava/gradle-visteg +} + +// to generate taskGraph.pdf +// - set enabled to true +// - run './gradlew :plugin-maven:test' +// - run 'rm plugin-maven/output.pdf' +// - run 'dot -Tpdf plugin-maven/build/reports/visteg.dot > plugin-maven/taskGraph.pdf' +visteg { + enabled = false + nodeShape = 'box' + startNodeShape = 'box' + endNodeShape = 'box' + colorscheme = 'pastel24' // http://www.graphviz.org/doc/info/colors.html +} + import com.github.mustachejava.DefaultMustacheFactory import java.nio.file.Files @@ -18,11 +39,6 @@ final MAVEN_PROJECT_DIR = "${BUILD_DIR}/mavenProject" final LOCAL_MAVEN_REPO_DIR = "${BUILD_DIR}/localMavenRepository" final MVNW = System.getProperty('os.name').toLowerCase().contains('win') ? 'mvnw.cmd' : './mvnw' -buildscript { - repositories { mavenCentral() } - dependencies { classpath "com.github.spullara.mustache.java:compiler:${VER_MUSTACHE}" } -} - dependencies { compile project(":lib") compile project(":lib-extra") diff --git a/plugin-maven/taskGraph.pdf b/plugin-maven/taskGraph.pdf new file mode 100644 index 0000000000000000000000000000000000000000..162bcc2f013dee53d9734af490b9e30e62c9fb78 GIT binary patch literal 17464 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 B=^+3B literal 0 HcmV?d00001 From bafc30cd7247ee13d1fd69179d290745ecbb9806 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 1 Feb 2018 15:05:18 -0800 Subject: [PATCH 58/91] Fixed the problem in the build. --- plugin-maven/build.gradle | 11 +++++++---- plugin-maven/taskGraph.pdf | Bin 17464 -> 22398 bytes 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index 695af87d52..9993b1639d 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -7,10 +7,10 @@ plugins { } // to generate taskGraph.pdf -// - set enabled to true -// - run './gradlew :plugin-maven:test' -// - run 'rm plugin-maven/output.pdf' -// - run 'dot -Tpdf plugin-maven/build/reports/visteg.dot > plugin-maven/taskGraph.pdf' +// - set enabled (below) to true +// - run: ./gradlew :plugin-maven:test +// - run: rm plugin-maven/output.pdf +// - run: dot -Tpdf plugin-maven/build/reports/visteg.dot > plugin-maven/taskGraph.pdf visteg { enabled = false nodeShape = 'box' @@ -155,6 +155,9 @@ jar.doLast { ) } +// usually test only depends on testClasses, which doesn't run the maven build that we need +test.dependsOn(jar) + test { testLogging { exceptionFormat = 'full' } // pass location of the local maven repository and plugin version to junit tests diff --git a/plugin-maven/taskGraph.pdf b/plugin-maven/taskGraph.pdf index 162bcc2f013dee53d9734af490b9e30e62c9fb78..3366d95b9e33a833aa8d5a3881a1db9717b36d98 100644 GIT binary patch delta 18449 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 PuxL0)SNBI3d(giD6}0a> delta 13480 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 From 9d3ea058859a2484691e99b64b4e2d621deae2eb Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 1 Feb 2018 15:25:22 -0800 Subject: [PATCH 59/91] Moved mvnw and the template poms into src/test/resources. --- plugin-maven/build.gradle | 4 ++-- .../spotless/maven/MavenIntegrationTest.java | 13 ++++++------- .../resources/.mvn/wrapper/maven-wrapper.jar | Bin .../.mvn/wrapper/maven-wrapper.properties | 0 plugin-maven/src/{main => test}/resources/mvnw | 0 plugin-maven/src/{main => test}/resources/mvnw.cmd | 0 .../resources/pom-build.xml.mustache} | 0 .../{pom.xml.mustache => pom-test.xml.mustache} | 0 8 files changed, 8 insertions(+), 9 deletions(-) rename plugin-maven/src/{main => test}/resources/.mvn/wrapper/maven-wrapper.jar (100%) rename plugin-maven/src/{main => test}/resources/.mvn/wrapper/maven-wrapper.properties (100%) rename plugin-maven/src/{main => test}/resources/mvnw (100%) rename plugin-maven/src/{main => test}/resources/mvnw.cmd (100%) rename plugin-maven/src/{main/resources/pom.xml.mustache => test/resources/pom-build.xml.mustache} (100%) rename plugin-maven/src/test/resources/{pom.xml.mustache => pom-test.xml.mustache} (100%) diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index 9993b1639d..736beb4f1a 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -65,7 +65,7 @@ task copySourceFiles(type: Sync) { } task copyMvnw(type: Copy) { - from 'src/main/resources' + from 'src/test/resources' include 'mvnw' include 'mvnw.cmd' include '.mvn/**' @@ -124,7 +124,7 @@ task createPomXml(dependsOn: installLocalDependencies) { localMavenRepositoryDir : LOCAL_MAVEN_REPO_DIR ] - def pomXmlTemplate = Paths.get(PROJECT_DIR, "src", "main", "resources", "pom.xml.mustache") + def pomXmlTemplate = Paths.get(PROJECT_DIR, "src/test/resources/pom-build.xml.mustache") def newPomXml = Paths.get(MAVEN_PROJECT_DIR, "pom.xml") Files.newBufferedReader(pomXmlTemplate).withCloseable { reader -> diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java index d8966aab50..76b6b85cdb 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java @@ -23,22 +23,22 @@ import java.io.File; import java.io.IOException; import java.io.StringWriter; +import java.net.URL; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import org.junit.Before; +import com.diffplug.common.io.Resources; +import com.diffplug.spotless.ResourceHarness; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.Mustache; import com.github.mustachejava.MustacheFactory; -import com.diffplug.common.io.Resources; -import com.diffplug.spotless.ResourceHarness; - public class MavenIntegrationTest extends ResourceHarness { private static final String LOCAL_MAVEN_REPOSITORY_DIR = "localMavenRepositoryDir"; @@ -99,9 +99,8 @@ protected MavenRunner mavenRunner() throws IOException { } private String createPomXmlContent(String group, String[] executions, String[] steps) throws IOException { - Path pomXml = Paths.get("src", "test", "resources", "pom.xml.mustache"); - - try (BufferedReader reader = Files.newBufferedReader(pomXml)) { + URL url = MavenIntegrationTest.class.getResource("/pom-test.xml.mustache"); + try (BufferedReader reader = Resources.asCharSource(url, StandardCharsets.UTF_8).openBufferedStream()) { Mustache mustache = mustacheFactory.compile(reader, "pom"); StringWriter writer = new StringWriter(); Map params = buildPomXmlParams(group, executions, steps); diff --git a/plugin-maven/src/main/resources/.mvn/wrapper/maven-wrapper.jar b/plugin-maven/src/test/resources/.mvn/wrapper/maven-wrapper.jar similarity index 100% rename from plugin-maven/src/main/resources/.mvn/wrapper/maven-wrapper.jar rename to plugin-maven/src/test/resources/.mvn/wrapper/maven-wrapper.jar diff --git a/plugin-maven/src/main/resources/.mvn/wrapper/maven-wrapper.properties b/plugin-maven/src/test/resources/.mvn/wrapper/maven-wrapper.properties similarity index 100% rename from plugin-maven/src/main/resources/.mvn/wrapper/maven-wrapper.properties rename to plugin-maven/src/test/resources/.mvn/wrapper/maven-wrapper.properties diff --git a/plugin-maven/src/main/resources/mvnw b/plugin-maven/src/test/resources/mvnw similarity index 100% rename from plugin-maven/src/main/resources/mvnw rename to plugin-maven/src/test/resources/mvnw diff --git a/plugin-maven/src/main/resources/mvnw.cmd b/plugin-maven/src/test/resources/mvnw.cmd similarity index 100% rename from plugin-maven/src/main/resources/mvnw.cmd rename to plugin-maven/src/test/resources/mvnw.cmd diff --git a/plugin-maven/src/main/resources/pom.xml.mustache b/plugin-maven/src/test/resources/pom-build.xml.mustache similarity index 100% rename from plugin-maven/src/main/resources/pom.xml.mustache rename to plugin-maven/src/test/resources/pom-build.xml.mustache diff --git a/plugin-maven/src/test/resources/pom.xml.mustache b/plugin-maven/src/test/resources/pom-test.xml.mustache similarity index 100% rename from plugin-maven/src/test/resources/pom.xml.mustache rename to plugin-maven/src/test/resources/pom-test.xml.mustache From e438881a2f2eec39a27be14553aad9970f6ddb0b Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 1 Feb 2018 15:36:43 -0800 Subject: [PATCH 60/91] Only run the maven tests on CI, for faster debugging. Also format fix. --- .travis.yml | 3 ++- plugin-maven/build.gradle | 3 +-- .../com/diffplug/spotless/maven/MavenIntegrationTest.java | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4e03c33888..5188e57aa3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,8 @@ language: java jdk: - oraclejdk8 -script: "./.ci/ci.sh" +#script: "./.ci/ci.sh" +script: "./gradlew :plugin-maven:test" before_cache: - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index 736beb4f1a..a8450c4c0b 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -2,8 +2,7 @@ buildscript { repositories { mavenCentral() } dependencies { classpath "com.github.spullara.mustache.java:compiler:${VER_MUSTACHE}" } } -plugins { - id 'cz.malohlava' version '1.0.3' // https://github.com/mmalohlava/gradle-visteg +plugins { id 'cz.malohlava' version '1.0.3' // https://github.com/mmalohlava/gradle-visteg } // to generate taskGraph.pdf diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java index 76b6b85cdb..d1eb1e44ec 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java @@ -33,12 +33,13 @@ import org.junit.Before; -import com.diffplug.common.io.Resources; -import com.diffplug.spotless.ResourceHarness; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.Mustache; import com.github.mustachejava.MustacheFactory; +import com.diffplug.common.io.Resources; +import com.diffplug.spotless.ResourceHarness; + public class MavenIntegrationTest extends ResourceHarness { private static final String LOCAL_MAVEN_REPOSITORY_DIR = "localMavenRepositoryDir"; From f8bf47d2d72b8a766614d57432f39d83c6f83d71 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 1 Feb 2018 16:02:55 -0800 Subject: [PATCH 61/91] mvnw now works on Windows. --- plugin-maven/build.gradle | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index a8450c4c0b..01ce98d443 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -36,7 +36,23 @@ final PROJECT_DIR = project.projectDir.toString() final BUILD_DIR = project.buildDir.toString() final MAVEN_PROJECT_DIR = "${BUILD_DIR}/mavenProject" final LOCAL_MAVEN_REPO_DIR = "${BUILD_DIR}/localMavenRepository" -final MVNW = System.getProperty('os.name').toLowerCase().contains('win') ? 'mvnw.cmd' : './mvnw' + +def mvnw(String args) { + boolean isWin = System.getProperty('os.name').toLowerCase().contains('win') + if (isWin) { + return [ + 'cmd', + '/c', + 'mvnw.cmd ' + args + ] + } else { + return [ + '/bin/sh', + '-c', + './mvnw ' + args + ] + } +} dependencies { compile project(":lib") @@ -89,13 +105,13 @@ libs.each { inputs.file(file) outputs.dir(project.file("${LOCAL_MAVEN_REPO_DIR}/${groupId.replace('.', '/')}/${artifactId}/${version}")) - commandLine MVNW, "org.apache.maven.plugins:maven-install-plugin:2.3.1:install-file", - "-Dfile=${file}", - "-DgroupId=${groupId}", - "-DartifactId=${artifactId}", - "-Dversion=${version}", - "-Dpackaging=jar", - "-DlocalRepositoryPath=${LOCAL_MAVEN_REPO_DIR}" + commandLine mvnw("org.apache.maven.plugins:maven-install-plugin:2.3.1:install-file " + + "-Dfile=${file} " + + "-DgroupId=${groupId} " + + "-DartifactId=${artifactId} " + + "-Dversion=${version} " + + "-Dpackaging=jar " + + "-DlocalRepositoryPath=${LOCAL_MAVEN_REPO_DIR}") } installDependency.dependsOn(jarTask) @@ -142,7 +158,7 @@ task runMavenBuild(type: Exec, dependsOn: [ createPomXml ]) { workingDir MAVEN_PROJECT_DIR - commandLine MVNW, "clean", "install" + commandLine mvnw("clean install") } jar.deleteAllActions() From d2170fe499e66183244725bd066ef7fa471ce297 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 1 Feb 2018 16:03:13 -0800 Subject: [PATCH 62/91] Disable the apache-snapshots repo. --- plugin-maven/src/test/resources/pom-build.xml.mustache | 10 ++++++++++ plugin-maven/src/test/resources/pom-test.xml.mustache | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/plugin-maven/src/test/resources/pom-build.xml.mustache b/plugin-maven/src/test/resources/pom-build.xml.mustache index df64cdb6b0..c829bf16f0 100644 --- a/plugin-maven/src/test/resources/pom-build.xml.mustache +++ b/plugin-maven/src/test/resources/pom-build.xml.mustache @@ -35,6 +35,16 @@ ignore + + apache-snapshots + https://repository.apache.org/snapshots/ + + false + + + false + + diff --git a/plugin-maven/src/test/resources/pom-test.xml.mustache b/plugin-maven/src/test/resources/pom-test.xml.mustache index f907160d67..524476fab5 100644 --- a/plugin-maven/src/test/resources/pom-test.xml.mustache +++ b/plugin-maven/src/test/resources/pom-test.xml.mustache @@ -29,6 +29,16 @@ ignore + + apache-snapshots + https://repository.apache.org/snapshots/ + + false + + + false + + From da36b36e9909462164eee0433d1ef87530932ed2 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 1 Feb 2018 16:08:38 -0800 Subject: [PATCH 63/91] Another attempt at disabling the apache-snapshots repo. --- plugin-maven/src/test/resources/pom-build.xml.mustache | 5 +++-- plugin-maven/src/test/resources/pom-test.xml.mustache | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/plugin-maven/src/test/resources/pom-build.xml.mustache b/plugin-maven/src/test/resources/pom-build.xml.mustache index c829bf16f0..fd6e27c949 100644 --- a/plugin-maven/src/test/resources/pom-build.xml.mustache +++ b/plugin-maven/src/test/resources/pom-build.xml.mustache @@ -36,8 +36,9 @@ - apache-snapshots - https://repository.apache.org/snapshots/ + apache.snapshots + Apache Development Snapshot Repository + https://repository.apache.org/content/repositories/snapshots/ false diff --git a/plugin-maven/src/test/resources/pom-test.xml.mustache b/plugin-maven/src/test/resources/pom-test.xml.mustache index 524476fab5..5935764c07 100644 --- a/plugin-maven/src/test/resources/pom-test.xml.mustache +++ b/plugin-maven/src/test/resources/pom-test.xml.mustache @@ -30,8 +30,9 @@ - apache-snapshots - https://repository.apache.org/snapshots/ + apache.snapshots + Apache Development Snapshot Repository + https://repository.apache.org/content/repositories/snapshots/ false From 07b6d689d2ab3b6249839af7e71c9442a8f4008b Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 1 Feb 2018 16:22:02 -0800 Subject: [PATCH 64/91] Update docs for skipping spotless:check. --- plugin-maven/README.md | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/plugin-maven/README.md b/plugin-maven/README.md index c9926a8692..69e4d08016 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -134,15 +134,10 @@ You can easily set the line endings of different files using [a `.gitattributes` ## Disabling warnings and error messages -The `test` phase is Maven's built-in task for grouping all verification tasks - unit tests, static analysis, etc. By default, `spotless-check` is added as a dependency to `test`. +By default, `spotless:check` is bound to the `verify` phase. You might want to disable this behavior. We [recommend against this](https://github.com/diffplug/spotless/issues/79#issuecomment-290844602), but it's easy to do if you'd like: -You might want to disable this behavior. We [recommend against this](https://github.com/diffplug/spotless/issues/79#issuecomment-290844602), but it's easy to do if you'd like: - -```xml - - false - -``` +- set `-Dspotless.check.skip=true` at the command line +- set `spotless.check.skip` to `true` in the `` section From 243035ea8ca25a53f3633457dba634f516423e0e Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 1 Feb 2018 16:27:43 -0800 Subject: [PATCH 65/91] Try to figure out what travis is using for $HOME/.m2/settings.xml --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5188e57aa3..40d278f121 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,10 @@ language: java jdk: - oraclejdk8 -#script: "./.ci/ci.sh" +script: + - cat $HOME/.m2/settings.xml +# - ./gradlew :plugin-maven:test +# - ./.ci/ci.sh script: "./gradlew :plugin-maven:test" before_cache: - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock From ea6ebb579ac0a90ae42c19b3920d3f97d9191a4b Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 1 Feb 2018 16:31:01 -0800 Subject: [PATCH 66/91] Attempt #2... --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 40d278f121..a0dd63573d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,6 @@ script: - cat $HOME/.m2/settings.xml # - ./gradlew :plugin-maven:test # - ./.ci/ci.sh -script: "./gradlew :plugin-maven:test" before_cache: - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ From 6d660c641161135180954470c179df405513b87d Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 1 Feb 2018 16:44:24 -0800 Subject: [PATCH 67/91] Instead of snapshot-repo-whackamole, I'm just setting a restrictive settings.xml. --- .travis.yml | 6 +++-- plugin-maven/.travis.m2.settings.xml | 23 +++++++++++++++++++ .../src/test/resources/pom-build.xml.mustache | 11 --------- .../src/test/resources/pom-test.xml.mustache | 11 --------- 4 files changed, 27 insertions(+), 24 deletions(-) create mode 100644 plugin-maven/.travis.m2.settings.xml diff --git a/.travis.yml b/.travis.yml index a0dd63573d..7ae69ad26b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,11 @@ language: java jdk: - oraclejdk8 +install: true +before_script: + - cp plugin-maven/.travis.m2.settings.xml $HOME/.m2/settings.xml script: - - cat $HOME/.m2/settings.xml -# - ./gradlew :plugin-maven:test + - ./gradlew :plugin-maven:test # - ./.ci/ci.sh before_cache: - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock diff --git a/plugin-maven/.travis.m2.settings.xml b/plugin-maven/.travis.m2.settings.xml new file mode 100644 index 0000000000..09239a1909 --- /dev/null +++ b/plugin-maven/.travis.m2.settings.xml @@ -0,0 +1,23 @@ + + + + central-only + + true + + + + central + Central Repository + http://repo.maven.apache.org/maven2 + + true + + + false + + + + + + diff --git a/plugin-maven/src/test/resources/pom-build.xml.mustache b/plugin-maven/src/test/resources/pom-build.xml.mustache index fd6e27c949..df64cdb6b0 100644 --- a/plugin-maven/src/test/resources/pom-build.xml.mustache +++ b/plugin-maven/src/test/resources/pom-build.xml.mustache @@ -35,17 +35,6 @@ ignore - - apache.snapshots - Apache Development Snapshot Repository - https://repository.apache.org/content/repositories/snapshots/ - - false - - - false - - diff --git a/plugin-maven/src/test/resources/pom-test.xml.mustache b/plugin-maven/src/test/resources/pom-test.xml.mustache index 5935764c07..f907160d67 100644 --- a/plugin-maven/src/test/resources/pom-test.xml.mustache +++ b/plugin-maven/src/test/resources/pom-test.xml.mustache @@ -29,17 +29,6 @@ ignore - - apache.snapshots - Apache Development Snapshot Repository - https://repository.apache.org/content/repositories/snapshots/ - - false - - - false - - From aef8b32fcd9fce75b982fe5989106a38678643b1 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 1 Feb 2018 19:43:40 -0800 Subject: [PATCH 68/91] Another shot at a settings.xml - none at all. --- .travis.yml | 2 +- plugin-maven/.travis.m2.settings.xml | 23 ----------------------- 2 files changed, 1 insertion(+), 24 deletions(-) delete mode 100644 plugin-maven/.travis.m2.settings.xml diff --git a/.travis.yml b/.travis.yml index 7ae69ad26b..4ae3844215 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ jdk: - oraclejdk8 install: true before_script: - - cp plugin-maven/.travis.m2.settings.xml $HOME/.m2/settings.xml + - rm $HOME/.m2/settings.xml script: - ./gradlew :plugin-maven:test # - ./.ci/ci.sh diff --git a/plugin-maven/.travis.m2.settings.xml b/plugin-maven/.travis.m2.settings.xml deleted file mode 100644 index 09239a1909..0000000000 --- a/plugin-maven/.travis.m2.settings.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - central-only - - true - - - - central - Central Repository - http://repo.maven.apache.org/maven2 - - true - - - false - - - - - - From 21f163bc7f944edb49c4042f2f6a7fbeec560dbc Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 1 Feb 2018 20:16:28 -0800 Subject: [PATCH 69/91] Force maven tests to run in "offline" mode. --- .../test/java/com/diffplug/spotless/maven/MavenRunner.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java index ecb984918e..1ed9c414c7 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java @@ -59,7 +59,9 @@ private Result run() throws IOException, InterruptedException { Objects.requireNonNull(projectDir, "Need to call withProjectDir() first"); Objects.requireNonNull(args, "Need to call withArguments() first"); // run maven with the given args in the given directory - List cmds = getPlatformCmds("-e " + Arrays.stream(args).collect(Collectors.joining(" "))); + // -e to display execution errors at the console + // -o to force offline mode, so that it uses the locally-built plugin and not one from a snapshot repo + List cmds = getPlatformCmds("-e -o " + Arrays.stream(args).collect(Collectors.joining(" "))); ProcessBuilder builder = new ProcessBuilder(cmds); builder.directory(projectDir); Process process = builder.start(); From e7cea1847d3e6ddf6dd7cd0363556b3a9f2b1428 Mon Sep 17 00:00:00 2001 From: lutovich Date: Sun, 4 Feb 2018 20:08:40 +0100 Subject: [PATCH 70/91] Run Maven with debug logging and use "special" version --- gradle.properties | 2 +- plugin-maven/build.gradle | 4 ++-- .../test/java/com/diffplug/spotless/maven/MavenRunner.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gradle.properties b/gradle.properties index a75bdca5aa..f4d13f8313 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ org=diffplug group=com.diffplug.spotless -versionLib=1.9.0-SNAPSHOT +versionLib=1.9.0-TEST-SNAPSHOT stableLib=1.8.0 artifactIdLib=spotless-lib artifactIdLibExtra=spotless-lib-extra diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index 01ce98d443..9629bf5c02 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -43,13 +43,13 @@ def mvnw(String args) { return [ 'cmd', '/c', - 'mvnw.cmd ' + args + 'mvnw.cmd -X ' + args ] } else { return [ '/bin/sh', '-c', - './mvnw ' + args + './mvnw -X ' + args ] } } diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java index 1ed9c414c7..0e87e59608 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java @@ -61,7 +61,7 @@ private Result run() throws IOException, InterruptedException { // run maven with the given args in the given directory // -e to display execution errors at the console // -o to force offline mode, so that it uses the locally-built plugin and not one from a snapshot repo - List cmds = getPlatformCmds("-e -o " + Arrays.stream(args).collect(Collectors.joining(" "))); + List cmds = getPlatformCmds("-X -o " + Arrays.stream(args).collect(Collectors.joining(" "))); ProcessBuilder builder = new ProcessBuilder(cmds); builder.directory(projectDir); Process process = builder.start(); From da77c392b80fa2e6ffed7af4a43435000b000591 Mon Sep 17 00:00:00 2001 From: lutovich Date: Sun, 4 Feb 2018 20:27:30 +0100 Subject: [PATCH 71/91] Set version back to normal --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index f4d13f8313..a75bdca5aa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ org=diffplug group=com.diffplug.spotless -versionLib=1.9.0-TEST-SNAPSHOT +versionLib=1.9.0-SNAPSHOT stableLib=1.8.0 artifactIdLib=spotless-lib artifactIdLibExtra=spotless-lib-extra From 34ff0e9ce93bbc3bf3ccec8ba3d86f8df7626483 Mon Sep 17 00:00:00 2001 From: lutovich Date: Sun, 4 Feb 2018 20:27:55 +0100 Subject: [PATCH 72/91] Local repo as repository, not only pluginRepository For tests only. --- .../src/test/resources/pom-test.xml.mustache | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/plugin-maven/src/test/resources/pom-test.xml.mustache b/plugin-maven/src/test/resources/pom-test.xml.mustache index f907160d67..183f3009eb 100644 --- a/plugin-maven/src/test/resources/pom-test.xml.mustache +++ b/plugin-maven/src/test/resources/pom-test.xml.mustache @@ -31,6 +31,23 @@ + + + local-repo + file://{{localMavenRepositoryDir}} + + true + always + ignore + + + true + always + ignore + + + + From 7de4e1a120b7b206ed5fcb6ce61dda37b069cb58 Mon Sep 17 00:00:00 2001 From: lutovich Date: Sun, 4 Feb 2018 21:01:01 +0100 Subject: [PATCH 73/91] Do not use offline mode for maven plugin tests --- .../src/test/java/com/diffplug/spotless/maven/MavenRunner.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java index 0e87e59608..9889de1eb8 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java @@ -60,8 +60,7 @@ private Result run() throws IOException, InterruptedException { Objects.requireNonNull(args, "Need to call withArguments() first"); // run maven with the given args in the given directory // -e to display execution errors at the console - // -o to force offline mode, so that it uses the locally-built plugin and not one from a snapshot repo - List cmds = getPlatformCmds("-X -o " + Arrays.stream(args).collect(Collectors.joining(" "))); + List cmds = getPlatformCmds("-X " + Arrays.stream(args).collect(Collectors.joining(" "))); ProcessBuilder builder = new ProcessBuilder(cmds); builder.directory(projectDir); Process process = builder.start(); From 8e77cf7502c0cbfefd012d7b9b9c69f24f88deff Mon Sep 17 00:00:00 2001 From: lutovich Date: Sun, 4 Feb 2018 21:31:43 +0100 Subject: [PATCH 74/91] Force snapshot updates in maven plugin tests --- .../src/test/java/com/diffplug/spotless/maven/MavenRunner.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java index 9889de1eb8..6931974a9d 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java @@ -60,7 +60,8 @@ private Result run() throws IOException, InterruptedException { Objects.requireNonNull(args, "Need to call withArguments() first"); // run maven with the given args in the given directory // -e to display execution errors at the console - List cmds = getPlatformCmds("-X " + Arrays.stream(args).collect(Collectors.joining(" "))); + // -U to force update of snapshots + List cmds = getPlatformCmds("-X -U " + Arrays.stream(args).collect(Collectors.joining(" "))); ProcessBuilder builder = new ProcessBuilder(cmds); builder.directory(projectDir); Process process = builder.start(); From fcebff75b6cae9f497d6d281d68c9464ba8aef65 Mon Sep 17 00:00:00 2001 From: lutovich Date: Sun, 4 Feb 2018 22:01:57 +0100 Subject: [PATCH 75/91] Install maven plugin to local repo during build --- plugin-maven/build.gradle | 2 +- .../diffplug/spotless/maven/MavenIntegrationTest.java | 3 ++- .../java/com/diffplug/spotless/maven/MavenRunner.java | 10 +++++++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index 9629bf5c02..71894a7e6b 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -158,7 +158,7 @@ task runMavenBuild(type: Exec, dependsOn: [ createPomXml ]) { workingDir MAVEN_PROJECT_DIR - commandLine mvnw("clean install") + commandLine mvnw("clean install -Dmaven.repo.local=${LOCAL_MAVEN_REPO_DIR}") } jar.deleteAllActions() diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java index d1eb1e44ec..147be22e99 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java @@ -96,7 +96,8 @@ protected void writePom(String group, String[] executions, String[] steps) throw protected MavenRunner mavenRunner() throws IOException { return MavenRunner.create() - .withProjectDir(rootFolder()); + .withProjectDir(rootFolder()) + .withLocalRepository(new File(getSystemProperty(LOCAL_MAVEN_REPOSITORY_DIR))); } private String createPomXmlContent(String group, String[] executions, String[] steps) throws IOException { diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java index 6931974a9d..599621ece4 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java @@ -44,6 +44,7 @@ private MavenRunner() {} private File projectDir; private String[] args; + private File localRepositoryDir; public MavenRunner withProjectDir(File projectDir) { this.projectDir = Objects.requireNonNull(projectDir); @@ -55,13 +56,16 @@ public MavenRunner withArguments(String... args) { return this; } + public MavenRunner withLocalRepository(File localRepositoryDir) { + this.localRepositoryDir = localRepositoryDir; + return this; + } + private Result run() throws IOException, InterruptedException { Objects.requireNonNull(projectDir, "Need to call withProjectDir() first"); Objects.requireNonNull(args, "Need to call withArguments() first"); // run maven with the given args in the given directory - // -e to display execution errors at the console - // -U to force update of snapshots - List cmds = getPlatformCmds("-X -U " + Arrays.stream(args).collect(Collectors.joining(" "))); + List cmds = getPlatformCmds("-X -Dmaven.repo.local=" + localRepositoryDir + " " + Arrays.stream(args).collect(Collectors.joining(" "))); ProcessBuilder builder = new ProcessBuilder(cmds); builder.directory(projectDir); Process process = builder.start(); From 53d8013eff0aeaec24b98ca1f0ed94d957b70963 Mon Sep 17 00:00:00 2001 From: lutovich Date: Sun, 4 Feb 2018 22:17:21 +0100 Subject: [PATCH 76/91] Turn off debug logging and cleanup local repo cmd --- plugin-maven/build.gradle | 4 ++-- .../test/java/com/diffplug/spotless/maven/MavenRunner.java | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index 71894a7e6b..8c37e929af 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -43,13 +43,13 @@ def mvnw(String args) { return [ 'cmd', '/c', - 'mvnw.cmd -X ' + args + 'mvnw.cmd -e ' + args ] } else { return [ '/bin/sh', '-c', - './mvnw -X ' + args + './mvnw -e ' + args ] } } diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java index 599621ece4..9df160a935 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenRunner.java @@ -15,6 +15,7 @@ */ package com.diffplug.spotless.maven; +import static java.util.stream.Collectors.joining; import static org.assertj.core.api.Assertions.assertThat; import java.io.ByteArrayOutputStream; @@ -26,7 +27,6 @@ import java.util.List; import java.util.Locale; import java.util.Objects; -import java.util.stream.Collectors; import com.diffplug.common.base.Throwables; import com.diffplug.common.io.ByteStreams; @@ -65,7 +65,8 @@ private Result run() throws IOException, InterruptedException { Objects.requireNonNull(projectDir, "Need to call withProjectDir() first"); Objects.requireNonNull(args, "Need to call withArguments() first"); // run maven with the given args in the given directory - List cmds = getPlatformCmds("-X -Dmaven.repo.local=" + localRepositoryDir + " " + Arrays.stream(args).collect(Collectors.joining(" "))); + String argsString = Arrays.stream(args).collect(joining(" ")); + List cmds = getPlatformCmds("-e -Dmaven.repo.local=" + localRepositoryDir + ' ' + argsString); ProcessBuilder builder = new ProcessBuilder(cmds); builder.directory(projectDir); Process process = builder.start(); From d52a448d336be5c7d6e077b6059df39bceefe9d3 Mon Sep 17 00:00:00 2001 From: lutovich Date: Sun, 4 Feb 2018 22:21:18 +0100 Subject: [PATCH 77/91] Run all tests on CI --- .travis.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4ae3844215..278e0f4470 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,11 +2,8 @@ language: java jdk: - oraclejdk8 install: true -before_script: - - rm $HOME/.m2/settings.xml script: - - ./gradlew :plugin-maven:test -# - ./.ci/ci.sh + - ./.ci/ci.sh before_cache: - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ From 079e9a28cd176cc5a14a8d8ea7c381c094f5f109 Mon Sep 17 00:00:00 2001 From: lutovich Date: Sun, 4 Feb 2018 22:59:31 +0100 Subject: [PATCH 78/91] Removed repository declaration from POMs It is not needed because maven plugin and tests specify custom local repository via `-Dmaven.repo.local` system property. --- plugin-maven/build.gradle | 3 +- .../src/test/resources/pom-build.xml.mustache | 17 ---------- .../src/test/resources/pom-test.xml.mustache | 34 ------------------- 3 files changed, 1 insertion(+), 53 deletions(-) diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index 8c37e929af..995e406dc6 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -135,8 +135,7 @@ task createPomXml(dependsOn: installLocalDependencies) { mavenApiVersion : VER_MAVEN_API, eclipseAetherVersion : VER_ECLIPSE_AETHER, spotlessLibVersion : project.versionLib, - additionalDependencies : additionalDependencies, - localMavenRepositoryDir : LOCAL_MAVEN_REPO_DIR + additionalDependencies : additionalDependencies ] def pomXmlTemplate = Paths.get(PROJECT_DIR, "src/test/resources/pom-build.xml.mustache") diff --git a/plugin-maven/src/test/resources/pom-build.xml.mustache b/plugin-maven/src/test/resources/pom-build.xml.mustache index df64cdb6b0..7fbd6fc08e 100644 --- a/plugin-maven/src/test/resources/pom-build.xml.mustache +++ b/plugin-maven/src/test/resources/pom-build.xml.mustache @@ -20,23 +20,6 @@ {{spotlessLibVersion}} - - - local-repo - file://{{localMavenRepositoryDir}} - - true - always - ignore - - - true - always - ignore - - - - org.apache.maven diff --git a/plugin-maven/src/test/resources/pom-test.xml.mustache b/plugin-maven/src/test/resources/pom-test.xml.mustache index 183f3009eb..26350411d5 100644 --- a/plugin-maven/src/test/resources/pom-test.xml.mustache +++ b/plugin-maven/src/test/resources/pom-test.xml.mustache @@ -14,40 +14,6 @@ 1.8 - - - local-repo - file://{{localMavenRepositoryDir}} - - true - always - ignore - - - true - always - ignore - - - - - - - local-repo - file://{{localMavenRepositoryDir}} - - true - always - ignore - - - true - always - ignore - - - - From 3fdc785c0db2a02deec38ad37d6275e2888502a6 Mon Sep 17 00:00:00 2001 From: lutovich Date: Sun, 4 Feb 2018 23:30:38 +0100 Subject: [PATCH 79/91] Less verbose download logging when building maven plugin --- plugin-maven/build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index 995e406dc6..3607cf005d 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -157,7 +157,8 @@ task runMavenBuild(type: Exec, dependsOn: [ createPomXml ]) { workingDir MAVEN_PROJECT_DIR - commandLine mvnw("clean install -Dmaven.repo.local=${LOCAL_MAVEN_REPO_DIR}") + // -B batch mode to make dependency download logging less verbose + commandLine mvnw("clean install -B -Dmaven.repo.local=${LOCAL_MAVEN_REPO_DIR}") } jar.deleteAllActions() From 95c7fc965c7601676b60f3f6e0a629d7975ce221 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sun, 4 Feb 2018 22:50:50 -0800 Subject: [PATCH 80/91] Cache the localMavenRepository on Travis, but delete the com.diffplug.spotless group before caching. --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 278e0f4470..64aaa75f85 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,8 +7,9 @@ script: before_cache: - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ + - rm -fr plugin-maven/localMavenRepository/com/diffplug/spotless/ cache: directories: - $HOME/.gradle/caches/ - $HOME/.gradle/wrapper/ - - $HOME/.m2/ + - plugin-maven/localMavenRepository From d215905795533d17e26b7819640e8ead35e4841e Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sun, 4 Feb 2018 23:05:23 -0800 Subject: [PATCH 81/91] Added support for google-java-format's style parameter. --- plugin-maven/README.md | 2 ++ .../diffplug/spotless/maven/java/GoogleJavaFormat.java | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/plugin-maven/README.md b/plugin-maven/README.md index 69e4d08016..05322ac2be 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -99,6 +99,8 @@ By default, all compileSourceRoots will be formatted. Each element under ` 1.5 + + diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/GoogleJavaFormat.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/GoogleJavaFormat.java index afa8f3dedd..3247b22b49 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/GoogleJavaFormat.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/GoogleJavaFormat.java @@ -26,9 +26,13 @@ public class GoogleJavaFormat implements FormatterStepFactory { @Parameter private String version; + @Parameter + private String style; + @Override public FormatterStep newFormatterStep(FormatterStepConfig config) { - String formatterVersion = version == null ? GoogleJavaFormatStep.defaultVersion() : version; - return GoogleJavaFormatStep.create(formatterVersion, config.getProvisioner()); + String version = this.version != null ? this.version : GoogleJavaFormatStep.defaultVersion(); + String style = this.style != null ? this.style : GoogleJavaFormatStep.defaultStyle(); + return GoogleJavaFormatStep.create(version, style, config.getProvisioner()); } } From 2345cbd05efba14aca7ca58e8d9f25de5ad18ba1 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sun, 4 Feb 2018 23:22:10 -0800 Subject: [PATCH 82/91] Added `~/.m2` as a cached directory, because stuff gets downloaded for maven-install-plugin and the wrapper. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 64aaa75f85..1e30855fcc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,4 +12,5 @@ cache: directories: - $HOME/.gradle/caches/ - $HOME/.gradle/wrapper/ + - $HOME/.m2/ - plugin-maven/localMavenRepository From 0f9ff8e31c5be299be4774700991e0880e4a85cc Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sun, 4 Feb 2018 23:22:43 -0800 Subject: [PATCH 83/91] Added a test for GoogleJavaFormat's style parameter. --- .../maven/java/GoogleJavaFormatTest.java | 19 +++++++++++++++++-- .../JavaCodeFormattedAOSP.test | 11 +++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 plugin-maven/src/test/resources/java/googlejavaformat/JavaCodeFormattedAOSP.test diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/GoogleJavaFormatTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/GoogleJavaFormatTest.java index e384fd7941..c3b37d5a5c 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/GoogleJavaFormatTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/GoogleJavaFormatTest.java @@ -23,18 +23,33 @@ public class GoogleJavaFormatTest extends MavenIntegrationTest { @Test - public void defaultVersion() throws Exception { + public void specificVersionDefaultStyle() throws Exception { writePomWithJavaSteps( "", " 1.2", ""); write("src/main/java/test.java", getTestResource("java/googlejavaformat/JavaCodeUnformatted.test")); - write("formatter.xml", getTestResource("java/eclipse/format/formatter.xml")); mavenRunner().withArguments("spotless:apply").runNoError(); String actual = read("src/main/java/test.java"); assertThat(actual).isEqualTo(getTestResource("java/googlejavaformat/JavaCodeFormatted.test")); } + + @Test + public void specificVersionSpecificStyle() throws Exception { + writePomWithJavaSteps( + "", + " 1.2", + " ", + ""); + + write("src/main/java/test.java", getTestResource("java/googlejavaformat/JavaCodeUnformatted.test")); + + mavenRunner().withArguments("spotless:apply").runNoError(); + + String actual = read("src/main/java/test.java"); + assertThat(actual).isEqualTo(getTestResource("java/googlejavaformat/JavaCodeFormattedAOSP.test")); + } } diff --git a/plugin-maven/src/test/resources/java/googlejavaformat/JavaCodeFormattedAOSP.test b/plugin-maven/src/test/resources/java/googlejavaformat/JavaCodeFormattedAOSP.test new file mode 100644 index 0000000000..10ef7c35f9 --- /dev/null +++ b/plugin-maven/src/test/resources/java/googlejavaformat/JavaCodeFormattedAOSP.test @@ -0,0 +1,11 @@ + +import mylib.UsedA; +import mylib.UsedB; + +public class Java { + public static void main(String[] args) { + System.out.println("hello"); + UsedB.someMethod(); + UsedA.someMethod(); + } +} From 9cee2666b566be410d08f74bf6e5d472460dab5b Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sun, 4 Feb 2018 23:37:19 -0800 Subject: [PATCH 84/91] Gah! Fumble-fingers, I forgot the build. --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1e30855fcc..5de9f5b2c5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,10 +7,10 @@ script: before_cache: - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ - - rm -fr plugin-maven/localMavenRepository/com/diffplug/spotless/ + - rm -fr plugin-maven/build/localMavenRepository/com/diffplug/spotless/ cache: directories: - $HOME/.gradle/caches/ - $HOME/.gradle/wrapper/ - $HOME/.m2/ - - plugin-maven/localMavenRepository + - plugin-maven/build/localMavenRepository/ From 15e65a097b95d7e4e0baf09a88fe84c2af24d8d5 Mon Sep 17 00:00:00 2001 From: lutovich Date: Sat, 10 Feb 2018 19:23:54 +0100 Subject: [PATCH 85/91] Allow custom file includes and excludes This commit makes it possible to configure includes and excludes for paths/files with Ant style pattern in configuration groups (currently Java and Scala). It also changes the default source roots for scanning. Default policy for scanning used to recursively start from the `basedir` and include files with needed extensions, like "*.java" or "*.scala". This worked fine for simple maven projects but resulted in a lot of extra work for multi-module maven projects. Same files had to be scanned more than once during parent and then child module scanning. Now scanning will use most common source roots for supported languages. They are "scr/main/java/**/*.java", "scr/test/java/**/*.java" for Java and "scr/main/scala/**/*.scala", "scr/main/scala/**/*.sc", "scr/test/scala/**/*.scala", "scr/test/scala/**/*.sc" for Scala. So only these common source roots will be scanned by default. Mentioned patters form default includes. Default excludes are empty, except output directory (usually "target"), temporary files and VCS files are always skipped. It is possible to override includes and add excludes. This can be done like this: ``` src/**/java/**/*.java other/java/**/*.java src/test/java/**/*Example.java ``` Similar configuration is possible for Scala. Custom includes completely override default includes. Default excludes of output directory, temporary and VCS files can't be overridden. --- .../spotless/maven/AbstractSpotlessMojo.java | 52 ++--- .../spotless/maven/FormatterFactory.java | 23 ++- .../diffplug/spotless/maven/java/Java.java | 10 +- .../diffplug/spotless/maven/scala/Scala.java | 7 +- .../spotless/maven/IncludesExcludesTest.java | 190 ++++++++++++++++++ 5 files changed, 239 insertions(+), 43 deletions(-) create mode 100644 plugin-maven/src/test/java/com/diffplug/spotless/maven/IncludesExcludesTest.java diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java index f574ac0ee7..95a038cfc0 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java @@ -15,22 +15,19 @@ */ package com.diffplug.spotless.maven; -import static java.util.stream.Collectors.toList; - import java.io.File; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.Arrays; +import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.stream.Stream; 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.codehaus.plexus.util.FileUtils; import org.eclipse.aether.RepositorySystem; import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.repository.RemoteRepository; @@ -46,8 +43,6 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo { private static final String DEFAULT_ENCODING = "UTF-8"; private static final String DEFAULT_LINE_ENDINGS = "GIT_ATTRIBUTES"; - private static final String FILE_EXTENSION_SEPARATOR = "."; - @Component private RepositorySystem repositorySystem; @@ -89,39 +84,34 @@ public final void execute() throws MojoExecutionException, MojoFailureException } private void execute(FormatterFactory formatterFactory) throws MojoExecutionException { - List files = collectFiles(formatterFactory.fileExtensions()); + List files = collectFiles(formatterFactory); Formatter formatter = formatterFactory.newFormatter(files, getFormatterConfig()); process(files, formatter); } - private List collectFiles(Set extensions) throws MojoExecutionException { - Path projectDir = baseDir.toPath(); - Path outputDir = targetDir.toPath(); + @SuppressWarnings("unchecked") + private List collectFiles(FormatterFactory formatterFactory) throws MojoExecutionException { + Set configuredIncludes = formatterFactory.includes(); + Set configuredExcludes = formatterFactory.excludes(); + + Set includes = configuredIncludes.isEmpty() ? formatterFactory.defaultIncludes() : configuredIncludes; + + Set excludes = new HashSet<>(FileUtils.getDefaultExcludesAsList()); + excludes.add(withTrailingSeparator(targetDir.toString())); + excludes.addAll(configuredExcludes); - try (Stream entries = Files.walk(projectDir)) { - return entries.filter(entry -> !entry.startsWith(outputDir)) - .filter(Files::isRegularFile) - .filter(file -> hasExtension(file, extensions)) - .map(Path::toFile) - .collect(toList()); + String includesString = String.join(",", includes); + String excludesString = String.join(",", excludes); + + try { + return FileUtils.getFiles(baseDir, includesString, excludesString); } catch (IOException e) { - throw new MojoExecutionException("Unable to walk the file tree rooted at " + projectDir, e); + throw new MojoExecutionException("Unable to scan file tree rooted at " + baseDir, e); } } - private static boolean hasExtension(Path file, Set extensions) { - Path fileName = file.getFileName(); - if (fileName == null) { - return false; - } else { - String fileNameString = fileName.toString(); - for (String extension : extensions) { - if (fileNameString.endsWith(FILE_EXTENSION_SEPARATOR + extension)) { - return true; - } - } - return false; - } + private static String withTrailingSeparator(String path) { + return path.endsWith(File.separator) ? path : path + File.separator; } private FormatterConfig getFormatterConfig() { diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java index aef9e27ad3..f459aa78b5 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java @@ -15,17 +15,16 @@ */ package com.diffplug.spotless.maven; +import static java.util.Collections.emptySet; import static java.util.stream.Collectors.toList; import java.io.File; import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.Set; +import java.util.*; import org.apache.maven.plugins.annotations.Parameter; +import com.diffplug.common.collect.Sets; import com.diffplug.spotless.FormatExceptionPolicyStrict; import com.diffplug.spotless.Formatter; import com.diffplug.spotless.FormatterStep; @@ -38,12 +37,26 @@ public abstract class FormatterFactory { @Parameter private LineEnding lineEndings; + @Parameter + private String[] includes; + + @Parameter + private String[] excludes; + private final List stepFactories = new ArrayList<>(); - public abstract Set fileExtensions(); + public abstract Set defaultIncludes(); public abstract String licenseHeaderDelimiter(); + public final Set includes() { + return includes == null ? emptySet() : Sets.newHashSet(includes); + } + + public final Set excludes() { + return excludes == null ? emptySet() : Sets.newHashSet(excludes); + } + public final Formatter newFormatter(List filesToFormat, FormatterConfig config) { Charset formatterEncoding = encoding(config); LineEnding formatterLineEndings = lineEndings(config); diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java index 8f9f4fb582..e63c5240d2 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java @@ -15,7 +15,8 @@ */ package com.diffplug.spotless.maven.java; -import static java.util.Collections.singleton; +import static com.diffplug.common.collect.Sets.newHashSet; +import static java.util.Collections.unmodifiableSet; import java.util.Set; @@ -23,12 +24,13 @@ import com.diffplug.spotless.maven.generic.LicenseHeader; public class Java extends FormatterFactory { - private static final String EXTENSION = "java"; + private static final Set DEFAULT_INCLUDES = unmodifiableSet(newHashSet("src/main/java/**/*.java", + "src/test/java/**/*.java")); private static final String LICENSE_HEADER_DELIMITER = "package "; @Override - public Set fileExtensions() { - return singleton(EXTENSION); + public Set defaultIncludes() { + return DEFAULT_INCLUDES; } @Override diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scala.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scala.java index e1df191946..3e9069631d 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scala.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scala.java @@ -24,12 +24,13 @@ import com.diffplug.spotless.maven.generic.LicenseHeader; public class Scala extends FormatterFactory { - private static final Set FILE_EXTENSIONS = unmodifiableSet(newHashSet("scala", "sc")); + private static final Set DEFAULT_INCLUDES = unmodifiableSet(newHashSet("src/main/scala/**/*.scala", + "src/test/scala/**/*.scala", "src/main/scala/**/*.sc", "src/test/scala/**/*.sc")); private static final String LICENSE_HEADER_DELIMITER = "package "; @Override - public Set fileExtensions() { - return FILE_EXTENSIONS; + public Set defaultIncludes() { + return DEFAULT_INCLUDES; } @Override diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/IncludesExcludesTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/IncludesExcludesTest.java new file mode 100644 index 0000000000..a6dd0807fa --- /dev/null +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/IncludesExcludesTest.java @@ -0,0 +1,190 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.spotless.maven; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; + +import org.junit.Test; + +public class IncludesExcludesTest extends MavenIntegrationTest { + + private static final String JAVA_FORMATTED = "java/eclipse/format/JavaCodeFormatted.test"; + private static final String JAVA_UNFORMATTED = "java/eclipse/format/JavaCodeUnformatted.test"; + private static final String SCALA_UNFORMATTED = "scala/scalafmt/basic.dirty"; + private static final String SCALA_FORMATTED = "scala/scalafmt/basic.clean"; + + @Test + public void testDefaultIncludesJava() throws Exception { + String unformattedCorrectLocation1 = "src/main/java/test1.java"; + String unformattedCorrectLocation2 = "src/main/java/test2.java"; + String unformattedCorrectLocation3 = "src/test/java/test3.java"; + String unformattedCorrectLocation4 = "src/test/java/test4.java"; + String formattedCorrectLocation = "src/main/java/test5.java"; + String unformattedIncorrectLocation1 = "src/main/my-java/test6.java"; + String unformattedIncorrectLocation2 = "sources/main/java/test7.java"; + + writePomWithJavaSteps( + "", + " ${basedir}/formatter.xml", + ""); + + write("formatter.xml", getTestResource("java/eclipse/format/formatter.xml")); + + writeUnformattedJava(unformattedCorrectLocation1); + writeUnformattedJava(unformattedCorrectLocation2); + writeUnformattedJava(unformattedCorrectLocation3); + writeUnformattedJava(unformattedCorrectLocation4); + writeFormattedJava(formattedCorrectLocation); + writeUnformattedJava(unformattedIncorrectLocation1); + writeUnformattedJava(unformattedIncorrectLocation2); + + mavenRunner().withArguments("spotless:apply").runNoError(); + + assertFormattedJava(unformattedCorrectLocation1); + assertFormattedJava(unformattedCorrectLocation2); + assertFormattedJava(unformattedCorrectLocation3); + assertFormattedJava(unformattedCorrectLocation4); + assertFormattedJava(formattedCorrectLocation); + assertUnformattedJava(unformattedIncorrectLocation1); + assertUnformattedJava(unformattedIncorrectLocation2); + } + + @Test + public void testDefaultIncludesScala() throws Exception { + String unformattedCorrectLocation1 = "src/main/scala/test1.scala"; + String unformattedCorrectLocation2 = "src/main/scala/test2.sc"; + String unformattedCorrectLocation3 = "src/test/scala/test3.sc"; + String unformattedCorrectLocation4 = "src/test/scala/test4.scala"; + String formattedCorrectLocation = "src/test/scala/test5.scala"; + String unformattedIncorrectLocation1 = "src/main/not-scala/test6.sc"; + String unformattedIncorrectLocation2 = "scala/scala/scala/test7.scala"; + + writePomWithScalaSteps(""); + + writeUnformattedScala(unformattedCorrectLocation1); + writeUnformattedScala(unformattedCorrectLocation2); + writeUnformattedScala(unformattedCorrectLocation3); + writeUnformattedScala(unformattedCorrectLocation4); + writeFormattedScala(formattedCorrectLocation); + writeUnformattedScala(unformattedIncorrectLocation1); + writeUnformattedScala(unformattedIncorrectLocation2); + + mavenRunner().withArguments("spotless:apply").runNoError(); + + assertFormattedScala(unformattedCorrectLocation1); + assertFormattedScala(unformattedCorrectLocation2); + assertFormattedScala(unformattedCorrectLocation3); + assertFormattedScala(unformattedCorrectLocation4); + assertFormattedScala(formattedCorrectLocation); + assertUnformattedScala(unformattedIncorrectLocation1); + assertUnformattedScala(unformattedIncorrectLocation2); + } + + @Test + public void testInclude() throws Exception { + String unformattedDefaultLocation1 = "src/main/scala/test1.scala"; + String unformattedDefaultLocation2 = "src/test/scala/test2.scala"; + String unformattedCustomLocation1 = "src/main/my-scala/test3.scala"; + String unformattedCustomLocation2 = "src/test/sc/test4.sc"; + + writePomWithScalaSteps( + "", + " src/**/my-scala/*.scala", + " src/test/sc/*.sc", + "", + ""); + + writeUnformattedScala(unformattedDefaultLocation1); + writeUnformattedScala(unformattedDefaultLocation2); + writeUnformattedScala(unformattedCustomLocation1); + writeUnformattedScala(unformattedCustomLocation2); + + mavenRunner().withArguments("spotless:apply").runNoError(); + + // includes override default ones, so files in default location should remain unformatted + assertUnformattedScala(unformattedDefaultLocation1); + assertUnformattedScala(unformattedDefaultLocation2); + // files included via "" should be formatted + assertFormattedScala(unformattedCustomLocation1); + assertFormattedScala(unformattedCustomLocation2); + } + + @Test + public void testExclude() throws Exception { + String unformatted1 = "src/main/scala/test1.scala"; + String unformatted2 = "src/main/scala/test2.sc"; + String unformatted3 = "src/test/scala/test3.scala"; + String unformatted4 = "src/test/scala/test4.sc"; + + writePomWithScalaSteps( + "", + " src/main/scala/*.scala", + "", + "", + " src/main/scala/*.sc", + " src/test/scala", + "", + ""); + + writeUnformattedScala(unformatted1); + writeUnformattedScala(unformatted2); + writeUnformattedScala(unformatted3); + writeUnformattedScala(unformatted4); + + mavenRunner().withArguments("spotless:apply").runNoError(); + + assertFormattedScala(unformatted1); + assertUnformattedScala(unformatted2); + assertUnformattedScala(unformatted3); + assertUnformattedScala(unformatted4); + } + + private void writeFormattedJava(String target) throws IOException { + write(target, getTestResource(JAVA_FORMATTED)); + } + + private void writeUnformattedJava(String target) throws IOException { + write(target, getTestResource(JAVA_UNFORMATTED)); + } + + private void assertFormattedJava(String target) throws IOException { + assertThat(read(target)).isEqualTo(getTestResource(JAVA_FORMATTED)); + } + + private void assertUnformattedJava(String target) throws IOException { + // #write() call adds a new line, append '\n' to the original unformatted java + assertThat(read(target)).isEqualTo(getTestResource(JAVA_UNFORMATTED) + '\n'); + } + + private void writeFormattedScala(String target) throws IOException { + write(target, getTestResource(SCALA_FORMATTED)); + } + + private void writeUnformattedScala(String target) throws IOException { + write(target, getTestResource(SCALA_UNFORMATTED)); + } + + private void assertFormattedScala(String target) throws IOException { + assertThat(read(target)).isEqualTo(getTestResource(SCALA_FORMATTED)); + } + + private void assertUnformattedScala(String target) throws IOException { + // #write() call adds a new line, append '\n' to the original unformatted scala + assertThat(read(target)).isEqualTo(getTestResource(SCALA_UNFORMATTED) + '\n'); + } +} From 740317cf26c21f3244c8dd3a11a580a1d67495ee Mon Sep 17 00:00:00 2001 From: lutovich Date: Sat, 10 Feb 2018 19:48:46 +0100 Subject: [PATCH 86/91] Added docs about includes & excludes configuration --- plugin-maven/README.md | 60 ++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/plugin-maven/README.md b/plugin-maven/README.md index 05322ac2be..6da86878cb 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -31,22 +31,25 @@ To people who use your build, it looks like this: ``` cmd> mvn spotless:check ... -:spotlessJavaCheck FAILED -> The following files had format violations: - src\main\java\com\diffplug\gradle\spotless\FormatExtension.java - @@ -109,7 +109,7 @@ - ... - -\t\t····if·(targets.length·==·0)·{ - +\t\tif·(targets.length·==·0)·{ - ... - Run 'mvn spotless:apply' to fix these violations. +[ERROR] ... The following files had format violations: +[ERROR] src\main\java\com\diffplug\gradle\spotless\FormatExtension.java +[ERROR] @@ -109,7 +109,7 @@ +[ERROR] ... +[ERROR] -\t\t····if·(targets.length·==·0)·{ +[ERROR] +\t\tif·(targets.length·==·0)·{ +[ERROR] ... +[ERROR] Run 'mvn spotless:apply' to fix these violations. +... cmd> mvn spotless:apply -:spotlessApply -BUILD SUCCESSFUL +... +[INFO] BUILD SUCCESS +... cmd> mvn spotless:check -BUILD SUCCESSFUL +... +[INFO] BUILD SUCCESS +... ``` To use it in your pom, just [add the Spotless dependency](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.diffplug.spotless%22%20AND%20a%3A%22spotless-maven-plugin%22), and configure it like so: @@ -81,7 +84,7 @@ Spotless requires Maven to be running on JRE 8+. ## Applying to Java source -By default, all compileSourceRoots will be formatted. Each element under `` is a step, and they will be applied in the order specified. Every step is optional, and they will be applied in the order specified. It doesn't make sense to use both eclipse and google-java-format. +By default, all files matching `src/main/java/**/*.java` and `src/test/java/**/*.java` Ant style pattern will be formatted. Each element under `` is a step, and they will be applied in the order specified. Every step is optional, and they will be applied in the order specified. It doesn't make sense to use both eclipse and google-java-format. ```xml @@ -134,12 +137,41 @@ You can easily set the line endings of different files using [a `.gitattributes` + + +## File incudes and excludes + +Spotless uses [Ant style patterns](https://ant.apache.org/manual/dirtasks.html) to define included and excluded files. +By default, most common compile and test source roots for the supported languages are included. They are `scr/main/java/**/*.java`, `scr/test/java/**/*.java` for Java and `scr/main/scala/**/*.scala`, `scr/main/scala/**/*.sc`, `scr/test/scala/**/*.scala`, `scr/test/scala/**/*.sc` for Scala. +Includes can be completely overriden using `...` configuration section. + +Default excludes only contain output directory (usually `target/`) and various temporary and VCS-related files. Additional excludes can also be configured. + +Includes and excludes can be configured the same way for all supported languages. Excample for Java: + +```xml + + + + src/**/java/**/*.java + + + other/java/**/*.java + + + + + src/test/java/**/*Example.java + + +``` + ## Disabling warnings and error messages By default, `spotless:check` is bound to the `verify` phase. You might want to disable this behavior. We [recommend against this](https://github.com/diffplug/spotless/issues/79#issuecomment-290844602), but it's easy to do if you'd like: - set `-Dspotless.check.skip=true` at the command line -- set `spotless.check.skip` to `true` in the `` section +- set `spotless.check.skip` to `true` in the `` section of the `pom.xml` From a154f599075b9c3bcca1d19cee0d6694d86a4e6c Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sat, 10 Feb 2018 11:51:58 -0800 Subject: [PATCH 87/91] Fix serialization warning. --- .../com/diffplug/spotless/maven/ArtifactResolutionException.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/ArtifactResolutionException.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/ArtifactResolutionException.java index 398b357a62..c15ee04274 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/ArtifactResolutionException.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/ArtifactResolutionException.java @@ -15,6 +15,7 @@ */ package com.diffplug.spotless.maven; +@SuppressWarnings("serial") public class ArtifactResolutionException extends RuntimeException { public ArtifactResolutionException(String message, Throwable cause) { From 49987d78d10968ecc9671e8dbc3ab9e29efcc913 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sat, 10 Feb 2018 12:26:11 -0800 Subject: [PATCH 88/91] Update README because maven-plugin is integrated with scala. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7a00046190..5b4a911ec1 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ lib('java.RemoveUnusedImportsStep') +'{{yes}} | {{yes}} extra('java.EclipseFormatterStep') +'{{yes}} | {{yes}} | {{no}} |', lib('kotlin.KtLintStep') +'{{yes}} | {{no}} | {{no}} |', lib('markdown.FreshMarkStep') +'{{yes}} | {{no}} | {{no}} |', -lib('scala.ScalaFmtStep') +'{{yes}} | {{no}} | {{no}} |', +lib('scala.ScalaFmtStep') +'{{yes}} | {{yes}} | {{no}} |', lib('sql.DBeaverSQLFormatterStep') +'{{yes}} | {{no}} | {{no}} |', '| [(Your FormatterStep here)](https://github.com/nedtwigg/spotless/blob/markdown-preview-temp/CONTRIBUTING.md#how-to-add-a-new-formatterstep) | {{no}} | {{no}} | {{no}} |', '| Fast up-to-date checking | {{yes}} | {{no}} | {{no}} |', @@ -68,7 +68,7 @@ lib('sql.DBeaverSQLFormatterStep') +'{{yes}} | {{no}} | [`java.EclipseFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/java/EclipseFormatterStep.java) | :+1: | :+1: | :white_large_square: | | [`kotlin.KtLintStep`](lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java) | :+1: | :white_large_square: | :white_large_square: | | [`markdown.FreshMarkStep`](lib/src/main/java/com/diffplug/spotless/markdown/FreshMarkStep.java) | :+1: | :white_large_square: | :white_large_square: | -| [`scala.ScalaFmtStep`](lib/src/main/java/com/diffplug/spotless/scala/ScalaFmtStep.java) | :+1: | :white_large_square: | :white_large_square: | +| [`scala.ScalaFmtStep`](lib/src/main/java/com/diffplug/spotless/scala/ScalaFmtStep.java) | :+1: | :+1: | :white_large_square: | | [`sql.DBeaverSQLFormatterStep`](lib/src/main/java/com/diffplug/spotless/sql/DBeaverSQLFormatterStep.java) | :+1: | :white_large_square: | :white_large_square: | | [(Your FormatterStep here)](https://github.com/nedtwigg/spotless/blob/markdown-preview-temp/CONTRIBUTING.md#how-to-add-a-new-formatterstep) | :white_large_square: | :white_large_square: | :white_large_square: | | Fast up-to-date checking | :+1: | :white_large_square: | :white_large_square: | From 81477a66fb1496c7ecf13eff920ef07727c532d0 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sat, 10 Feb 2018 12:27:19 -0800 Subject: [PATCH 89/91] Add @lutovich as first author of the maven plugin for the mavencentral pom. --- gradle/java-publish.gradle | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gradle/java-publish.gradle b/gradle/java-publish.gradle index bd98439492..6502b6e7fc 100644 --- a/gradle/java-publish.gradle +++ b/gradle/java-publish.gradle @@ -98,6 +98,13 @@ model { } } developers { + if (project.ext.artifactId == 'spotless-plugin-maven') { + developer { + id 'lutovich' + name 'Konstantin Lutovich' + email 'konstantin.lutovich@neotechnology.com' + } + } developer { id 'nedtwigg' name 'Ned Twigg' From a934a735c8b975e7d727d00697ab9c6c698f863b Mon Sep 17 00:00:00 2001 From: lutovich Date: Mon, 12 Feb 2018 00:51:09 +0100 Subject: [PATCH 90/91] Fixed LicenseHeader when configured globally Generic formatting steps, like LicenseHeader can be defined both globally and inside language configs. Example: ``` ... ... ``` Previously global config had no effect. This commit fixes the problem by passing globally configured generic steps down to `FormatterFactory` which creates steps and uses globally configured ones, unless overridden. --- .../spotless/maven/AbstractSpotlessMojo.java | 30 ++++++++++++---- .../spotless/maven/FormatterConfig.java | 12 ++++++- .../spotless/maven/FormatterFactory.java | 24 +++++++++++-- .../spotless/maven/MavenIntegrationTest.java | 35 ++++++++++++------- .../spotless/maven/SpotlessCheckMojoTest.java | 10 +++--- .../maven/generic/LicenseHeaderTest.java | 11 ++++++ 6 files changed, 96 insertions(+), 26 deletions(-) diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java index 95a038cfc0..04fb5001cf 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java @@ -15,12 +15,15 @@ */ package com.diffplug.spotless.maven; +import static java.util.stream.Collectors.toList; + import java.io.File; import java.io.IOException; -import java.util.Arrays; import java.util.HashSet; import java.util.List; +import java.util.Objects; import java.util.Set; +import java.util.stream.Stream; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; @@ -35,6 +38,7 @@ import com.diffplug.spotless.Formatter; import com.diffplug.spotless.LineEnding; import com.diffplug.spotless.Provisioner; +import com.diffplug.spotless.maven.generic.LicenseHeader; import com.diffplug.spotless.maven.java.Java; import com.diffplug.spotless.maven.scala.Scala; @@ -64,6 +68,9 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo { @Parameter(defaultValue = DEFAULT_LINE_ENDINGS) private LineEnding lineEndings; + @Parameter + private LicenseHeader licenseHeader; + @Parameter private Java java; @@ -74,12 +81,10 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo { @Override public final void execute() throws MojoExecutionException, MojoFailureException { - List formatterFactories = Arrays.asList(java, scala); + List formatterFactories = getFormatterFactories(); for (FormatterFactory formatterFactory : formatterFactories) { - if (formatterFactory != null) { - execute(formatterFactory); - } + execute(formatterFactory); } } @@ -117,6 +122,19 @@ private static String withTrailingSeparator(String path) { private FormatterConfig getFormatterConfig() { ArtifactResolver resolver = new ArtifactResolver(repositorySystem, repositorySystemSession, repositories, getLog()); Provisioner provisioner = MavenProvisioner.create(resolver); - return new FormatterConfig(baseDir, encoding, lineEndings, provisioner); + List formatterStepFactories = getFormatterStepFactories(); + return new FormatterConfig(baseDir, encoding, lineEndings, provisioner, formatterStepFactories); + } + + private List getFormatterFactories() { + return Stream.of(java, scala) + .filter(Objects::nonNull) + .collect(toList()); + } + + private List getFormatterStepFactories() { + return Stream.of(licenseHeader) + .filter(Objects::nonNull) + .collect(toList()); } } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java index a31ac47ab3..5656ddb8f9 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java @@ -15,7 +15,10 @@ */ package com.diffplug.spotless.maven; +import static java.util.Collections.unmodifiableList; + import java.io.File; +import java.util.List; import com.diffplug.spotless.LineEnding; import com.diffplug.spotless.Provisioner; @@ -26,12 +29,15 @@ public class FormatterConfig { private final String encoding; private final LineEnding lineEndings; private final Provisioner provisioner; + private final List globalStepFactories; - public FormatterConfig(File baseDir, String encoding, LineEnding lineEndings, Provisioner provisioner) { + public FormatterConfig(File baseDir, String encoding, LineEnding lineEndings, Provisioner provisioner, + List globalStepFactories) { this.baseDir = baseDir; this.encoding = encoding; this.lineEndings = lineEndings; this.provisioner = provisioner; + this.globalStepFactories = globalStepFactories; } public File getBaseDir() { @@ -49,4 +55,8 @@ public LineEnding getLineEndings() { public Provisioner getProvisioner() { return provisioner; } + + public List getGlobalStepFactories() { + return unmodifiableList(globalStepFactories); + } } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java index f459aa78b5..770c23ee17 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java @@ -20,7 +20,10 @@ import java.io.File; import java.nio.charset.Charset; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Set; import org.apache.maven.plugins.annotations.Parameter; @@ -63,8 +66,9 @@ public final Formatter newFormatter(List filesToFormat, FormatterConfig co LineEnding.Policy formatterLineEndingPolicy = formatterLineEndings.createPolicy(config.getBaseDir(), () -> filesToFormat); FormatterStepConfig stepConfig = stepConfig(formatterEncoding, config); + List factories = gatherStepFactories(config.getGlobalStepFactories(), stepFactories); - List formatterSteps = stepFactories.stream() + List formatterSteps = factories.stream() .filter(Objects::nonNull) // all unrecognized steps from XML config appear as nulls in the list .map(factory -> factory.newFormatterStep(stepConfig)) .collect(toList()); @@ -94,4 +98,20 @@ private LineEnding lineEndings(FormatterConfig config) { private FormatterStepConfig stepConfig(Charset encoding, FormatterConfig config) { return new FormatterStepConfig(encoding, licenseHeaderDelimiter(), config.getProvisioner()); } + + private static List gatherStepFactories(List allGlobal, List allConfigured) { + List result = new ArrayList<>(); + for (FormatterStepFactory global : allGlobal) { + if (!formatterStepOverriden(global, allConfigured)) { + result.add(global); + } + } + result.addAll(allConfigured); + return result; + } + + private static boolean formatterStepOverriden(FormatterStepFactory global, List allConfigured) { + return allConfigured.stream() + .anyMatch(configured -> configured.getClass() == global.getClass()); + } } diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java index 147be22e99..d9f25a2bd1 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java @@ -16,7 +16,6 @@ package com.diffplug.spotless.maven; import static com.diffplug.common.base.Strings.isNullOrEmpty; -import static java.util.stream.Collectors.joining; import static org.junit.Assert.fail; import java.io.BufferedReader; @@ -27,7 +26,6 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -82,15 +80,19 @@ private File copy(String path) throws IOException { } protected void writePomWithJavaSteps(String... steps) throws IOException { - writePom("java", null, steps); + writePom(groupWithSteps("java", steps)); } protected void writePomWithScalaSteps(String... steps) throws IOException { - writePom("scala", null, steps); + writePom(groupWithSteps("scala", steps)); } - protected void writePom(String group, String[] executions, String[] steps) throws IOException { - String pomXmlContent = createPomXmlContent(group, executions, steps); + protected void writePom(String... configuration) throws IOException { + writePom(null, configuration); + } + + protected void writePom(String[] executions, String[] configuration) throws IOException { + String pomXmlContent = createPomXmlContent(executions, configuration); write("pom.xml", pomXmlContent); } @@ -100,26 +102,25 @@ protected MavenRunner mavenRunner() throws IOException { .withLocalRepository(new File(getSystemProperty(LOCAL_MAVEN_REPOSITORY_DIR))); } - private String createPomXmlContent(String group, String[] executions, String[] steps) throws IOException { + private String createPomXmlContent(String[] executions, String[] configuration) throws IOException { URL url = MavenIntegrationTest.class.getResource("/pom-test.xml.mustache"); try (BufferedReader reader = Resources.asCharSource(url, StandardCharsets.UTF_8).openBufferedStream()) { Mustache mustache = mustacheFactory.compile(reader, "pom"); StringWriter writer = new StringWriter(); - Map params = buildPomXmlParams(group, executions, steps); + Map params = buildPomXmlParams(executions, configuration); mustache.execute(writer, params); return writer.toString(); } } - private static Map buildPomXmlParams(String group, String[] executions, String[] steps) { + private static Map buildPomXmlParams(String[] executions, String[] configuration) { Map params = new HashMap<>(); params.put(LOCAL_MAVEN_REPOSITORY_DIR, getSystemProperty(LOCAL_MAVEN_REPOSITORY_DIR)); params.put(SPOTLESS_MAVEN_PLUGIN_VERSION, getSystemProperty(SPOTLESS_MAVEN_PLUGIN_VERSION)); - String prefix = String.format("<%s>\n", group); - String suffix = String.format("\n", group); - String stepsXml = Arrays.stream(steps).collect(joining("\n", prefix, suffix)); - params.put(CONFIGURATION, stepsXml); + if (configuration != null) { + params.put(CONFIGURATION, String.join("\n", configuration)); + } if (executions != null) { params.put(EXECUTIONS, String.join("\n", executions)); @@ -135,4 +136,12 @@ private static String getSystemProperty(String name) { } return value; } + + private static String[] groupWithSteps(String group, String... steps) { + String[] result = new String[steps.length + 2]; + result[0] = '<' + group + '>'; + System.arraycopy(steps, 0, result, 1, steps.length); + result[result.length - 1] = "'; + return result; + } } diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/SpotlessCheckMojoTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/SpotlessCheckMojoTest.java index 7db1bafcde..cda89aba4f 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/SpotlessCheckMojoTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/SpotlessCheckMojoTest.java @@ -46,7 +46,7 @@ public void testSkipSpotlessCheckWithFormattingViolations() throws Exception { @Test public void testSpotlessCheckBindingToVerifyPhase() throws Exception { - writePom("java", + writePom( new String[]{ "", " check", @@ -55,9 +55,11 @@ public void testSpotlessCheckBindingToVerifyPhase() throws Exception { " ", ""}, new String[]{ - "", - " ${basedir}/license.txt", - ""}); + "", + " ", + " ${basedir}/license.txt", + " ", + ""}); testSpotlessCheck(UNFORMATTED_FILE, "verify", true); } diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/generic/LicenseHeaderTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/generic/LicenseHeaderTest.java index 80986d0311..cf41bbbbc7 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/generic/LicenseHeaderTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/generic/LicenseHeaderTest.java @@ -46,6 +46,17 @@ public void fromContent() throws Exception { runTest(); } + @Test + public void fromFileGlobal() throws Exception { + write("license.txt", getTestResource(KEY_LICENSE)); + writePom("", + " ${basedir}/license.txt", + "", + ""); + + runTest(); + } + private void runTest() throws Exception { write("src/main/java/test.java", getTestResource("license/MissingLicense.test")); mavenRunner().withArguments("spotless:apply").runNoError(); From 41625694f378377a3d8534e5714de455c34b767c Mon Sep 17 00:00:00 2001 From: lutovich Date: Mon, 12 Feb 2018 01:02:35 +0100 Subject: [PATCH 91/91] Moved license header config handling to FormatterFactory License header is a generic step that is applicable to both `Java` and `Scala`. This commit moves adder for it to `FormatterFactory`, which is super class of both `Java` and `Scala`. Code duplication is thus a bit reduced. --- .../java/com/diffplug/spotless/maven/FormatterFactory.java | 5 +++++ .../src/main/java/com/diffplug/spotless/maven/java/Java.java | 5 ----- .../main/java/com/diffplug/spotless/maven/scala/Scala.java | 5 ----- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java index 770c23ee17..47b692a8c2 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java @@ -32,6 +32,7 @@ import com.diffplug.spotless.Formatter; import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.LineEnding; +import com.diffplug.spotless.maven.generic.LicenseHeader; public abstract class FormatterFactory { @Parameter @@ -82,6 +83,10 @@ public final Formatter newFormatter(List filesToFormat, FormatterConfig co .build(); } + public final void addLicenseHeader(LicenseHeader licenseHeader) { + addStepFactory(licenseHeader); + } + protected void addStepFactory(FormatterStepFactory stepFactory) { Objects.requireNonNull(stepFactory); stepFactories.add(stepFactory); diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java index e63c5240d2..f15444f75f 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Java.java @@ -21,7 +21,6 @@ import java.util.Set; import com.diffplug.spotless.maven.FormatterFactory; -import com.diffplug.spotless.maven.generic.LicenseHeader; public class Java extends FormatterFactory { private static final Set DEFAULT_INCLUDES = unmodifiableSet(newHashSet("src/main/java/**/*.java", @@ -38,10 +37,6 @@ public String licenseHeaderDelimiter() { return LICENSE_HEADER_DELIMITER; } - public void addLicenseHeader(LicenseHeader licenseHeader) { - addStepFactory(licenseHeader); - } - public void addEclipse(Eclipse eclipse) { addStepFactory(eclipse); } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scala.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scala.java index 3e9069631d..0f2034e883 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scala.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/scala/Scala.java @@ -21,7 +21,6 @@ import java.util.Set; import com.diffplug.spotless.maven.FormatterFactory; -import com.diffplug.spotless.maven.generic.LicenseHeader; public class Scala extends FormatterFactory { private static final Set DEFAULT_INCLUDES = unmodifiableSet(newHashSet("src/main/scala/**/*.scala", @@ -38,10 +37,6 @@ public String licenseHeaderDelimiter() { return LICENSE_HEADER_DELIMITER; } - public void addLicenseHeader(LicenseHeader licenseHeader) { - addStepFactory(licenseHeader); - } - public void addScalafmt(Scalafmt scalafmt) { addStepFactory(scalafmt); }