Skip to content

Commit 3e3c969

Browse files
authored
Merge pull request #555 from source-knights/master
Add Prettier to Maven plugin
2 parents 17ad8af + ef591ef commit 3e3c969

File tree

13 files changed

+368
-3
lines changed

13 files changed

+368
-3
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ lib('java.RemoveUnusedImportsStep') +'{{yes}} | {{yes}}
4646
extra('java.EclipseFormatterStep') +'{{yes}} | {{yes}} | {{no}} |',
4747
lib('kotlin.KtLintStep') +'{{yes}} | {{yes}} | {{no}} |',
4848
lib('markdown.FreshMarkStep') +'{{yes}} | {{no}} | {{no}} |',
49-
lib('npm.PrettierFormatterStep') +'{{yes}} | {{no}} | {{no}} |',
49+
lib('npm.PrettierFormatterStep') +'{{yes}} | {{yes}} | {{no}} |',
5050
lib('npm.TsFmtFormatterStep') +'{{yes}} | {{yes}} | {{no}} |',
5151
lib('scala.ScalaFmtStep') +'{{yes}} | {{yes}} | {{no}} |',
5252
lib('sql.DBeaverSQLFormatterStep') +'{{yes}} | {{no}} | {{no}} |',
@@ -73,7 +73,7 @@ extra('wtp.EclipseWtpFormatterStep') +'{{yes}} | {{yes}}
7373
| [`java.EclipseFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/java/EclipseFormatterStep.java) | :+1: | :+1: | :white_large_square: |
7474
| [`kotlin.KtLintStep`](lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java) | :+1: | :+1: | :white_large_square: |
7575
| [`markdown.FreshMarkStep`](lib/src/main/java/com/diffplug/spotless/markdown/FreshMarkStep.java) | :+1: | :white_large_square: | :white_large_square: |
76-
| [`npm.PrettierFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/PrettierFormatterStep.java) | :+1: | :white_large_square: | :white_large_square: |
76+
| [`npm.PrettierFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/PrettierFormatterStep.java) | :+1: | :+1: | :white_large_square: |
7777
| [`npm.TsFmtFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/TsFmtFormatterStep.java) | :+1: | :+1: | :white_large_square: |
7878
| [`scala.ScalaFmtStep`](lib/src/main/java/com/diffplug/spotless/scala/ScalaFmtStep.java) | :+1: | :+1: | :white_large_square: |
7979
| [`sql.DBeaverSQLFormatterStep`](lib/src/main/java/com/diffplug/spotless/sql/DBeaverSQLFormatterStep.java) | :+1: | :white_large_square: | :white_large_square: |

plugin-maven/CHANGES.md

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`).
44

55
## [Unreleased]
6+
###
7+
* Support for prettier ([#555](https://github.com/diffplug/spotless/pull/555)).
68

79
## [1.29.0] - 2020-04-02
810
### Added

plugin-maven/README.md

+66-1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ Spotless supports the following powerful formatters:
7676
* Eclipse's [CDT](https://www.eclipse.org/cdt/) C/C++ code formatter
7777
* Eclipse's [WTP](https://www.eclipse.org/webtools/) Web-Tools code formatters
7878
* Google's [google-java-format](https://github.com/google/google-java-format)
79+
* [Typescript Tsfmt formatter](https://github.com/vvakame/typescript-formatter)
80+
* [Prettier formatter](https://prettier.io)
7981
* User-defined license enforcement, regex replacement, etc.
8082

8183
Contributions are welcome, see [the contributing guide](../CONTRIBUTING.md) for development info.
@@ -200,11 +202,13 @@ Use the Eclipse to define the *Code Style preferences* (see [Eclipse documentati
200202
```xml
201203
<configuration>
202204
<typescript>
203-
<tsfmt>
205+
204206
<!-- optionally define which files will be formatted. -->
205207
<includes>
206208
<include>src/**/*.ts</include> <!-- default value if nothing is specified -->
207209
</includes>
210+
211+
<tsfmt>
208212
<!-- must specify exactly one of the following "{foo}File" or "config" elements -->
209213
<tslintFile>${basedir}/path/to/repo/tslint.json</tslintFile>
210214
<tsfmtFile>${basedir}/path/to/repo/tsfmt.json</tsfmtFile>
@@ -243,6 +247,67 @@ Spotless will try to auto-discover an npm installation. If that is not working f
243247

244248
Spotless uses npm to install necessary packages locally. It runs tsfmt using [J2V8](https://github.com/eclipsesource/J2V8) internally after that.
245249

250+
<a name="prettier"></a>
251+
252+
## Applying [Prettier](https://prettier.io) to javascript | flow | typeScript | css | scss | less | jsx | graphQL | yaml | etc.
253+
254+
Prettier is a formatter that can format [multiple file types](https://prettier.io/docs/en/language-support.html).
255+
256+
To use prettier, you first have to specify the files that you want it to apply to. Then you specify prettier, and how you want to apply it.
257+
258+
```xml
259+
<configuration>
260+
<formats>
261+
262+
<format>
263+
<includes>
264+
<include>src/**/typescript/**/*.ts</include>
265+
</includes>
266+
267+
<prettier>
268+
<!-- Specify either simple prettier version (1.19.0 is max supported,
269+
which is also default) or whole devDependencies -->
270+
<prettierVersion>1.19.0</prettierVersion>
271+
<devDependencies>
272+
<prettier>1.19.0</prettier>
273+
</devDependencies>
274+
275+
<!-- Specify config file and/or inline config -->
276+
<configFile>${basedir}/path/to/configfile</configFile>
277+
<config>
278+
<useTabs>true</useTabs>
279+
</config>
280+
</prettier>
281+
</format>
282+
283+
</formats>
284+
</configuration>
285+
```
286+
287+
Supported config options are documented on [prettier.io](https://prettier.io/docs/en/options.html).
288+
Supported config file variants are documented on [prettier.io](https://prettier.io/docs/en/configuration.html).
289+
290+
*Please note:*
291+
- The auto-discovery of config files (up the file tree) will not work when using prettier within spotless.
292+
- Prettier's override syntax is not supported when using prettier within spotless.
293+
294+
To apply prettier to more kinds of files, just add more formats.
295+
296+
### Prerequisite: prettier requires a working NodeJS version
297+
298+
Prettier, like tsfmt, is based on NodeJS, so to use it, a working NodeJS installation (especially npm) is required on the host running spotless.
299+
Spotless will try to auto-discover an npm installation. If that is not working for you, it is possible to directly configure the npm binary to use.
300+
301+
```xml
302+
<formats><format><prettier>
303+
<npmExecutable>/usr/bin/npm</npmExecutable>
304+
...
305+
```
306+
307+
Spotless uses npm to install necessary packages locally. It runs prettier using [J2V8](https://github.com/eclipsesource/J2V8) internally after that.
308+
Development for J2V8 for non android envs is stopped (for Windows since J2V8 4.6.0 and Unix 4.8.0), therefore Prettier is limited to <= v1.19.0 as newer versions
309+
use ES6 feature and that needs a newer J2V8 version.
310+
246311
<a name="format"></a>
247312

248313
## Applying to custom sources

plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java

+4
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ public final void addEclipseWtp(EclipseWtp eclipseWtp) {
111111
addStepFactory(eclipseWtp);
112112
}
113113

114+
public final void addPrettier(Prettier prettier) {
115+
addStepFactory(prettier);
116+
}
117+
114118
protected final void addStepFactory(FormatterStepFactory stepFactory) {
115119
Objects.requireNonNull(stepFactory);
116120
stepFactories.add(stepFactory);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Copyright 2016 DiffPlug
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.diffplug.spotless.maven.generic;
17+
18+
import java.io.File;
19+
import java.util.LinkedHashMap;
20+
import java.util.Map;
21+
22+
import org.apache.maven.plugins.annotations.Parameter;
23+
24+
import com.diffplug.spotless.FormatterStep;
25+
import com.diffplug.spotless.maven.FormatterStepConfig;
26+
import com.diffplug.spotless.maven.FormatterStepFactory;
27+
import com.diffplug.spotless.npm.PrettierConfig;
28+
import com.diffplug.spotless.npm.PrettierFormatterStep;
29+
30+
public class Prettier implements FormatterStepFactory {
31+
32+
@Parameter
33+
private String prettierVersion;
34+
35+
@Parameter
36+
private Map<String, String> devDependencies;
37+
38+
@Parameter
39+
private Map<String, String> config;
40+
41+
@Parameter
42+
private String configFile;
43+
44+
@Parameter
45+
private String npmExecutable;
46+
47+
@Override
48+
public FormatterStep newFormatterStep(FormatterStepConfig stepConfig) {
49+
50+
// check if config is only setup in one way
51+
if (this.prettierVersion != null && this.devDependencies != null) {
52+
throw onlyOneConfig();
53+
}
54+
55+
// set dev dependencies
56+
if (devDependencies == null) {
57+
if (prettierVersion == null || prettierVersion.isEmpty()) {
58+
devDependencies = PrettierFormatterStep.defaultDevDependencies();
59+
} else {
60+
devDependencies = PrettierFormatterStep.defaultDevDependenciesWithPrettier(prettierVersion);
61+
}
62+
}
63+
64+
File npm = npmExecutable != null ? stepConfig.getFileLocator().locateLocal(npmExecutable) : null;
65+
66+
// process config file or inline config
67+
File configFileHandler;
68+
if (this.configFile != null) {
69+
configFileHandler = stepConfig.getFileLocator().locateLocal(this.configFile);
70+
} else {
71+
configFileHandler = null;
72+
}
73+
74+
Map<String, Object> configInline;
75+
if (config != null) {
76+
configInline = new LinkedHashMap<>();
77+
// try to parse string values as integers or booleans
78+
for (Map.Entry<String, String> e : config.entrySet()) {
79+
try {
80+
configInline.put(e.getKey(), Integer.parseInt(e.getValue()));
81+
} catch (NumberFormatException ignore) {
82+
try {
83+
configInline.put(e.getKey(), Boolean.parseBoolean(e.getValue()));
84+
} catch (IllegalArgumentException ignore2) {
85+
configInline.put(e.getKey(), e.getValue());
86+
}
87+
}
88+
}
89+
} else {
90+
configInline = null;
91+
}
92+
93+
// create the format step
94+
PrettierConfig prettierConfig = new PrettierConfig(configFileHandler, configInline);
95+
File buildDir = stepConfig.getFileLocator().getBuildDir();
96+
return PrettierFormatterStep.create(devDependencies, stepConfig.getProvisioner(), buildDir, npm, prettierConfig);
97+
}
98+
99+
private static IllegalArgumentException onlyOneConfig() {
100+
return new IllegalArgumentException("must specify exactly one configFile or config");
101+
}
102+
}

plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationTest.java

+4
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ protected void writePomWithTypescriptSteps(String... steps) throws IOException {
130130
writePom(groupWithSteps("typescript", steps));
131131
}
132132

133+
protected void writePomWithPrettierSteps(String includes, String... steps) throws IOException {
134+
writePom(formats(groupWithSteps("format", including(includes), steps)));
135+
}
136+
133137
protected void writePom(String... configuration) throws IOException {
134138
writePom(null, configuration);
135139
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* Copyright 2016 DiffPlug
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.diffplug.spotless.maven.prettier;
17+
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
20+
import java.io.IOException;
21+
22+
import org.junit.Test;
23+
24+
import com.diffplug.spotless.maven.MavenIntegrationTest;
25+
import com.diffplug.spotless.maven.MavenRunner;
26+
27+
public class PrettierFormatStepTest extends MavenIntegrationTest {
28+
29+
private void run(String kind, String suffix) throws IOException, InterruptedException {
30+
String configPath = ".prettierrc.yml";
31+
setFile(configPath).toResource("npm/prettier/filetypes/" + kind + "/" + ".prettierrc.yml");
32+
String path = "src/main/" + kind + "/test." + suffix;
33+
setFile(path).toResource("npm/prettier/filetypes/" + kind + "/" + kind + ".dirty");
34+
mavenRunner().withArguments("spotless:apply").runNoError();
35+
assertFile(path).sameAsResource("npm/prettier/filetypes/" + kind + "/" + kind + ".clean");
36+
}
37+
38+
@Test
39+
public void prettier_typescript() throws Exception {
40+
String suffix = "ts";
41+
writePomWithPrettierSteps("**/*." + suffix,
42+
"<prettier>",
43+
" <prettierVersion>1.16.4</prettierVersion>",
44+
" <configFile>.prettierrc.yml</configFile>",
45+
"</prettier>");
46+
run("typescript", suffix);
47+
}
48+
49+
@Test
50+
public void prettier_html() throws Exception {
51+
String suffix = "html";
52+
writePomWithPrettierSteps("**/*." + suffix,
53+
"<prettier>",
54+
" <prettierVersion>1.16.4</prettierVersion>",
55+
" <configFile>.prettierrc.yml</configFile>",
56+
"</prettier>");
57+
run("html", suffix);
58+
}
59+
60+
@Test
61+
public void prettier_tsx() throws Exception {
62+
String suffix = "tsx";
63+
writePomWithPrettierSteps("src/main/**/*." + suffix,
64+
"<includes><include>src/**/*.tsx</include></includes>",
65+
"<prettier>",
66+
" <prettierVersion>1.16.4</prettierVersion>",
67+
" <configFile>.prettierrc.yml</configFile>",
68+
"</prettier>");
69+
run("tsx", suffix);
70+
}
71+
72+
@Test
73+
public void prettier_tsx_inline_config() throws Exception {
74+
String suffix = "tsx";
75+
writePomWithPrettierSteps("src/main/**/*." + suffix,
76+
"<prettier>",
77+
" <prettierVersion>1.16.4</prettierVersion>",
78+
" <config><parser>typescript</parser></config>",
79+
"</prettier>");
80+
run("tsx", suffix);
81+
}
82+
83+
@Test
84+
public void unique_dependency_config() throws Exception {
85+
writePomWithFormatSteps(
86+
"<includes><include>**/*.ts</include></includes>",
87+
"<prettier>",
88+
" <prettierVersion>1.16.4</prettierVersion>",
89+
" <devDependencies><prettier>1.16.4</prettier></devDependencies>",
90+
"</prettier>");
91+
92+
MavenRunner.Result result = mavenRunner().withArguments("spotless:apply").runHasError();
93+
assertThat(result.output()).contains("must specify exactly one configFile or config");
94+
}
95+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
parser: html
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html dir="ltr" lang="en">
3+
<head>
4+
<meta charset="viewport" content="with=device-width" />
5+
<title>Test</title>
6+
<script type="module" src="module.js"></script>
7+
<script type="module2" src="module2.js"></script>
8+
9+
<link rel="stylesheet" type="text/css" href="style.css" />
10+
</head>
11+
12+
<body></body>
13+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!DOCTYPE html>
2+
<html dir="ltr" lang="en">
3+
4+
<head>
5+
<meta
6+
charset="viewport"
7+
content="with=device-width">
8+
<title>Test</title><script type="module" src="module.js"></script>
9+
<script type="module2" src="module2.js"></script>
10+
11+
<link rel="stylesheet" type ="text/css" href="style.css">
12+
</head>
13+
14+
<body>
15+
16+
</body></html>
17+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
parser: typescript
2+
files: "scr/**/*.tsx"
3+
excludeFiles: "target/**"

0 commit comments

Comments
 (0)