Skip to content

Commit dd6f120

Browse files
committed
add support for prettier-plugins to maven-builds and document in README
1 parent 8eff924 commit dd6f120

File tree

3 files changed

+141
-32
lines changed

3 files changed

+141
-32
lines changed

plugin-maven/README.md

+68-6
Original file line numberDiff line numberDiff line change
@@ -287,13 +287,21 @@ To use prettier, you first have to specify the files that you want it to apply t
287287
</includes>
288288

289289
<prettier>
290-
<!-- Specify either simple prettier version (1.19.0 is max supported,
291-
which is also default) or whole devDependencies -->
290+
<!-- Specify at most one of the following 3 configs: either 'prettierVersion' (2.0.5 is default), 'devDependencies' or 'devDependencyProperties' -->
292291
<prettierVersion>1.19.0</prettierVersion>
293292
<devDependencies>
294293
<prettier>1.19.0</prettier>
295294
</devDependencies>
296-
295+
<devDependencyProperties>
296+
<property>
297+
<name>prettier</name>
298+
<value>2.0.5</value>
299+
</property>
300+
<property>
301+
<name>@prettier/plugin-php</name> <!-- this could not be written in the simpler to write 'devDependencies' element. -->
302+
<value>0.14.2</value>
303+
</property>
304+
</devDependencyProperties>
297305
<!-- Specify config file and/or inline config -->
298306
<configFile>${basedir}/path/to/configfile</configFile>
299307
<config>
@@ -315,6 +323,62 @@ Supported config file variants are documented on [prettier.io](https://prettier.
315323

316324
To apply prettier to more kinds of files, just add more formats.
317325

326+
<a name="prettier-plugins"></a>
327+
### Using plugins for prettier
328+
329+
Since spotless uses the actual npm prettier package behind the scenes, it is possible to use prettier with
330+
[plugins](https://prettier.io/docs/en/plugins.html#official-plugins) or [community-plugins](https://www.npmjs.com/search?q=prettier-plugin) in order to support even more file types.
331+
332+
```xml
333+
<configuration>
334+
<formats>
335+
<!-- prettier with java-plugin -->
336+
<format>
337+
<includes>
338+
<include>src/*/java/**/*.java</include>
339+
</includes>
340+
341+
<prettier>
342+
<devDependencies>
343+
<prettier>2.0.5</prettier>
344+
<prettier-plugin-java>0.8.0</prettier-plugin-java>
345+
</devDependencies>
346+
<config>
347+
<tabWidth>4</tabWidth>
348+
<parser>java</parser>
349+
</config>
350+
</prettier>
351+
</format>
352+
353+
<!-- prettier with php-plugin -->
354+
<format>
355+
<includes>
356+
<include>src/**/*.php</include>
357+
</includes>
358+
359+
<prettier>
360+
<!-- use the devDependencyProperties writing style when the property-names are not well-formed such as @prettier/plugin-php -->
361+
<devDependencyProperties>
362+
<property>
363+
<name>prettier</name>
364+
<value>2.0.5</value>
365+
</property>
366+
<property>
367+
<name>@prettier/plugin-php</name>
368+
<value>0.14.2</value>
369+
</property>
370+
</devDependencyProperties>
371+
<config>
372+
<tabWidth>3</tabWidth>
373+
<parser>php</parser>
374+
</config>
375+
</prettier>
376+
</format>
377+
378+
</formats>
379+
</configuration>
380+
```
381+
318382
### Prerequisite: prettier requires a working NodeJS version
319383

320384
Prettier, like tsfmt, is based on NodeJS, so to use it, a working NodeJS installation (especially npm) is required on the host running spotless.
@@ -326,9 +390,7 @@ Spotless will try to auto-discover an npm installation. If that is not working f
326390
...
327391
```
328392

329-
Spotless uses npm to install necessary packages locally. It runs prettier using [J2V8](https://github.com/eclipsesource/J2V8) internally after that.
330-
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
331-
use ES6 feature and that needs a newer J2V8 version.
393+
Spotless uses npm to install necessary packages and to run the prettier formatter after that.
332394

333395
<a name="format"></a>
334396

plugin-maven/src/main/java/com/diffplug/spotless/maven/generic/Prettier.java

+45-25
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016 DiffPlug
2+
* Copyright 2016-2020 DiffPlug
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,8 +16,8 @@
1616
package com.diffplug.spotless.maven.generic;
1717

1818
import java.io.File;
19-
import java.util.LinkedHashMap;
20-
import java.util.Map;
19+
import java.util.*;
20+
import java.util.stream.Collectors;
2121

2222
import org.apache.maven.plugins.annotations.Parameter;
2323

@@ -29,12 +29,17 @@
2929

3030
public class Prettier implements FormatterStepFactory {
3131

32+
public static final String ERROR_MESSAGE_ONLY_ONE_CONFIG = "must specify exactly one prettierVersion, devDependencies or devDependencyProperties";
33+
3234
@Parameter
3335
private String prettierVersion;
3436

3537
@Parameter
3638
private Map<String, String> devDependencies;
3739

40+
@Parameter
41+
private Properties devDependencyProperties;
42+
3843
@Parameter
3944
private Map<String, String> config;
4045

@@ -48,17 +53,17 @@ public class Prettier implements FormatterStepFactory {
4853
public FormatterStep newFormatterStep(FormatterStepConfig stepConfig) {
4954

5055
// check if config is only setup in one way
51-
if (this.prettierVersion != null && this.devDependencies != null) {
56+
if (moreThanOneNonNull(this.prettierVersion, this.devDependencies, this.devDependencyProperties)) {
5257
throw onlyOneConfig();
5358
}
54-
55-
// set dev dependencies
5659
if (devDependencies == null) {
57-
if (prettierVersion == null || prettierVersion.isEmpty()) {
58-
devDependencies = PrettierFormatterStep.defaultDevDependencies();
59-
} else {
60-
devDependencies = PrettierFormatterStep.defaultDevDependenciesWithPrettier(prettierVersion);
61-
}
60+
devDependencies = PrettierFormatterStep.defaultDevDependencies(); // fallback
61+
}
62+
63+
if (prettierVersion != null && !prettierVersion.isEmpty()) {
64+
this.devDependencies = PrettierFormatterStep.defaultDevDependenciesWithPrettier(prettierVersion);
65+
} else if (devDependencyProperties != null) {
66+
this.devDependencies = dependencyPropertiesAsMap();
6267
}
6368

6469
File npm = npmExecutable != null ? stepConfig.getFileLocator().locateFile(npmExecutable) : null;
@@ -73,19 +78,20 @@ public FormatterStep newFormatterStep(FormatterStepConfig stepConfig) {
7378

7479
Map<String, Object> configInline;
7580
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-
}
81+
configInline = config.entrySet().stream()
82+
.map(entry -> {
83+
try {
84+
Integer value = Integer.parseInt(entry.getValue());
85+
return new AbstractMap.SimpleEntry<>(entry.getKey(), value);
86+
} catch (NumberFormatException ignore) {
87+
// ignored
88+
}
89+
if (Boolean.TRUE.toString().equalsIgnoreCase(entry.getValue()) || Boolean.FALSE.toString().equalsIgnoreCase(entry.getValue())) {
90+
return new AbstractMap.SimpleEntry<>(entry.getKey(), Boolean.parseBoolean(entry.getValue()));
91+
}
92+
return entry;
93+
})
94+
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a, LinkedHashMap::new));
8995
} else {
9096
configInline = null;
9197
}
@@ -96,7 +102,21 @@ public FormatterStep newFormatterStep(FormatterStepConfig stepConfig) {
96102
return PrettierFormatterStep.create(devDependencies, stepConfig.getProvisioner(), buildDir, npm, prettierConfig);
97103
}
98104

105+
private boolean moreThanOneNonNull(Object... objects) {
106+
return Arrays.stream(objects)
107+
.filter(Objects::nonNull)
108+
.filter(o -> !(o instanceof String) || !((String) o).isEmpty()) // if it is a string, it should not be empty
109+
.count() > 1;
110+
}
111+
112+
private Map<String, String> dependencyPropertiesAsMap() {
113+
return this.devDependencyProperties.stringPropertyNames()
114+
.stream()
115+
.map(name -> new AbstractMap.SimpleEntry<>(name, this.devDependencyProperties.getProperty(name)))
116+
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
117+
}
118+
99119
private static IllegalArgumentException onlyOneConfig() {
100-
return new IllegalArgumentException("must specify exactly one configFile or config");
120+
return new IllegalArgumentException(ERROR_MESSAGE_ONLY_ONE_CONFIG);
101121
}
102122
}

plugin-maven/src/test/java/com/diffplug/spotless/maven/prettier/PrettierFormatStepTest.java

+28-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import java.io.IOException;
2121

22+
import com.diffplug.spotless.maven.generic.Prettier;
2223
import org.junit.Test;
2324
import org.junit.experimental.categories.Category;
2425

@@ -93,6 +94,32 @@ public void unique_dependency_config() throws Exception {
9394
"</prettier>");
9495

9596
MavenRunner.Result result = mavenRunner().withArguments("spotless:apply").runHasError();
96-
assertThat(result.output()).contains("must specify exactly one configFile or config");
97+
assertThat(result.output()).contains(Prettier.ERROR_MESSAGE_ONLY_ONE_CONFIG);
98+
}
99+
100+
@Test
101+
public void custom_plugin() throws Exception {
102+
writePomWithFormatSteps(
103+
"<includes><include>php-example.php</include></includes>",
104+
"<prettier>",
105+
" <devDependencyProperties>",
106+
" <property>",
107+
" <name>prettier</name>",
108+
" <value>2.0.5</value>",
109+
" </property>",
110+
" <property>",
111+
" <name>@prettier/plugin-php</name>",
112+
" <value>0.14.2</value>",
113+
" </property>",
114+
" </devDependencyProperties>",
115+
" <config>",
116+
" <tabWidth>3</tabWidth>",
117+
" <parser>php</parser>",
118+
" </config>",
119+
"</prettier>");
120+
121+
setFile("php-example.php").toResource("npm/prettier/plugins/php.dirty");
122+
mavenRunner().withArguments("spotless:apply").runNoError();
123+
assertFile("php-example.php").sameAsResource("npm/prettier/plugins/php.clean");
97124
}
98125
}

0 commit comments

Comments
 (0)