Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support multiple formats in Maven plugin #242

Merged
merged 2 commits into from
May 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions plugin-maven/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Fixed a bug in `LicenseHeaderStep` which caused an exception with some malformed date-aware licenses. ([#222](https://github.com/diffplug/spotless/pull/222))
* Added support for Kotlin and Ktlint in Maven plugin ([#223](https://github.com/diffplug/spotless/pull/223)).
* Updated default ktlint from 0.14.0 to 0.21.0
* Added support for multiple generic formatters in Maven plugin ([#242](https://github.com/diffplug/spotless/pull/242)).

### Version 1.0.0.BETA4 - February 27th 2018 ([javadoc](https://diffplug.github.io/spotless/javadoc/spotless-maven-plugin/1.0.0.BETA4/), [jcenter](https://bintray.com/diffplug/opensource/spotless-maven-plugin/1.0.0.BETA4))

Expand Down
95 changes: 51 additions & 44 deletions plugin-maven/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,53 +168,60 @@ By default, all files matching `src/main/kotlin/**/*.kt` and `src/test/kotlin/**

## Applying to custom sources

By default, no Ant-Style include patterns are defined. Each element under `<format>` 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.
By default, no Ant-Style include patterns are defined. Each element under `<format>` 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 is possible to define multiple custom formats.

```xml
<configuration>
<format>
<includes>
<!-- include all property files in "resource" folders under "src" -->
<include>src/**/resources/**/*.properties</include>
</includes>

<licenseHeader>
<!-- Specify either content or file, but not both -->
<content>/* Licensed under Apache-2.0 */</content>
<file>${basedir}/license-header</file>
<!-- conent until first occurrence of the delimiter regex will be interpreted as header section -->
<delimiter>#</delimiter>
</licenseHeader>

<!-- Files must end with a newline -->
<endWithNewline />

<!-- Specify whether to use tabs or spaces for indentation -->
<indent>
<!-- Specify either spaces or tabs -->
<spaces>true</spaces>
<tabs>true</tabs>
<!-- Specify how many spaces are used to convert one tab and vice versa. Defaults to 4 -->
<spacesPerTab>4</spacesPerTab>
</indent>

<!-- Trim trailing whitespaces -->
<trimTrailingWhitespace />

<!-- Specify replacements using search and replace -->
<replace>
<name>Say Hello to Mars</name>
<search>World</search>
<replacement>Mars</replacement>
</replace>

<!-- Specify replacements using regex match and replace -->
<replaceRegex>
<name>Say Hello to Mars from Regex</name>
<searchRegex>(Hello) W[a-z]{3}d</searchRegex>
<replacement>$1 Mars</replacement>
</replaceRegex>
</format>
<formats>

<!-- Define first formatter that operates on properties files -->
<format>
<includes>
<!-- Include all property files in "resource" folders under "src" -->
<include>src/**/resources/**/*.properties</include>
</includes>

<licenseHeader>
<!-- Specify either content or file, but not both -->
<content>/* Licensed under Apache-2.0 */</content>
<file>${basedir}/license-header</file>
<!-- conent until first occurrence of the delimiter regex will be interpreted as header section -->
<delimiter>#</delimiter>
</licenseHeader>

<!-- Files must end with a newline -->
<endWithNewline />

<!-- Specify whether to use tabs or spaces for indentation -->
<indent>
<!-- Specify either spaces or tabs -->
<spaces>true</spaces>
<tabs>true</tabs>
<!-- Specify how many spaces are used to convert one tab and vice versa. Defaults to 4 -->
<spacesPerTab>4</spacesPerTab>
</indent>

<!-- Trim trailing whitespaces -->
<trimTrailingWhitespace />

<!-- Specify replacements using search and replace -->
<replace>
<name>Say Hello to Mars</name>
<search>World</search>
<replacement>Mars</replacement>
</replace>

<!-- Specify replacements using regex match and replace -->
<replaceRegex>
<name>Say Hello to Mars from Regex</name>
<searchRegex>(Hello) W[a-z]{3}d</searchRegex>
<replacement>$1 Mars</replacement>
</replaceRegex>
</format>

<!-- Other formats can be defined here, they will be applied in the order specified -->

</formats>
</configuration>
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@

import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.*;
import java.util.stream.Stream;

import org.apache.maven.plugin.AbstractMojo;
Expand Down Expand Up @@ -78,7 +75,7 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo {
private LicenseHeader licenseHeader;

@Parameter
private Format format;
private List<Format> formats = Collections.emptyList();

@Parameter
private Java java;
Expand Down Expand Up @@ -146,7 +143,7 @@ private FileLocator getFileLocator() {
}

private List<FormatterFactory> getFormatterFactories() {
return Stream.of(format, java, scala, kotlin)
return Stream.concat(formats.stream(), Stream.of(java, scala, kotlin))
.filter(Objects::nonNull)
.collect(toList());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ private File copy(String path) throws IOException {
}

protected void writePomWithFormatSteps(String... steps) throws IOException {
writePom(groupWithSteps("format", including("<include>src/**/java/**/*.java</include>"), steps));
writePom(formats(groupWithSteps("format", including("<include>src/**/java/**/*.java</include>"), steps)));
}

protected void writePomWithJavaSteps(String... steps) throws IOException {
Expand Down Expand Up @@ -177,12 +177,12 @@ private static String[] groupWithSteps(String group, String... steps) {
return groupWithSteps(group, new String[]{}, steps);
}

private static String[] including(String... include) {
String[] result = new String[include.length + 2];
result[0] = "<includes>";
System.arraycopy(include, 0, result, 1, include.length);
result[result.length - 1] = "</includes>";
return result;
private static String[] including(String... includes) {
return groupWithSteps("includes", includes);
}

private static String[] formats(String... formats) {
return groupWithSteps("formats", formats);
}

protected class MultiModuleProjectCreator {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* 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 MultipleFormatsTest extends MavenIntegrationTest {

@Test
public void testMultipleFormatsWithDifferentIncludes() throws Exception {
writePom(
"<formats>",
" <format>",
" <includes>",
" <include>src/**/java/**/*.java</include>",
" </includes>",
" <replace>",
" <name>Greetings to Mars</name>",
" <search>World</search>",
" <replacement>Mars</replacement>",
" </replace>",
" <licenseHeader>",
" <content>// License Header #1</content>",
" <delimiter>package</delimiter>",
" </licenseHeader>",
" </format>",
" <format>",
" <includes>",
" <include>src/**/txt/**/*.txt</include>",
" </includes>",
" <replace>",
" <name>Greetings to Titan</name>",
" <search>World</search>",
" <replacement>Titan</replacement>",
" </replace>",
" <licenseHeader>",
" <content>// License Header #2</content>",
" <delimiter>Just</delimiter>",
" </licenseHeader>",
" </format>",
"</formats>");

String path1 = "src/main/java/test1.java";
String path2 = "src/main/java/test2.java";

String path3 = "src/main/txt/test1.txt";
String path4 = "src/main/txt/test2.txt";
String path5 = "src/main/txt/test3.txt";

setFile(path1).toContent("package test;\npublic class JavaWorld1 {}");
setFile(path2).toContent("package test;\npublic class JavaWorld2 {}");

setFile(path3).toContent("Just a text file #1\nHello World!");
setFile(path4).toContent("Just a text file #2\nHello World!");
setFile(path5).toContent("Just a text file #3\nHello World!");

mavenRunner().withArguments("spotless:apply").runNoError();

assertFile(path1).hasContent("// License Header #1\npackage test;\npublic class JavaMars1 {}");
assertFile(path2).hasContent("// License Header #1\npackage test;\npublic class JavaMars2 {}");

assertFile(path3).hasContent("// License Header #2\nJust a text file #1\nHello Titan!");
assertFile(path4).hasContent("// License Header #2\nJust a text file #2\nHello Titan!");
assertFile(path5).hasContent("// License Header #2\nJust a text file #3\nHello Titan!");
}
}