Skip to content

Commit

Permalink
Merge pull request #283 from simschla/feature/typescript-formatting-u…
Browse files Browse the repository at this point in the history
…sing-nodejs-in-j2v8

Adding npm-based formatters typescript-formatter (tsfmt) and prettier
  • Loading branch information
nedtwigg authored Sep 24, 2018
2 parents 8818804 + 60f2bcd commit 8506a63
Show file tree
Hide file tree
Showing 78 changed files with 3,102 additions and 13 deletions.
1 change: 1 addition & 0 deletions .ci/ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# Do the Gradle build
./gradlew build || exit 1
./gradlew npmTest || exit 1

if [ "$TRAVIS_REPO_SLUG" == "diffplug/spotless" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_BRANCH" == "master" ]; then
# Make sure that all pom are up-to-date
Expand Down
6 changes: 5 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
language: java
jdk:
- oraclejdk8
- oraclejdk8
env:
- NODE_VERSION="6.10.2"
before_install:
- nvm install $NODE_VERSION
install: true
script:
- ./.ci/ci.sh
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ output = [
[![License Apache](https://img.shields.io/badge/license-apache-brightgreen.svg)](https://tldrlegal.com/license/apache-license-2.0-(apache-2.0))
<!---freshmark /shields -->

Spotless can format &lt;java | kotlin | scala | sql | groovy | markdown | license headers | anything> using &lt;gradle | maven | anything>.
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>.

- [Spotless for Gradle](plugin-gradle)
- [Spotless for Maven](plugin-maven)
Expand Down Expand Up @@ -46,6 +46,8 @@ lib('java.RemoveUnusedImportsStep') +'{{yes}} | {{yes}}
extra('java.EclipseFormatterStep') +'{{yes}} | {{yes}} | {{no}} |',
lib('kotlin.KtLintStep') +'{{yes}} | {{yes}} | {{no}} |',
lib('markdown.FreshMarkStep') +'{{yes}} | {{no}} | {{no}} |',
lib('npm.PrettierFormatterStep') +'{{yes}} | {{no}} | {{no}} |',
lib('npm.TsFmtFormatterStep') +'{{yes}} | {{no}} | {{no}} |',
lib('scala.ScalaFmtStep') +'{{yes}} | {{yes}} | {{no}} |',
lib('sql.DBeaverSQLFormatterStep') +'{{yes}} | {{no}} | {{no}} |',
extra('wtp.WtpEclipseFormatterStep') +'{{yes}} | {{yes}} | {{no}} |',
Expand All @@ -71,6 +73,8 @@ extra('wtp.WtpEclipseFormatterStep') +'{{yes}} | {{yes}}
| [`java.EclipseFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/java/EclipseFormatterStep.java) | :+1: | :+1: | :white_large_square: |
| [`kotlin.KtLintStep`](lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java) | :+1: | :+1: | :white_large_square: |
| [`markdown.FreshMarkStep`](lib/src/main/java/com/diffplug/spotless/markdown/FreshMarkStep.java) | :+1: | :white_large_square: | :white_large_square: |
| [`npm.PrettierFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/PrettierFormatterStep.java) | :+1: | :white_large_square: | :white_large_square: |
| [`npm.TsFmtFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/TsFmtFormatterStep.java) | :+1: | :white_large_square: | :white_large_square: |
| [`scala.ScalaFmtStep`](lib/src/main/java/com/diffplug/spotless/scala/ScalaFmtStep.java) | :+1: | :+1: | :white_large_square: |
| [`sql.DBeaverSQLFormatterStep`](lib/src/main/java/com/diffplug/spotless/sql/DBeaverSQLFormatterStep.java) | :+1: | :white_large_square: | :white_large_square: |
| [`wtp.WtpEclipseFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/wtp/WtpEclipseFormatterStep.java) | :+1: | :+1: | :white_large_square: |
Expand Down
1 change: 0 additions & 1 deletion lib-extra/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,3 @@ dependencies {

// we'll hold the core lib to a high standard
spotbugs { reportLevel = 'low' } // low|medium|high (low = sensitive to even minor mistakes)

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* 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.npm;

class BlacklistedOptionException extends RuntimeException {
private static final long serialVersionUID = -5876348893394153811L;

public BlacklistedOptionException(String blacklistedOption) {
super("The config option '" + blacklistedOption + "' is not supported.");
}
}
106 changes: 106 additions & 0 deletions lib/src/main/java/com/diffplug/spotless/npm/NodeJSWrapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* 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.npm;

import java.io.File;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;

class NodeJSWrapper extends ReflectiveObjectWrapper {

public static final String V8_RUNTIME_CLASS = "com.eclipsesource.v8.V8";
public static final String V8_VALUE_CLASS = "com.eclipsesource.v8.V8Value";

public static final String WRAPPED_CLASS = "com.eclipsesource.v8.NodeJS";

private static final AtomicBoolean flagsSet = new AtomicBoolean(false);

public NodeJSWrapper(ClassLoader classLoader) {
super(Reflective.withClassLoader(classLoader),
reflective -> {
final boolean firstRun = flagsSet.compareAndSet(false, true);
if (firstRun) {
reflective.invokeStaticMethod(V8_RUNTIME_CLASS, "setFlags", "-color=false"); // required to run prettier on windows
}
return reflective.invokeStaticMethod(WRAPPED_CLASS, "createNodeJS");
});
}

public V8ObjectWrapper require(File npmModulePath) {
Objects.requireNonNull(npmModulePath);
Object v8Object = invoke("require", npmModulePath);
return new V8ObjectWrapper(reflective(), v8Object);
}

public V8ObjectWrapper createNewObject() {
Object v8Object = reflective().invokeConstructor(V8ObjectWrapper.WRAPPED_CLASS, nodeJsRuntime());
V8ObjectWrapper objectWrapper = new V8ObjectWrapper(reflective(), v8Object);
return objectWrapper;
}

public V8ObjectWrapper createNewObject(Map<String, Object> values) {
Objects.requireNonNull(values);
V8ObjectWrapper obj = createNewObject();
values.forEach(obj::add);
return obj;
}

public V8ArrayWrapper createNewArray(Object... elements) {
final V8ArrayWrapper v8ArrayWrapper = this.createNewArray();
for (Object element : elements) {
v8ArrayWrapper.push(element);
}
return v8ArrayWrapper;
}

public V8ArrayWrapper createNewArray() {
Object v8Array = reflective().invokeConstructor(V8ArrayWrapper.WRAPPED_CLASS, nodeJsRuntime());
V8ArrayWrapper arrayWrapper = new V8ArrayWrapper(reflective(), v8Array);
return arrayWrapper;
}

public V8FunctionWrapper createNewFunction(V8FunctionWrapper.WrappedJavaCallback callback) {
Object v8Function = reflective().invokeConstructor(V8FunctionWrapper.WRAPPED_CLASS,
reflective().typed(
V8_RUNTIME_CLASS,
nodeJsRuntime()),
reflective().typed(
V8FunctionWrapper.CALLBACK_WRAPPED_CLASS,
V8FunctionWrapper.proxiedCallback(callback, reflective())));
V8FunctionWrapper functionWrapper = new V8FunctionWrapper(reflective(), v8Function);
return functionWrapper;
}

public void handleMessage() {
invoke("handleMessage");
}

private Object nodeJsRuntime() {
return invoke("getRuntime");
}

public Object v8NullValue(Object value) {
if (value == null) {
return reflective().staticField(V8_VALUE_CLASS, "NULL");
}
return value;
}

public boolean isV8NullValue(Object v8Object) {
return reflective().staticField(V8_VALUE_CLASS, "NULL") == v8Object;
}
}
40 changes: 40 additions & 0 deletions lib/src/main/java/com/diffplug/spotless/npm/NpmConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* 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.npm;

import java.io.Serializable;

class NpmConfig implements Serializable {

private static final long serialVersionUID = -1866722789779160491L;

private final String packageJsonContent;

private final String npmModule;

public NpmConfig(String packageJsonContent, String npmModule) {
this.packageJsonContent = packageJsonContent;
this.npmModule = npmModule;
}

public String getPackageJsonContent() {
return packageJsonContent;
}

public String getNpmModule() {
return npmModule;
}
}
108 changes: 108 additions & 0 deletions lib/src/main/java/com/diffplug/spotless/npm/NpmExecutableResolver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* 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.npm;

import static com.diffplug.spotless.npm.PlatformInfo.OS.WINDOWS;

import java.io.File;
import java.util.Arrays;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.Stream;

/**
* Utility class to resolve an npm binary to be used by npm-based steps.
* Tries to find an npm executable in the following order:
* <ol>
* <li>from System-Property {@code npm.exec} (unverified)</li>
* <li>from Environment-Properties in the following order:</li>
* <ol>
* <li> from NVM_BIN environment variable, if available </li>
* <li> from NVM_SYMLINK environment variable, if available </li>
* <li> from NODE_PATH environment variable, if available </li>
* <li>fallback: PATH environment variable</li>
* </ol>
* </ol>
*/
class NpmExecutableResolver {

private NpmExecutableResolver() {
// no instance
}

static String npmExecutableName() {
String npmName = "npm";
if (PlatformInfo.normalizedOS() == WINDOWS) {
npmName += ".cmd";
}
return npmName;
}

static Supplier<Optional<File>> systemProperty() {
return () -> Optional.ofNullable(System.getProperty("npm.exec"))
.map(File::new);
}

static Supplier<Optional<File>> environmentNvmBin() {
return () -> Optional.ofNullable(System.getenv("NVM_BIN"))
.map(File::new)
.map(binDir -> new File(binDir, npmExecutableName()))
.filter(File::exists)
.filter(File::canExecute);
}

static Supplier<Optional<File>> environmentNvmSymlink() {
return pathListFromEnvironment("NVM_SYMLINK");
}

static Supplier<Optional<File>> environmentNodepath() {
return pathListFromEnvironment("NODE_PATH");
}

static Supplier<Optional<File>> environmentPath() {
return pathListFromEnvironment("PATH");
}

static Optional<File> tryFind() {
return Stream.of(systemProperty(),
environmentNvmBin(),
environmentNvmSymlink(),
environmentNodepath(),
environmentPath())
.map(Supplier::get)
.filter(Optional::isPresent)
.map(Optional::get)
.findFirst();
}

private static Supplier<Optional<File>> pathListFromEnvironment(String environmentPathListName) {
return () -> {
String pathList = System.getenv(environmentPathListName);
if (pathList != null) {
return Arrays.stream(pathList.split(System.getProperty("path.separator", ":")))
.map(File::new)
.map(dir -> dir.getName().equalsIgnoreCase("node_modules") ? dir.getParentFile() : dir)
.map(dir -> new File(dir, npmExecutableName()))
.filter(File::exists)
.filter(File::canExecute)
.findFirst();

}
return Optional.empty();
};
}

}
Loading

0 comments on commit 8506a63

Please sign in to comment.