Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 8cbbb27

Browse files
committedJun 12, 2020
add support for prettier-plugins to maven-builds and document in README
1 parent 8eff924 commit 8cbbb27

File tree

3 files changed

+137
-31
lines changed

3 files changed

+137
-31
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

+43-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

@@ -35,6 +35,9 @@ public class Prettier implements FormatterStepFactory {
3535
@Parameter
3636
private Map<String, String> devDependencies;
3737

38+
@Parameter
39+
private Properties devDependencyProperties;
40+
3841
@Parameter
3942
private Map<String, String> config;
4043

@@ -48,17 +51,17 @@ public class Prettier implements FormatterStepFactory {
4851
public FormatterStep newFormatterStep(FormatterStepConfig stepConfig) {
4952

5053
// check if config is only setup in one way
51-
if (this.prettierVersion != null && this.devDependencies != null) {
54+
if (moreThanOneNonNull(this.prettierVersion, this.devDependencies, this.devDependencyProperties)) {
5255
throw onlyOneConfig();
5356
}
54-
55-
// set dev dependencies
5657
if (devDependencies == null) {
57-
if (prettierVersion == null || prettierVersion.isEmpty()) {
58-
devDependencies = PrettierFormatterStep.defaultDevDependencies();
59-
} else {
60-
devDependencies = PrettierFormatterStep.defaultDevDependenciesWithPrettier(prettierVersion);
61-
}
58+
devDependencies = PrettierFormatterStep.defaultDevDependencies(); // fallback
59+
}
60+
61+
if (prettierVersion != null && !prettierVersion.isEmpty()) {
62+
this.devDependencies = PrettierFormatterStep.defaultDevDependenciesWithPrettier(prettierVersion);
63+
} else if (devDependencyProperties != null) {
64+
this.devDependencies = dependencyPropertiesAsMap();
6265
}
6366

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

7477
Map<String, Object> configInline;
7578
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-
}
79+
configInline = config.entrySet().stream()
80+
.map(entry -> {
81+
try {
82+
Integer value = Integer.parseInt(entry.getValue());
83+
return new AbstractMap.SimpleEntry<>(entry.getKey(), value);
84+
} catch (NumberFormatException ignore) {
85+
// ignored
86+
}
87+
if (Boolean.TRUE.toString().equalsIgnoreCase(entry.getValue()) || Boolean.FALSE.toString().equalsIgnoreCase(entry.getValue())) {
88+
return new AbstractMap.SimpleEntry<>(entry.getKey(), Boolean.parseBoolean(entry.getValue()));
89+
}
90+
return entry;
91+
})
92+
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a, LinkedHashMap::new));
8993
} else {
9094
configInline = null;
9195
}
@@ -96,7 +100,21 @@ public FormatterStep newFormatterStep(FormatterStepConfig stepConfig) {
96100
return PrettierFormatterStep.create(devDependencies, stepConfig.getProvisioner(), buildDir, npm, prettierConfig);
97101
}
98102

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

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

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

0 commit comments

Comments
 (0)
Please sign in to comment.