Skip to content

Commit 8506a63

Browse files
authored
Merge pull request #283 from simschla/feature/typescript-formatting-using-nodejs-in-j2v8
Adding npm-based formatters typescript-formatter (tsfmt) and prettier
2 parents 8818804 + 60f2bcd commit 8506a63

File tree

78 files changed

+3102
-13
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+3102
-13
lines changed

.ci/ci.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
# Do the Gradle build
44
./gradlew build || exit 1
5+
./gradlew npmTest || exit 1
56

67
if [ "$TRAVIS_REPO_SLUG" == "diffplug/spotless" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_BRANCH" == "master" ]; then
78
# Make sure that all pom are up-to-date

.travis.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
language: java
22
jdk:
3-
- oraclejdk8
3+
- oraclejdk8
4+
env:
5+
- NODE_VERSION="6.10.2"
6+
before_install:
7+
- nvm install $NODE_VERSION
48
install: true
59
script:
610
- ./.ci/ci.sh

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ output = [
1212
[![License Apache](https://img.shields.io/badge/license-apache-brightgreen.svg)](https://tldrlegal.com/license/apache-license-2.0-(apache-2.0))
1313
<!---freshmark /shields -->
1414

15-
Spotless can format &lt;java | kotlin | scala | sql | groovy | markdown | license headers | anything> using &lt;gradle | maven | anything>.
15+
Spotless can format &lt;java | kotlin | scala | sql | groovy | javascript | flow | typeScript | css | scss | less | jsx | vue | graphql | json | yaml | markdown | license headers | anything> using &lt;gradle | maven | anything>.
1616

1717
- [Spotless for Gradle](plugin-gradle)
1818
- [Spotless for Maven](plugin-maven)
@@ -46,6 +46,8 @@ 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}} |',
50+
lib('npm.TsFmtFormatterStep') +'{{yes}} | {{no}} | {{no}} |',
4951
lib('scala.ScalaFmtStep') +'{{yes}} | {{yes}} | {{no}} |',
5052
lib('sql.DBeaverSQLFormatterStep') +'{{yes}} | {{no}} | {{no}} |',
5153
extra('wtp.WtpEclipseFormatterStep') +'{{yes}} | {{yes}} | {{no}} |',
@@ -71,6 +73,8 @@ extra('wtp.WtpEclipseFormatterStep') +'{{yes}} | {{yes}}
7173
| [`java.EclipseFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/java/EclipseFormatterStep.java) | :+1: | :+1: | :white_large_square: |
7274
| [`kotlin.KtLintStep`](lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java) | :+1: | :+1: | :white_large_square: |
7375
| [`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: |
77+
| [`npm.TsFmtFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/TsFmtFormatterStep.java) | :+1: | :white_large_square: | :white_large_square: |
7478
| [`scala.ScalaFmtStep`](lib/src/main/java/com/diffplug/spotless/scala/ScalaFmtStep.java) | :+1: | :+1: | :white_large_square: |
7579
| [`sql.DBeaverSQLFormatterStep`](lib/src/main/java/com/diffplug/spotless/sql/DBeaverSQLFormatterStep.java) | :+1: | :white_large_square: | :white_large_square: |
7680
| [`wtp.WtpEclipseFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/wtp/WtpEclipseFormatterStep.java) | :+1: | :+1: | :white_large_square: |

lib-extra/build.gradle

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,3 @@ dependencies {
2323

2424
// we'll hold the core lib to a high standard
2525
spotbugs { reportLevel = 'low' } // low|medium|high (low = sensitive to even minor mistakes)
26-
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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.npm;
17+
18+
class BlacklistedOptionException extends RuntimeException {
19+
private static final long serialVersionUID = -5876348893394153811L;
20+
21+
public BlacklistedOptionException(String blacklistedOption) {
22+
super("The config option '" + blacklistedOption + "' is not supported.");
23+
}
24+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
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.npm;
17+
18+
import java.io.File;
19+
import java.util.Map;
20+
import java.util.Objects;
21+
import java.util.concurrent.atomic.AtomicBoolean;
22+
23+
class NodeJSWrapper extends ReflectiveObjectWrapper {
24+
25+
public static final String V8_RUNTIME_CLASS = "com.eclipsesource.v8.V8";
26+
public static final String V8_VALUE_CLASS = "com.eclipsesource.v8.V8Value";
27+
28+
public static final String WRAPPED_CLASS = "com.eclipsesource.v8.NodeJS";
29+
30+
private static final AtomicBoolean flagsSet = new AtomicBoolean(false);
31+
32+
public NodeJSWrapper(ClassLoader classLoader) {
33+
super(Reflective.withClassLoader(classLoader),
34+
reflective -> {
35+
final boolean firstRun = flagsSet.compareAndSet(false, true);
36+
if (firstRun) {
37+
reflective.invokeStaticMethod(V8_RUNTIME_CLASS, "setFlags", "-color=false"); // required to run prettier on windows
38+
}
39+
return reflective.invokeStaticMethod(WRAPPED_CLASS, "createNodeJS");
40+
});
41+
}
42+
43+
public V8ObjectWrapper require(File npmModulePath) {
44+
Objects.requireNonNull(npmModulePath);
45+
Object v8Object = invoke("require", npmModulePath);
46+
return new V8ObjectWrapper(reflective(), v8Object);
47+
}
48+
49+
public V8ObjectWrapper createNewObject() {
50+
Object v8Object = reflective().invokeConstructor(V8ObjectWrapper.WRAPPED_CLASS, nodeJsRuntime());
51+
V8ObjectWrapper objectWrapper = new V8ObjectWrapper(reflective(), v8Object);
52+
return objectWrapper;
53+
}
54+
55+
public V8ObjectWrapper createNewObject(Map<String, Object> values) {
56+
Objects.requireNonNull(values);
57+
V8ObjectWrapper obj = createNewObject();
58+
values.forEach(obj::add);
59+
return obj;
60+
}
61+
62+
public V8ArrayWrapper createNewArray(Object... elements) {
63+
final V8ArrayWrapper v8ArrayWrapper = this.createNewArray();
64+
for (Object element : elements) {
65+
v8ArrayWrapper.push(element);
66+
}
67+
return v8ArrayWrapper;
68+
}
69+
70+
public V8ArrayWrapper createNewArray() {
71+
Object v8Array = reflective().invokeConstructor(V8ArrayWrapper.WRAPPED_CLASS, nodeJsRuntime());
72+
V8ArrayWrapper arrayWrapper = new V8ArrayWrapper(reflective(), v8Array);
73+
return arrayWrapper;
74+
}
75+
76+
public V8FunctionWrapper createNewFunction(V8FunctionWrapper.WrappedJavaCallback callback) {
77+
Object v8Function = reflective().invokeConstructor(V8FunctionWrapper.WRAPPED_CLASS,
78+
reflective().typed(
79+
V8_RUNTIME_CLASS,
80+
nodeJsRuntime()),
81+
reflective().typed(
82+
V8FunctionWrapper.CALLBACK_WRAPPED_CLASS,
83+
V8FunctionWrapper.proxiedCallback(callback, reflective())));
84+
V8FunctionWrapper functionWrapper = new V8FunctionWrapper(reflective(), v8Function);
85+
return functionWrapper;
86+
}
87+
88+
public void handleMessage() {
89+
invoke("handleMessage");
90+
}
91+
92+
private Object nodeJsRuntime() {
93+
return invoke("getRuntime");
94+
}
95+
96+
public Object v8NullValue(Object value) {
97+
if (value == null) {
98+
return reflective().staticField(V8_VALUE_CLASS, "NULL");
99+
}
100+
return value;
101+
}
102+
103+
public boolean isV8NullValue(Object v8Object) {
104+
return reflective().staticField(V8_VALUE_CLASS, "NULL") == v8Object;
105+
}
106+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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.npm;
17+
18+
import java.io.Serializable;
19+
20+
class NpmConfig implements Serializable {
21+
22+
private static final long serialVersionUID = -1866722789779160491L;
23+
24+
private final String packageJsonContent;
25+
26+
private final String npmModule;
27+
28+
public NpmConfig(String packageJsonContent, String npmModule) {
29+
this.packageJsonContent = packageJsonContent;
30+
this.npmModule = npmModule;
31+
}
32+
33+
public String getPackageJsonContent() {
34+
return packageJsonContent;
35+
}
36+
37+
public String getNpmModule() {
38+
return npmModule;
39+
}
40+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
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.npm;
17+
18+
import static com.diffplug.spotless.npm.PlatformInfo.OS.WINDOWS;
19+
20+
import java.io.File;
21+
import java.util.Arrays;
22+
import java.util.Optional;
23+
import java.util.function.Supplier;
24+
import java.util.stream.Stream;
25+
26+
/**
27+
* Utility class to resolve an npm binary to be used by npm-based steps.
28+
* Tries to find an npm executable in the following order:
29+
* <ol>
30+
* <li>from System-Property {@code npm.exec} (unverified)</li>
31+
* <li>from Environment-Properties in the following order:</li>
32+
* <ol>
33+
* <li> from NVM_BIN environment variable, if available </li>
34+
* <li> from NVM_SYMLINK environment variable, if available </li>
35+
* <li> from NODE_PATH environment variable, if available </li>
36+
* <li>fallback: PATH environment variable</li>
37+
* </ol>
38+
* </ol>
39+
*/
40+
class NpmExecutableResolver {
41+
42+
private NpmExecutableResolver() {
43+
// no instance
44+
}
45+
46+
static String npmExecutableName() {
47+
String npmName = "npm";
48+
if (PlatformInfo.normalizedOS() == WINDOWS) {
49+
npmName += ".cmd";
50+
}
51+
return npmName;
52+
}
53+
54+
static Supplier<Optional<File>> systemProperty() {
55+
return () -> Optional.ofNullable(System.getProperty("npm.exec"))
56+
.map(File::new);
57+
}
58+
59+
static Supplier<Optional<File>> environmentNvmBin() {
60+
return () -> Optional.ofNullable(System.getenv("NVM_BIN"))
61+
.map(File::new)
62+
.map(binDir -> new File(binDir, npmExecutableName()))
63+
.filter(File::exists)
64+
.filter(File::canExecute);
65+
}
66+
67+
static Supplier<Optional<File>> environmentNvmSymlink() {
68+
return pathListFromEnvironment("NVM_SYMLINK");
69+
}
70+
71+
static Supplier<Optional<File>> environmentNodepath() {
72+
return pathListFromEnvironment("NODE_PATH");
73+
}
74+
75+
static Supplier<Optional<File>> environmentPath() {
76+
return pathListFromEnvironment("PATH");
77+
}
78+
79+
static Optional<File> tryFind() {
80+
return Stream.of(systemProperty(),
81+
environmentNvmBin(),
82+
environmentNvmSymlink(),
83+
environmentNodepath(),
84+
environmentPath())
85+
.map(Supplier::get)
86+
.filter(Optional::isPresent)
87+
.map(Optional::get)
88+
.findFirst();
89+
}
90+
91+
private static Supplier<Optional<File>> pathListFromEnvironment(String environmentPathListName) {
92+
return () -> {
93+
String pathList = System.getenv(environmentPathListName);
94+
if (pathList != null) {
95+
return Arrays.stream(pathList.split(System.getProperty("path.separator", ":")))
96+
.map(File::new)
97+
.map(dir -> dir.getName().equalsIgnoreCase("node_modules") ? dir.getParentFile() : dir)
98+
.map(dir -> new File(dir, npmExecutableName()))
99+
.filter(File::exists)
100+
.filter(File::canExecute)
101+
.findFirst();
102+
103+
}
104+
return Optional.empty();
105+
};
106+
}
107+
108+
}

0 commit comments

Comments
 (0)