Skip to content

Commit

Permalink
Improved config handling in maven plugin
Browse files Browse the repository at this point in the history
Exposed `encoding` and `lineEndings` in the plugin xml configuration.
Renamed `eclipseFormatFile` to `eclipseConfigFile` and moved it inside
the `<java>` 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:

```
<plugin>
  <groupId>com.diffplug.spotless</groupId>
  <artifactId>spotless-maven-plugin</artifactId>
  <version>${spotless.version}</version>
  <configuration>
    <encoding>UTF-8</encoding>
    <lineEndings>UNIX</lineEndings>
    <java>
      <eclipseConfigFile>${basedir}/eclipse-fmt.xml</eclipseConfigFile>
    </java>
  </configuration>
</plugin>
```

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`.
  • Loading branch information
lutovich committed Jan 17, 2018
1 parent 9956473 commit c219ef1
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 53 deletions.
Original file line number Diff line number Diff line change
@@ -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<RemoteRepository> 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<Path> getAllSourceRoots() {
Stream<String> compileSourceRoots = project.getCompileSourceRoots().stream();
Stream<String> 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<File> filesToFormat) {
return lineEndings.createPolicy(getRootDir(), () -> filesToFormat);
}

protected File getRootDir() {
return project.getBasedir();
}

protected Java getJavaConfig() {
return java;
}
}
30 changes: 30 additions & 0 deletions plugin-maven/src/main/java/com/diffplug/gradle/spotless/Java.java
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<RemoteRepository> 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<File> filesToFormat = collectFilesToFormat();

// create the eclipse step
Set<File> 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<File> toFormat = new ArrayList<>();
for (String compileSourceRoot : project.getCompileSourceRoots()) {
Path root = Paths.get(compileSourceRoot);
formatAll(filesToFormat, formatter);
}

private List<File> collectFilesToFormat() throws MojoExecutionException {
List<File> filesToFormat = new ArrayList<>();
for (Path root : getAllSourceRoots()) {
try (Stream<Path> 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<File> 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<File> 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<File> 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);
}
}
}

0 comments on commit c219ef1

Please sign in to comment.